mirror of
https://github.com/Sonny93/my-links.git
synced 2025-12-10 07:25:35 +00:00
Début ajout modal ajout catégories
This commit is contained in:
@@ -1,6 +1,19 @@
|
|||||||
|
import { useState } from 'react';
|
||||||
|
import { signIn, signOut } from "next-auth/react"
|
||||||
|
|
||||||
|
import ModalAddCategory from './ModalAddCategory';
|
||||||
|
|
||||||
import styles from '../../styles/categories.module.scss';
|
import styles from '../../styles/categories.module.scss';
|
||||||
|
|
||||||
export default function Categories({ categories, favorites, handleSelectCategory, categoryActive }) {
|
export default function Categories({
|
||||||
|
categories,
|
||||||
|
favorites,
|
||||||
|
handleSelectCategory,
|
||||||
|
categoryActive,
|
||||||
|
session
|
||||||
|
}) {
|
||||||
|
const [modalOpen, setModalOpen] = useState(false);
|
||||||
|
|
||||||
return (<div className={styles['categories-wrapper']}>
|
return (<div className={styles['categories-wrapper']}>
|
||||||
<div className={`${styles['block-wrapper']} ${styles['favorites']}`}>
|
<div className={`${styles['block-wrapper']} ${styles['favorites']}`}>
|
||||||
<h4>Favoris</h4>
|
<h4>Favoris</h4>
|
||||||
@@ -30,8 +43,18 @@ export default function Categories({ categories, favorites, handleSelectCategory
|
|||||||
})}
|
})}
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<div className={`${styles['block-wrapper']} ${styles['controls']}`}>
|
{session !== null ?
|
||||||
|
<button onClick={() => setModalOpen((state) => !state)}>
|
||||||
|
Ajouter une catégorie
|
||||||
|
</button> :
|
||||||
|
<div className={`${styles['block-wrapper']} ${styles['controls']}`} onClick={signIn}>
|
||||||
<button>Se connecter</button>
|
<button>Se connecter</button>
|
||||||
</div>
|
</div>}
|
||||||
|
|
||||||
|
<ModalAddCategory
|
||||||
|
categories={categories}
|
||||||
|
isOpen={modalOpen}
|
||||||
|
closeModal={() => setModalOpen(false)}
|
||||||
|
/>
|
||||||
</div>);
|
</div>);
|
||||||
}
|
}
|
||||||
34
components/Categories/ModalAddCategory.js
Normal file
34
components/Categories/ModalAddCategory.js
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
import Modal from 'react-modal';
|
||||||
|
|
||||||
|
import styles from '../../styles/categories.module.scss';
|
||||||
|
|
||||||
|
Modal.setAppElement('#__next');
|
||||||
|
|
||||||
|
const customStyles = {
|
||||||
|
content: {
|
||||||
|
top: '50%',
|
||||||
|
left: '50%',
|
||||||
|
right: 'auto',
|
||||||
|
bottom: 'auto',
|
||||||
|
marginRight: '-50%',
|
||||||
|
transform: 'translate(-50%, -50%)',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export default function ModalAddCategory({ categories, isOpen, closeModal }) {
|
||||||
|
function handleAddCategory() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Modal
|
||||||
|
className={styles['modal-overlay']}
|
||||||
|
isOpen={isOpen}
|
||||||
|
onRequestClose={closeModal}
|
||||||
|
style={customStyles}
|
||||||
|
>
|
||||||
|
<h2>Ajouter une catégorie</h2>
|
||||||
|
<button onClick={closeModal}>close</button>
|
||||||
|
</Modal>
|
||||||
|
);
|
||||||
|
}
|
||||||
949
package-lock.json
generated
949
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -8,16 +8,19 @@
|
|||||||
"lint": "next lint"
|
"lint": "next lint"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@prisma/client": "^3.7.0",
|
"@prisma/client": "3.6.0",
|
||||||
|
"bcrypt": "^5.0.1",
|
||||||
"next": "12.0.7",
|
"next": "12.0.7",
|
||||||
|
"next-auth": "^4.0.6",
|
||||||
"react": "17.0.2",
|
"react": "17.0.2",
|
||||||
"react-dom": "17.0.2",
|
"react-dom": "17.0.2",
|
||||||
"react-intersection-observer": "^8.33.1",
|
"react-intersection-observer": "^8.33.1",
|
||||||
|
"react-modal": "^3.14.4",
|
||||||
"sass": "^1.46.0"
|
"sass": "^1.46.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"eslint": "7",
|
"eslint": "7",
|
||||||
"eslint-config-next": "12.0.7",
|
"eslint-config-next": "12.0.7",
|
||||||
"prisma": "^3.7.0"
|
"prisma": "3.6.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,15 @@
|
|||||||
import '../styles/globals.scss';
|
import '../styles/globals.scss';
|
||||||
|
import { SessionProvider } from 'next-auth/react';
|
||||||
|
|
||||||
function MyApp({ Component, pageProps }) {
|
function MyApp({
|
||||||
return <Component {...pageProps} />;
|
Component,
|
||||||
|
pageProps: { session, ...pageProps }
|
||||||
|
}) {
|
||||||
|
return (
|
||||||
|
<SessionProvider session={session}>
|
||||||
|
<Component {...pageProps} />
|
||||||
|
</SessionProvider>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export default MyApp;
|
export default MyApp;
|
||||||
48
pages/api/auth/[...nextauth].js
Normal file
48
pages/api/auth/[...nextauth].js
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
import NextAuth from 'next-auth'
|
||||||
|
import CredentialsProvider from 'next-auth/providers/credentials';
|
||||||
|
import bcrypt from 'bcrypt';
|
||||||
|
|
||||||
|
import { PrismaClient } from '@prisma/client';
|
||||||
|
const prisma = new PrismaClient();
|
||||||
|
|
||||||
|
export default NextAuth({
|
||||||
|
providers: [
|
||||||
|
CredentialsProvider({
|
||||||
|
name: 'Credentials',
|
||||||
|
credentials: {
|
||||||
|
username: { label: 'Email', type: 'text', placeholder: 'user@example.com' },
|
||||||
|
password: { label: 'Mot de passe', type: 'password', placeholder: '********' }
|
||||||
|
},
|
||||||
|
async authorize(credentials, req) {
|
||||||
|
return { email: 'user@example.com' };
|
||||||
|
|
||||||
|
const email = credentials?.email;
|
||||||
|
const password = credentials?.password;
|
||||||
|
|
||||||
|
if (!email || !password)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
let user;
|
||||||
|
try {
|
||||||
|
user = await prisma.user.findUnique({
|
||||||
|
where: { email }
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`Impossible de récupérer l'utilisateur avec les identifiants : ${credentials}`);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!user)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
const passwordMatch = await bcrypt.compare(password, user.password);
|
||||||
|
if (!passwordMatch)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
return {
|
||||||
|
email: user.email
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
]
|
||||||
|
})
|
||||||
@@ -1,14 +1,16 @@
|
|||||||
import { createRef, useRef, useState } from 'react';
|
import { createRef, useRef, useState } from 'react';
|
||||||
|
import { useSession } from 'next-auth/react';
|
||||||
|
|
||||||
import Categories from '../components/Categories/Categories';
|
import Categories from '../components/Categories/Categories';
|
||||||
import Links from '../components/Links/Links';
|
import Links from '../components/Links/Links';
|
||||||
|
|
||||||
import styles from '../styles/Home.module.scss';
|
import styles from '../styles/Home.module.scss';
|
||||||
|
|
||||||
import { PrismaClient } from '@prisma/client'
|
import { PrismaClient } from '@prisma/client';
|
||||||
const prisma = new PrismaClient()
|
const prisma = new PrismaClient();
|
||||||
|
|
||||||
export default function Home({ categories, favorites }) {
|
export default function Home({ categories, favorites }) {
|
||||||
|
const { data: session, status } = useSession();
|
||||||
const [categoryActive, setCategoryActive] = useState(categories?.[0]?.id);
|
const [categoryActive, setCategoryActive] = useState(categories?.[0]?.id);
|
||||||
const refCategoryActive = useRef();
|
const refCategoryActive = useRef();
|
||||||
|
|
||||||
@@ -21,6 +23,7 @@ export default function Home({ categories, favorites }) {
|
|||||||
behavior: 'smooth'
|
behavior: 'smooth'
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
console.log(session, session?.user);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={styles.App}>
|
<div className={styles.App}>
|
||||||
@@ -29,11 +32,13 @@ export default function Home({ categories, favorites }) {
|
|||||||
favorites={favorites}
|
favorites={favorites}
|
||||||
handleSelectCategory={handleSelectCategory}
|
handleSelectCategory={handleSelectCategory}
|
||||||
categoryActive={categoryActive}
|
categoryActive={categoryActive}
|
||||||
|
session={session}
|
||||||
/>
|
/>
|
||||||
<Links
|
<Links
|
||||||
categories={categories}
|
categories={categories}
|
||||||
setCategoryActive={setCategoryActive}
|
setCategoryActive={setCategoryActive}
|
||||||
refCategoryActive={refCategoryActive}
|
refCategoryActive={refCategoryActive}
|
||||||
|
session={session}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -41,6 +41,7 @@
|
|||||||
|
|
||||||
&:hover:not(.active) {
|
&:hover:not(.active) {
|
||||||
color: #3f88c5;
|
color: #3f88c5;
|
||||||
|
background: #eee;
|
||||||
border-bottom: 2px solid #3f88c5;
|
border-bottom: 2px solid #3f88c5;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -84,3 +85,8 @@
|
|||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.modal {
|
||||||
|
height: 500px;
|
||||||
|
width: 500px;
|
||||||
|
}
|
||||||
@@ -52,3 +52,18 @@ li {
|
|||||||
background: #1e5c8f;
|
background: #1e5c8f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
button {
|
||||||
|
cursor: pointer;
|
||||||
|
width: 100%;
|
||||||
|
color: #fff;
|
||||||
|
background: #3f88c5;
|
||||||
|
padding: 10px;
|
||||||
|
border: 1px solid #3f88c5;
|
||||||
|
border-radius: 3px;
|
||||||
|
transition: .15s;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
transform: scale(1.01);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -43,7 +43,8 @@
|
|||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
border-bottom-color: #3f88c5;
|
border-bottom-color: #3f88c5;
|
||||||
transform: scale(1.01);
|
background: #eee;
|
||||||
|
margin: 0 5px 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
& .link-name .link-category {
|
& .link-name .link-category {
|
||||||
|
|||||||
Reference in New Issue
Block a user