mirror of
https://github.com/formbricks/formbricks.git
synced 2026-04-21 11:30:27 -05:00
102 lines
2.9 KiB
TypeScript
102 lines
2.9 KiB
TypeScript
import { useEffect, useMemo, useState } from "react";
|
|
import { Survey } from "./engineTypes";
|
|
import Progressbar from "./Progressbar";
|
|
import { SurveyPage } from "./SurveyPage";
|
|
|
|
interface SurveyProps {
|
|
survey: Survey;
|
|
formbricksUrl: string;
|
|
formId: string;
|
|
}
|
|
|
|
export function Survey({ survey, formbricksUrl, formId }: SurveyProps) {
|
|
const [currentPage, setCurrentPage] = useState(survey.pages[0]);
|
|
const [progress, setProgress] = useState(0);
|
|
const [submission, setSubmission] = useState<any>({});
|
|
const [finished, setFinished] = useState(false);
|
|
|
|
const schema = useMemo(() => generateSchema(survey), [survey]);
|
|
|
|
useEffect(() => {
|
|
// warmup request
|
|
fetch(`${formbricksUrl}/api/capture/forms/${formId}/submissions`, {
|
|
method: "OPTIONS",
|
|
});
|
|
});
|
|
|
|
const navigateToNextPage = (currentSubmission: any) => {
|
|
const nextPage = calculateNextPage(survey, currentSubmission);
|
|
setCurrentPage(nextPage);
|
|
if (nextPage.endScreen) {
|
|
setFinished(true);
|
|
setProgress(1);
|
|
} else {
|
|
const nextPageIdx = survey.pages.findIndex((p) => p.id === nextPage.id);
|
|
setProgress(nextPageIdx / survey.pages.length);
|
|
}
|
|
};
|
|
|
|
const calculateNextPage = (survey: Survey, submission: any) => {
|
|
if (currentPage.branchingRules) {
|
|
for (const rule of currentPage.branchingRules) {
|
|
if (rule.type === "value") {
|
|
if (rule.value === submission[rule.name]) {
|
|
const nextPage = survey.pages.find((p) => p.id === rule.nextPageId);
|
|
if (!nextPage) {
|
|
throw new Error(`Next page ${rule.nextPageId} not found`);
|
|
}
|
|
return nextPage;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
const currentPageIdx = survey.pages.findIndex((p) => p.id === currentPage.id);
|
|
return survey.pages[currentPageIdx + 1];
|
|
};
|
|
|
|
return (
|
|
<div className="flex h-full w-full flex-col">
|
|
{!(survey.config?.progressBar === false) && (
|
|
<div className="mb-8 h-3">
|
|
<Progressbar progress={progress} />
|
|
</div>
|
|
)}
|
|
|
|
<SurveyPage
|
|
page={currentPage}
|
|
onSkip={() => navigateToNextPage(submission)}
|
|
onSubmit={(updatedSubmission) => navigateToNextPage(updatedSubmission)}
|
|
submission={submission}
|
|
setSubmission={setSubmission}
|
|
finished={finished}
|
|
formbricksUrl={formbricksUrl}
|
|
formId={formId}
|
|
schema={schema}
|
|
/>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
function generateSchema(survey: Survey) {
|
|
const schema: any = JSON.parse(JSON.stringify(survey));
|
|
deleteProps(schema, "frontend");
|
|
return schema;
|
|
}
|
|
|
|
function deleteProps(obj: any, propName: string) {
|
|
if (Array.isArray(obj)) {
|
|
for (let v of obj) {
|
|
if (v instanceof Object) {
|
|
deleteProps(v, propName);
|
|
}
|
|
}
|
|
return;
|
|
}
|
|
delete obj[propName];
|
|
for (let v of Object.values(obj)) {
|
|
if (v instanceof Object) {
|
|
deleteProps(v, propName);
|
|
}
|
|
}
|
|
}
|