From 59fe49e5933e218e3902b9b66d1c3254f5ff417e Mon Sep 17 00:00:00 2001 From: hhn <hhn@uio.no> Date: Mon, 21 Aug 2023 15:37:30 +0200 Subject: [PATCH] Add ability for sponsors to filter expired guests from confirmed guest table Filtering is toggleable through a checkbox. --- frontend/public/locales/en/common.json | 1 + frontend/public/locales/nb/common.json | 1 + frontend/public/locales/nn/common.json | 1 + .../src/routes/sponsor/frontpage/index.tsx | 69 ++++++++++++++++++- 4 files changed, 71 insertions(+), 1 deletion(-) diff --git a/frontend/public/locales/en/common.json b/frontend/public/locales/en/common.json index e89574e0..2d1afd33 100644 --- a/frontend/public/locales/en/common.json +++ b/frontend/public/locales/en/common.json @@ -107,6 +107,7 @@ "foundNoGuests": "Found no guests", "sentInvitations": "Sent invitations", "placeholder": "Search for guest", + "filterGuests": "Filter expired guests", "chooseUnits": "Choose unit(s)", "sentInvitationsDescription": "Invitations awaiting response from guest.", "noInvitations": "No invitations", diff --git a/frontend/public/locales/nb/common.json b/frontend/public/locales/nb/common.json index 5e9091fe..e61869ca 100644 --- a/frontend/public/locales/nb/common.json +++ b/frontend/public/locales/nb/common.json @@ -107,6 +107,7 @@ "foundNoGuests": "Fant ingen gjester", "sentInvitations": "Sendte invitasjoner", "placeholder": "Søk etter gjest", + "filterGuests": "Filtrer utgåtte gjester", "chooseUnits": "Velg avdeling(er)", "sentInvitationsDescription": "Invitasjoner som venter på at gjesten skal ferdigstille registreringen.", "noInvitations": "Ingen invitasjoner", diff --git a/frontend/public/locales/nn/common.json b/frontend/public/locales/nn/common.json index 6a931673..37fbc45d 100644 --- a/frontend/public/locales/nn/common.json +++ b/frontend/public/locales/nn/common.json @@ -107,6 +107,7 @@ "foundNoGuests": "Fann ingen gjester", "sentInvitations": "Sendte invitasjonar", "placeholder": "Søk etter gjest", + "filterGuests": "Filtrer utgåtte gjester", "chooseUnits": "Vel avdeling(ar)", "sentInvitationsDescription": "Invitasjonar som venter på at gjesten skal ferdigstille registreringa.", "noInvitations": "Ingen invitasjonar", diff --git a/frontend/src/routes/sponsor/frontpage/index.tsx b/frontend/src/routes/sponsor/frontpage/index.tsx index fe091143..97dc7355 100644 --- a/frontend/src/routes/sponsor/frontpage/index.tsx +++ b/frontend/src/routes/sponsor/frontpage/index.tsx @@ -1,4 +1,5 @@ import { useEffect, useState } from 'react' +import _ from 'lodash' import ArrowUpwardIcon from '@mui/icons-material/ArrowUpward' import NotificationsActiveIcon from '@mui/icons-material/NotificationsActive' @@ -7,6 +8,7 @@ import { AccordionDetails, AccordionSummary, Button, + Checkbox, Chip, FormControl, InputAdornment, @@ -41,6 +43,11 @@ interface GuestProps { persons: Guest[] } +interface FilterInactiveGuestsCheckboxProps { + isChecked: boolean + onChange: () => void +} + interface PersonLineProps { person: Guest role: Role @@ -653,6 +660,15 @@ function ActiveGuests({ persons }: GuestProps) { const [selectedUnits, setSelectedUnits] = useState<string[]>([]) const [searchInput, setSearchInput] = useState<string>('') const [searching, setSearching] = useState<boolean>(false) + const initialHideInactiveGuests = localStorage.getItem('hideInactiveGuests') + const [hideInactiveGuests, setHideInactiveGuests] = useState<boolean>( + initialHideInactiveGuests === null + ? false + : JSON.parse(initialHideInactiveGuests) + ) + const [filteredInactiveGuests, setFilteredInactiveGuests] = useState<Guest[]>( + [] + ) const [t] = useTranslation(['common']) @@ -684,6 +700,22 @@ function ActiveGuests({ persons }: GuestProps) { return () => clearTimeout(delaySearch) }, [searchInput]) + useEffect(() => { + if (!hideInactiveGuests) { + return () => setFilteredInactiveGuests([]) + } + const guestsCopy = + searchGuests.length > 0 ? _.cloneDeep(searchGuests) : _.cloneDeep(guests) + // eslint-disable-next-line no-restricted-syntax + for (const guest of guestsCopy) { + guest.roles = guest.roles.filter( + (role) => calculateStatus(guest, role)[0] !== 'expired' + ) + } + setFilteredInactiveGuests(guestsCopy) + return () => {} + }, [hideInactiveGuests, searchGuests]) + const getSponsorGuests = (event: React.ChangeEvent<HTMLInputElement>) => { if (event.target.value) { setSearchInput(event.target.value.toLowerCase()) @@ -692,6 +724,31 @@ function ActiveGuests({ persons }: GuestProps) { } } + const FilterInactiveGuestsCheckbox = ({ + isChecked, + onChange, + }: FilterInactiveGuestsCheckboxProps) => ( + <div> + <Typography + variant="body1" + sx={{ marginTop: '.5rem', marginBottom: '.5rem' }} + > + <Checkbox checked={isChecked} onChange={onChange} /> + {t('common:filterGuests')} + </Typography> + </div> + ) + + const getConfirmedGuests = () => { + if (hideInactiveGuests) { + return filteredInactiveGuests + } + if (searchInput) { + return searchGuests + } + return guests + } + return ( <StyledAccordion expanded={activeExpanded} @@ -737,6 +794,16 @@ function ActiveGuests({ persons }: GuestProps) { placeholder={t('placeholder')} onChange={getSponsorGuests} /> + <FilterInactiveGuestsCheckbox + isChecked={hideInactiveGuests} + onChange={() => { + setHideInactiveGuests(!hideInactiveGuests) + localStorage.setItem( + 'hideInactiveGuests', + (!hideInactiveGuests).toString() + ) + }} + /> </FormControl> <UnitFilterSelect guests={guests} @@ -745,7 +812,7 @@ function ActiveGuests({ persons }: GuestProps) { </Box> {!searching ? ( <GuestTable - guests={searchInput ? searchGuests : guests} + guests={getConfirmedGuests()} emptyText={ searchInput ? t('common:foundNoGuests') -- GitLab