diff --git a/src/features/surveys/components/SurveyLinkDialog.tsx b/src/features/surveys/components/SurveyLinkDialog.tsx new file mode 100644 index 000000000..d9b7f76f1 --- /dev/null +++ b/src/features/surveys/components/SurveyLinkDialog.tsx @@ -0,0 +1,75 @@ +import { ArrowForward } from '@mui/icons-material'; +import { + Box, + Button, + Dialog, + DialogActions, + DialogContent, + DialogTitle, + Divider, + Typography, +} from '@mui/material'; + +import messageIds from '../l10n/messageIds'; +import { useNumericRouteParams } from 'core/hooks'; +import { useMessages } from 'core/i18n'; +import usePersonMutations from 'features/profile/hooks/usePersonMutations'; +import { ZetkinPerson } from 'utils/types/zetkin'; +import ZUIPersonAvatar from 'zui/ZUIPersonAvatar'; + +const SurveyLinkDialog = ({ + email, + onClose, + open, + person, +}: { + email: string; + onClose: () => void; + open: boolean; + person: ZetkinPerson; +}) => { + const messages = useMessages(messageIds); + const { orgId } = useNumericRouteParams(); + const { updatePerson } = usePersonMutations(orgId, person.id); + + return ( + + {messages.surveyDialog.title()} + + + + {email} + + + + + + {person?.first_name} {person?.last_name} + + + {messages.surveyDialog.description()} + + + + + + + ); +}; + +export default SurveyLinkDialog; diff --git a/src/features/surveys/components/SurveySubmissionsList.tsx b/src/features/surveys/components/SurveySubmissionsList.tsx index 14a96d63a..f4d0c0780 100644 --- a/src/features/surveys/components/SurveySubmissionsList.tsx +++ b/src/features/surveys/components/SurveySubmissionsList.tsx @@ -7,9 +7,10 @@ import { GridRenderCellParams, useGridApiContext, } from '@mui/x-data-grid-pro'; -import { FC, useEffect, useMemo } from 'react'; +import { FC, useEffect, useMemo, useState } from 'react'; import messageIds from '../l10n/messageIds'; +import SurveyLinkDialog from './SurveyLinkDialog'; import SurveySubmissionPane from '../panes/SurveySubmissionPane'; import { useNumericRouteParams } from 'core/hooks'; import { usePanes } from 'utils/panes'; @@ -31,6 +32,9 @@ const SurveySubmissionsList = ({ const { orgId } = useRouter().query; const { openPane } = usePanes(); + const [dialogPerson, setDialogPerson] = useState(null); + const [dialogEmail, setDialogEmail] = useState(''); + const sortedSubmissions = useMemo(() => { const sorted = [...submissions].sort((subOne, subTwo) => { const dateOne = new Date(subOne.submitted); @@ -198,6 +202,15 @@ const SurveySubmissionsList = ({ id: row.id, }); setRespondentId(person?.id || null); + + const respondentEmail = row.respondent?.email; + if (person) { + const personHasNoEmail = person.email == null || person.email == ''; + if (personHasNoEmail && respondentEmail != undefined) { + setDialogEmail(respondentEmail); + setDialogPerson(person); + } + } }; return ( @@ -247,6 +260,14 @@ const SurveySubmissionsList = ({ border: 'none', }} /> + {dialogPerson && ( + setDialogPerson(null)} + open={!!dialogPerson} + person={dialogPerson} + /> + )} ); }; diff --git a/src/features/surveys/l10n/messageIds.ts b/src/features/surveys/l10n/messageIds.ts index f83e84f67..5dd6c4f0e 100644 --- a/src/features/surveys/l10n/messageIds.ts +++ b/src/features/surveys/l10n/messageIds.ts @@ -171,6 +171,14 @@ export default makeMessages('feat.surveys', { suggestedPeople: m('Suggested people'), unlink: m('Unlink'), }, + surveyDialog: { + add: m('Add'), + cancel: m("Don't add"), + description: m( + 'The person you are about to link does not have an email address while the survey response does. Would you like to add it the person?' + ), + title: m('Add email address'), + }, surveyForm: { accept: m('I accept the terms stated below'), error: m( diff --git a/src/features/surveys/store.ts b/src/features/surveys/store.ts index db0513878..73035d4fc 100644 --- a/src/features/surveys/store.ts +++ b/src/features/surveys/store.ts @@ -1,5 +1,6 @@ import { createSlice, PayloadAction } from '@reduxjs/toolkit'; +import { personUpdated } from 'features/profile/store'; import { SurveyStats } from './rpc/getSurveyStats'; import { ELEMENT_TYPE, @@ -39,6 +40,33 @@ const initialState: SurveysStoreSlice = { }; const surveysSlice = createSlice({ + extraReducers: (builder) => + builder.addCase(personUpdated, (state, action) => { + const person = action.payload; + const item = state.submissionList.items.find( + (item) => item?.data?.respondent?.id === person.id + ); + + if (item?.data?.respondent) { + const respondent = item.data.respondent; + + if (person.email) { + respondent.email = person.email; + } + if (person.first_name) { + respondent.first_name = person.first_name; + } + if (person.last_name) { + respondent.last_name = person.last_name; + } + } + const submissionsUpdated = state.submissionList.items + .map((item) => item.data) + .filter((data): data is ZetkinSurveySubmission => data !== null); + + addSubmissionToState(state, submissionsUpdated); + }), + initialState, name: 'surveys', reducers: {