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