diff --git a/src/components/Navbar.tsx b/src/components/Navbar.tsx index ae060e0..a1dd61f 100644 --- a/src/components/Navbar.tsx +++ b/src/components/Navbar.tsx @@ -5,61 +5,86 @@ import { ButtonGroup, Button, Image, -} from '@chakra-ui/react'; -import {useRouter} from 'next/router'; -import {signOut, useSession} from 'next-auth/react'; + Link, +} from "@chakra-ui/react"; +import { useRouter } from "next/router"; +import { signOut, useSession } from "next-auth/react"; +import Nextlink from "next/link"; type Props = { - variant: "static" | "fixed" -} + variant: "static" | "fixed"; +}; -export default function Navbar({variant = "fixed"}: Props) { +export default function Navbar({ variant = "fixed" }: Props) { const router = useRouter(); - const {data: session, status} = useSession(); + const { data: session, status } = useSession(); const RightSection = () => { - if (status === "authenticated" && session.user) return ( - - {session.user.email} - + if (status === "authenticated" && session.user) + return ( + - - ); - else return ( - + ); + else + return ( + + - - ); + ); }; return ( - - - - - + + + + + - - A propos - Contact - Aide - - - + + {status === "authenticated" ? ( + <> + + Tableau de bord + + + Profile + + + ) : ( + <> + A propos + Contact + Aide + + )} - - ); + + + + ); } diff --git a/src/components/form/LoginForm.tsx b/src/components/form/LoginForm.tsx index dc1bda4..13b621d 100644 --- a/src/components/form/LoginForm.tsx +++ b/src/components/form/LoginForm.tsx @@ -1,91 +1,115 @@ import { - Box, Button, + Box, + Button, Flex, FormControl, FormLabel, Heading, Input, Container, -} from '@chakra-ui/react'; -import {useState} from 'react'; -import {useRouter} from 'next/router'; -import {signIn, SignInResponse} from 'next-auth/react'; + FormErrorMessage, +} from "@chakra-ui/react"; +import { useState } from "react"; +import { useRouter } from "next/router"; +import { signIn, SignInResponse } from "next-auth/react"; -import {LoginData} from '@/models/form/LoginData'; +import { LoginData } from "@/models/form/LoginData"; +import { useForm } from "react-hook-form"; export default function LoginForm() { const router = useRouter(); - const [loginData, setLoginData] = useState(new LoginData()); const [isLoading, setIsLoading] = useState(false); - const [invalidInput, setInvalidInput] = useState(false); + const [wrongPasswordError, setWrongPasswordError] = useState(false); - const buttonWidth = {base: '100%', md: 'unset'}; + const { + handleSubmit, + register, + formState: { errors, isSubmitting }, + } = useForm(); - const handleInput = (data: any) => { - setInvalidInput(false); - setLoginData({...loginData, ...data}); - }; + const buttonWidth = { base: "100%", md: "unset" }; - const handleSubmit = async () => { - setIsLoading(true) - signIn('credentials', {...loginData, redirect: false}) - .then((res: unknown) => { - const {ok: connexionSuccess} = res as SignInResponse; + const errorPassword = "Mot de passe incorrect"; - if (!connexionSuccess) { + const loginUser = async (value: LoginData) => { + setIsLoading(true); + signIn("credentials", { ...value, redirect: false }).then( + (res: unknown) => { + const { ok: connexionSuccess } = res as SignInResponse; setIsLoading(false); - setInvalidInput(true); + + if (connexionSuccess) router.push("/dashboard"); + else setWrongPasswordError(true); } - else router.push('/dashboard'); - }); + ); }; return ( - - - Connexion - - {/* Email */} - + + +
+ + Connexion + + {/*Email*/} + Adresse email handleInput({email: evt.target.value})} - placeholder={'adresse@email.com'} - required={true} + type="text" + {...register("email", { + required: { value: true, message: "Adresse email requise" }, + pattern: { + value: /^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}$/i, + message: "Adresse email invalide", + }, + })} + placeholder="adresse@email.com" /> + {errors.email?.message} - {/* Mot de passe */ - } - - Mot de passe - handleInput({password: evt.target.value})} - placeholder={'Mot de passe'} - required={true} - /> + {/*Mot de passe*/} + + Mot de passe + + {errors.password?.message} + + {wrongPasswordError && errorPassword} + - {/*Boutons*/ - } - - - + {/*Boutons*/} + + + +
-
-) - -} \ No newline at end of file +
+ ); +} diff --git a/src/components/form/RegisterForm.tsx b/src/components/form/RegisterForm.tsx index 6f44cc8..d3d3234 100644 --- a/src/components/form/RegisterForm.tsx +++ b/src/components/form/RegisterForm.tsx @@ -1,135 +1,192 @@ import { - Box, Button, + Box, + Button, Flex, FormControl, FormLabel, Heading, Input, Container, -} from '@chakra-ui/react'; -import {useRouter} from 'next/router'; -import {useState} from 'react'; -import {signIn, SignInResponse} from 'next-auth/react'; -import {RegisterData} from '@/models/form/RegisterData'; + FormErrorMessage, +} from "@chakra-ui/react"; +import { useRouter } from "next/router"; +import { useState } from "react"; +import { signIn, SignInResponse } from "next-auth/react"; +import { RegisterData } from "@/models/form/RegisterData"; +import { useForm } from "react-hook-form"; export default function RegisterForm() { const router = useRouter(); - const [registerData, setRegisterData] = useState(new RegisterData()); - const [isLoading, setIsLoading] = useState(false); - const [invalidInput, setInvalidInput] = useState(false); - const buttonWidth = {base: '100%', md: 'unset'}; + const { + handleSubmit, + register, + watch, + formState: { errors, isSubmitting }, + } = useForm(); - const handleInput = (data: any) => { - setInvalidInput(false); - setRegisterData({...registerData, ...data}); + const buttonWidth = { base: "100%", md: "unset" }; + + const validateDate = (value: string) => { + const selected = new Date(value).getFullYear(); + const now = new Date().getFullYear(); + return now - selected >= 18 || "Vous devez avoir 18 ans ou plus"; }; - const handleSubmit = () => { - let {email, firstName, lastName, password, confirmPassword} = registerData; - if (password !== confirmPassword) setInvalidInput(true); + const registerUser = (values: RegisterData) => { + let { email, firstName, lastName, birthdate, password, confirmPassword } = + values; + const date = new Date(birthdate); const options = { - method: 'POST', - headers: {'Content-Type': 'application/json'}, - body: JSON.stringify({email, firstName, lastName, password}), + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ + email, + firstName, + lastName, + password, + birthdate: date, + }), }; - setIsLoading(true); - fetch('/api/users', options).then(() => { - signIn('credentials', {email, password, redirect: false}) - .then((res: unknown) => { - const {ok: connexionSuccess} = res as SignInResponse; + fetch("/api/users", options) + .then(() => { + signIn("credentials", { email, password, redirect: false }).then( + (res: unknown) => { + const { ok: connexionSuccess } = res as SignInResponse; // TODO If success -> goto interactive form else login - router.push(connexionSuccess ? '/' : '/login'); - }); - }).catch(() => { - setIsLoading(false); - setInvalidInput(true); - setRegisterData({...registerData, password: '', confirmPassword: ''}); - }); + router.push(connexionSuccess ? "/dashboard" : "/"); + } + ); + }) + .catch(() => {}); }; return ( - - - Inscription + + +
+ + Inscription + - + {/*Prénom*/} - + Prénom handleInput({firstName: evt.target.value})} - placeholder="Prénom" - required={true} + type="text" + placeholder="Prénom" + {...register("firstName", { + required: { value: true, message: "Prénom requis" }, + })} /> + {errors.firstName?.message} {/*Nom*/} - + Nom handleInput({lastName: evt.target.value})} - placeholder="Nom" - required={true} + type="text" + placeholder="Nom" + {...register("lastName", { + required: { value: true, message: "Nom requis" }, + })} /> + {errors.lastName?.message} {/*Email*/} - + Adresse email handleInput({email: evt.target.value})} - placeholder="adresse@email.com" + type="text" + {...register("email", { + required: { value: true, message: "Adresse email requise" }, + pattern: { + value: /^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}$/i, + message: "Adresse email invalide", + }, + })} + placeholder="adresse@email.com" /> + {errors.email?.message} + + + {/*Date de naissance*/} + + Date de naissance + + {errors.birthdate?.message} {/*Mot de passe*/} - + Mot de passe handleInput({password: evt.target.value})} - placeholder="Mot de passe" + type="password" + placeholder="Mot de passe" + {...register("password", { + required: { value: true, message: "Mot de passe requis" }, + })} /> + {errors.password?.message} {/*Mot de passe (2)*/} - + Confirmation du mot de passe handleInput( - {confirmPassword: evt.target.value})} - placeholder="Mot de passe" + type="password" + placeholder="Mot de passe" + {...register("confirmPassword", { + required: { value: true, message: "Confirmation requise" }, + validate: (value: string) => { + return ( + watch("password") === value || + "Les mots de passe ne correspondent pas" + ); + }, + })} /> + + {errors.confirmPassword?.message} + - - - - + + + - - + +
+
); - } diff --git a/src/models/form/RegisterData.ts b/src/models/form/RegisterData.ts index 6350cd4..7143fb9 100644 --- a/src/models/form/RegisterData.ts +++ b/src/models/form/RegisterData.ts @@ -1,10 +1,10 @@ export class RegisterData { - constructor( - public firstName: string = "", - public lastName: string = "", - public email: string = "", - public password: string = "", - public confirmPassword: string = "", + public firstName: string = "", + public lastName: string = "", + public email: string = "", + public birthdate: string = "", + public password: string = "", + public confirmPassword: string = "" ) {} -} \ No newline at end of file +}