From 799e031f3dc7204c215953f9f1bb123fbbb8990f Mon Sep 17 00:00:00 2001 From: Tore Brede <Tore.Brede@uib.no> Date: Thu, 25 Nov 2021 15:45:58 +0100 Subject: [PATCH] Putting guests into a hook and adding a reload function --- frontend/src/hooks/useGuests/index.tsx | 47 +++++++++++++++++++ .../routes/sponsor/guest/guestInfo/index.tsx | 9 ++-- frontend/src/routes/sponsor/guest/index.tsx | 7 ++- frontend/src/routes/sponsor/index.tsx | 40 ++-------------- gregui/api/views/invitation.py | 7 ++- 5 files changed, 65 insertions(+), 45 deletions(-) create mode 100644 frontend/src/hooks/useGuests/index.tsx diff --git a/frontend/src/hooks/useGuests/index.tsx b/frontend/src/hooks/useGuests/index.tsx new file mode 100644 index 00000000..d18b2465 --- /dev/null +++ b/frontend/src/hooks/useGuests/index.tsx @@ -0,0 +1,47 @@ +import { useEffect, useState } from 'react' +import { FetchedGuest, Guest } from '../../interfaces' +import { parseRole } from '../../utils' + +const useGuests = () => { + const [guests, setGuests] = useState<Guest[]>([]) + + const getGuestsInfo = async () => { + try { + const response = await fetch('/api/ui/v1/guests/?format=json') + const jsonResponse = await response.json() + if (response.ok) { + const persons = await jsonResponse.persons + setGuests( + persons.map( + (person: FetchedGuest): Guest => ({ + pid: person.pid, + first: person.first, + last: person.last, + email: person.email, + mobile: person.mobile, + fnr: person.fnr, + active: person.active, + roles: person.roles.map((role) => parseRole(role)), + registered: person.registered, + verified: person.verified, + }) + ) + ) + } + } catch (error) { + setGuests([]) + } + } + + const reloadGuests = () => { + getGuestsInfo() + } + + useEffect(() => { + getGuestsInfo() + }, []) + + return { guests, reloadGuests } +} + +export default useGuests diff --git a/frontend/src/routes/sponsor/guest/guestInfo/index.tsx b/frontend/src/routes/sponsor/guest/guestInfo/index.tsx index 453d4139..d01f6f02 100644 --- a/frontend/src/routes/sponsor/guest/guestInfo/index.tsx +++ b/frontend/src/routes/sponsor/guest/guestInfo/index.tsx @@ -33,6 +33,7 @@ type GuestInfoProps = { guest: Guest updateEmail: (validEmail: string) => void resend: () => void + reloadGuests: () => void } type CancelConfirmationDialogProps = { @@ -81,6 +82,7 @@ export default function GuestInfo({ guest, updateEmail, resend, + reloadGuests, }: GuestInfoProps) { const { pid } = useParams<GuestInfoParams>() const [t] = useTranslation(['common']) @@ -127,11 +129,8 @@ export default function GuestInfo({ .then((result) => { if (result !== null) { // The invite for the guest has been cancelled, send the user back to the sponsor front page - // Sending the user first to "/" since this clears the state. If the user is sent - // directly to "/sponsor" then the page does not reload and the cancelled entry is - // still in the list of sent invites - history.push('/') - history.replace('/sponsor') + reloadGuests() + history.push('/sponsor') } }) .catch((error) => { diff --git a/frontend/src/routes/sponsor/guest/index.tsx b/frontend/src/routes/sponsor/guest/index.tsx index c1a60676..8046bae7 100644 --- a/frontend/src/routes/sponsor/guest/index.tsx +++ b/frontend/src/routes/sponsor/guest/index.tsx @@ -9,7 +9,11 @@ type GuestInfoParams = { pid: string } -function GuestRoutes() { +type GuestRoutesProps = { + reloadGuests: () => void +} + +function GuestRoutes({ reloadGuests }: GuestRoutesProps) { const { pid } = useParams<GuestInfoParams>() const { guestInfo, reloadGuestInfo } = useGuest(pid) @@ -62,6 +66,7 @@ function GuestRoutes() { guest={guestInfo} updateEmail={updateEmail} resend={resend} + reloadGuests={reloadGuests} /> </Route> </> diff --git a/frontend/src/routes/sponsor/index.tsx b/frontend/src/routes/sponsor/index.tsx index d070e2b2..0ae81216 100644 --- a/frontend/src/routes/sponsor/index.tsx +++ b/frontend/src/routes/sponsor/index.tsx @@ -1,50 +1,16 @@ -import { useEffect, useState } from 'react' import { Route } from 'react-router-dom' import FrontPage from 'routes/sponsor/frontpage' -import { FetchedGuest, Guest } from 'interfaces' -import { parseRole } from 'utils' import GuestRoutes from './guest' +import useGuests from '../../hooks/useGuests' function Sponsor() { - const [guests, setGuests] = useState<Guest[]>([]) - - const getGuestsInfo = async () => { - try { - const response = await fetch('/api/ui/v1/guests/?format=json') - const jsonResponse = await response.json() - if (response.ok) { - const persons = await jsonResponse.persons - setGuests( - persons.map( - (person: FetchedGuest): Guest => ({ - pid: person.pid, - first: person.first, - last: person.last, - email: person.email, - mobile: person.mobile, - fnr: person.fnr, - active: person.active, - roles: person.roles.map((role) => parseRole(role)), - registered: person.registered, - verified: person.verified, - }) - ) - ) - } - } catch (error) { - setGuests([]) - } - } - - useEffect(() => { - getGuestsInfo() - }, []) + const { guests, reloadGuests } = useGuests() return ( <> <Route path="/sponsor/guest/:pid"> - <GuestRoutes /> + <GuestRoutes reloadGuests={reloadGuests} /> </Route> <Route exact path="/sponsor"> <FrontPage guests={guests} /> diff --git a/gregui/api/views/invitation.py b/gregui/api/views/invitation.py index bf32e2e7..88531650 100644 --- a/gregui/api/views/invitation.py +++ b/gregui/api/views/invitation.py @@ -80,8 +80,11 @@ class InvitationView(CreateAPIView, DestroyAPIView): return Response(status=status.HTTP_201_CREATED) def delete(self, request, *args, **kwargs) -> Response: - person_id = int(request.query_params["person_id"]) - person = Person.objects.get(id=person_id) + try: + person_id = int(request.query_params["person_id"]) + person = Person.objects.get(id=person_id) + except Person.DoesNotExist: + return Response(status=status.HTTP_404_NOT_FOUND) if person.is_registered or person.is_verified: # The guest has already gone through the registration step. The guest should -- GitLab