From ca0cdf59fda49719020e0987f5d4268139ffec53 Mon Sep 17 00:00:00 2001 From: Pyry Koivisto Date: Wed, 3 Jan 2024 14:51:31 +0200 Subject: [PATCH 1/4] YKI(Frontend): Improve error handling when subscribing to notifications of available seats [deploy] --- .../yki/public/i18n/fi-FI/public.json | 8 +++-- .../components/registration/EnrollToQueue.tsx | 31 ++++++------------- .../yki/src/interfaces/reservation.ts | 11 +++++++ .../yki/src/redux/reducers/reservation.ts | 16 +++++++--- .../yki/src/redux/sagas/reservation.ts | 16 ++++++++-- 5 files changed, 51 insertions(+), 31 deletions(-) diff --git a/frontend/packages/yki/public/i18n/fi-FI/public.json b/frontend/packages/yki/public/i18n/fi-FI/public.json index 2aab1aa51..783b26bde 100644 --- a/frontend/packages/yki/public/i18n/fi-FI/public.json +++ b/frontend/packages/yki/public/i18n/fi-FI/public.json @@ -108,13 +108,17 @@ "description": "Olet jo aiemmin tilannut ilmoituksen peruutuspaikoista sähköpostiisi.", "title": "Ilmoituksen tilaaminen ei onnistunut" }, - "genericError": { - "description": "Tapahtui odottamaton virhe. Voit yrittää uudelleen.", + "fullQueue": { + "description": "Kaikki peruutuspaikat ovat juuri nyt varattuja. Voit yrittää myöhemmin uudelleen.", "title": "Ilmoituksen tilaaminen ei onnistunut" }, "inputError": { "description": "Tarkista antamasi sähköpostiosoite.", "title": "Tiedoissa on korjattavaa!" + }, + "unknown": { + "description": "Tapahtui odottamaton virhe. Voit yrittää uudelleen.", + "title": "Ilmoituksen tilaaminen ei onnistunut" } }, "header": "Tilaa ilmoitus peruutuspaikoista", diff --git a/frontend/packages/yki/src/components/registration/EnrollToQueue.tsx b/frontend/packages/yki/src/components/registration/EnrollToQueue.tsx index 47a5e521d..f496d8299 100644 --- a/frontend/packages/yki/src/components/registration/EnrollToQueue.tsx +++ b/frontend/packages/yki/src/components/registration/EnrollToQueue.tsx @@ -43,7 +43,7 @@ const getConfirmEmailError = (email: string, confirmEmail: string) => { const useDialogOnError = () => { const { showDialog } = useDialog(); - const { status, emailAlreadyQueued } = useAppSelector(reservationSelector); + const { status, errorCause } = useAppSelector(reservationSelector); const { t } = usePublicTranslation({ keyPrefix: 'yki.component.registration.enrollToQueue.dialog', }); @@ -51,27 +51,16 @@ const useDialogOnError = () => { useEffect(() => { if (status === APIResponseStatus.Error) { - if (emailAlreadyQueued) { - showDialog({ - title: t('emailAlreadyQueued.title'), - description: t('emailAlreadyQueued.description'), - severity: Severity.Info, - actions: [ - { title: translateCommon('back'), variant: Variant.Contained }, - ], - }); - } else { - showDialog({ - title: t('genericError.title'), - description: t('genericError.description'), - severity: Severity.Error, - actions: [ - { title: translateCommon('back'), variant: Variant.Contained }, - ], - }); - } + showDialog({ + title: t(`${errorCause}.title`), + description: t(`${errorCause}.description`), + severity: Severity.Info, + actions: [ + { title: translateCommon('back'), variant: Variant.Contained }, + ], + }); } - }, [emailAlreadyQueued, showDialog, status, t, translateCommon]); + }, [errorCause, showDialog, status, t, translateCommon]); }; export const EnrollToQueue = () => { diff --git a/frontend/packages/yki/src/interfaces/reservation.ts b/frontend/packages/yki/src/interfaces/reservation.ts index 98458f642..600769156 100644 --- a/frontend/packages/yki/src/interfaces/reservation.ts +++ b/frontend/packages/yki/src/interfaces/reservation.ts @@ -2,3 +2,14 @@ export interface ReservationRequest { email: string; examSessionId: number; } + +export interface ReservationErrorResponse { + exists: boolean; + full: boolean; +} + +export enum ReservationErrorCause { + EmailAlreadyQueued = 'emailAlreadyQueued', + FullQueue = 'fullQueue', + Unknown = 'unknown', +} diff --git a/frontend/packages/yki/src/redux/reducers/reservation.ts b/frontend/packages/yki/src/redux/reducers/reservation.ts index 2845f8695..6da991ef7 100644 --- a/frontend/packages/yki/src/redux/reducers/reservation.ts +++ b/frontend/packages/yki/src/redux/reducers/reservation.ts @@ -1,16 +1,18 @@ import { createSlice, PayloadAction } from '@reduxjs/toolkit'; import { APIResponseStatus } from 'shared/enums'; -import { ReservationRequest } from 'interfaces/reservation'; +import { + ReservationErrorCause, + ReservationRequest, +} from 'interfaces/reservation'; interface ReservationState extends Partial { status: APIResponseStatus; - emailAlreadyQueued: boolean; + errorCause?: ReservationErrorCause; } const initialState: ReservationState = { status: APIResponseStatus.NotStarted, - emailAlreadyQueued: false, }; const reservationSlice = createSlice({ @@ -20,15 +22,19 @@ const reservationSlice = createSlice({ acceptReservationRequest(state) { state.status = APIResponseStatus.Success; }, - rejectReservationRequest(state, action: PayloadAction) { + rejectReservationRequest( + state, + action: PayloadAction + ) { state.status = APIResponseStatus.Error; - state.emailAlreadyQueued = action.payload; + state.errorCause = action.payload; }, resetReservationRequest(_) { return initialState; }, sendReservationRequest(state, action: PayloadAction) { state.status = APIResponseStatus.InProgress; + state.errorCause = undefined; state.email = action.payload.email; state.examSessionId = action.payload.examSessionId; }, diff --git a/frontend/packages/yki/src/redux/sagas/reservation.ts b/frontend/packages/yki/src/redux/sagas/reservation.ts index b5ff4557d..47f42565f 100644 --- a/frontend/packages/yki/src/redux/sagas/reservation.ts +++ b/frontend/packages/yki/src/redux/sagas/reservation.ts @@ -5,7 +5,11 @@ import { call, put, takeLatest } from 'redux-saga/effects'; import axiosInstance from 'configs/axios'; import { getCurrentLang } from 'configs/i18n'; import { APIEndpoints } from 'enums/api'; -import { ReservationRequest } from 'interfaces/reservation'; +import { + ReservationErrorCause, + ReservationErrorResponse, + ReservationRequest, +} from 'interfaces/reservation'; import { acceptReservationRequest, rejectReservationRequest, @@ -32,9 +36,15 @@ function* sendReservationRequestSaga( yield put(acceptReservationRequest()); } catch (error) { if (axios.isAxiosError(error) && error.response) { - yield put(rejectReservationRequest(!!error.response.data)); + const errorResponse = error.response.data as ReservationErrorResponse; + const errorCause = errorResponse.exists + ? ReservationErrorCause.EmailAlreadyQueued + : errorResponse.full + ? ReservationErrorCause.FullQueue + : ReservationErrorCause.Unknown; + yield put(rejectReservationRequest(errorCause)); } else { - yield put(rejectReservationRequest(false)); + yield put(rejectReservationRequest(ReservationErrorCause.Unknown)); } } } From f2e89c675ec257f89eefe8542a22e1608b02ad59 Mon Sep 17 00:00:00 2001 From: Pyry Koivisto Date: Fri, 12 Jan 2024 13:02:18 +0200 Subject: [PATCH 2/4] YKI(Frontend): Add translations supplied by OPH --- frontend/packages/yki/public/i18n/en-GB/public.json | 4 ++++ frontend/packages/yki/public/i18n/fi-FI/public.json | 2 +- frontend/packages/yki/public/i18n/sv-SE/public.json | 4 ++++ 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/frontend/packages/yki/public/i18n/en-GB/public.json b/frontend/packages/yki/public/i18n/en-GB/public.json index e57619d8b..04289e2c5 100644 --- a/frontend/packages/yki/public/i18n/en-GB/public.json +++ b/frontend/packages/yki/public/i18n/en-GB/public.json @@ -108,6 +108,10 @@ "description": "You have already subscribed for notifications of available seats.", "title": "Subscription failed" }, + "fullQueue": { + "description": "You can no longer subscribe for notifications for this test. The maximum number of subscribers is 50.", + "title": "Subscription failed" + }, "genericError": { "description": "An unexpected error occurred. Please try again.", "title": "Subscription failed" diff --git a/frontend/packages/yki/public/i18n/fi-FI/public.json b/frontend/packages/yki/public/i18n/fi-FI/public.json index 783b26bde..4b0d93024 100644 --- a/frontend/packages/yki/public/i18n/fi-FI/public.json +++ b/frontend/packages/yki/public/i18n/fi-FI/public.json @@ -109,7 +109,7 @@ "title": "Ilmoituksen tilaaminen ei onnistunut" }, "fullQueue": { - "description": "Kaikki peruutuspaikat ovat juuri nyt varattuja. Voit yrittää myöhemmin uudelleen.", + "description": "Et voi enää tilata ilmoituksia tästä tutkinnosta. Tilaajia voi olla enintään 50.", "title": "Ilmoituksen tilaaminen ei onnistunut" }, "inputError": { diff --git a/frontend/packages/yki/public/i18n/sv-SE/public.json b/frontend/packages/yki/public/i18n/sv-SE/public.json index d53f70660..452ac4b19 100644 --- a/frontend/packages/yki/public/i18n/sv-SE/public.json +++ b/frontend/packages/yki/public/i18n/sv-SE/public.json @@ -108,6 +108,10 @@ "description": "Du har redan tidigare beställt en notifiering om lediga platser vid examenstillfället till din e-post.", "title": "Beställningen misslyckades" }, + "fullQueue": { + "description": "Du kan inte längre beställa en notifiering om det här examenstillfället. Högst 50 personer kan beställa en notifiering.", + "title": "Beställningen misslyckades" + }, "genericError": { "description": "Ett oväntat fel har uppstått. Vänligen försök på nytt.", "title": "Beställningen misslyckades" From b8fa76057b5ba7ba0a50be0b2b4d9d789c2cc81c Mon Sep 17 00:00:00 2001 From: Pyry Koivisto Date: Fri, 12 Jan 2024 13:47:27 +0200 Subject: [PATCH 3/4] YKI(Frontend): Rename a few keys --- frontend/packages/yki/public/i18n/en-GB/public.json | 8 ++++---- frontend/packages/yki/public/i18n/sv-SE/public.json | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/frontend/packages/yki/public/i18n/en-GB/public.json b/frontend/packages/yki/public/i18n/en-GB/public.json index 04289e2c5..402895375 100644 --- a/frontend/packages/yki/public/i18n/en-GB/public.json +++ b/frontend/packages/yki/public/i18n/en-GB/public.json @@ -112,13 +112,13 @@ "description": "You can no longer subscribe for notifications for this test. The maximum number of subscribers is 50.", "title": "Subscription failed" }, - "genericError": { - "description": "An unexpected error occurred. Please try again.", - "title": "Subscription failed" - }, "inputError": { "description": "Verify your email address", "title": "Invalid information!" + }, + "unknown": { + "description": "An unexpected error occurred. Please try again.", + "title": "Subscription failed" } }, "header": "Subscribe to notifications of available seats", diff --git a/frontend/packages/yki/public/i18n/sv-SE/public.json b/frontend/packages/yki/public/i18n/sv-SE/public.json index 452ac4b19..4a588bce3 100644 --- a/frontend/packages/yki/public/i18n/sv-SE/public.json +++ b/frontend/packages/yki/public/i18n/sv-SE/public.json @@ -112,13 +112,13 @@ "description": "Du kan inte längre beställa en notifiering om det här examenstillfället. Högst 50 personer kan beställa en notifiering.", "title": "Beställningen misslyckades" }, - "genericError": { - "description": "Ett oväntat fel har uppstått. Vänligen försök på nytt.", - "title": "Beställningen misslyckades" - }, "inputError": { "description": "Kontrollera din e-postadress", "title": "Felaktiga uppgifter!" + }, + "unknown": { + "description": "Ett oväntat fel har uppstått. Vänligen försök på nytt.", + "title": "Beställningen misslyckades" } }, "header": "Beställ en notifiering om lediga platser", From e535b4177a511bfc3c49b67b1a1f7de1f7c02a18 Mon Sep 17 00:00:00 2001 From: Pyry Koivisto Date: Mon, 15 Jan 2024 14:17:39 +0200 Subject: [PATCH 4/4] YKI(Frontend): Fix cleanup on unmount --- .../yki/src/components/registration/EnrollToQueue.tsx | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/frontend/packages/yki/src/components/registration/EnrollToQueue.tsx b/frontend/packages/yki/src/components/registration/EnrollToQueue.tsx index f496d8299..7c60a4cec 100644 --- a/frontend/packages/yki/src/components/registration/EnrollToQueue.tsx +++ b/frontend/packages/yki/src/components/registration/EnrollToQueue.tsx @@ -163,7 +163,11 @@ export const EnrollToQueue = () => { ); useEffect(() => { - dispatch(resetReservationRequest()); + const cleanUp = () => { + dispatch(resetReservationRequest()); + }; + + return cleanUp; }, [dispatch]); useDialogOnError();