Sign in screen with token retrieval
This commit is contained in:
100
client/src/components/SignInModule.tsx
Normal file
100
client/src/components/SignInModule.tsx
Normal file
@@ -0,0 +1,100 @@
|
||||
import { Button, Link } from "@nextui-org/react";
|
||||
import { Formik, Form } from "formik";
|
||||
import * as Yup from "yup";
|
||||
import axios from "axios";
|
||||
import config from "../config";
|
||||
import NextUIFormikInput from "./NextUIFormikInput";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { ChevronLeftIcon } from "../icons";
|
||||
|
||||
const validationSchema = Yup.object({
|
||||
email: Yup.string()
|
||||
.trim()
|
||||
.lowercase()
|
||||
.min(5)
|
||||
.max(69)
|
||||
.email("Invalid email format")
|
||||
.required("Email is required"),
|
||||
password: Yup.string()
|
||||
.trim()
|
||||
.max(69, "Password must be at most 69 characters")
|
||||
.matches(
|
||||
/^(?=.*[a-zA-Z])(?=.*[0-9]).{1,}$/,
|
||||
"Password contains only letters and numbers"
|
||||
)
|
||||
.required("Password is required"),
|
||||
});
|
||||
|
||||
export default function SignInModule() {
|
||||
const navigate = useNavigate();
|
||||
|
||||
const initialValues = {
|
||||
email: "",
|
||||
password: "",
|
||||
};
|
||||
|
||||
const handleSubmit = async (values: any) => {
|
||||
try {
|
||||
const response = await axios.post(
|
||||
config.serverAddress + "/users/login",
|
||||
values
|
||||
);
|
||||
console.log(response.data.accessToken);
|
||||
} catch (error) {
|
||||
console.error("Error logging in:", error);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="flex flex-col gap-16">
|
||||
<div className="flex flex-col gap-1">
|
||||
<p className="text-4xl font-bold">Sign In</p>
|
||||
<p className="text-2xl">to ecoconnect</p>
|
||||
</div>
|
||||
<Formik
|
||||
initialValues={initialValues}
|
||||
validationSchema={validationSchema}
|
||||
onSubmit={handleSubmit}
|
||||
>
|
||||
{({ isValid, dirty }) => (
|
||||
<Form className="flex flex-col gap-4">
|
||||
<NextUIFormikInput
|
||||
label="Email"
|
||||
name="email"
|
||||
type="email"
|
||||
placeholder="johndoe@email.com"
|
||||
labelPlacement="outside"
|
||||
/>
|
||||
<NextUIFormikInput
|
||||
label="Password"
|
||||
name="password"
|
||||
type="password"
|
||||
placeholder=" "
|
||||
labelPlacement="outside"
|
||||
/>
|
||||
<Button
|
||||
type="submit"
|
||||
color="primary"
|
||||
size="lg"
|
||||
className="mx-auto"
|
||||
isIconOnly
|
||||
isDisabled={!isValid || !dirty}
|
||||
>
|
||||
<ChevronLeftIcon />
|
||||
</Button>
|
||||
</Form>
|
||||
)}
|
||||
</Formik>
|
||||
<div className="w-full flex flex-col gap-2 *:mx-auto">
|
||||
<p>New here?</p>
|
||||
<Link
|
||||
onPress={() => {
|
||||
navigate("/signup");
|
||||
}}
|
||||
>
|
||||
Sign up
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -4,6 +4,7 @@ import * as Yup from "yup";
|
||||
import axios from "axios";
|
||||
import config from "../config";
|
||||
import NextUIFormikInput from "./NextUIFormikInput";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
|
||||
const validationSchema = Yup.object({
|
||||
firstName: Yup.string()
|
||||
@@ -44,6 +45,8 @@ const validationSchema = Yup.object({
|
||||
});
|
||||
|
||||
export default function SignUpModule() {
|
||||
const navigate = useNavigate();
|
||||
|
||||
const initialValues = {
|
||||
firstName: "",
|
||||
lastName: "",
|
||||
@@ -66,7 +69,7 @@ export default function SignUpModule() {
|
||||
};
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div className="flex flex-col gap-16">
|
||||
<Formik
|
||||
initialValues={initialValues}
|
||||
validationSchema={validationSchema}
|
||||
@@ -140,6 +143,16 @@ export default function SignUpModule() {
|
||||
</Form>
|
||||
)}
|
||||
</Formik>
|
||||
<div className="w-full flex flex-col gap-2 *:mx-auto">
|
||||
<p>Already here before?</p>
|
||||
<Link
|
||||
onPress={() => {
|
||||
navigate("/signin");
|
||||
}}
|
||||
>
|
||||
Sign in
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ import { Link } from "@nextui-org/react";
|
||||
export default function SingaporeAgencyStrip() {
|
||||
return (
|
||||
<div className="h-8 bg-neutral-200 text-black relative">
|
||||
<div className="flex flex-row gap-2 *:my-auto pl-16 h-full text-sm">
|
||||
<div className="mx-auto w-full flex flex-row gap-2 *:my-auto h-full text-sm max-w-7xl pl-4">
|
||||
<img src="../assets/Merlion.svg" alt="Merlion Icon" className="w-6" />
|
||||
<p>A Singapore Government Agency Website</p>
|
||||
<Link size="sm">How to identify</Link>
|
||||
|
||||
Reference in New Issue
Block a user