Close survey after x responses now needs to be set to a higher number than the number of current responses (#606)

* fix: fixes close survey on x response issue

* feat: updates

* chore: don't update _count

* chore: optimizations

* fix: fixes issue with not being able to enter a lower value at all

* update toast message

* add response count to toast

* only count completed responses

---------

Co-authored-by: Johannes <johannes@formbricks.com>
Co-authored-by: Matthias Nannt <mail@matthiasnannt.com>
This commit is contained in:
Pradumn Kumar
2023-08-07 18:52:37 +05:30
committed by GitHub
parent 488e2801f0
commit b6c0dbf5d3
6 changed files with 47 additions and 10 deletions

View File

@@ -5,6 +5,7 @@ import { DatePicker, Input, Label, Switch } from "@formbricks/ui";
import { CheckCircleIcon } from "@heroicons/react/24/solid";
import * as Collapsible from "@radix-ui/react-collapsible";
import { useEffect, useState } from "react";
import toast from "react-hot-toast";
interface ResponseOptionsCardProps {
localSurvey: Survey;
@@ -117,13 +118,27 @@ export default function ResponseOptionsCard({ localSurvey, setLocalSurvey }: Res
}
};
const handleInputResponse = (e: any) => {
let value = parseInt(e.target.value);
if (value < 1) value = 1;
const updatedSurvey: Survey = { ...localSurvey, autoComplete: value };
const handleInputResponse = (e) => {
const updatedSurvey: Survey = { ...localSurvey, autoComplete: parseInt(e.target.value) };
setLocalSurvey(updatedSurvey);
};
const handleInputResponseBlur = (e) => {
if (parseInt(e.target.value) === 0) {
toast.error("Response limit can't be set to 0");
return;
}
const inputResponses = localSurvey?._count?.responses || 0;
if (parseInt(e.target.value) <= inputResponses) {
toast.error(
`Response limit needs to exceed number of received responses (${localSurvey?._count?.responses}).`
);
return;
}
};
return (
<Collapsible.Root
open={open}
@@ -169,11 +184,16 @@ export default function ResponseOptionsCard({ localSurvey, setLocalSurvey }: Res
<Input
autoFocus
type="number"
min="1"
min={
localSurvey?._count?.responses
? (localSurvey?._count?.responses + 1).toString()
: "1"
}
id="autoCompleteResponses"
value={localSurvey.autoComplete?.toString()}
onChange={(e) => handleInputResponse(e)}
className="ml-2 mr-2 inline w-16 bg-white text-center text-sm"
onChange={handleInputResponse}
onBlur={handleInputResponseBlur}
className="ml-2 mr-2 inline w-20 bg-white text-center text-sm"
/>
completed responses.
</p>

View File

@@ -23,7 +23,7 @@ export default function SurveyEditor({ environmentId, surveyId }: SurveyEditorPr
const [activeQuestionId, setActiveQuestionId] = useState<string | null>(null);
const [localSurvey, setLocalSurvey] = useState<Survey | null>();
const [invalidQuestions, setInvalidQuestions] = useState<String[] | null>(null);
const { survey, isLoadingSurvey, isErrorSurvey } = useSurvey(environmentId, surveyId);
const { survey, isLoadingSurvey, isErrorSurvey } = useSurvey(environmentId, surveyId, true);
const { product, isLoadingProduct, isErrorProduct } = useProduct(environmentId);
const { environment, isLoadingEnvironment, isErrorEnvironment } = useEnvironment(environmentId);

View File

@@ -106,6 +106,17 @@ export default function SurveyMenuBar({
return false;
}
/*
Check whether the count for autocomplete responses is not less
than the current count of accepted response and also it is not set to 0
*/
if (
(survey.autoComplete && survey._count?.responses && survey._count.responses >= survey.autoComplete) ||
survey?.autoComplete === 0
) {
return false;
}
return true;
};

View File

@@ -27,9 +27,9 @@ export const useSurveys = (environmentId: string) => {
};
};
export const useSurvey = (environmentId: string, id: string) => {
export const useSurvey = (environmentId: string, id: string, analytics?: boolean) => {
const { data, error, mutate, isLoading } = useSWR(
`/api/v1/environments/${environmentId}/surveys/${id}`,
`/api/v1/environments/${environmentId}/surveys/${id}${analytics ? "?analytics=true" : ""}`,
fetcher
);

View File

@@ -9,6 +9,8 @@ export default async function handle(req: NextApiRequest, res: NextApiResponse)
const surveyId = req.query.surveyId?.toString();
const analytics = req.query.analytics?.toString() === "true";
if (environmentId === undefined) {
return res.status(400).json({ message: "Missing environmentId" });
}
@@ -31,6 +33,7 @@ export default async function handle(req: NextApiRequest, res: NextApiResponse)
include: {
triggers: true,
attributeFilters: true,
_count: analytics ? { select: { responses: { where: { finished: true } } } } : false,
},
});
@@ -83,6 +86,8 @@ export default async function handle(req: NextApiRequest, res: NextApiResponse)
const body = { ...req.body };
delete body.updatedAt;
// preventing issue with unknowingly updating analytics
delete body._count;
// delete unused fields for link surveys
if (body.type === "link") {

View File

@@ -33,6 +33,7 @@ export interface Survey {
autoComplete: number | null;
surveyClosedMessage: SurveyClosedMessage | null;
closeOnDate: Date | null;
_count: { responses: number | null } | null;
}
export interface AttributeFilter {