diff --git a/.github/workflows/cron-reportUsageToStripe.yml b/.github/workflows/cron-reportUsageToStripe.yml index 62a50b5fae..15892818a2 100644 --- a/.github/workflows/cron-reportUsageToStripe.yml +++ b/.github/workflows/cron-reportUsageToStripe.yml @@ -1,4 +1,4 @@ -name: Cron - reportUsageToStripe +name: Cron - Report usage to Stripe on: # "Scheduled workflows run on the latest commit on the default or base branch." diff --git a/.github/workflows/cron-closeOnDate.yml b/.github/workflows/cron-surveyStatusUpdate.yml similarity index 87% rename from .github/workflows/cron-closeOnDate.yml rename to .github/workflows/cron-surveyStatusUpdate.yml index dadfda8e01..95d40fb894 100644 --- a/.github/workflows/cron-closeOnDate.yml +++ b/.github/workflows/cron-surveyStatusUpdate.yml @@ -1,4 +1,4 @@ -name: Cron - closeOnDate +name: Cron - Survey status update on: # "Scheduled workflows run on the latest commit on the default or base branch." @@ -16,7 +16,7 @@ jobs: - name: cURL request if: ${{ env.APP_URL && env.CRON_SECRET }} run: | - curl ${{ env.APP_URL }}/api/cron/close_surveys \ + curl ${{ env.APP_URL }}/api/cron/survey-status \ -X POST \ -H 'content-type: application/json' \ -H 'x-api-key: ${{ env.CRON_SECRET }}' \ diff --git a/.github/workflows/cron-weeklySummary.yml b/.github/workflows/cron-weeklySummary.yml index 0014ff40b2..975128849a 100644 --- a/.github/workflows/cron-weeklySummary.yml +++ b/.github/workflows/cron-weeklySummary.yml @@ -1,4 +1,4 @@ -name: Cron - weeklySummary +name: Cron - Weekly summary on: # "Scheduled workflows run on the latest commit on the default or base branch." @@ -16,7 +16,7 @@ jobs: - name: cURL request if: ${{ env.APP_URL && env.CRON_SECRET }} run: | - curl ${{ env.APP_URL }}/api/cron/weekly_summary \ + curl ${{ env.APP_URL }}/api/cron/weekly-summary \ -X POST \ -H 'content-type: application/json' \ -H 'x-api-key: ${{ env.CRON_SECRET }}' \ diff --git a/apps/web/app/(app)/environments/[environmentId]/surveys/[surveyId]/components/SummaryHeader.tsx b/apps/web/app/(app)/environments/[environmentId]/surveys/[surveyId]/components/SummaryHeader.tsx index 6fb88a08d8..74957fd8e4 100644 --- a/apps/web/app/(app)/environments/[environmentId]/surveys/[surveyId]/components/SummaryHeader.tsx +++ b/apps/web/app/(app)/environments/[environmentId]/surveys/[surveyId]/components/SummaryHeader.tsx @@ -119,6 +119,7 @@ const SummaryHeader = ({ )} + {survey.status === "scheduled" && "Scheduled"} {survey.status === "inProgress" && "In-progress"} {survey.status === "paused" && "Paused"} {survey.status === "completed" && "Completed"} diff --git a/apps/web/app/(app)/environments/[environmentId]/surveys/[surveyId]/components/SurveyStatusDropdown.tsx b/apps/web/app/(app)/environments/[environmentId]/surveys/[surveyId]/components/SurveyStatusDropdown.tsx index 002b82893c..eb24167eb1 100644 --- a/apps/web/app/(app)/environments/[environmentId]/surveys/[surveyId]/components/SurveyStatusDropdown.tsx +++ b/apps/web/app/(app)/environments/[environmentId]/surveys/[surveyId]/components/SurveyStatusDropdown.tsx @@ -10,18 +10,22 @@ import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@ import { SurveyStatusIndicator } from "@formbricks/ui/SurveyStatusIndicator"; import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@formbricks/ui/Tooltip"; +interface SurveyStatusDropdownProps { + environment: TEnvironment; + updateLocalSurveyStatus?: (status: TSurvey["status"]) => void; + survey: TSurvey; +} + export default function SurveyStatusDropdown({ environment, updateLocalSurveyStatus, survey, -}: { - environment: TEnvironment; - updateLocalSurveyStatus?: (status: "draft" | "inProgress" | "paused" | "completed" | "archived") => void; - survey: TSurvey; -}) { +}: SurveyStatusDropdownProps) { const isCloseOnDateEnabled = survey.closeOnDate !== null; const closeOnDate = survey.closeOnDate ? new Date(survey.closeOnDate) : null; - const isStatusChangeDisabled = (isCloseOnDateEnabled && closeOnDate && closeOnDate < new Date()) ?? false; + const isStatusChangeDisabled = + (survey.status === "scheduled" || (isCloseOnDateEnabled && closeOnDate && closeOnDate < new Date())) ?? + false; return ( <> @@ -34,7 +38,7 @@ export default function SurveyStatusDropdown({ value={survey.status} disabled={isStatusChangeDisabled} onValueChange={(value) => { - const castedValue = value as "draft" | "inProgress" | "paused" | "completed"; + const castedValue = value as TSurvey["status"]; updateSurveyAction({ ...survey, status: castedValue }) .then(() => { toast.success( @@ -51,8 +55,7 @@ export default function SurveyStatusDropdown({ toast.error(`Error: ${error.message}`); }); - if (updateLocalSurveyStatus) - updateLocalSurveyStatus(value as "draft" | "inProgress" | "paused" | "completed" | "archived"); + if (updateLocalSurveyStatus) updateLocalSurveyStatus(value as TSurvey["status"]); }}> @@ -64,6 +67,7 @@ export default function SurveyStatusDropdown({ )} + {survey.status === "scheduled" && "Scheduled"} {survey.status === "inProgress" && "In-progress"} {survey.status === "paused" && "Paused"} {survey.status === "completed" && "Completed"} @@ -88,8 +92,8 @@ export default function SurveyStatusDropdown({ - To update the survey status, update the “Close -
survey on date” setting in the Response Options. + To update the survey status, update the schedule and close setting in the survey response + options.
diff --git a/apps/web/app/(app)/environments/[environmentId]/surveys/[surveyId]/edit/components/ResponseOptionsCard.tsx b/apps/web/app/(app)/environments/[environmentId]/surveys/[surveyId]/edit/components/ResponseOptionsCard.tsx index 364fa3746d..c3e57f2dff 100644 --- a/apps/web/app/(app)/environments/[environmentId]/surveys/[surveyId]/edit/components/ResponseOptionsCard.tsx +++ b/apps/web/app/(app)/environments/[environmentId]/surveys/[surveyId]/edit/components/ResponseOptionsCard.tsx @@ -1,7 +1,8 @@ "use client"; import * as Collapsible from "@radix-ui/react-collapsible"; -import { CheckIcon } from "lucide-react"; +import { ArrowUpRight, CheckIcon } from "lucide-react"; +import Link from "next/link"; import { KeyboardEventHandler, useEffect, useState } from "react"; import toast from "react-hot-toast"; @@ -27,7 +28,8 @@ export default function ResponseOptionsCard({ const [open, setOpen] = useState(localSurvey.type === "link" ? true : false); const autoComplete = localSurvey.autoComplete !== null; const [redirectToggle, setRedirectToggle] = useState(false); - const [surveyCloseOnDateToggle, setSurveyCloseOnDateToggle] = useState(false); + const [runOnDateToggle, setRunOnDateToggle] = useState(false); + const [closeOnDateToggle, setCloseOnDateToggle] = useState(false); useState; const [redirectUrl, setRedirectUrl] = useState(""); const [surveyClosedMessageToggle, setSurveyClosedMessageToggle] = useState(false); @@ -48,7 +50,8 @@ export default function ResponseOptionsCard({ name: "", subheading: "", }); - const [closeOnDate, setCloseOnDate] = useState(); + const [runOnDate, setRunOnDate] = useState(null); + const [closeOnDate, setCloseOnDate] = useState(null); const isPinProtectionEnabled = localSurvey.pin !== null; @@ -63,19 +66,28 @@ export default function ResponseOptionsCard({ } }; - const handleSurveyCloseOnDateToggle = () => { - if (surveyCloseOnDateToggle && localSurvey.closeOnDate) { - setSurveyCloseOnDateToggle(false); - setCloseOnDate(undefined); - setLocalSurvey({ ...localSurvey, closeOnDate: null }); - return; + const handleRunOnDateToggle = () => { + if (runOnDateToggle) { + setRunOnDateToggle(false); + if (localSurvey.runOnDate) { + setRunOnDate(null); + setLocalSurvey({ ...localSurvey, runOnDate: null }); + } + } else { + setRunOnDateToggle(true); } + }; - if (surveyCloseOnDateToggle) { - setSurveyCloseOnDateToggle(false); - return; + const handleCloseOnDateToggle = () => { + if (closeOnDateToggle) { + setCloseOnDateToggle(false); + if (localSurvey.closeOnDate) { + setCloseOnDate(null); + setLocalSurvey({ ...localSurvey, closeOnDate: null }); + } + } else { + setCloseOnDateToggle(true); } - setSurveyCloseOnDateToggle(true); }; const handleProtectSurveyWithPinToggle = () => { @@ -126,6 +138,15 @@ export default function ResponseOptionsCard({ } }; + const handleRunOnDateChange = (date: Date) => { + const equivalentDate = date?.getDate(); + date?.setUTCHours(0, 0, 0, 0); + date?.setDate(equivalentDate); + + setRunOnDate(date); + setLocalSurvey({ ...localSurvey, runOnDate: date ?? null }); + }; + const handleCloseOnDateChange = (date: Date) => { const equivalentDate = date?.getDate(); date?.setUTCHours(0, 0, 0, 0); @@ -143,7 +164,7 @@ export default function ResponseOptionsCard({ subheading?: string; }) => { const message = { - enabled: surveyCloseOnDateToggle, + enabled: closeOnDateToggle, heading: heading ?? surveyClosedMessage.heading, subheading: subheading ?? surveyClosedMessage.subheading, }; @@ -245,9 +266,14 @@ export default function ResponseOptionsCard({ setVerifyEmailToggle(true); } + if (localSurvey.runOnDate) { + setRunOnDate(localSurvey.runOnDate); + setRunOnDateToggle(true); + } + if (localSurvey.closeOnDate) { setCloseOnDate(localSurvey.closeOnDate); - setSurveyCloseOnDateToggle(true); + setCloseOnDateToggle(true); } }, [ localSurvey, @@ -318,7 +344,7 @@ export default function ResponseOptionsCard({ description="Automatically close the survey after a certain number of responses." childBorder={true}>