mirror of
https://github.com/wasp-lang/wasp.git
synced 2024-11-27 14:55:20 +03:00
Martech (#1319)
* Martech * Record zip downloads * fix --------- Co-authored-by: Martin Sosic <sosic.martin@gmail.com> Co-authored-by: Martin Šošić <Martinsos@users.noreply.github.com>
This commit is contained in:
parent
f605726712
commit
bcbd138244
@ -75,6 +75,11 @@ action startGeneratingNewApp {
|
||||
]
|
||||
}
|
||||
|
||||
action registerZipDownload {
|
||||
fn: import { registerZipDownload } from "@server/operations.js",
|
||||
entities: [Project]
|
||||
}
|
||||
|
||||
query getAppGenerationResult {
|
||||
fn: import { getAppGenerationResult } from "@server/operations.js",
|
||||
entities: [
|
||||
@ -116,6 +121,8 @@ entity Project {=psl
|
||||
creativityLevel String @default("balanced")
|
||||
createdAt DateTime @default(now())
|
||||
status String @default("pending")
|
||||
referrer String @default("unknown")
|
||||
zipDownloadedAt DateTime?
|
||||
userId Int?
|
||||
user User? @relation(fields: [userId], references: [id])
|
||||
files File[]
|
||||
|
2
wasp-ai/migrations/20230713120447_asdf/migration.sql
Normal file
2
wasp-ai/migrations/20230713120447_asdf/migration.sql
Normal file
@ -0,0 +1,2 @@
|
||||
-- AlterTable
|
||||
ALTER TABLE "Project" ADD COLUMN "referrer" TEXT NOT NULL DEFAULT 'unknown';
|
2
wasp-ai/migrations/20230713123032_zip/migration.sql
Normal file
2
wasp-ai/migrations/20230713123032_zip/migration.sql
Normal file
@ -0,0 +1,2 @@
|
||||
-- AlterTable
|
||||
ALTER TABLE "Project" ADD COLUMN "zipDownloadedAt" TIMESTAMP(3);
|
@ -1,9 +1,10 @@
|
||||
import { useEffect, useMemo } from "react";
|
||||
import { useLocation } from "react-router-dom";
|
||||
import { useHistory, useLocation } from "react-router-dom";
|
||||
import Prism from "prismjs";
|
||||
import "prismjs/components/prism-json";
|
||||
import addWaspLangauge from "./prism/wasp";
|
||||
import addPrismaLanguage from "./prism/prisma";
|
||||
import { saveReferrerToLocalStorage } from "./storage";
|
||||
|
||||
import "./Main.css";
|
||||
|
||||
@ -11,18 +12,26 @@ addPrismaLanguage(Prism);
|
||||
addWaspLangauge(Prism);
|
||||
|
||||
export function RootComponent({ children }) {
|
||||
function recordAndDeleteReferrer() {
|
||||
const urlParams = new URLSearchParams(window.location.search);
|
||||
saveReferrerToLocalStorage(urlParams);
|
||||
history.replace({
|
||||
search: "",
|
||||
});
|
||||
}
|
||||
|
||||
// const { isAlreadyShown } = useWelcomeDialog();
|
||||
// const [isDialogOpen, setIsDialogOpen] = useState(!isAlreadyShown);
|
||||
const history = useHistory();
|
||||
const location = useLocation();
|
||||
|
||||
const shouldDisplayTopBanner = useMemo(() => {
|
||||
return !(location.pathname.startsWith("/result/"));
|
||||
}, [location]);
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
recordAndDeleteReferrer();
|
||||
const script = document.createElement("script");
|
||||
|
||||
script.src = "https://buttons.github.io/buttons.js"; // <----- add your script url
|
||||
script.async = true;
|
||||
|
||||
@ -88,7 +97,7 @@ export function RootComponent({ children }) {
|
||||
rel="noopener noreferrer"
|
||||
className="text-sky-500 hover:text-sky-600"
|
||||
>
|
||||
Wasp {'=}'}
|
||||
Wasp {"=}"}
|
||||
</a>
|
||||
</p>
|
||||
<p className="text-center text-slate-500 text-sm mt-2">
|
||||
|
@ -8,6 +8,7 @@ import { availableColors } from "../components/Color";
|
||||
import { Faq } from "../components/Faq";
|
||||
import { exampleIdeas } from "../examples";
|
||||
import { PiMagicWandDuotone } from "react-icons/pi";
|
||||
import { readReferrerFromLocalStorage } from "../storage";
|
||||
|
||||
const MainPage = () => {
|
||||
const [appName, setAppName] = useState("");
|
||||
@ -74,7 +75,9 @@ const MainPage = () => {
|
||||
message: "Starting...",
|
||||
});
|
||||
try {
|
||||
const referrer = readReferrerFromLocalStorage();
|
||||
const appId = await startGeneratingNewApp({
|
||||
referrer,
|
||||
appName,
|
||||
appDesc,
|
||||
appPrimaryColor: appPrimaryColor.name,
|
||||
|
@ -1,6 +1,7 @@
|
||||
import { useState, useEffect, useMemo } from "react";
|
||||
import getAppGenerationResult from "@wasp/queries/getAppGenerationResult";
|
||||
import startGeneratingNewApp from "@wasp/actions/startGeneratingNewApp";
|
||||
import registerZipDownload from "@wasp/actions/registerZipDownload";
|
||||
import { useQuery } from "@wasp/queries";
|
||||
import { CodeHighlight } from "../components/CodeHighlight";
|
||||
import { FileTree } from "../components/FileTree";
|
||||
@ -146,14 +147,21 @@ export const ResultPage = () => {
|
||||
setIsMobileFileBrowserOpen(false);
|
||||
}, [activeFilePath]);
|
||||
|
||||
function downloadZip() {
|
||||
async function downloadZip() {
|
||||
const zipName = getUniqueZipName();
|
||||
createFilesAndDownloadZip(files, zipName);
|
||||
registerZipDownload({
|
||||
appId: appGenerationResult?.project?.id,
|
||||
});
|
||||
}
|
||||
|
||||
function getUniqueZipName() {
|
||||
const safeAppName = appGenerationResult?.project?.name.replace(
|
||||
/[^a-zA-Z0-9]/g,
|
||||
"_"
|
||||
);
|
||||
const randomSuffix = Math.random().toString(36).substring(2, 7);
|
||||
const appNameWithSuffix = `${safeAppName}-${randomSuffix}`;
|
||||
createFilesAndDownloadZip(files, appNameWithSuffix);
|
||||
return `${safeAppName}-${randomSuffix}`;
|
||||
}
|
||||
|
||||
async function retry() {
|
||||
|
14
wasp-ai/src/client/storage.ts
Normal file
14
wasp-ai/src/client/storage.ts
Normal file
@ -0,0 +1,14 @@
|
||||
const REFERRER_KEY = "ref";
|
||||
const UNKNOWN_REFERRER = "unknown";
|
||||
|
||||
export function saveReferrerToLocalStorage(urlParams: URLSearchParams) {
|
||||
const newRefValue = urlParams.get(REFERRER_KEY) ?? UNKNOWN_REFERRER;
|
||||
const oldRefValue = localStorage.getItem(REFERRER_KEY);
|
||||
if (oldRefValue === null) {
|
||||
localStorage.setItem(REFERRER_KEY, newRefValue);
|
||||
}
|
||||
}
|
||||
|
||||
export function readReferrerFromLocalStorage() {
|
||||
return localStorage.getItem(REFERRER_KEY) ?? UNKNOWN_REFERRER;
|
||||
}
|
@ -1,10 +1,14 @@
|
||||
import { StartGeneratingNewApp } from "@wasp/actions/types";
|
||||
import {
|
||||
RegisterZipDownload,
|
||||
StartGeneratingNewApp,
|
||||
} from "@wasp/actions/types";
|
||||
import { GetAppGenerationResult, GetStats } from "@wasp/queries/types";
|
||||
import HttpError from "@wasp/core/HttpError.js";
|
||||
import { checkPendingAppsJob } from "@wasp/jobs/checkPendingAppsJob.js";
|
||||
|
||||
export const startGeneratingNewApp: StartGeneratingNewApp<
|
||||
{
|
||||
referrer: string;
|
||||
appName: string;
|
||||
appDesc: string;
|
||||
appPrimaryColor: string;
|
||||
@ -42,6 +46,7 @@ export const startGeneratingNewApp: StartGeneratingNewApp<
|
||||
primaryColor: args.appPrimaryColor,
|
||||
authMethod: args.appAuthMethod,
|
||||
creativityLevel: args.appCreativityLevel,
|
||||
referrer: args.referrer,
|
||||
...optionalUser,
|
||||
},
|
||||
});
|
||||
@ -53,6 +58,24 @@ export const startGeneratingNewApp: StartGeneratingNewApp<
|
||||
return appId;
|
||||
};
|
||||
|
||||
export const registerZipDownload: RegisterZipDownload<{
|
||||
appId: string;
|
||||
}> = async (args, context) => {
|
||||
const appId = args.appId;
|
||||
try {
|
||||
await context.entities.Project.update({
|
||||
where: { id: appId },
|
||||
data: {
|
||||
zipDownloadedAt: new Date(),
|
||||
},
|
||||
});
|
||||
} catch (e) {
|
||||
if (e.name === "NotFoundError") {
|
||||
throw new HttpError(404, "App not found.");
|
||||
} else { throw e; }
|
||||
}
|
||||
};
|
||||
|
||||
export const getAppGenerationResult = (async (args, context) => {
|
||||
const appId = args.appId;
|
||||
const { Project } = context.entities;
|
||||
@ -84,7 +107,9 @@ export const getAppGenerationResult = (async (args, context) => {
|
||||
numberOfProjectsAheadInQueue,
|
||||
};
|
||||
} catch (e) {
|
||||
throw new HttpError(404, "App not found.");
|
||||
if (e.name === "NotFoundError") {
|
||||
throw new HttpError(404, "App not found.");
|
||||
} else { throw e; }
|
||||
}
|
||||
}) satisfies GetAppGenerationResult<{
|
||||
appId: string;
|
||||
|
Loading…
Reference in New Issue
Block a user