From 3aa9c778f4691e0b179691ec4b74e83f8383ef75 Mon Sep 17 00:00:00 2001
From: Marte Fossum <myf@uio.no>
Date: Tue, 17 Jan 2023 10:42:07 +0100
Subject: [PATCH] GREG-309: Show confirmation or error box when cancel
 invitation

---
 frontend/public/locales/en/common.json        |   2 +
 frontend/public/locales/nb/common.json        |   2 +
 frontend/public/locales/nn/common.json        |   2 +
 .../routes/components/sponsorGuestButtons.tsx | 130 ++++++++++--------
 .../routes/sponsor/guest/guestInfo/index.tsx  |  13 +-
 5 files changed, 92 insertions(+), 57 deletions(-)

diff --git a/frontend/public/locales/en/common.json b/frontend/public/locales/en/common.json
index fec1141f..1a4a743b 100644
--- a/frontend/public/locales/en/common.json
+++ b/frontend/public/locales/en/common.json
@@ -51,6 +51,7 @@
     "choiceDate": "Choice date",
     "consentName": "Consent type",
     "periodChanged": "Period changed",
+    "invitationCancelled": "The invitation to {{name}} cancelled",
     "registeredInfo": "Registererd information on you",
     "registeredInfoExplanation": "Here is the contact information, roles and consent information that is registered on you.",
     "roleInfoHead": "Roles and periods",
@@ -199,6 +200,7 @@
   "error": {
     "error": "Error",
     "changePeriodFailed": "Failed to change period",
+    "invitationCancelFailed": "Failed to cancel invite",
     "invitationCreationFailedHeader": "Failed to create invite",
     "errorStatusCode": "Status code: {{statusCode}} (<3>{{statusText}}</3>)",
     "genericServerErrorBody": "Message:<1>{{errorBodyText}}</1>",
diff --git a/frontend/public/locales/nb/common.json b/frontend/public/locales/nb/common.json
index bba31d68..4a864726 100644
--- a/frontend/public/locales/nb/common.json
+++ b/frontend/public/locales/nb/common.json
@@ -51,6 +51,7 @@
     "choiceDate": "Valgdato",
     "consentName": "Samtykketype",
     "periodChanged": "Rolleperiode endret",
+    "invitationCancelled": "Invitasjonen til {{name}} kansellert",
     "registeredInfo": "Registrert informasjon om deg",
     "registeredInfoExplanation": "Her er en oversikt over kontaktinformasjon, roller og samtykker som er registrert om deg.",
     "roleInfoHead": "Roller og perioder",
@@ -199,6 +200,7 @@
   "error": {
     "error": "Feil",
     "changePeriodFailed": "Kunne ikke endre periode",
+    "invitationCancelFailed": "Kunne ikke kansellere invitasjon",
     "invitationCreationFailedHeader": "Kunne ikke opprette invitasjon",
     "errorStatusCode": "Statuskode: {{statusCode}} (<3>{{statusText}}</3>)",
     "genericServerErrorBody": "Melding:<1>{{errorBodyText}}</1>",
diff --git a/frontend/public/locales/nn/common.json b/frontend/public/locales/nn/common.json
index cff78a45..1e8ce82a 100644
--- a/frontend/public/locales/nn/common.json
+++ b/frontend/public/locales/nn/common.json
@@ -51,6 +51,7 @@
     "choiceDate": "Valdato",
     "consentName": "Samtykketype",
     "periodChanged": "Rolleperiode endra",
+    "invitationCancelled": "Invitasjonen til {{name}} kansellert",
     "registeredInfo": "Registrert informasjon om deg",
     "registeredInfoExplanation": "Her er ei oversikt over kontaktinformasjon, roller og samtykke som er registrert om deg.",
     "roleInfoTableText": "Gjesteroller",
@@ -199,6 +200,7 @@
   "error": {
     "error": "Feil",
     "changePeriodFailed": "Kunne ikkje endre periode",
+    "invitationCancelFailed": "Kunne ikkje kansellere invitasjon",
     "invitationCreationFailedHeader": "Kunne ikkje opprette invitasjon",
     "errorStatusCode": "Statuskode: {{statusCode}} (<3>{{statusText}}</3>)",
     "genericServerErrorBody": "Melding:<1>{{errorBodyText}}</1>",
diff --git a/frontend/src/routes/components/sponsorGuestButtons.tsx b/frontend/src/routes/components/sponsorGuestButtons.tsx
index af30b5ba..2b1168d7 100644
--- a/frontend/src/routes/components/sponsorGuestButtons.tsx
+++ b/frontend/src/routes/components/sponsorGuestButtons.tsx
@@ -1,9 +1,8 @@
 import PersonIcon from '@mui/icons-material/Person'
-import { Box, IconButton, styled, Theme } from '@mui/material'
+import { Alert, Box, IconButton, styled, Theme } from '@mui/material'
 import PersonAddIcon from '@mui/icons-material/PersonAdd'
-import React from 'react'
 import { useTranslation } from 'react-i18next'
-import { useNavigate } from 'react-router-dom'
+import { useLocation, useNavigate } from 'react-router-dom'
 
 interface SponsorGuestButtonsProps {
   yourGuestsActive?: boolean
@@ -17,11 +16,19 @@ const StyledIconButton = styled(IconButton)({
   fontSize: '1.375rem',
 })
 
+interface LocationState {
+  cancelledInvitationFor: string
+}
+
 export default function SponsorGuestButtons(props: SponsorGuestButtonsProps) {
   const { yourGuestsActive, registerNewGuestActive } = props
   const { t } = useTranslation(['common'])
   const navigate = useNavigate()
 
+  const location = useLocation()
+  const state = location.state as LocationState
+  const cancelledInvitationFor = state?.cancelledInvitationFor || ''
+
   const goToOverview = () => {
     navigate('/sponsor')
   }
@@ -31,66 +38,79 @@ export default function SponsorGuestButtons(props: SponsorGuestButtonsProps) {
   }
 
   return (
-    <Box
-      sx={{
-        display: 'flex',
-        flexDirection: 'row',
-        justifyContent: 'space-evenly',
-        marginBottom: '2rem',
-        fontSize: '1.375rem',
-      }}
-    >
-      <StyledIconButton
-        onClick={goToOverview}
+    <Box sx={{ display: 'flex', flexDirection: 'column' }}>
+      <Box
         sx={{
-          color: () => (yourGuestsActive ? 'black' : undefined),
-          textDecorationLine: () => (yourGuestsActive ? 'underline' : ''),
+          display: 'flex',
+          flexDirection: 'row',
+          justifyContent: 'space-evenly',
+          marginBottom: '2rem',
+          fontSize: '1.375rem',
         }}
       >
-        <PersonIcon
+        <StyledIconButton
+          onClick={goToOverview}
           sx={{
-            fontSize: '5rem',
-            borderRadius: '4rem',
-            borderStyle: 'solid',
-            borderColor: (theme: Theme) =>
-              yourGuestsActive
-                ? theme.palette.secondary.main
-                : theme.greg.deactivatedColor,
-            fill: 'white',
-            backgroundColor: (theme: Theme) =>
-              yourGuestsActive
-                ? theme.palette.secondary.main
-                : theme.greg.deactivatedColor,
+            color: () => (yourGuestsActive ? 'black' : undefined),
+            textDecorationLine: () => (yourGuestsActive ? 'underline' : ''),
           }}
-        />
-        {t('yourGuests')}
-      </StyledIconButton>
+        >
+          <PersonIcon
+            sx={{
+              fontSize: '5rem',
+              borderRadius: '4rem',
+              borderStyle: 'solid',
+              borderColor: (theme: Theme) =>
+                yourGuestsActive
+                  ? theme.palette.secondary.main
+                  : theme.greg.deactivatedColor,
+              fill: 'white',
+              backgroundColor: (theme: Theme) =>
+                yourGuestsActive
+                  ? theme.palette.secondary.main
+                  : theme.greg.deactivatedColor,
+            }}
+          />
+          {t('yourGuests')}
+        </StyledIconButton>
 
-      <StyledIconButton
-        onClick={goToRegister}
-        sx={{
-          color: () => (registerNewGuestActive ? 'black' : undefined),
-          textDecorationLine: () => (registerNewGuestActive ? 'underline' : ''),
-        }}
-      >
-        <PersonAddIcon
+        <StyledIconButton
+          onClick={goToRegister}
           sx={{
-            fontSize: '5rem',
-            borderRadius: '4rem',
-            borderStyle: 'solid',
-            borderColor: (theme: Theme) =>
-              registerNewGuestActive
-                ? theme.palette.secondary.main
-                : theme.greg.deactivatedColor,
-            fill: 'white',
-            backgroundColor: (theme: Theme) =>
-              registerNewGuestActive
-                ? theme.palette.secondary.main
-                : theme.greg.deactivatedColor,
+            color: () => (registerNewGuestActive ? 'black' : undefined),
+            textDecorationLine: () =>
+              registerNewGuestActive ? 'underline' : '',
           }}
-        />
-        {t('registerNewGuest')}
-      </StyledIconButton>
+        >
+          <PersonAddIcon
+            sx={{
+              fontSize: '5rem',
+              borderRadius: '4rem',
+              borderStyle: 'solid',
+              borderColor: (theme: Theme) =>
+                registerNewGuestActive
+                  ? theme.palette.secondary.main
+                  : theme.greg.deactivatedColor,
+              fill: 'white',
+              backgroundColor: (theme: Theme) =>
+                registerNewGuestActive
+                  ? theme.palette.secondary.main
+                  : theme.greg.deactivatedColor,
+            }}
+          />
+          {t('registerNewGuest')}
+        </StyledIconButton>
+      </Box>
+      {cancelledInvitationFor && (
+        <Alert
+          sx={{ fontSize: '1.375rem', marginTop: '1rem', marginBottom: '1rem' }}
+          severity="info"
+        >
+          {t('guestInfo.invitationCancelled', {
+            name: cancelledInvitationFor,
+          })}
+        </Alert>
+      )}
     </Box>
   )
 }
diff --git a/frontend/src/routes/sponsor/guest/guestInfo/index.tsx b/frontend/src/routes/sponsor/guest/guestInfo/index.tsx
index 18d304c1..eece2f39 100644
--- a/frontend/src/routes/sponsor/guest/guestInfo/index.tsx
+++ b/frontend/src/routes/sponsor/guest/guestInfo/index.tsx
@@ -102,6 +102,7 @@ export default function GuestInfo({
   const [emailUpdateError, setEmailUpdateError] =
     useState<ServerErrorReportData>()
   const [updateOKMsg, setUpdateOKMsg] = useState<string>('')
+  const [showErrorMessage, setShowErrorMessage] = useState<Boolean>(false)
 
   // Using useForm even though only the e-mail is allow to change at present, since useForm makes setup and validation easier
   const {
@@ -206,11 +207,14 @@ export default function GuestInfo({
         if (result !== null) {
           // The invite for the guest has been cancelled, send the user back to the sponsor front page
           reloadGuests()
-          navigate('/sponsor')
+          navigate('/sponsor', {
+            state: { cancelledInvitationFor: `${guest.first} ${guest.last}` },
+          })
         }
       })
       .catch((error) => {
-        // TODO User should get some feedback telling him something failed
+        setConfirmCancelDialogOpen(false)
+        setShowErrorMessage(true)
         console.log('error', error)
       })
   }
@@ -262,6 +266,11 @@ export default function GuestInfo({
               {t(updateOKMsg)}
             </Alert>
           )}
+          {showErrorMessage && (
+            <Alert severity="error" sx={{ marginBottom: '1rem' }}>
+              {t('error.invitationCancelFailed')}
+            </Alert>
+          )}
           {showEmailSent && (
             <Alert
               severity="success"
-- 
GitLab