feat: schedule automatic form closure
This commit is contained in:
@@ -20,6 +20,8 @@ import {
|
||||
} from "@/app/actions/questions";
|
||||
import { Plus, Trash, ArrowUp, ArrowDown, Loader2, Image as ImageIcon, X, Check, GripVertical, AlertCircle } from "lucide-react";
|
||||
import Image from 'next/image';
|
||||
import { format, parseISO } from "date-fns";
|
||||
import { DateTimePicker } from "@/components/date-time-picker";
|
||||
import { RichTextEditor } from "@/components/rich-text-editor";
|
||||
import { getErrorMessage } from "@/lib/utils";
|
||||
import {
|
||||
@@ -66,6 +68,8 @@ import {
|
||||
FieldDescription,
|
||||
FieldGroup,
|
||||
FieldLabel,
|
||||
FieldLegend,
|
||||
FieldSet,
|
||||
} from "@/components/ui/field";
|
||||
|
||||
interface Question {
|
||||
@@ -87,16 +91,28 @@ interface FormEditorClientProps {
|
||||
title: string;
|
||||
description: string | null;
|
||||
isOpen: boolean;
|
||||
closesAt: string | null;
|
||||
allowMultipleSubmissions: boolean;
|
||||
};
|
||||
initialQuestions: Question[];
|
||||
}
|
||||
|
||||
function toDateTimeLocalValue(value: string | null) {
|
||||
if (!value) return "";
|
||||
|
||||
const date = new Date(value);
|
||||
const localDate = new Date(date.getTime() - date.getTimezoneOffset() * 60_000);
|
||||
return localDate.toISOString().slice(0, 16);
|
||||
}
|
||||
|
||||
export default function FormEditorClient({ form, initialQuestions }: FormEditorClientProps) {
|
||||
const router = useRouter();
|
||||
const [formTitle, setFormTitle] = useState(form.title);
|
||||
const [formDescription, setFormDescription] = useState(form.description || "");
|
||||
const [formIsOpen, setFormIsOpen] = useState(form.isOpen);
|
||||
const [closesAt, setClosesAt] = useState(
|
||||
toDateTimeLocalValue(form.closesAt)
|
||||
);
|
||||
const [allowMultipleSubmissions, setAllowMultipleSubmissions] = useState(
|
||||
form.allowMultipleSubmissions
|
||||
);
|
||||
@@ -108,6 +124,7 @@ export default function FormEditorClient({ form, initialQuestions }: FormEditorC
|
||||
const formTitleRef = useRef(formTitle);
|
||||
const formDescriptionRef = useRef(formDescription);
|
||||
const formIsOpenRef = useRef(formIsOpen);
|
||||
const closesAtRef = useRef(closesAt);
|
||||
const allowMultipleSubmissionsRef = useRef(allowMultipleSubmissions);
|
||||
const questionsRef = useRef(questions);
|
||||
|
||||
@@ -115,9 +132,10 @@ export default function FormEditorClient({ form, initialQuestions }: FormEditorC
|
||||
formTitleRef.current = formTitle;
|
||||
formDescriptionRef.current = formDescription;
|
||||
formIsOpenRef.current = formIsOpen;
|
||||
closesAtRef.current = closesAt;
|
||||
allowMultipleSubmissionsRef.current = allowMultipleSubmissions;
|
||||
questionsRef.current = questions;
|
||||
}, [allowMultipleSubmissions, formDescription, formIsOpen, formTitle, questions]);
|
||||
}, [allowMultipleSubmissions, closesAt, formDescription, formIsOpen, formTitle, questions]);
|
||||
|
||||
const saveForm = useCallback(async () => {
|
||||
const title = formTitleRef.current;
|
||||
@@ -128,6 +146,9 @@ export default function FormEditorClient({ form, initialQuestions }: FormEditorC
|
||||
title: title.trim(),
|
||||
description: formDescriptionRef.current,
|
||||
isOpen: formIsOpenRef.current,
|
||||
closesAt: closesAtRef.current
|
||||
? new Date(closesAtRef.current).toISOString()
|
||||
: null,
|
||||
allowMultipleSubmissions: allowMultipleSubmissionsRef.current,
|
||||
});
|
||||
router.refresh();
|
||||
@@ -169,6 +190,14 @@ export default function FormEditorClient({ form, initialQuestions }: FormEditorC
|
||||
formAutoSave.schedule();
|
||||
};
|
||||
|
||||
const handleClosesAtChange = (val: string) => {
|
||||
closesAtRef.current = val;
|
||||
setClosesAt(val);
|
||||
formAutoSave.schedule();
|
||||
};
|
||||
|
||||
const selectedCloseDateTime = closesAt ? parseISO(closesAt) : undefined;
|
||||
|
||||
const handleAllowMultipleSubmissionsChange = (val: boolean) => {
|
||||
allowMultipleSubmissionsRef.current = val;
|
||||
setAllowMultipleSubmissions(val);
|
||||
@@ -389,6 +418,27 @@ export default function FormEditorClient({ form, initialQuestions }: FormEditorC
|
||||
Accepting Submissions
|
||||
</FieldLabel>
|
||||
</Field>
|
||||
<FieldSet className="gap-3">
|
||||
<FieldLegend variant="label">
|
||||
Automatically close submissions
|
||||
</FieldLegend>
|
||||
<Field>
|
||||
<FieldLabel htmlFor="form-close-date">Date and time</FieldLabel>
|
||||
<DateTimePicker
|
||||
id="form-close-date"
|
||||
value={selectedCloseDateTime}
|
||||
onChange={(date) =>
|
||||
handleClosesAtChange(
|
||||
date ? format(date, "yyyy-MM-dd'T'HH:mm") : ""
|
||||
)
|
||||
}
|
||||
/>
|
||||
</Field>
|
||||
<FieldDescription>
|
||||
Changes are saved automatically. Leave blank for no deadline.
|
||||
The selected date and time use your device's time zone.
|
||||
</FieldDescription>
|
||||
</FieldSet>
|
||||
<Field orientation="horizontal">
|
||||
<Switch
|
||||
id="allow-multiple-submissions"
|
||||
|
||||
Reference in New Issue
Block a user