Enhanced archived account signin experience

This commit is contained in:
2024-06-26 15:00:48 +08:00
parent 161fa3dd1d
commit d3838100e0
6 changed files with 130 additions and 93 deletions

View File

@@ -1,7 +1,7 @@
import { Button, Link } from "@nextui-org/react";
import { Formik, Form } from "formik";
import * as Yup from "yup";
import axios from "axios";
import axios, { AxiosError } from "axios";
import config from "../config";
import NextUIFormikInput from "./NextUIFormikInput";
import { useNavigate } from "react-router-dom";
@@ -33,16 +33,15 @@ export default function SignInModule() {
password: "",
};
const handleSubmit = async (values: any) => {
try {
const response = await axios.post(
config.serverAddress + "/users/login",
values
);
const handleSubmit = (values: any) => {
axios
.post(config.serverAddress + "/users/login", values)
.then((response) => {
navigate("/springboard/" + response.data.accessToken);
} catch (error) {
console.error("Error logging in:", error);
}
})
.catch((error) => {
throw ((error as AxiosError).response?.data as any).message;
});
};
return (

View File

@@ -1,7 +1,7 @@
import { Button, Checkbox, Link } from "@nextui-org/react";
import { Formik, Form, Field, ErrorMessage } from "formik";
import * as Yup from "yup";
import axios from "axios";
import axios, { AxiosError } from "axios";
import config from "../config";
import NextUIFormikInput from "./NextUIFormikInput";
import { useNavigate } from "react-router-dom";
@@ -64,7 +64,7 @@ export default function SignUpModule() {
);
console.log("User created successfully:", response.data);
} catch (error) {
console.error("Error creating user:", error);
throw ((error as AxiosError).response?.data as any).message;
}
};

View File

@@ -1,4 +1,4 @@
import axios from "axios";
import axios, { AxiosError } from "axios";
import * as Yup from "yup";
import config from "../config";
import { useEffect, useState } from "react";
@@ -18,7 +18,13 @@ export default function UpdateAccountModule({
let [userInformation, setUserInformation] = useState<any>();
useEffect(() => {
retrieveUserInformation(accessToken!, setUserInformation);
retrieveUserInformation(accessToken!)
.then((response) => {
setUserInformation(response);
})
.catch(() => {
navigate("/springboard/" + accessToken);
});
}, [accessToken]);
const validationSchema = Yup.object({
@@ -63,7 +69,7 @@ export default function UpdateAccountModule({
console.log("User updated successfully:", response.data);
navigate("/springboard/" + accessToken);
} catch (error) {
console.error("Error updating user:", error);
throw ((error as AxiosError).response?.data as any).message;
}
};
@@ -95,7 +101,7 @@ export default function UpdateAccountModule({
}
)
.then(() => {
navigate("/login");
navigate("/signin");
})
.catch((err) => {
console.log("Archive failed: " + err);

View File

@@ -10,6 +10,7 @@ import { retrieveUserInformation } from "../security/users";
export default function SpringboardPage() {
let { accessToken } = useParams<string>(); // TODO: Replace AT from props with AT from localstorage
let [userInformation, setUserInformation] = useState<any>();
let [accountUnavailable, setAccountUnavaliable] = useState(false);
let timeOfDay = getTimeOfDay();
const navigate = useNavigate();
@@ -23,13 +24,20 @@ export default function SpringboardPage() {
greeting = "Good evening";
}
useEffect(
() => retrieveUserInformation(accessToken!, setUserInformation),
[]
);
useEffect(() => {
retrieveUserInformation(accessToken!)
.then((response) => {
setUserInformation(response);
})
.catch((error) => {
setAccountUnavaliable(true);
});
return;
}, []);
return (
<DefaultLayout>
<div>
{userInformation && (
<div className="flex flex-col w-full">
<div className="flex flex-row justify-between p-8 *:my-auto">
@@ -80,6 +88,38 @@ export default function SpringboardPage() {
<div className="w-full h-[600px] bg-red-500"></div>
</div>
)}
</div>
<div>
{accountUnavailable && (
<div className="flex flex-col">
<div className="flex flex-col gap-8 p-4 justify-center bg-red-500 text-center text-white h-96">
<p className="text-9xl">🔒</p>
<div className="flex flex-col gap-4">
<p className="text-4xl font-bold">Account unavailable.</p>
<div className="flex flex-col">
<p className="text-xl">
This account seems to have been archived.
</p>
<p>
In order to recover the account, please{" "}
<Link className="text-white px-1 rounded-md bg-red-400">
contact us
</Link>
</p>
</div>
<div className="w-min mx-auto"></div>
</div>
</div>
<div className="flex flex-col justify-center p-8">
<div className="w-min mx-auto">
<Button color="primary" onPress={() => navigate("/signin")}>
Sign in with a different account
</Button>
</div>
</div>
</div>
)}
</div>
</DefaultLayout>
);
}

View File

@@ -1,31 +1,23 @@
import axios from "axios";
import axios, { AxiosError } from "axios";
import config from "../config";
export function retrieveUserInformation(
accessToken: string,
andThen: React.Dispatch<any>
) {
axios
.get(`${config.serverAddress}/users/auth`, {
export async function retrieveUserInformation(accessToken: string) {
try {
let userId = await axios.get(`${config.serverAddress}/users/auth`, {
headers: {
Authorization: `Bearer ${accessToken}`,
},
})
.then((response) => {
axios
.get(`${config.serverAddress}/users/individual/${response.data.id}`, {
});
let userInformation = await axios.get(
`${config.serverAddress}/users/individual/${userId.data.id}`,
{
headers: {
Authorization: `Bearer ${accessToken}`,
},
})
.then((response) => {
andThen(response.data);
})
.catch((error) => {
console.error("Error retrieving user information:", error);
});
})
.catch((error) => {
console.error("Error retrieving user ID:", error);
});
}
);
return userInformation.data;
} catch (error) {
throw ((error as AxiosError).response?.data as any).message;
}
}

View File

@@ -96,7 +96,7 @@ router.get("/individual/:id", validateToken, async (req, res) => {
if (user.isArchived) {
res.status(400).json({
message: `Account ${id} is archived.`,
message: `ERR_ACC_IS_ARCHIVED`,
});
} else {
res.json(user);