From 4bc9d3144a467f8351610ab4e107a08fc773017d Mon Sep 17 00:00:00 2001 From: Rebe R <36491300+rebecarubio@users.noreply.github.com> Date: Fri, 13 Dec 2024 12:26:50 +0100 Subject: [PATCH 1/3] add check to trigger handleUpdateEmail() --- .../components/SurveySubmissionsList.tsx | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/src/features/surveys/components/SurveySubmissionsList.tsx b/src/features/surveys/components/SurveySubmissionsList.tsx index 14a96d63a0..b199a46089 100644 --- a/src/features/surveys/components/SurveySubmissionsList.tsx +++ b/src/features/surveys/components/SurveySubmissionsList.tsx @@ -7,7 +7,7 @@ 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 SurveySubmissionPane from '../panes/SurveySubmissionPane'; @@ -30,6 +30,15 @@ const SurveySubmissionsList = ({ const messages = useMessages(messageIds); const { orgId } = useRouter().query; const { openPane } = usePanes(); + const [dialogOpen, setDialogOpen] = useState(false); + const [dialogPerson, setDialogPerson] = useState(); + const [dialogEmail, setDialogEmail] = useState(''); + + const handleUpdateEmail = (option: ZetkinPerson, email: string) => { + setDialogEmail(email); + setDialogPerson(option); + setDialogOpen(true); + }; const sortedSubmissions = useMemo(() => { const sorted = [...submissions].sort((subOne, subTwo) => { @@ -198,6 +207,12 @@ const SurveySubmissionsList = ({ id: row.id, }); setRespondentId(person?.id || null); + + const personHasNoEmail = person?.id !== null && person?.email === null; + const respondentEmail = row.respondent?.email; + if (personHasNoEmail && respondentEmail !== undefined) { + handleUpdateEmail(person, respondentEmail); + } }; return ( From 007e2465605f734dd88b291bbe69e3280e76b0fa Mon Sep 17 00:00:00 2001 From: Rebe R <36491300+rebecarubio@users.noreply.github.com> Date: Fri, 13 Dec 2024 12:29:00 +0100 Subject: [PATCH 2/3] add surveySubmissionsList component and implement it --- .../surveys/components/SurveyDialogLink.tsx | 66 +++++++++++++++++++ .../components/SurveySubmissionsList.tsx | 9 +++ src/features/surveys/l10n/messageIds.ts | 8 +++ 3 files changed, 83 insertions(+) create mode 100644 src/features/surveys/components/SurveyDialogLink.tsx diff --git a/src/features/surveys/components/SurveyDialogLink.tsx b/src/features/surveys/components/SurveyDialogLink.tsx new file mode 100644 index 0000000000..c3fbcd450b --- /dev/null +++ b/src/features/surveys/components/SurveyDialogLink.tsx @@ -0,0 +1,66 @@ +import { ArrowForward } from '@mui/icons-material'; +import { + Box, + Button, + Dialog, + DialogActions, + DialogContent, + DialogTitle, + 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 SurveyDialogLink = ({ + 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 SurveyDialogLink; diff --git a/src/features/surveys/components/SurveySubmissionsList.tsx b/src/features/surveys/components/SurveySubmissionsList.tsx index b199a46089..790f95ea21 100644 --- a/src/features/surveys/components/SurveySubmissionsList.tsx +++ b/src/features/surveys/components/SurveySubmissionsList.tsx @@ -10,6 +10,7 @@ import { import { FC, useEffect, useMemo, useState } from 'react'; import messageIds from '../l10n/messageIds'; +import SurveyDialogLink from './SurveyDialogLink'; import SurveySubmissionPane from '../panes/SurveySubmissionPane'; import { useNumericRouteParams } from 'core/hooks'; import { usePanes } from 'utils/panes'; @@ -262,6 +263,14 @@ const SurveySubmissionsList = ({ border: 'none', }} /> + {dialogPerson && ( + setDialogOpen(false)} + open={dialogOpen} + person={dialogPerson} + /> + )} ); }; diff --git a/src/features/surveys/l10n/messageIds.ts b/src/features/surveys/l10n/messageIds.ts index f83e84f67a..311b8117f3 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 response does. Would you like to add it to the person?' + ), + title: m('Add email address'), + }, surveyForm: { accept: m('I accept the terms stated below'), error: m( From c2473003e13e4bde368d213c511927959cf37a95 Mon Sep 17 00:00:00 2001 From: Rebe R <36491300+rebecarubio@users.noreply.github.com> Date: Fri, 13 Dec 2024 12:35:02 +0100 Subject: [PATCH 3/3] add a new extraReducer to update the submissionsList when person is updated --- src/features/surveys/store.ts | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/src/features/surveys/store.ts b/src/features/surveys/store.ts index db05138783..73035d4fc9 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: {