diff --git a/apps/web/modules/survey/hooks/useSingleUseId.tsx b/apps/web/modules/survey/hooks/useSingleUseId.tsx index 979cf35140..9971f5c751 100644 --- a/apps/web/modules/survey/hooks/useSingleUseId.tsx +++ b/apps/web/modules/survey/hooks/useSingleUseId.tsx @@ -1,4 +1,4 @@ -import { useCallback, useEffect, useState } from "react"; +import { useCallback, useState } from "react"; import toast from "react-hot-toast"; import type { TSurvey } from "@formbricks/types/surveys/types"; import { getFormattedErrorMessage } from "@/lib/utils/helper"; @@ -30,10 +30,6 @@ export const useSingleUseId = (survey: TSurvey | TSurveyList, isReadOnly: boolea } }, [survey, isReadOnly]); - useEffect(() => { - refreshSingleUseId(); - }, [refreshSingleUseId]); - return { singleUseId: isReadOnly ? undefined : singleUseId, refreshSingleUseId: isReadOnly ? async () => undefined : refreshSingleUseId, diff --git a/apps/web/modules/survey/list/components/survey-card.tsx b/apps/web/modules/survey/list/components/survey-card.tsx index 52424e66d1..8928d1f53c 100644 --- a/apps/web/modules/survey/list/components/survey-card.tsx +++ b/apps/web/modules/survey/list/components/survey-card.tsx @@ -6,7 +6,6 @@ import { useTranslation } from "react-i18next"; import { TUserLocale } from "@formbricks/types/user"; import { cn } from "@/lib/cn"; import { convertDateString, timeSince } from "@/lib/time"; -import { useSingleUseId } from "@/modules/survey/hooks/useSingleUseId"; import { SurveyTypeIndicator } from "@/modules/survey/list/components/survey-type-indicator"; import { TSurvey } from "@/modules/survey/list/types/surveys"; import { SurveyStatusIndicator } from "@/modules/ui/components/survey-status-indicator"; @@ -48,8 +47,6 @@ export const SurveyCard = ({ const isSurveyCreationDeletionDisabled = isReadOnly; - const { refreshSingleUseId } = useSingleUseId(survey, isReadOnly); - const linkHref = useMemo(() => { return survey.status === "draft" ? `/environments/${environmentId}/surveys/${survey.id}/edit` @@ -101,7 +98,6 @@ export const SurveyCard = ({ environmentId={environmentId} publicDomain={publicDomain} disabled={isDraftAndReadOnly} - refreshSingleUseId={refreshSingleUseId} isSurveyCreationDeletionDisabled={isSurveyCreationDeletionDisabled} deleteSurvey={deleteSurvey} onSurveysCopied={onSurveysCopied} diff --git a/apps/web/modules/survey/list/components/survey-dropdown-menu.tsx b/apps/web/modules/survey/list/components/survey-dropdown-menu.tsx index 059ad98816..0502306bfd 100644 --- a/apps/web/modules/survey/list/components/survey-dropdown-menu.tsx +++ b/apps/web/modules/survey/list/components/survey-dropdown-menu.tsx @@ -11,7 +11,7 @@ import { } from "lucide-react"; import Link from "next/link"; import { useRouter } from "next/navigation"; -import { useEffect, useMemo, useState } from "react"; +import { useMemo, useState } from "react"; import toast from "react-hot-toast"; import { useTranslation } from "react-i18next"; import { logger } from "@formbricks/logger"; @@ -39,7 +39,6 @@ interface SurveyDropDownMenuProps { environmentId: string; survey: TSurvey; publicDomain: string; - refreshSingleUseId: () => Promise; disabled?: boolean; isSurveyCreationDeletionDisabled?: boolean; deleteSurvey: (surveyId: string) => void; @@ -50,7 +49,6 @@ export const SurveyDropDownMenu = ({ environmentId, survey, publicDomain, - refreshSingleUseId, disabled, isSurveyCreationDeletionDisabled, deleteSurvey, @@ -62,26 +60,11 @@ export const SurveyDropDownMenu = ({ const [isDropDownOpen, setIsDropDownOpen] = useState(false); const [isCopyFormOpen, setIsCopyFormOpen] = useState(false); const [isCautionDialogOpen, setIsCautionDialogOpen] = useState(false); - const [newSingleUseId, setNewSingleUseId] = useState(undefined); const router = useRouter(); const surveyLink = useMemo(() => publicDomain + "/s/" + survey.id, [survey.id, publicDomain]); - - // Pre-fetch single-use ID when dropdown opens to avoid async delay during clipboard operation - // This ensures Safari's clipboard API works by maintaining the user gesture context - useEffect(() => { - if (!isDropDownOpen) return; - const fetchNewId = async () => { - try { - const newId = await refreshSingleUseId(); - setNewSingleUseId(newId ?? undefined); - } catch (error) { - logger.error(error); - } - }; - fetchNewId(); - }, [refreshSingleUseId, isDropDownOpen]); + const isSingleUseEnabled = survey.singleUse?.enabled ?? false; const handleDeleteSurvey = async (surveyId: string) => { setLoading(true); @@ -100,7 +83,8 @@ export const SurveyDropDownMenu = ({ try { e.preventDefault(); setIsDropDownOpen(false); - const copiedLink = copySurveyLink(surveyLink, newSingleUseId); + // For single-use surveys, this button is disabled, so we just copy the base link + const copiedLink = copySurveyLink(surveyLink); navigator.clipboard.writeText(copiedLink); toast.success(t("common.copied_to_clipboard")); } catch (error) { @@ -205,31 +189,36 @@ export const SurveyDropDownMenu = ({ <> - {!survey.singleUse?.enabled && ( - - - - )} + + + )} {!isSurveyCreationDeletionDisabled && ( diff --git a/apps/web/modules/survey/list/components/survey-filters.tsx b/apps/web/modules/survey/list/components/survey-filters.tsx index 271e970d3d..52844550c2 100644 --- a/apps/web/modules/survey/list/components/survey-filters.tsx +++ b/apps/web/modules/survey/list/components/survey-filters.tsx @@ -7,8 +7,9 @@ import { useTranslation } from "react-i18next"; import { useDebounce } from "react-use"; import { TProjectConfigChannel } from "@formbricks/types/project"; import { TFilterOption, TSortOption, TSurveyFilters } from "@formbricks/types/surveys/types"; +import { FORMBRICKS_SURVEYS_FILTERS_KEY_LS } from "@/lib/localStorage"; import { SortOption } from "@/modules/survey/list/components/sort-option"; -import { initialFilters } from "@/modules/survey/list/components/survey-list"; +import { initialFilters } from "@/modules/survey/list/lib/constants"; import { Button } from "@/modules/ui/components/button"; import { DropdownMenu, @@ -154,12 +155,13 @@ export const SurveyFilters = ({ )} - {(createdBy.length > 0 || status.length > 0 || type.length > 0) && ( + {(createdBy.length > 0 || status.length > 0 || type.length > 0 || name) && (