From 2ee205959d2f228eb6dc7c3d0d80e6e87eb9a447 Mon Sep 17 00:00:00 2001 From: faucomte97 Date: Thu, 2 Jan 2025 17:11:15 +0000 Subject: [PATCH] Logout redirects --- src/app/schemas.ts | 9 ++++++ src/components/form/UpdateAccountForm.tsx | 35 ++++++++++++++++------- 2 files changed, 34 insertions(+), 10 deletions(-) diff --git a/src/app/schemas.ts b/src/app/schemas.ts index f9ed0ab..0300105 100644 --- a/src/app/schemas.ts +++ b/src/app/schemas.ts @@ -27,3 +27,12 @@ export const indyPasswordSchema = yup .matches(/[A-Z]/, "password must contain at least one uppercase letter") .matches(/[a-z]/, "password must contain at least one lowercase letter") .matches(/[0-9]/, "password must contain at least one digit") + +// A nullable schema allowing for empty values. Use when needing to apply a +// schema to an optional field, e.g. the new password field in the account form. +// Apply to any other schema using .concat(). +// TODO: Reassess the need for this after we split the account details form +export const nullableSchema = yup + .string() + .nullable() + .transform((curr: string, orig: string) => (orig === "" ? null : curr)) diff --git a/src/components/form/UpdateAccountForm.tsx b/src/components/form/UpdateAccountForm.tsx index 1a93817..74763b2 100644 --- a/src/components/form/UpdateAccountForm.tsx +++ b/src/components/form/UpdateAccountForm.tsx @@ -2,6 +2,7 @@ import * as forms from "codeforlife/components/form" import { getDirty, isDirty } from "codeforlife/utils/form" import { type FC } from "react" import { Typography } from "@mui/material" +import { generatePath } from "react-router" import { useNavigate } from "codeforlife/hooks" import { @@ -12,10 +13,13 @@ import { } from "../../api/user" import { indyPasswordSchema, + nullableSchema, studentPasswordSchema, teacherPasswordSchema, } from "../../app/schemas" import { LastNameField } from "./index" +import { paths } from "../../routes" +import { useLogoutMutation } from "../../api" export interface UpdateAccountFormProps { user: RetrieveUserResult @@ -23,6 +27,7 @@ export interface UpdateAccountFormProps { const UpdateAccountForm: FC = ({ user }) => { const navigate = useNavigate() + const [logout] = useLogoutMutation() const initialValues = user.student ? { @@ -88,22 +93,32 @@ const UpdateAccountForm: FC = ({ user }) => { return arg }, then: (_: UpdateUserResult, values: typeof initialValues) => { + let redirectPath = generatePath(".") const messages = [ "Your account details have been changed successfully.", ] if (isDirty(values, initialValues, "email")) { - // TODO: implement this behavior on the backend. - messages.push( - "Your email will be changed once you have verified it, until then you can still log in with your old email.", - ) + redirectPath = generatePath(paths.login.teacher._) + void logout(null) + .unwrap() + .then(() => { + messages.push( + "Your email will be changed once you have verified it, until then you can still log in with your old email.", + ) + }) } if (isDirty(values, initialValues, "password")) { - messages.push( - "Going forward, please login using your new password.", - ) + redirectPath = generatePath(paths.login.teacher._) + void logout(null) + .unwrap() + .then(() => { + messages.push( + "Going forward, please log in using your new password.", + ) + }) } - navigate(".", { + navigate(redirectPath, { state: { notifications: messages.map(message => ({ props: { children: message }, @@ -119,12 +134,12 @@ const UpdateAccountForm: FC = ({ user }) => { "password", ]) - let passwordSchema = indyPasswordSchema + let passwordSchema = indyPasswordSchema.concat(nullableSchema) if (user.student) { passwordSchema = studentPasswordSchema } else if (user.teacher) { - passwordSchema = teacherPasswordSchema + passwordSchema = teacherPasswordSchema.concat(nullableSchema) } if (isDirty(form.values, initialValues, "current_password")) {