diff --git a/frontend/public/locales/en/common.json b/frontend/public/locales/en/common.json index 06e4febf51b28aca1862859d25620c884fe789fd..5ff11a78228ca0b41391eb9512252edfb4c459cb 100644 --- a/frontend/public/locales/en/common.json +++ b/frontend/public/locales/en/common.json @@ -58,6 +58,12 @@ "activeGuests": "Your active guests", "activeGuestsDescription": "Make changes to your existing guests", "noActiveGuests": "No active guests", + "sentInvitations": "Sent invitations", + "sentInvitationsDescription": "Invitations awaiting response from guest.", + "noInvitations": "No invitations", + "status": "Status", + "active": "Active", + "expired": "Expired", "details": "Details", "nationalIdNumber": "National ID number", "validation": { diff --git a/frontend/public/locales/nb/common.json b/frontend/public/locales/nb/common.json index 0a715f9e268d974c3d151c401c6233c4550d87aa..4b2b4ae26ee9f88e176106e32ff593fa2bb02d76 100644 --- a/frontend/public/locales/nb/common.json +++ b/frontend/public/locales/nb/common.json @@ -57,6 +57,12 @@ "activeGuests": "Dine aktive gjester", "activeGuestsDescription": "Her kan du endre på eksisterende gjester", "noActiveGuests": "Ingen aktive gjester", + "sentInvitations": "Sendte invitasjoner", + "sentInvitationsDescription": "Invitasjoner som venter på at gjesten skal ferdigstille registreringen.", + "noInvitations": "Ingen invitasjoner", + "status": "Status", + "active": "Aktiv", + "expired": "Utgått", "details": "Detaljer", "nationalIdNumber": "Fødselsnummer", "validation": { diff --git a/frontend/public/locales/nn/common.json b/frontend/public/locales/nn/common.json index 7cfe9c12f4ece559cdff4a4fc9e35824ef0bb2aa..23ff342f4192359ebd8760f491d4d24b3fd326ad 100644 --- a/frontend/public/locales/nn/common.json +++ b/frontend/public/locales/nn/common.json @@ -58,6 +58,12 @@ "activeGuests": "Dine aktive gjester", "activeGuestsDescription": "Her kan du endre på eksisterende gjester", "noActiveGuests": "Ingen aktive gjester", + "sentInvitations": "Sendte invitasjonar", + "sentInvitationsDescription": "Invitasjonar som venter på at gjesten skal ferdigstille registreringa.", + "noInvitations": "Ingen invitasjonar", + "status": "Status", + "active": "Aktiv", + "expired": "Utgått", "details": "Detaljer", "nationalIdNumber": "Fødselsnummer", "validation": { diff --git a/frontend/src/interfaces/index.ts b/frontend/src/interfaces/index.ts index 9dad342987b651d1e214c55b6aa0159d8dccf4fd..2fcb395309af8118e41f2e79078a293881338a64 100644 --- a/frontend/src/interfaces/index.ts +++ b/frontend/src/interfaces/index.ts @@ -6,6 +6,8 @@ export type Guest = { mobile: string fnr: string active: boolean + registered: boolean + verified: boolean roles: Role[] } @@ -17,6 +19,8 @@ export interface FetchedGuest { mobile: string fnr: string active: boolean + registered: boolean + verified: boolean roles: FetchedRole[] } diff --git a/frontend/src/routes/sponsor/frontpage/index.tsx b/frontend/src/routes/sponsor/frontpage/index.tsx index 3d2a10a52df14bc04392158ee467121478680c82..d20af82b1dd33929132485347856ff5d4062d075 100644 --- a/frontend/src/routes/sponsor/frontpage/index.tsx +++ b/frontend/src/routes/sponsor/frontpage/index.tsx @@ -24,12 +24,14 @@ import SponsorGuestButtons from '../../components/sponsorGuestButtons' interface GuestProps { persons: Guest[] } + interface PersonLineProps { person: Guest role: Role + showStatusColumn?: boolean } -const PersonLine = ({ person, role }: PersonLineProps) => { +const PersonLine = ({ person, role, showStatusColumn }: PersonLineProps) => { const [t, i18n] = useTranslation(['common']) return ( @@ -43,6 +45,18 @@ const PersonLine = ({ person, role }: PersonLineProps) => { <TableCell align="left"> {i18n.language === 'en' ? role.name_en : role.name_nb} </TableCell> + + {showStatusColumn && + (person.active ? ( + <TableCell sx={{ color: 'green' }} align="left"> + {t('common:active')} + </TableCell> + ) : ( + <TableCell sx={{ color: 'red' }} align="left"> + {t('common:expired')} + </TableCell> + ))} + <TableCell align="left"> {role.start_date ? format(role.start_date, 'yyyy-MM-dd') : null} -{' '} {format(role.end_date, 'yyyy-MM-dd')} @@ -63,13 +77,78 @@ const PersonLine = ({ person, role }: PersonLineProps) => { ) } +PersonLine.defaultProps = { + showStatusColumn: false, +} + +const WaitingForGuestRegistration = ({ persons }: GuestProps) => { + const [activeExpanded, setActiveExpanded] = useState(false) + + // Show guests that have not responded to the invite yet + let guests = persons.length > 0 ? persons : [] + + if (guests.length > 0) { + guests = guests.filter((person) => !person.registered) + } + const [t] = useTranslation(['common']) + return ( + <Accordion + expanded={activeExpanded} + onChange={() => { + setActiveExpanded(!activeExpanded) + }} + > + <AccordionSummary expandIcon={<ExpandMoreIcon />}> + <h4>{t('common:sentInvitations')}</h4> + </AccordionSummary> + <AccordionDetails> + <p>{t('common:sentInvitationsDescription')}</p> + <TableContainer component={Paper}> + <Table sx={{ minWidth: 650 }} aria-label="simple table"> + <TableHead sx={{ backgroundColor: 'primary.light' }}> + <TableRow> + <TableCell>{t('common:name')}</TableCell> + <TableCell align="left">{t('common:role')}</TableCell> + <TableCell align="left">{t('common:period')}</TableCell> + <TableCell align="left">{t('common:ou')}</TableCell> + <TableCell align="left">{t('common:choice')}</TableCell> + </TableRow> + </TableHead> + <TableBody> + {guests.length > 0 ? ( + guests.map((person) => + person.roles ? ( + person.roles.map((role) => ( + <PersonLine role={role} person={person} /> + )) + ) : ( + <></> + ) + ) + ) : ( + <></> + )} + + <TableRow> + <TableCell> + {guests.length > 0 ? '' : t('common:noActiveGuests')} + </TableCell> + </TableRow> + </TableBody> + </Table> + </TableContainer> + </AccordionDetails> + </Accordion> + ) +} + const ActiveGuests = ({ persons }: GuestProps) => { const [activeExpanded, setActiveExpanded] = useState(false) - // Only show active people + // Show all verified guests let guests = persons.length > 0 ? persons : [] if (guests.length > 0) { - guests = guests.filter((person) => person.active) + guests = guests.filter((person) => person.verified) } const [t] = useTranslation(['common']) return ( @@ -90,6 +169,9 @@ const ActiveGuests = ({ persons }: GuestProps) => { <TableRow> <TableCell>{t('common:name')}</TableCell> <TableCell align="left">{t('common:role')}</TableCell> + + <TableCell align="left">{t('common:status')}</TableCell> + <TableCell align="left">{t('common:period')}</TableCell> <TableCell align="left">{t('common:ou')}</TableCell> <TableCell align="left">{t('common:choice')}</TableCell> @@ -100,7 +182,11 @@ const ActiveGuests = ({ persons }: GuestProps) => { guests.map((person) => person.roles ? ( person.roles.map((role) => ( - <PersonLine role={role} person={person} /> + <PersonLine + role={role} + person={person} + showStatusColumn + /> )) ) : ( <></> @@ -126,10 +212,10 @@ const ActiveGuests = ({ persons }: GuestProps) => { const WaitingGuests = ({ persons }: GuestProps) => { const [waitingExpanded, setWaitingExpanded] = useState(false) - // Only show non-active people + // Show guests that have completed the registration but are not verified yet let guests = persons.length > 0 ? persons : [] if (guests.length > 0) { - guests = guests.filter((person) => !person.active) + guests = guests.filter((person) => person.registered && !person.verified) } const [t] = useTranslation(['common']) @@ -193,6 +279,7 @@ function FrontPage({ guests }: FrontPageProps) { return ( <Page> <SponsorGuestButtons yourGuestsActive /> + <WaitingForGuestRegistration persons={guests} /> <WaitingGuests persons={guests} /> <ActiveGuests persons={guests} /> </Page> diff --git a/frontend/src/routes/sponsor/guestInfo/index.tsx b/frontend/src/routes/sponsor/guestInfo/index.tsx index 0e46c0799d6437f6554eec76fe5732d1bae6513c..ea8dad32642d6d381082de3b8d5258c3aa4acfbf 100644 --- a/frontend/src/routes/sponsor/guestInfo/index.tsx +++ b/frontend/src/routes/sponsor/guestInfo/index.tsx @@ -67,6 +67,8 @@ export default function GuestInfo() { fnr: '', mobile: '', active: false, + registered: false, + verified: false, roles: [], }) const [roles, setRoles] = useState<Role[]>([]) @@ -84,6 +86,8 @@ export default function GuestInfo() { mobile: rjson.mobile, fnr: rjson.fnr, active: rjson.active, + registered: rjson.registered, + verified: rjson.verified, roles: rjson.roles, }) setRoles(rjson.roles.map((role: FetchedRole) => parseRole(role))) diff --git a/frontend/src/routes/sponsor/index.tsx b/frontend/src/routes/sponsor/index.tsx index e097b1b0881e35efcb447c5c4da83dd9e66ddde6..1df6b21dc7f462e8dfc369de0f765c732191ab89 100644 --- a/frontend/src/routes/sponsor/index.tsx +++ b/frontend/src/routes/sponsor/index.tsx @@ -27,6 +27,8 @@ function Sponsor() { fnr: person.fnr, active: person.active, roles: person.roles.map((role) => parseRole(role)), + registered: person.registered, + verified: person.verified, }) ) ) diff --git a/gregui/views.py b/gregui/views.py index b2be0d591e74caddb26178d6b9985d17c41afea9..15e6e264ce87afe18682107efe00ee6980cb6daa 100644 --- a/gregui/views.py +++ b/gregui/views.py @@ -106,6 +106,8 @@ class GuestInfoView(APIView): "mobile": person.private_mobile and person.private_mobile.value, "fnr": person.fnr and "".join((person.fnr.value[:-5], "*****")), "active": person.is_registered and person.is_verified, + "registered": person.is_registered, + "verified": person.is_verified, "roles": [ { "id": role.id,