Toasts
This commit is contained in:
@@ -1,11 +1,12 @@
|
|||||||
import { Button, Link } from "@nextui-org/react";
|
import { Button, Link } from "@nextui-org/react";
|
||||||
import { Formik, Form } from "formik";
|
import { Formik, Form } from "formik";
|
||||||
import * as Yup from "yup";
|
import * as Yup from "yup";
|
||||||
import axios, { AxiosError } from "axios";
|
import axios from "axios";
|
||||||
import config from "../config";
|
import config from "../config";
|
||||||
import NextUIFormikInput from "./NextUIFormikInput";
|
import NextUIFormikInput from "./NextUIFormikInput";
|
||||||
import { useNavigate } from "react-router-dom";
|
import { useNavigate } from "react-router-dom";
|
||||||
import { ChevronLeftIcon } from "../icons";
|
import { ChevronLeftIcon } from "../icons";
|
||||||
|
import { popErrorToast } from "../utilities";
|
||||||
|
|
||||||
const validationSchema = Yup.object({
|
const validationSchema = Yup.object({
|
||||||
email: Yup.string()
|
email: Yup.string()
|
||||||
@@ -33,14 +34,14 @@ export default function SignInModule() {
|
|||||||
password: "",
|
password: "",
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleSubmit = (values: any) => {
|
const handleSubmit = (values: any): void => {
|
||||||
axios
|
axios
|
||||||
.post(config.serverAddress + "/users/login", values)
|
.post(config.serverAddress + "/users/login", values)
|
||||||
.then((response) => {
|
.then((response) => {
|
||||||
navigate("/springboard/" + response.data.accessToken);
|
navigate("/springboard/" + response.data.accessToken);
|
||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
throw ((error as AxiosError).response?.data as any).message;
|
popErrorToast(error);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,11 @@
|
|||||||
import { Button, Checkbox, Link } from "@nextui-org/react";
|
import { Button, Checkbox, Link } from "@nextui-org/react";
|
||||||
import { Formik, Form, Field, ErrorMessage } from "formik";
|
import { Formik, Form, Field, ErrorMessage } from "formik";
|
||||||
import * as Yup from "yup";
|
import * as Yup from "yup";
|
||||||
import axios, { AxiosError } from "axios";
|
import axios from "axios";
|
||||||
import config from "../config";
|
import config from "../config";
|
||||||
import NextUIFormikInput from "./NextUIFormikInput";
|
import NextUIFormikInput from "./NextUIFormikInput";
|
||||||
import { useNavigate } from "react-router-dom";
|
import { useNavigate } from "react-router-dom";
|
||||||
|
import { popErrorToast } from "../utilities";
|
||||||
|
|
||||||
const validationSchema = Yup.object({
|
const validationSchema = Yup.object({
|
||||||
firstName: Yup.string()
|
firstName: Yup.string()
|
||||||
@@ -64,7 +65,7 @@ export default function SignUpModule() {
|
|||||||
);
|
);
|
||||||
console.log("User created successfully:", response.data);
|
console.log("User created successfully:", response.data);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
throw ((error as AxiosError).response?.data as any).message;
|
popErrorToast(error);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import axios, { AxiosError } from "axios";
|
import axios from "axios";
|
||||||
import * as Yup from "yup";
|
import * as Yup from "yup";
|
||||||
import config from "../config";
|
import config from "../config";
|
||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
@@ -18,6 +18,7 @@ import { Form, Formik } from "formik";
|
|||||||
import NextUIFormikInput from "./NextUIFormikInput";
|
import NextUIFormikInput from "./NextUIFormikInput";
|
||||||
import { useNavigate } from "react-router-dom";
|
import { useNavigate } from "react-router-dom";
|
||||||
import UserProfilePicture from "./UserProfilePicture";
|
import UserProfilePicture from "./UserProfilePicture";
|
||||||
|
import { popErrorToast } from "../utilities";
|
||||||
|
|
||||||
export default function UpdateAccountModule({
|
export default function UpdateAccountModule({
|
||||||
accessToken,
|
accessToken,
|
||||||
@@ -81,7 +82,7 @@ export default function UpdateAccountModule({
|
|||||||
console.log("User updated successfully:", response.data);
|
console.log("User updated successfully:", response.data);
|
||||||
navigate("/springboard/" + accessToken);
|
navigate("/springboard/" + accessToken);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
throw ((error as AxiosError).response?.data as any).message;
|
popErrorToast(error);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import axios from "axios";
|
|||||||
import React, { useRef, useState } from "react";
|
import React, { useRef, useState } from "react";
|
||||||
import config from "../config";
|
import config from "../config";
|
||||||
import { Button, Image } from "@nextui-org/react";
|
import { Button, Image } from "@nextui-org/react";
|
||||||
|
import { popErrorToast } from "../utilities";
|
||||||
|
|
||||||
export default function UserProfilePicture({
|
export default function UserProfilePicture({
|
||||||
userId,
|
userId,
|
||||||
@@ -36,7 +37,7 @@ export default function UserProfilePicture({
|
|||||||
);
|
);
|
||||||
return response.data;
|
return response.data;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
throw error;
|
popErrorToast(error);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import { Toaster } from "react-hot-toast";
|
||||||
import SingaporeAgencyStrip from "../components/SingaporeAgencyStrip";
|
import SingaporeAgencyStrip from "../components/SingaporeAgencyStrip";
|
||||||
|
|
||||||
export default function DefaultLayout({
|
export default function DefaultLayout({
|
||||||
@@ -9,6 +10,7 @@ export default function DefaultLayout({
|
|||||||
<div className="relative flex flex-col h-screen">
|
<div className="relative flex flex-col h-screen">
|
||||||
<SingaporeAgencyStrip />
|
<SingaporeAgencyStrip />
|
||||||
<main className=" flex-grow">{children}</main>
|
<main className=" flex-grow">{children}</main>
|
||||||
|
<Toaster />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
import { AxiosError } from "axios";
|
||||||
|
import toast from "react-hot-toast";
|
||||||
|
|
||||||
export function getTimeOfDay(): number {
|
export function getTimeOfDay(): number {
|
||||||
const currentHour = new Date().getHours();
|
const currentHour = new Date().getHours();
|
||||||
|
|
||||||
@@ -9,3 +12,30 @@ export function getTimeOfDay(): number {
|
|||||||
return 2; // Evening
|
return 2; // Evening
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const popToast = (message: string, type: number) => {
|
||||||
|
const words = message.split(" ");
|
||||||
|
const duration = Math.max(4, words.length * 1);
|
||||||
|
|
||||||
|
toast(message, {
|
||||||
|
duration: duration * 1000, // Convert to milliseconds
|
||||||
|
position: "top-center",
|
||||||
|
|
||||||
|
// Custom Icon
|
||||||
|
icon: type === 0 ? "ℹ️" : type === 1 ? "✅" : type === 2 ? "❌" : undefined,
|
||||||
|
|
||||||
|
// Aria
|
||||||
|
ariaProps: {
|
||||||
|
role: "status",
|
||||||
|
"aria-live": "polite",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
export const popErrorToast = (error: any) => {
|
||||||
|
try {
|
||||||
|
popToast(((error as AxiosError).response?.data as any).message, 2);
|
||||||
|
} catch {
|
||||||
|
popToast("An unexpected error occured!\nPlease try again later.", 2);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|||||||
@@ -270,11 +270,20 @@ router.put(
|
|||||||
const maxSize = 5 * 1024 * 1024; // 5MB
|
const maxSize = 5 * 1024 * 1024; // 5MB
|
||||||
|
|
||||||
if (!allowedTypes.includes(mimetype)) {
|
if (!allowedTypes.includes(mimetype)) {
|
||||||
return res.status(400).json({ message: "Invalid file type" });
|
return res.status(400).json({
|
||||||
|
message:
|
||||||
|
"Invalid file type\nSupported: jpeg, png, gif\nUploaded: " +
|
||||||
|
mimetype.substring(6),
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (size > maxSize) {
|
if (size > maxSize) {
|
||||||
return res.status(400).json({ message: "File too large" });
|
return res.status(400).json({
|
||||||
|
message:
|
||||||
|
"File too large!\nMaximum: 5MB, Uploaded: " +
|
||||||
|
(size / 1000000).toFixed(2) +
|
||||||
|
"MB",
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Crop the image to a square
|
// Crop the image to a square
|
||||||
|
|||||||
Reference in New Issue
Block a user