diff --git a/apps/web/app/(app)/(onboarding)/organizations/[organizationId]/projects/new/settings/components/ProjectSettings.tsx b/apps/web/app/(app)/(onboarding)/organizations/[organizationId]/projects/new/settings/components/ProjectSettings.tsx index 475249e6ce..cf85a9fd78 100644 --- a/apps/web/app/(app)/(onboarding)/organizations/[organizationId]/projects/new/settings/components/ProjectSettings.tsx +++ b/apps/web/app/(app)/(onboarding)/organizations/[organizationId]/projects/new/settings/components/ProjectSettings.tsx @@ -231,6 +231,7 @@ export const ProjectSettings = ({

{t("common.preview")}

file.name} />
diff --git a/apps/web/modules/survey/link/components/link-survey.tsx b/apps/web/modules/survey/link/components/link-survey.tsx index 392d59d2be..a018222dca 100644 --- a/apps/web/modules/survey/link/components/link-survey.tsx +++ b/apps/web/modules/survey/link/components/link-survey.tsx @@ -170,14 +170,14 @@ export const LinkSurvey = ({ PRIVACY_URL={PRIVACY_URL} isBrandingEnabled={project.linkSurveyBranding}> `https://formbricks.com/${file.name}` : undefined} // eslint-disable-next-line jsx-a11y/no-autofocus -- need it as focus behaviour is different in normal surveys and survey preview autoFocus={autoFocus} prefillResponseData={prefillValue} diff --git a/apps/web/modules/survey/templates/components/template-container.tsx b/apps/web/modules/survey/templates/components/template-container.tsx index b8a7b30467..b5371d4777 100644 --- a/apps/web/modules/survey/templates/components/template-container.tsx +++ b/apps/web/modules/survey/templates/components/template-container.tsx @@ -84,7 +84,6 @@ export const TemplateContainerWithPreview = ({ project={project} environment={environment} languageCode={"default"} - onFileUpload={async (file) => file.name} /> )} diff --git a/apps/web/modules/ui/components/preview-survey/index.tsx b/apps/web/modules/ui/components/preview-survey/index.tsx index 96f0d7107a..70aeddf9cd 100644 --- a/apps/web/modules/ui/components/preview-survey/index.tsx +++ b/apps/web/modules/ui/components/preview-survey/index.tsx @@ -9,9 +9,7 @@ import { useTranslate } from "@tolgee/react"; import { Variants, motion } from "framer-motion"; import { ExpandIcon, MonitorIcon, ShrinkIcon, SmartphoneIcon } from "lucide-react"; import { useCallback, useEffect, useMemo, useRef, useState } from "react"; -import { TJsFileUploadParams } from "@formbricks/types/js"; import { TProjectStyling } from "@formbricks/types/project"; -import { TUploadFileConfig } from "@formbricks/types/storage"; import { TSurvey, TSurveyQuestionId, TSurveyStyling } from "@formbricks/types/surveys/types"; import { Modal } from "./components/modal"; import { TabOption } from "./components/tab-option"; @@ -25,7 +23,6 @@ interface PreviewSurveyProps { project: Project; environment: Pick; languageCode: string; - onFileUpload: (file: TJsFileUploadParams["file"], config?: TUploadFileConfig) => Promise; } let surveyNameTemp: string; @@ -66,7 +63,6 @@ export const PreviewSurvey = ({ project, environment, languageCode, - onFileUpload, }: PreviewSurveyProps) => { const [isModalOpen, setIsModalOpen] = useState(true); const [isFullScreenPreview, setIsFullScreenPreview] = useState(false); @@ -265,11 +261,11 @@ export const PreviewSurvey = ({ borderRadius={styling?.roundness ?? 8} background={styling?.cardBackgroundColor?.light}>
{ + if (isPreviewMode) { + // return mock url since an url is required for the preview + return `https://example.com/${file.name}`; + } + if (!apiClient) { throw new Error("apiClient not initialized"); } @@ -206,6 +211,17 @@ export function Survey({ }, [questionId]); const createDisplay = useCallback(async () => { + // Skip display creation in preview mode but still trigger the onDisplayCreated callback + if (isPreviewMode) { + if (onDisplayCreated) { + onDisplayCreated(); + } + if (onDisplay) { + onDisplay(); + } + return; + } + if (apiClient && surveyState && responseQueue) { try { const display = await apiClient.createDisplay({ @@ -229,7 +245,17 @@ export function Survey({ console.error("error creating display: ", err); } } - }, [apiClient, surveyState, responseQueue, survey.id, userId, contactId, onDisplayCreated]); + }, [ + apiClient, + surveyState, + responseQueue, + survey.id, + userId, + contactId, + onDisplayCreated, + isPreviewMode, + onDisplay, + ]); useEffect(() => { // call onDisplay when component is mounted @@ -385,6 +411,32 @@ export function Survey({ const onResponseCreateOrUpdate = useCallback( (responseUpdate: TResponseUpdate) => { + // Always trigger the onResponse callback even in preview mode + if (!apiHost || !environmentId) { + onResponse?.({ + data: responseUpdate.data, + ttc: responseUpdate.ttc, + finished: responseUpdate.finished, + variables: responseUpdate.variables, + language: responseUpdate.language, + endingId: responseUpdate.endingId, + }); + return; + } + + // Skip response creation in preview mode but still trigger the onResponseCreated callback + if (isPreviewMode) { + if (onResponseCreated) { + onResponseCreated(); + } + + // When in preview mode, set isResponseSendingFinished to true if the response is finished + if (responseUpdate.finished) { + setIsResponseSendingFinished(true); + } + return; + } + if (surveyState && responseQueue) { if (contactId) { surveyState.updateContactId(contactId); @@ -415,7 +467,20 @@ export function Survey({ } } }, - [surveyState, responseQueue, contactId, userId, survey, action, hiddenFieldsRecord, onResponseCreated] + [ + apiHost, + environmentId, + isPreviewMode, + surveyState, + responseQueue, + contactId, + userId, + survey, + action, + hiddenFieldsRecord, + onResponseCreated, + onResponse, + ] ); useEffect(() => { @@ -446,25 +511,14 @@ export function Survey({ onChange(surveyResponseData); onChangeVariables(calculatedVariables); - if (apiHost && environmentId) { - onResponseCreateOrUpdate({ - data: surveyResponseData, - ttc: responsettc, - finished, - variables: calculatedVariables, - language: selectedLanguage, - endingId, - }); - } else { - onResponse?.({ - data: surveyResponseData, - ttc: responsettc, - finished, - variables: calculatedVariables, - language: selectedLanguage, - endingId, - }); - } + onResponseCreateOrUpdate({ + data: surveyResponseData, + ttc: responsettc, + finished, + variables: calculatedVariables, + language: selectedLanguage, + endingId, + }); if (nextQuestionId) { setQuestionId(nextQuestionId); @@ -573,7 +627,7 @@ export function Survey({ onBack={onBack} ttc={ttc} setTtc={setTtc} - onFileUpload={apiHost && environmentId ? onFileUploadApi : onFileUpload!} + onFileUpload={onFileUpload ?? onFileUploadApi} isFirstQuestion={question.id === localSurvey.questions[0]?.id} skipPrefilled={skipPrefilled} prefilledQuestionValue={getQuestionPrefillData(question.id, offset)} diff --git a/packages/types/formbricks-surveys.ts b/packages/types/formbricks-surveys.ts index 26f7af4dfe..43f4e6a071 100644 --- a/packages/types/formbricks-surveys.ts +++ b/packages/types/formbricks-surveys.ts @@ -45,6 +45,7 @@ export interface SurveyModalProps extends SurveyBaseProps { export interface SurveyContainerProps extends Omit { apiHost?: string; environmentId?: string; + isPreviewMode?: boolean; userId?: string; contactId?: string; onDisplayCreated?: () => void | Promise;