mirror of
https://github.com/formbricks/formbricks.git
synced 2026-05-07 11:20:39 -05:00
use swr to autosave in builder
This commit is contained in:
@@ -1,56 +1,37 @@
|
||||
import Link from "next/link";
|
||||
import { useCallback, useEffect, useState } from "react";
|
||||
import { v4 as uuidv4 } from "uuid";
|
||||
import { persistNoCodeForm, useNoCodeForm } from "../../lib/noCodeForm";
|
||||
import Loading from "../Loading";
|
||||
import Page from "./Page";
|
||||
import UsageIntro from "./UsageIntro";
|
||||
import LoadingModal from "../LoadingModal";
|
||||
import Link from "next/link";
|
||||
|
||||
export default function Builder({ formId }) {
|
||||
const { noCodeForm, isLoadingNoCodeForm, mutateNoCodeForm } =
|
||||
useNoCodeForm(formId);
|
||||
const [pagesDraft, setPagesDraft] = useState([]);
|
||||
const [isInitialized, setIsInitialized] = useState(false);
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
|
||||
// autosave
|
||||
useEffect(() => {
|
||||
if (isInitialized) {
|
||||
save();
|
||||
}
|
||||
}, [pagesDraft, isInitialized]);
|
||||
|
||||
const save = async () => {
|
||||
setIsLoading(true);
|
||||
const addPage = useCallback(async () => {
|
||||
const newNoCodeForm = JSON.parse(JSON.stringify(noCodeForm));
|
||||
newNoCodeForm.pagesDraft = pagesDraft;
|
||||
await persistNoCodeForm(newNoCodeForm);
|
||||
mutateNoCodeForm(newNoCodeForm);
|
||||
setIsLoading(false);
|
||||
};
|
||||
|
||||
const addPage = useCallback(() => {
|
||||
const newPagesDraft = JSON.parse(JSON.stringify(pagesDraft));
|
||||
newPagesDraft.push({
|
||||
newNoCodeForm.pagesDraft.push({
|
||||
id: uuidv4(),
|
||||
blocks: [],
|
||||
});
|
||||
setPagesDraft(newPagesDraft);
|
||||
}, [pagesDraft, setPagesDraft]);
|
||||
await persistNoCodeForm(newNoCodeForm);
|
||||
mutateNoCodeForm(newNoCodeForm);
|
||||
}, [noCodeForm, mutateNoCodeForm]);
|
||||
|
||||
const deletePage = (pageIdx) => {
|
||||
const newPagesDraft = JSON.parse(JSON.stringify(pagesDraft));
|
||||
newPagesDraft.splice(pageIdx, 1);
|
||||
setPagesDraft(newPagesDraft);
|
||||
const deletePage = async (pageIdx) => {
|
||||
const newNoCodeForm = JSON.parse(JSON.stringify(noCodeForm));
|
||||
newNoCodeForm.pagesDraft.splice(pageIdx, 1);
|
||||
await persistNoCodeForm(newNoCodeForm);
|
||||
mutateNoCodeForm(newNoCodeForm);
|
||||
};
|
||||
|
||||
const initPages = useCallback(() => {
|
||||
const initPages = useCallback(async () => {
|
||||
if (!isLoadingNoCodeForm && !isInitialized) {
|
||||
if (noCodeForm.pagesDraft.length === 0) {
|
||||
addPage();
|
||||
} else {
|
||||
setPagesDraft(noCodeForm.pagesDraft);
|
||||
await addPage();
|
||||
}
|
||||
setIsInitialized(true);
|
||||
}
|
||||
@@ -61,7 +42,7 @@ export default function Builder({ formId }) {
|
||||
}, [isLoadingNoCodeForm, initPages]);
|
||||
|
||||
if (isLoadingNoCodeForm) {
|
||||
<Loading />;
|
||||
return <Loading />;
|
||||
}
|
||||
|
||||
return (
|
||||
@@ -91,13 +72,12 @@ export default function Builder({ formId }) {
|
||||
<div className="px-10">
|
||||
<UsageIntro />
|
||||
</div>
|
||||
{pagesDraft.map((page, pageIdx) => (
|
||||
{noCodeForm.pagesDraft.map((page, pageIdx) => (
|
||||
<Page
|
||||
key={page.id}
|
||||
formId={formId}
|
||||
page={page}
|
||||
pageIdx={pageIdx}
|
||||
pagesDraft={pagesDraft}
|
||||
setPagesDraft={setPagesDraft}
|
||||
deletePageAction={deletePage}
|
||||
/>
|
||||
))}
|
||||
@@ -105,7 +85,6 @@ export default function Builder({ formId }) {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<LoadingModal isLoading={isLoading} />
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
+17
-13
@@ -1,21 +1,21 @@
|
||||
import { TrashIcon } from "@heroicons/react/outline";
|
||||
import dynamic from "next/dynamic";
|
||||
import { persistNoCodeForm, useNoCodeForm } from "../../lib/noCodeForm";
|
||||
import Loading from "../Loading";
|
||||
let Editor = dynamic(() => import("../editorjs/Editor"), {
|
||||
ssr: false,
|
||||
});
|
||||
|
||||
export default function Page({
|
||||
page,
|
||||
pageIdx,
|
||||
pagesDraft,
|
||||
setPagesDraft,
|
||||
deletePageAction,
|
||||
}) {
|
||||
const updatePage = (blocks) => {
|
||||
const newPagesDraft = JSON.parse(JSON.stringify(pagesDraft));
|
||||
if (pageIdx < newPagesDraft.length) {
|
||||
newPagesDraft[pageIdx].blocks = blocks;
|
||||
setPagesDraft(newPagesDraft);
|
||||
export default function Page({ formId, page, pageIdx, deletePageAction }) {
|
||||
const { noCodeForm, isLoadingNoCodeForm, mutateNoCodeForm } =
|
||||
useNoCodeForm(formId);
|
||||
|
||||
const updatePage = async (blocks) => {
|
||||
const newNoCodeForm = JSON.parse(JSON.stringify(noCodeForm));
|
||||
if (pageIdx < newNoCodeForm.pagesDraft.length) {
|
||||
newNoCodeForm.pagesDraft[pageIdx].blocks = blocks;
|
||||
await persistNoCodeForm(newNoCodeForm);
|
||||
mutateNoCodeForm(newNoCodeForm);
|
||||
} else {
|
||||
throw Error(
|
||||
`updatePage error: Page at position ${pageIdx} not found in pagesDraft`
|
||||
@@ -23,6 +23,10 @@ export default function Page({
|
||||
}
|
||||
};
|
||||
|
||||
if (isLoadingNoCodeForm) {
|
||||
return <Loading />;
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="flex w-full">
|
||||
<div className="flex w-8">
|
||||
@@ -46,7 +50,7 @@ export default function Page({
|
||||
id={`${page.id}-editor`}
|
||||
autofocus={pageIdx === 0}
|
||||
onChange={(blocks) => updatePage(blocks)}
|
||||
value={pagesDraft[pageIdx]}
|
||||
value={noCodeForm.pagesDraft[pageIdx]}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
|
||||
@@ -4,8 +4,7 @@ import { useNoCodeForm } from "../../lib/noCodeForm";
|
||||
import Loading from "../Loading";
|
||||
|
||||
export default function App({ id = "", formId, draft = false }) {
|
||||
const { noCodeForm, isLoadingNoCodeForm, mutateNoCodeForm } =
|
||||
useNoCodeForm(formId);
|
||||
const { noCodeForm, isLoadingNoCodeForm } = useNoCodeForm(formId);
|
||||
const pages = useMemo(() => {
|
||||
if (!isLoadingNoCodeForm) {
|
||||
return noCodeForm[draft ? "pagesDraft" : "pages"];
|
||||
|
||||
Reference in New Issue
Block a user