import { GetServerSideProps, NextPage } from "next"; import dynamic from "next/dynamic"; import Head from "next/head"; import { useRouter } from "next/router"; import { useTranslation } from "next-i18next"; import { serverSideTranslations } from "next-i18next/serverSideTranslations"; import { usePlausible } from "next-plausible"; import React from "react"; import { useMutation } from "react-query"; import { useSessionStorage } from "react-use"; import { createPoll } from "../api-client/create-poll"; import Button from "../components/button"; import { NewEventData, PollDetailsData, PollDetailsForm, PollOptionsData, PollOptionsForm, UserDetailsData, UserDetailsForm, } from "../components/forms"; import StandardLayout from "../components/standard-layout"; import Steps from "../components/steps"; import { useUserName } from "../components/user-name-context"; import { encodeDateOption } from "../utils/date-time-utils"; type StepName = "eventDetails" | "options" | "userDetails"; const steps: StepName[] = ["eventDetails", "options", "userDetails"]; const required = (v: T | undefined): T => { if (!v) { throw new Error("Required value is missing"); } return v; }; const initialNewEventData: NewEventData = { currentStep: 0 }; const sessionStorageKey = "newEventFormData"; const Page: NextPage<{ title?: string; location?: string; description?: string; view?: "week" | "month"; }> = ({ title, location, description, view }) => { const { t } = useTranslation("app"); const router = useRouter(); const [persistedFormData, setPersistedFormData] = useSessionStorage(sessionStorageKey, { currentStep: 0, eventDetails: { title, location, description, }, options: { view, }, }); const [formData, setTransientFormData] = React.useState(persistedFormData); const setFormData = React.useCallback( (newEventData: NewEventData) => { setTransientFormData(newEventData); setPersistedFormData(newEventData); }, [setPersistedFormData], ); const currentStepIndex = formData?.currentStep ?? 0; const currentStepName = steps[currentStepIndex]; const [isRedirecting, setIsRedirecting] = React.useState(false); const [, setUserName] = useUserName(); const plausible = usePlausible(); const { mutate: createEventMutation, isLoading: isCreatingPoll } = useMutation( () => { const title = required(formData?.eventDetails?.title); return createPoll({ title: title, type: "date", location: formData?.eventDetails?.location, description: formData?.eventDetails?.description, user: { name: required(formData?.userDetails?.name), email: required(formData?.userDetails?.contact), }, timeZone: formData?.options?.timeZone, options: required(formData?.options?.options).map(encodeDateOption), }); }, { onSuccess: (poll) => { setIsRedirecting(true); setUserName(poll.authorName); plausible("Created poll", { props: { numberOfOptions: formData.options?.options?.length, optionsView: formData?.options?.view, }, }); setPersistedFormData(initialNewEventData); router.replace(`/admin/${poll.urlId}`); }, }, ); const isBusy = isRedirecting || isCreatingPoll; const handleSubmit = ( data: PollDetailsData | PollOptionsData | UserDetailsData, ) => { if (currentStepIndex < steps.length - 1) { setFormData({ ...formData, currentStep: currentStepIndex + 1, [currentStepName]: data, }); } else { // last step createEventMutation(); } }; const handleChange = ( data: Partial, ) => { setFormData({ ...formData, currentStep: currentStepIndex, [currentStepName]: data, }); }; return ( {formData?.eventDetails?.title ?? t("newPoll")}

New Poll

{(() => { switch (currentStepName) { case "eventDetails": return ( ); case "options": return ( ); case "userDetails": return ( ); } })()}
{currentStepIndex > 0 ? ( ) : null}
); }; export const getServerSideProps: GetServerSideProps = async ({ locale = "en", query, }) => { return { props: { ...(await serverSideTranslations(locale, ["app"])), ...query, }, }; }; // We disable SSR because the data on this page relies on sessionStore export default dynamic(() => Promise.resolve(Page), { ssr: false });