diff --git a/src/features/surveys/components/surveyForm/ErrorMessage.tsx b/src/features/surveys/components/surveyForm/ErrorMessage.tsx new file mode 100644 index 0000000000..3b40e872d1 --- /dev/null +++ b/src/features/surveys/components/surveyForm/ErrorMessage.tsx @@ -0,0 +1,14 @@ +import Box from '@mui/material/Box'; +import { FC } from 'react'; +import messageIds from 'features/surveys/l10n/messageIds'; +import { Msg } from 'core/i18n'; + +const ErrorMessage: FC = () => { + return ( + + + + ); +}; + +export default ErrorMessage; diff --git a/src/features/surveys/l10n/messageIds.ts b/src/features/surveys/l10n/messageIds.ts index 865b700e58..181b3a6163 100644 --- a/src/features/surveys/l10n/messageIds.ts +++ b/src/features/surveys/l10n/messageIds.ts @@ -164,6 +164,9 @@ export default makeMessages('feat.surveys', { authenticatedOption: m<{ email: string; person: string }>( 'Sign as {person} with email {email}' ), + error: m( + 'Something went wrong when submitting your answers. Please try again later.' + ), nameEmailOption: m('Sign with name and email'), policy: { link: m('https://zetkin.org/privacy'), diff --git a/src/pages/o/[orgId]/surveys/[surveyId]/index.tsx b/src/pages/o/[orgId]/surveys/[surveyId]/index.tsx index 49a886120d..9120c5f617 100644 --- a/src/pages/o/[orgId]/surveys/[surveyId]/index.tsx +++ b/src/pages/o/[orgId]/surveys/[surveyId]/index.tsx @@ -8,16 +8,16 @@ import { parse } from 'querystring'; import { scaffold } from 'utils/next'; import useCurrentUser from 'features/user/hooks/useCurrentUser'; import { + ZetkinSurveyExtended, ZetkinSurveyOptionsQuestionElement, ZetkinSurveyTextElement, ZetkinSurveyTextQuestionElement, } from 'utils/types/zetkin'; +import ErrorMessage from 'features/surveys/components/surveyForm/ErrorMessage'; import OptionsQuestion from 'features/surveys/components/surveyForm/OptionsQuestion'; import TextBlock from 'features/surveys/components/surveyForm/TextBlock'; import TextQuestion from 'features/surveys/components/surveyForm/TextQuestion'; -import useSurvey from 'features/surveys/hooks/useSurvey'; -import useSurveyElements from 'features/surveys/hooks/useSurveyElements'; import ZUIAvatar from 'zui/ZUIAvatar'; import { FC, useState } from 'react'; @@ -54,6 +54,17 @@ function parseRequest( export const getServerSideProps = scaffold(async (ctx) => { const { req, res } = ctx; const { surveyId, orgId } = ctx.params!; + let status: FormStatus = 'editing'; + + const apiClient = new BackendApiClient(req.headers); + let survey: ZetkinSurveyExtended; + try { + survey = await apiClient.get( + `/api/orgs/${orgId}/surveys/${surveyId}` + ); + } catch (e) { + return { notFound: true }; + } if (req.method === 'POST') { const form = await parseRequest(req); @@ -111,46 +122,49 @@ export const getServerSideProps = scaffold(async (ctx) => { }; } - const apiClient = new BackendApiClient(req.headers); - const requestUrl = `/api/orgs/${orgId}/surveys/${surveyId}/submissions`; try { - await apiClient.post(requestUrl, { - responses: Object.values(responses), - signature, - }); + await apiClient.post( + `/api/orgs/${orgId}/surveys/${surveyId}/submissions`, + { + responses: Object.values(responses), + signature, + } + ); } catch (e) { - // eslint-disable-next-line no-console - console.log(e); + status = 'error'; + } + if (status !== 'error') { + status = 'submitted'; } - res.writeHead(302, { - Location: `/o/${orgId}/surveys/${surveyId}/submitted`, - }); - res.end(); + if (status === 'submitted') { + res.writeHead(302, { + Location: `/o/${orgId}/surveys/${surveyId}/submitted`, + }); + res.end(); + } } return { props: { orgId, - surveyId, + status, + survey, }, }; }, scaffoldOptions); type PageProps = { orgId: string; - surveyId: string; + status: FormStatus; + survey: ZetkinSurveyExtended; }; +type FormStatus = 'editing' | 'invalid' | 'error' | 'submitted'; type SignatureOption = 'authenticated' | 'email' | 'anonymous'; -const Page: FC = ({ orgId, surveyId }) => { - const elements = useSurveyElements( - parseInt(orgId, 10), - parseInt(surveyId, 10) - ); +const Page: FC = ({ orgId, status, survey }) => { const messages = useMessages(messageIds); - const survey = useSurvey(parseInt(orgId, 10), parseInt(surveyId, 10)); const [selectedOption, setSelectedOption] = useState( null @@ -164,17 +178,19 @@ const Page: FC = ({ orgId, surveyId }) => { return ( <> -

{survey.data?.title}

+

{survey.title}

+ + {status === 'error' && } - {survey.data?.info_text &&

{survey.data?.info_text}

} + {survey.info_text &&

{survey.info_text}

} - {survey.data?.organization.title} + {survey.organization.title}
- {(elements.data || []).map((element) => ( + {survey.elements.map((element) => (
{element.type === 'question' && ( <> @@ -238,7 +254,7 @@ const Page: FC = ({ orgId, surveyId }) => { } value="email" /> - {survey.data?.signature === 'allow_anonymous' && ( + {survey.signature === 'allow_anonymous' && ( } label={ @@ -260,7 +276,7 @@ const Page: FC = ({ orgId, surveyId }) => {