Create User Login/Logout

Took 3 hours 40 minutes
This commit is contained in:
Lucàs
2023-03-22 15:36:20 +01:00
parent f1e39e12e9
commit 843b5fcda8
18 changed files with 3351 additions and 2620 deletions
+5 -2
View File
@@ -1,11 +1,14 @@
import '@/styles/globals.css';
import type {AppProps} from 'next/app';
import {ChakraProvider} from '@chakra-ui/react';
import { SessionProvider } from "next-auth/react"
export default function App({Component, pageProps}: AppProps) {
export default function App({Component, pageProps: { session, ...pageProps }}: AppProps) {
return (
<ChakraProvider>
<Component {...pageProps} />
<SessionProvider session={session}>
<Component {...pageProps} />
</SessionProvider>
</ChakraProvider>
);
}
+49
View File
@@ -0,0 +1,49 @@
import NextAuth from "next-auth"
import CredentialsProvider from "next-auth/providers/credentials";
import {PrismaClient} from '@prisma/client';
import {NextApiRequest, NextApiResponse} from 'next';
import {LoginData} from '@/models/form/LoginData';
const prisma = new PrismaClient();
export default async function auth(req: NextApiRequest, res: NextApiResponse) {
const providers = [
CredentialsProvider({
name: "Credentials",
credentials: {
email: { label: "Email", type: "text", placeholder: "adress@email.com" },
password: { label: "Password", type: "password" }
},
async authorize(credentials) {
const {email, password} = credentials as LoginData;
if (!email || !password) return null;
// Appel à la base de donnée
const user = await prisma.user.findUnique({
where: {email}
});
// Vérification de la connexion
if (user && user.password === password) return user;
return null;
},
})
];
return await NextAuth(req, res, {
providers,
session: {strategy: "jwt",},
secret: process.env.NEXTAUTH_SECRET,
callbacks: {
async session({ session, token }: { session: any; token: any }) {
const user = await prisma.user.findFirst({
where: { email: session.user.email }
});
session.token = token.sub
session.user = user
return session
},
},
})
}
-18
View File
@@ -1,18 +0,0 @@
import {NextApiRequest, NextApiResponse} from 'next';
import { PrismaClient } from '@prisma/client'
import type {CreateUserQuery} from '@/models/api/user';
const prisma = new PrismaClient();
export default async function createUser(req: NextApiRequest, res: NextApiResponse) {
const {email, password, firstName, lastName} = req.body as CreateUserQuery;
if (!email || !password || !firstName || !lastName)
return res.status(400).send({message: req.body});
const newUser = await prisma.user.create({
data: {email, password, firstName, lastName},
});
return res.status(201).send({message: "createUser", newUser});
}
-15
View File
@@ -1,15 +0,0 @@
import {NextApiRequest, NextApiResponse} from 'next';
import { PrismaClient } from '@prisma/client'
import type {DeleteUserQuery} from '@/models/api/user';
const prisma = new PrismaClient();
export default async function deleteUser(req: NextApiRequest, res: NextApiResponse) {
const {id} = req.query as DeleteUserQuery
if (!id) return res.status(400).send({message: "error"});
const deletedUser = await prisma.user.delete({
where: { id }
});
return res.status(200).send({message: "deleteUser", deletedUser});
}
+7 -10
View File
@@ -1,5 +1,4 @@
import type {NextApiRequest, NextApiResponse} from 'next';
import updateUser from '@/pages/api/user/updateUser';
import CRUD from '@/utils/CRUD';
import {CreateUserQuery, DeleteUserQuery} from '@/models/api/user';
import {PrismaClient} from '@prisma/client';
@@ -8,13 +7,13 @@ export default function handler(
req: NextApiRequest,
res: NextApiResponse,
) {
const {method} = req;
if (method === CRUD.CREATE) return createUser(req, res);
if (method === CRUD.READ) return readUser(req, res);
if (method === CRUD.UPDATE) return updateUser(req, res);
if (method === CRUD.DELETE) return deleteUser(req, res);
return help(res);
switch (req.method) {
case CRUD.CREATE: return createUser(req, res);
case CRUD.READ: return readUser(req, res);
// case CRUD.UPDATE: return updateUser(req, res);
case CRUD.DELETE: return deleteUser(req, res);
default: return help(res);
}
}
function help(res: NextApiResponse) {
@@ -35,7 +34,6 @@ async function createUser(req: NextApiRequest, res: NextApiResponse) {
return res.status(201).send({message: 'createUser', newUser});
}
async function deleteUser(req: NextApiRequest, res: NextApiResponse) {
const {id} = req.query as DeleteUserQuery;
if (!id) return res.status(400).send({message: 'error'});
@@ -45,7 +43,6 @@ async function deleteUser(req: NextApiRequest, res: NextApiResponse) {
});
return res.status(200).send({message: 'deleteUser', deletedUser});
}
async function readUser(req: NextApiRequest, res: NextApiResponse) {
const users = await prisma.user.findMany();
-24
View File
@@ -1,24 +0,0 @@
import { NextApiRequest, NextApiResponse } from "next";
import { PrismaClient } from "@prisma/client";
const prisma = new PrismaClient();
export default async function readUser(
req: NextApiRequest,
res: NextApiResponse
) {
const { email, password } = req.query;
if (!email && !password) {
const users = await prisma.user.findMany();
return res.status(200).send({ message: "readUser", users });
}
const user = await prisma.user.findUnique({ where: { email: email } });
if (user?.password == password) {
res.status(200).send({ message: "User found", user });
}
res.status(400).send({ message: "Mot de passe incorrect" });
}
-5
View File
@@ -1,5 +0,0 @@
import {NextApiRequest, NextApiResponse} from 'next';
export default function updateUser(req: NextApiRequest, res: NextApiResponse) {
return res.status(200).send({message: "updateUser"}); // TODO
}
-114
View File
@@ -1,114 +0,0 @@
import {
Box,
Button,
Flex,
FormControl,
FormLabel,
Heading,
Image,
Input,
Spacer,
} from "@chakra-ui/react";
import { useRouter } from "next/router";
import { useForm } from "react-hook-form";
export default function Login() {
const {
handleSubmit,
register,
formState: { errors, isSubmitting },
} = useForm();
const router = useRouter();
const onLogin = async (values) => {
try {
const response = await fetch(`/api/user/?email=${values.email}&password=${values.password}`, {
method: "GET",
headers: {
"Content-Type": "application/json"
}
});
const data = await response.json();
if (data.error) {
alert(data.message);
} else {
console.log(data);
alert("connexion réussie");
// router.push("/");
}
} catch (error) {
console.log(error);
}
};
const redirect_home = () => {
router.push("/");
};
const RightSide = () => (
<Flex
justify={"center"}
direction={"column"}
flexBasis={"100%"}
align={"center"}
>
<Heading mb={"2.5rem"}>Connexion</Heading>
<Box w={"25vw"}>
<form onSubmit={handleSubmit(onLogin)}>
<FormControl isInvalid={errors.name}>
<Box mb={"1rem"}>
<FormLabel>Adresse email</FormLabel>
<Input
id="email"
type="email"
placeholder="Adresse@email.com"
{...register("email", {
required: "This is required",
})}
/>
</Box>
<Box mb={"1rem"}>
<FormLabel>Mot de passe</FormLabel>
<Input
id="password"
type="password"
placeholder="Mot de passe"
{...register("password", {
required: "This is required",
})}
/>
</Box>
<Flex mt={"1rem"} w={"100%"}>
<Button onClick={redirect_home}>Retour</Button>
<Spacer />
<Button colorScheme="purple" type="submit">
Connexion
</Button>
</Flex>
</FormControl>
</form>
</Box>
</Flex>
);
const LeftSide = () => (
<Box flexBasis={"100%"}>
<Image
h={"100vh"}
w={"100%"}
src={"/couple_horizon.png"}
alt="couple looking at horizon"
/>
</Box>
);
return (
<Box>
<Flex gap={10}>
<LeftSide />
<RightSide />
</Flex>
</Box>
);
}
+11 -92
View File
@@ -1,102 +1,21 @@
import {
Box,
Button,
Flex,
FormControl,
FormLabel,
Heading,
Image,
Input,
Spacer,
} from '@chakra-ui/react';
import {useRouter} from 'next/router';
import {useForm} from 'react-hook-form';
import LoginForm from '@/components/form/LoginForm';
type FormValues = {
email: string
password: string
}
export default function Login() {
const {
handleSubmit,
register,
formState: {errors, isSubmitting},
} = useForm();
const router = useRouter();
const onLogin = async (values: FormValues) => {
alert(JSON.stringify(values, null, 2));
// faut voir ce qu'on fait quand on se connecte
};
const goHome = () => {
router.push('/');
};
const RightSide = () => (
<Flex
justify={'center'}
direction={'column'}
flexBasis={'100%'}
align={'center'}
>
<Heading mb={'2.5rem'}>Connexion</Heading>
<Box w={'25vw'}>
<form onSubmit={handleSubmit(onLogin)}>
<FormControl isInvalid={errors.name}>
<Box mb={'1rem'}>
<FormLabel>Adresse email</FormLabel>
<Input
id="email"
type="email"
placeholder="Adresse@email.com"
{...register('email', {
required: 'This is required',
})}
/>
</Box>
<Box mb={'1rem'}>
<FormLabel>Mot de passe</FormLabel>
<Input
id="pwd"
type="password"
placeholder="Mot de passe"
{...register('password', {
required: 'This is required',
})}
/>
</Box>
<Flex mt={'1rem'} w={'100%'}>
<Button onClick={goHome}>Retour</Button>
<Spacer/>
<Button colorScheme="purple" type="submit">Connexion</Button>
</Flex>
</FormControl>
</form>
</Box>
return (
<Flex gap={5} h={'100vh'} justify={'center'} alignItems={'center'}>
<Box flexBasis={'100%'}
display={{base: "none", md: "block"}}
h={"100%"}
bgImage={'/couple_horizon.png'}
bgSize={'cover'}
bgPos={'center'}
/>
<LoginForm/>
</Flex>
);
const LeftSide = () => (
<Box flexBasis={'100%'}>
<Image
h={'100vh'}
w={'100%'}
src={'/couple_horizon.png'}
alt="couple looking at horizon"
/>
</Box>
);
return (
<Box>
<Flex gap={10}>
<LeftSide/>
<RightSide/>
</Flex>
</Box>
);
}