From 728c84d0f990cc129dc63ff136df8a24b0965aa8 Mon Sep 17 00:00:00 2001 From: AntonyKLINGER Date: Mon, 27 May 2024 11:23:27 +0200 Subject: [PATCH 001/100] maj comptes admin + dr --- components/AllSessions.jsx | 46 +++++----- components/Comptes.jsx | 155 +++++++++++++++++++++++++++++++++ components/Header.jsx | 2 +- components/Modules.jsx | 9 +- components/ModulesBack.jsx | 28 +++--- components/SessionsBack.jsx | 50 ++++++----- components/SessionsModule.jsx | 47 +++++----- pages/admin.js | 31 ++++--- pages/api/accounts/create.js | 63 ++++++++++++++ pages/api/accounts/delete.js | 23 +++++ pages/api/accounts/index.js | 10 +++ pages/api/accounts/lib/auth.js | 28 ++++++ pages/api/accounts/lib/jwt.js | 27 ++++++ pages/api/emails/newAccount.js | 53 +++++++++++ pages/connexion.js | 58 ++++++++---- prisma/schema.prisma | 7 ++ styles/Admin.module.css | 31 +++++++ views/emails/newaccount.hbs | 73 ++++++++++++++++ 18 files changed, 631 insertions(+), 110 deletions(-) create mode 100644 components/Comptes.jsx create mode 100644 pages/api/accounts/create.js create mode 100644 pages/api/accounts/delete.js create mode 100644 pages/api/accounts/index.js create mode 100644 pages/api/accounts/lib/auth.js create mode 100644 pages/api/accounts/lib/jwt.js create mode 100644 pages/api/emails/newAccount.js create mode 100644 views/emails/newaccount.hbs diff --git a/components/AllSessions.jsx b/components/AllSessions.jsx index 7a8adf1..912fb5a 100644 --- a/components/AllSessions.jsx +++ b/components/AllSessions.jsx @@ -11,7 +11,7 @@ import AddSession from '@/components/AddSession' import SessionsModule from '@/components/SessionsModule' import styles from '@/styles/Admin.module.css' -export default function Modules({setPage, page}){ +export default function Modules({setPage, page, user}){ const [open, setOpen] = useState(null) const [alert, setAlert] = useState(null) @@ -107,7 +107,6 @@ export default function Modules({setPage, page}){ getSessions(tri, status, region, codes); } - console.log(sessions) return ( <> @@ -169,25 +168,28 @@ export default function Modules({setPage, page}){
{sessions.length > 0 ? ( sessions.map((session, index) => { - return ( -
- deleteSession(session.id)} - status={session.status} - setActions={setActions} - session={session} - /> -
- ) + if(session.status == 'publish' || user.type == 'Administrateur' || user.id == 10){ + return ( +
+ deleteSession(session.id)} + status={session.status} + setActions={setActions} + session={session} + user={user} + /> +
+ ) + } }) ) : ( <> @@ -229,7 +231,7 @@ export default function Modules({setPage, page}){
setOpen(null)} className={styles.Back}>Retour aux modules
- + )} diff --git a/components/Comptes.jsx b/components/Comptes.jsx new file mode 100644 index 0000000..a721771 --- /dev/null +++ b/components/Comptes.jsx @@ -0,0 +1,155 @@ +import { useState, useEffect } from 'react' +import Alert from '@/components/Alert' +import { Notif } from '@/components/Notif' +import styles from '@/styles/Admin.module.css' + +export default function Comptes(){ + + const [alert, setAlert] = useState(null) + const [notif, setNotif] = useState(null) + const [create, setCreate] = useState(false) + const [actions, setActions] = useState(1) + const [account, setAccount] = useState({}) + const [listAccount, setListAccount] = useState([]) + + useEffect(() => { + const getAccounts = async () => { + const geter = await fetch(`/api/accounts/`) + const json = await geter.json() + setListAccount(json) + } + getAccounts() + }, [alert, actions]) + + const handleChange = (e) => { + const { name, type, value } = e.target + setAccount(prev => { + return { + ...prev, + [name]: value + } + }) + } + + const createAccount = async () => { + const { email, type } = account + if(email && type){ + const add = await fetch(`/api/accounts/create`, { + method: 'POST', + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + email: email, + type: type + }) + }) + const json = await add.json() + if(json.status == "success"){ + + //reset + setCreate(false) + setAccount({}) + setActions(prev => prev+1) + + setNotif({ + text: 'Le compte a bien été créé !', + icon: 'done' + }); + } + else{ + setNotif({ + text: 'Cette adresse e-mail admin ou DR existe déjà !', + icon: 'close' + }); + } + } + else{ + setNotif({ + text: 'Une information est manquante.', + icon: 'close' + }); + } + } + + const preDeleteAccount = (id) => { + setAlert({ + icon: 'warning', + text: 'Êtes-vous sûr de vouloir supprimer ce compte ?', + action: () => deleteAccount(id) + }); + } + + const deleteAccount = async (id) => { + const response = await fetch(`/api/accounts/delete/?id=${id}`, { + method: 'DELETE', + headers: { + 'Content-Type': 'application/json', + }, + }); + if(response.ok){ + setNotif({ + text: 'Le compte a bien été supprimé.', + icon: 'done' + }); + } + setAlert(null) + } + + return ( + <> +
+ Comptes administrateurs et DR + +
+ {create && ( +
+
+
+ Adresse e-mail du compte + +
+
+ Type de compte +
+ + expand_more +
+
+
+ +
+ )} + {listAccount.length > 0 ? ( + <> + {listAccount.map((acc, i) => { + return ( +
+

{acc.email}

+
+ {acc.type} + +
+
+ ) + })} + + ) : ( + <> +

Aucun compte n'a été créé pour le moment.

+ + )} + + {alert != null && ( + + )} + {notif != null && ( + + )} + + ) +} \ No newline at end of file diff --git a/components/Header.jsx b/components/Header.jsx index 7ccafab..99fb35f 100644 --- a/components/Header.jsx +++ b/components/Header.jsx @@ -45,7 +45,7 @@ export default function Header(){
  • setActiveMenu(prev => !prev)}>Les Rencontres
  • {user?.id ? ( <> - {user.id == 10 ? ( + {(user.id == 10 || user.type == 'Administrateur' || user.type == 'DR') ? (
  • setActiveMenu(prev => !prev)} className={styles.pf}>Administration
  • ) : (
  • setActiveMenu(prev => !prev)} className={styles.pf}>Espace personnel
  • diff --git a/components/Modules.jsx b/components/Modules.jsx index 53262da..ff9aba9 100644 --- a/components/Modules.jsx +++ b/components/Modules.jsx @@ -8,7 +8,7 @@ import AddSession from '@/components/AddSession' import SessionsModule from '@/components/SessionsModule' import styles from '@/styles/Admin.module.css' -export default function Modules(setPage){ +export default function Modules({setPage, user}){ const [open, setOpen] = useState(null) const [alert, setAlert] = useState(null) @@ -115,7 +115,9 @@ export default function Modules(setPage){ <>
    Tous les modules - + {user.type != 'DR' && ( + + )}
    @@ -159,6 +161,7 @@ export default function Modules(setPage){ setAlert={setAlert} sessions={module.sessions} action={() => deleteModule(module.id)} + user={user} />
    ) @@ -197,7 +200,7 @@ export default function Modules(setPage){
    setOpen(null)} className={styles.Back}>Retour aux modules
    - + )} diff --git a/components/ModulesBack.jsx b/components/ModulesBack.jsx index a388448..6034920 100644 --- a/components/ModulesBack.jsx +++ b/components/ModulesBack.jsx @@ -2,7 +2,7 @@ import Link from 'next/link' import { useState, useEffect } from 'react' import styles from '@/styles/ModuleBack.module.css' -export default function ModulesBack({date, code, lastUpdate, category, title, id, setOpen, setAlert, action, sessions}){ +export default function ModulesBack({date, code, lastUpdate, category, title, id, setOpen, setAlert, action, sessions, user}){ function formatDate(dateString) { const date = new Date(dateString); @@ -37,17 +37,21 @@ export default function ModulesBack({date, code, lastUpdate, category, title, id Module ({nbSession} session{nbSession > 1 ? 's' : ''} à venir) :{title}
    - - + {user.type != 'DR' && ( + <> + + + + )}
    diff --git a/components/SessionsBack.jsx b/components/SessionsBack.jsx index c6b6aaa..b3113ba 100644 --- a/components/SessionsBack.jsx +++ b/components/SessionsBack.jsx @@ -2,7 +2,7 @@ import Link from 'next/link' import { useState, useEffect } from 'react' import styles from '@/styles/SessionsBack.module.css' -export default function SessionsBack({isModule, date, session, code, region, title, id, setOpen, setAlert, setActions, action, status, moduleId, dept}){ +export default function SessionsBack({isModule, date, session, code, region, title, id, setOpen, setAlert, setActions, action, status, moduleId, dept, user}){ function formatDate(dateString) { const date = new Date(dateString); @@ -70,28 +70,32 @@ export default function SessionsBack({isModule, date, session, code, region, tit
    - - - {status == 'brouillon' && ( - + {user.type != 'DR' && ( + <> + + + {status == 'brouillon' && ( + + )} + )}
    {!isModule && ( diff --git a/components/SessionsModule.jsx b/components/SessionsModule.jsx index 822c782..cdbd149 100644 --- a/components/SessionsModule.jsx +++ b/components/SessionsModule.jsx @@ -5,7 +5,7 @@ import EditModule from '@/components/EditModule' import AddModule from '@/components/AddModule' import styles from '@/styles/Admin.module.css' -export default function SessionsModule({ id, setOpen, open, nom }){ +export default function SessionsModule({ id, setOpen, open, nom, user }){ const [nav, setNav] = useState(0) const [alert, setAlert] = useState(null) @@ -60,7 +60,9 @@ export default function SessionsModule({ id, setOpen, open, nom }){ <>
    Toutes les sessions pour le module :
    {nom}
    - + {user.type != 'DR' && ( + + )}
    @@ -69,25 +71,28 @@ export default function SessionsModule({ id, setOpen, open, nom }){
    {sessions.length > 0 ? ( sessions.map((session, index) => { - return ( -
    - deleteSession(session.id)} - status={session.status} - setActions={setActions} - session={session} - isModule="yes" - /> -
    - ) + if(session.status == "publish" || user.type == 'Administrateur' || user.id == 10){ + return ( +
    + deleteSession(session.id)} + status={session.status} + setActions={setActions} + session={session} + isModule="yes" + user={user} + /> +
    + ) + } }) ) : ( <> diff --git a/pages/admin.js b/pages/admin.js index 696a51c..8dc73f7 100644 --- a/pages/admin.js +++ b/pages/admin.js @@ -3,30 +3,34 @@ import { useState, uesEffect } from 'react' import nextCookies from 'next-cookies'; import { verifyToken } from '@/utils/auth'; import Modules from '@/components/Modules' -import Inscriptions from '@/components/Inscriptions' +import Comptes from '@/components/Comptes' import Sessions from '@/components/Sessions' import AllSessions from '@/components/AllSessions' import styles from '@/styles/Admin.module.css' export async function getServerSideProps(context) { const { auth: token } = nextCookies(context); + console.log('Token:', token); const user = verifyToken(token); - - if (!user || user.id != 10) { - return { - redirect: { - destination: '/connexion', - permanent: false, - }, - }; + console.log('User:', user); + + if (!user || (user.id != 10 && user.type != 'Administrateur' && user.type != 'DR')) { + return { + redirect: { + destination: '/connexion', + permanent: false, + }, + }; } - + return { props: { user } }; } export default function Admin({ user }){ + console.log('User in Admin component:', user); const [page, setPage] = useState(0) + const [userInfo, setUserInfo] = useState(user) const logout = async () => { const unlog = await fetch('/api/logout') @@ -48,6 +52,7 @@ export default function Admin({ user }){
    • {setPage(0)}}>Voir les modules
    • {setPage(2)}}>Voir les sessions
    • +
    • {setPage(1)}}>Comptes
    • {/*
    • {setPage(1)}}>Inscriptions
    • */}
    • Déconnexion
    @@ -55,13 +60,13 @@ export default function Admin({ user }){
    {page == 0 && ( - + )} {page == 1 && ( - + )} {page == 2 && ( - + )}
    diff --git a/pages/api/accounts/create.js b/pages/api/accounts/create.js new file mode 100644 index 0000000..fbb69fe --- /dev/null +++ b/pages/api/accounts/create.js @@ -0,0 +1,63 @@ +import bcrypt from 'bcrypt'; +import prisma from '@/prisma'; +import fetch from 'node-fetch'; + +const SALT_ROUNDS = 10; + +function generatePassword(length) { + const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; + let password = ''; + for (let i = 0; i < length; i++) { + password += chars.charAt(Math.floor(Math.random() * chars.length)); + } + return password; +} + +export default async function handle(req, res) { + if (req.method === 'POST') { + const { email, type } = req.body; + + try { + // Vérifier si un compte avec cet email existe déjà + const existingAccount = await prisma.account.findUnique({ + where: { email }, + }); + + if (existingAccount) { + res.status(200).json({ status: 'already exist' }); + return; + } + + // Générer un mot de passe de 12 caractères + let password = generatePassword(12); + const hashedPassword = await bcrypt.hash(password, SALT_ROUNDS); + + const newAccount = await prisma.account.create({ + data: { + email, + type, + password: hashedPassword, + }, + }); + + await fetch(`${process.env.WEBSITE_URL}/api/emails/newAccount`, { + method: 'POST', + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + email, + type, + password, + }), + }); + + res.status(201).json({ status: 'success' }); + } catch (error) { + res.status(500).json({ error: `Impossible de créer le compte: ${error.message}` }); + } + } else { + res.setHeader('Allow', ['POST']); + res.status(405).end(`Method ${req.method} Not Allowed`); + } +} diff --git a/pages/api/accounts/delete.js b/pages/api/accounts/delete.js new file mode 100644 index 0000000..4315d70 --- /dev/null +++ b/pages/api/accounts/delete.js @@ -0,0 +1,23 @@ +import prisma from '@/prisma' + +export default async function handle(req, res) { + if (req.method === 'DELETE') { + const { id } = req.query; + const accountId = parseInt(id); + + try { + + await prisma.account.delete({ + where: { id: accountId }, + }); + + res.json({ message: 'Compte supprimé avec succès' }); + } catch (error) { + console.error(error); + res.status(500).json({ error: `Impossible de supprimer le compte : ${error.message}` }); + } + } else { + res.setHeader('Allow', ['DELETE']); + res.status(405).end(`Method ${req.method} Not Allowed`); + } +} diff --git a/pages/api/accounts/index.js b/pages/api/accounts/index.js new file mode 100644 index 0000000..691ecf8 --- /dev/null +++ b/pages/api/accounts/index.js @@ -0,0 +1,10 @@ +import prisma from '@/prisma' + +export default async function handle(req, res) { + + let queryOptions = {} + + const accounts = await prisma.account.findMany(queryOptions) || []; + + res.json(accounts); +} diff --git a/pages/api/accounts/lib/auth.js b/pages/api/accounts/lib/auth.js new file mode 100644 index 0000000..fcc0e75 --- /dev/null +++ b/pages/api/accounts/lib/auth.js @@ -0,0 +1,28 @@ +import bcrypt from 'bcrypt'; +import prisma from '@/prisma'; + +async function verifyUser(email, motDePasse) { + const user = await prisma.account.findUnique({ + where: { email: email }, + }); + + if (!user) { + return { success: false, message: "Utilisateur non trouvé." }; + } + + const match = await bcrypt.compare(motDePasse, user.password); + + if (match) { + return { success: true, account: user }; + } else { + return { success: false, message: "Mot de passe incorrect." }; + } +} + +export default async function handle(req, res) { + const { mail, motDePasse } = req.query; + + const verify = await verifyUser(mail, motDePasse); + + res.json(verify); +} diff --git a/pages/api/accounts/lib/jwt.js b/pages/api/accounts/lib/jwt.js new file mode 100644 index 0000000..39b6520 --- /dev/null +++ b/pages/api/accounts/lib/jwt.js @@ -0,0 +1,27 @@ +import cookie from 'cookie'; +import jwt from 'jsonwebtoken'; + +export default async function handle(req, res) { + if(req.method === 'POST') { + const { mail, id, type } = req.body + + const token = jwt.sign( + { mail: mail, id: id, type: type }, + process.env.JWT_SECRET, + { expiresIn: '5h' } + ); + + res.setHeader('Set-Cookie', cookie.serialize('auth', token, { + httpOnly: true, + secure: process.env.NODE_ENV !== 'development', + maxAge: 60 * 60 * 5, + path: '/', + sameSite: 'strict', + })); + + res.status(200).json({ success: true, message: 'Connexion réussie et cookie créé.' }); + } else { + res.setHeader('Allow', ['POST']); + res.status(405).end(`Method ${req.method} Not Allowed`); + } +} diff --git a/pages/api/emails/newAccount.js b/pages/api/emails/newAccount.js new file mode 100644 index 0000000..a6953ea --- /dev/null +++ b/pages/api/emails/newAccount.js @@ -0,0 +1,53 @@ +const nodemailer = require('nodemailer'); +const hbs = require('nodemailer-express-handlebars'); +const path = require('path'); + + +export default async function handler(req, res) { + + const { email, password, type } = req.body + + const transporter = nodemailer.createTransport({ + host: 'smtp-relay.brevo.com', + port: 587, + secure: false, + auth: { + user: 'contact@territoiresentransitions.fr', + pass: process.env.BREVO_KEY + }, + tls: {rejectUnauthorized: false} + }); + + transporter.use('compile', hbs({ + viewEngine: { + extName: '.hbs', + partialsDir: path.resolve('./views/emails'), + defaultLayout: false, + }, + viewPath: path.resolve('./views/emails'), + extName: '.hbs', + })); + + const mailOptions = { + from: '"ADEME" ', + to: email, + subject: "Votre nouveau compte sur les Rencontres Territoire Engagé Transition écologique !", + template: 'newaccount', + context: { + password: password, + type: type, + email: email, + siteUrl: process.env.WEBSITE_URL, + } + }; + + transporter.sendMail(mailOptions, (error, info) => { + if (error) { + res.json(error) + // return console.log(error); + } + console.log('Message sent: %s', info.messageId); + res.status(200).json({ status: 'sended' }) + }); + +} \ No newline at end of file diff --git a/pages/connexion.js b/pages/connexion.js index 0c8c39e..7908d29 100644 --- a/pages/connexion.js +++ b/pages/connexion.js @@ -14,38 +14,56 @@ export default function Login(){ const router = useRouter(); const handleChange = async (event) => { - const { name, type, value } = event.target + const { name, type, checked, value } = event.target setUserLogin(prev => { return { ...prev, - [name]: value + [name]: type == 'checkbox' ? checked : value } }) } const login = async () => { - const { mail, motDePasse } = userLogin; + const { mail, motDePasse, isAdmin } = userLogin; if (mail && motDePasse) { - const test = await fetch(`/api/users/lib/auth/?mail=${mail}&motDePasse=${motDePasse}`); - const json = await test.json(); - if (json.success == true) { - + if(isAdmin){ + const test = await fetch(`/api/accounts/lib/auth/?mail=${mail}&motDePasse=${motDePasse}`); + const json = await test.json(); + if (json.success == true) { + const jwtResponse = await fetch(`/api/accounts/lib/jwt`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ id: json.account.id, mail: json.account.mail, type: json.account.type }), + }); + + const jwtJson = await jwtResponse.json(); + if(jwtJson.success){ + router.push('/admin'); + } + } else { + setNotif({ + text: 'Identifiant ou mot de passe invalide(s)', + icon: 'close' + }); + } + } + else{ + const test = await fetch(`/api/users/lib/auth/?mail=${mail}&motDePasse=${motDePasse}`); + const json = await test.json(); + if (json.success == true) { const jwtResponse = await fetch(`/api/users/lib/jwt`, { method: 'POST', headers: { 'Content-Type': 'application/json', }, - body: JSON.stringify({ id: json.user.id, mail: json.user.mail }), + body: JSON.stringify({ id: json.user.id, mail: json.user.mail, type: 'user' }), }); const jwtJson = await jwtResponse.json(); if(jwtJson){ - if(json.user.id == 10){ - router.push('/admin'); - } - else{ - router.push('/espace-personnel'); - } + router.push('/espace-personnel'); } } else { @@ -54,8 +72,8 @@ export default function Login(){ icon: 'close' }); } - } + } else { setNotif({ text: 'Veuillez remplir tous les champs !', @@ -118,6 +136,16 @@ export default function Login(){
    +
    + +    + Je suis administrateur ou DR +
    Créer un compte diff --git a/prisma/schema.prisma b/prisma/schema.prisma index 3172b18..4f17334 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -119,3 +119,10 @@ model Review { session Session @relation(fields: [sessionId], references: [id]) user User @relation(fields: [userId], references: [id]) } + +model Account { + id Int @id @default(autoincrement()) @db.SmallInt + email String @unique + password String? + type String? +} diff --git a/styles/Admin.module.css b/styles/Admin.module.css index 7b5398b..af363cf 100644 --- a/styles/Admin.module.css +++ b/styles/Admin.module.css @@ -282,4 +282,35 @@ .visubox button span{ color:#FFF; font-size: 1.15rem; +} + +.Subtitle{ + font-size: 1.1rem; + margin-bottom: 5px; + font-weight: 500; +} + +.acc{ + border-bottom:1px solid rgba(0,0,0,.05) +} + +.acc p{ + width: 50%; +} + +.acc span{ + background-color: var(--primaryBack); + color: var(--primary); + display: inline-block; + padding:10px 15px; + border-radius: 8px; +} + +.acc button{ + color:#FFF; + background-color: var(--primary); + border:0px; + border-radius: 8px; + padding:10px 15px; + cursor:pointer; } \ No newline at end of file diff --git a/views/emails/newaccount.hbs b/views/emails/newaccount.hbs new file mode 100644 index 0000000..995b60a --- /dev/null +++ b/views/emails/newaccount.hbs @@ -0,0 +1,73 @@ + + + + + + + + + + +
    +
    + top email +
    +

    Votre compte {{type}} vient d'être créé !

    +

    Pour vous connecter, utilisez vos accès : votre adresse e-mail : {{email}} et votre nouveau mot de passe.

    +

    Voici votre nouveau mot de passe :

    + {{password}} +

    Attention à le garder secrètement de votre côté.

    +

    Vous pouvez vous connecter à partir de ce lien : Connexion.

    +
    + +
    +
    + + From c377c2cd0fd4283326c7e8ed6cb75a57429dfa38 Mon Sep 17 00:00:00 2001 From: lollybet_antony Date: Wed, 29 May 2024 10:25:53 +0200 Subject: [PATCH 002/100] =?UTF-8?q?mise=20=C3=A0=20jour=2029/05?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- components/AddModule.jsx | 33 +++++--- components/EditModule.jsx | 33 +++++--- components/Participant.jsx | 6 +- components/Participants.jsx | 2 +- components/SessionBox.jsx | 6 +- pages/admin.js | 4 +- pages/api/registrations/bySession.js | 1 + pages/api/uploadVisuel.js | 102 +++++++++++++++++++++++ pages/rencontres/[category]/[session].js | 6 +- pages/rencontres/[category]/index.js | 4 + prisma/schema.prisma | 1 + public/uploads/1716970875967.png | Bin 0 -> 144384 bytes styles/Module.module.css | 13 +++ styles/globals.css | 4 + views/emails/session_register.hbs | 4 +- views/emails/session_relance_days.hbs | 6 +- views/emails/session_relance_weeks.hbs | 4 +- 17 files changed, 190 insertions(+), 39 deletions(-) create mode 100644 public/uploads/1716970875967.png diff --git a/components/AddModule.jsx b/components/AddModule.jsx index e607af5..02fb000 100644 --- a/components/AddModule.jsx +++ b/components/AddModule.jsx @@ -279,18 +279,31 @@ export default function AddModule({setOpen}){ const [selectedImage, setSelectedImage] = useState(null); const [previewUrl, setPreviewUrl] = useState(null); - const handleImageChange = (event) => { + const handleImageChange = async (event) => { if (event.target.files && event.target.files[0]) { - const file = event.target.files[0]; - setSelectedImage(file); // Mettez à jour l'état avec le fichier sélectionné si vous l'utilisez + const file = event.target.files[0]; + setSelectedImage(file); + + const formData = new FormData(); + formData.append('file', file); - // Créer une URL pour le fichier sélectionné - const reader = new FileReader(); - reader.onloadend = () => { - // Lorsque la lecture est terminée, stockez l'URL résultante dans l'état previewUrl - setPreviewUrl(reader.result); - }; - reader.readAsDataURL(file); // Démarrez la lecture du fichier + try { + const response = await fetch('/api/uploadVisuel', { + method: 'POST', + body: formData, + }); + + const data = await response.json(); + + if (response.ok) { + const publicUrl = data.urlsPDF[0].url; + setPreviewUrl(publicUrl); + } else { + console.error('Erreur lors de l\'upload:', data.error); + } + } catch (error) { + console.error('Erreur lors de l\'upload:', error); + } } }; diff --git a/components/EditModule.jsx b/components/EditModule.jsx index 31667da..d5302c6 100644 --- a/components/EditModule.jsx +++ b/components/EditModule.jsx @@ -272,18 +272,31 @@ export default function EditModule({setOpen, id}){ const [selectedImage, setSelectedImage] = useState(null); const [previewUrl, setPreviewUrl] = useState(null); - const handleImageChange = (event) => { + const handleImageChange = async (event) => { if (event.target.files && event.target.files[0]) { - const file = event.target.files[0]; - setSelectedImage(file); // Mettez à jour l'état avec le fichier sélectionné si vous l'utilisez + const file = event.target.files[0]; + setSelectedImage(file); + + const formData = new FormData(); + formData.append('file', file); - // Créer une URL pour le fichier sélectionné - const reader = new FileReader(); - reader.onloadend = () => { - // Lorsque la lecture est terminée, stockez l'URL résultante dans l'état previewUrl - setPreviewUrl(reader.result); - }; - reader.readAsDataURL(file); // Démarrez la lecture du fichier + try { + const response = await fetch('/api/uploadVisuel', { + method: 'POST', + body: formData, + }); + + const data = await response.json(); + + if (response.ok) { + const publicUrl = data.urlsPDF[0].url; + setPreviewUrl(publicUrl); + } else { + console.error('Erreur lors de l\'upload:', data.error); + } + } catch (error) { + console.error('Erreur lors de l\'upload:', error); + } } }; diff --git a/components/Participant.jsx b/components/Participant.jsx index 12e8da4..cc472b0 100644 --- a/components/Participant.jsx +++ b/components/Participant.jsx @@ -3,7 +3,7 @@ import Alert from '@/components/Alert' import { useState, useEffect } from 'react' import styles from '@/styles/Participants.module.css' -export default function Participant({ data, setActions }){ +export default function Participant({ data, setActions, session }){ const [alert, setAlert] = useState(null) const [notif, setNotif] = useState(null) @@ -24,6 +24,8 @@ export default function Participant({ data, setActions }){ }); } + console.log(data.session.metasSession.nombreJours) + return ( <>
    @@ -43,7 +45,7 @@ export default function Participant({ data, setActions }){
    Type de fonction{data.typeFonction}
    Ville{data.ville ? data.ville : '-'}
    Transport{data.transport}
    -
    Repas{data.repas ? 'J1 : Oui' : 'J1 : Non'}{data.repas2 ? ' / J2 : Oui' : ' / J2 : Non'}{data.regime ? ` (${data.regime})` : ''}
    +
    Repas{data.repas ? 'J1 : Oui' : 'J1 : Non'}{data.session.metasSession.nombreJours == 2 ? data.repas2 ? ' / J2 : Oui' : ' / J2 : Non' : ''}{data.regime ? ` (${data.regime})` : ''}
    Besoin spécifique{data.besoins != null ? data.besoins : '-'}
    Présence{data.deleted ? 'Annulée' : data.days ? 'Complète' : '1/2'}
    diff --git a/components/Participants.jsx b/components/Participants.jsx index 2934c3b..e11c0b9 100644 --- a/components/Participants.jsx +++ b/components/Participants.jsx @@ -143,7 +143,7 @@ export default function Participants({ session, setOpen }){ )} {users.filter(user => selectedFonction === '' || user.fonction === selectedFonction).map((user, index) => { - return + return })} {users.length === 0 &&
    Pas de participant pour cette session.
    }
    diff --git a/components/SessionBox.jsx b/components/SessionBox.jsx index 24ad99b..6e3bd45 100644 --- a/components/SessionBox.jsx +++ b/components/SessionBox.jsx @@ -1,7 +1,7 @@ import Link from 'next/link' import styles from '@/styles/SessionBox.module.css' -export default function SessionBox({date, region, title, link, data, register, dept, see, detail}){ +export default function SessionBox({date, region, title, link, data, register, dept, see, detail, displayDept}){ function formatDate(dateString) { const date = new Date(dateString); @@ -11,14 +11,12 @@ export default function SessionBox({date, region, title, link, data, register, d return `${day}/${month}/${year}`; } - console.log(data) - return ( <>
    {date} - {dept && `${dept} - `}{region} + {displayDept != "no" ? dept && `${dept} - ` : ''}{region}
    diff --git a/pages/admin.js b/pages/admin.js index 8dc73f7..a60d3c0 100644 --- a/pages/admin.js +++ b/pages/admin.js @@ -10,9 +10,9 @@ import styles from '@/styles/Admin.module.css' export async function getServerSideProps(context) { const { auth: token } = nextCookies(context); - console.log('Token:', token); + const user = verifyToken(token); - console.log('User:', user); + if (!user || (user.id != 10 && user.type != 'Administrateur' && user.type != 'DR')) { return { diff --git a/pages/api/registrations/bySession.js b/pages/api/registrations/bySession.js index edfe985..c72dc3a 100644 --- a/pages/api/registrations/bySession.js +++ b/pages/api/registrations/bySession.js @@ -14,6 +14,7 @@ export default async function handle(req, res) { session: { include: { reviews: true, + metasSession: true, } } }, diff --git a/pages/api/uploadVisuel.js b/pages/api/uploadVisuel.js index e69de29..1811532 100644 --- a/pages/api/uploadVisuel.js +++ b/pages/api/uploadVisuel.js @@ -0,0 +1,102 @@ +import { IncomingForm } from 'formidable'; +import fs from 'fs'; +import path from 'path'; +import { createClient } from '@supabase/supabase-js'; + +export const config = { + api: { + bodyParser: false, + }, +}; + +const supabaseUrl = process.env.NEXT_PUBLIC_SUPABASE_URL; +const supabaseKey = process.env.NEXT_PUBLIC_SUPABASE_KEY; +const supabase = createClient(supabaseUrl, supabaseKey); + +// Fonction utilitaire pour nettoyer et encoder le nom de fichier +const sanitizeFilename = (filename) => { + return filename.replace(/[^a-z0-9_.-]/gi, '_').toLowerCase(); +}; + +export default async function handler(req, res) { + const uploadDir = path.resolve('/tmp/uploads'); + if (!fs.existsSync(uploadDir)) { + fs.mkdirSync(uploadDir, { recursive: true }); + } + + const data = await new Promise((resolve, reject) => { + const form = new IncomingForm({ + uploadDir: uploadDir, + keepExtensions: true, + multiples: true, + }); + + form.parse(req, (err, fields, files) => { + if (err) return reject(err); + resolve({ files }); + }); + }).catch(err => { + console.error(err); + res.status(500).json({ error: `Erreur lors de l'analyse du formulaire: ${err.message}` }); + return; + }); + + if (!data) return; + + const urlsPDF = []; + + for (const fileArray of Object.values(data.files)) { + const files = Array.isArray(fileArray) ? fileArray : [fileArray]; + for (const file of files) { + const filePath = path.relative('.', file.filepath); + const fileBuffer = fs.readFileSync(file.filepath); + const sanitizedFilename = sanitizeFilename(file.originalFilename); + const filename = `uploads/${sanitizedFilename}`; + + const { data: existingFiles, error: listError } = await supabase + .storage + .from('ademe') + .list('uploads', { + search: sanitizedFilename + }); + + if (listError) { + console.error('Erreur lors de la vérification de l\'existence du fichier sur Supabase:', listError); + continue; + } + + let uploadFilename = filename; + if (existingFiles && existingFiles.length > 0) { + const timestamp = Date.now(); + uploadFilename = `uploads/${timestamp}_${sanitizedFilename}`; + } + + const { data: uploadData, error: uploadError } = await supabase.storage + .from('ademe') + .upload(uploadFilename, fileBuffer, { + contentType: file.mimetype, + }); + + if (uploadError) { + console.error('Erreur lors de l\'upload sur Supabase:', uploadError); + continue; + } + + const { data: publicURL, error: urlError } = await supabase.storage + .from('ademe') + .getPublicUrl(uploadFilename); + + if (urlError) { + console.error('Erreur lors de la récupération de l\'URL publique sur Supabase:', urlError); + continue; + } + + urlsPDF.push({ + nom: file.originalFilename, + url: publicURL.publicUrl + }); + } + } + + res.status(200).json({ urlsPDF }); +} diff --git a/pages/rencontres/[category]/[session].js b/pages/rencontres/[category]/[session].js index 5393bec..e4eb9e2 100644 --- a/pages/rencontres/[category]/[session].js +++ b/pages/rencontres/[category]/[session].js @@ -169,7 +169,7 @@ export default function Session({ data, user }){ const register = async () => { const { civilite, nom, prenom, mail, structure, fonction, type_fonction, ville, region, telephone, transport, besoins, hebergement, repas, rgpd, rgpd2 } = inscription - if(civilite && nom && prenom && mail && structure && fonction && type_fonction && region && transport && hebergement){ + if(civilite && nom && prenom && mail && structure && fonction && type_fonction && region && transport){ if(rgpd && rgpd2){ if(mail.includes('@') && mail.includes('.')){ setAlert({ @@ -255,7 +255,7 @@ export default function Session({ data, user }){ const checker = async () => { const fetcher = await fetch(`/api/registrations/byUserSession?userId=${user.id}&sessionId=${data.id}`) const json = await fetcher.json() - if(json.length > 0){ + if(json.length > 0 && json[0].deleted == false){ setCheck(true) } } @@ -650,7 +650,7 @@ export default function Session({ data, user }){ expand_more
    -
    +
    expand_more
    -
    +
    +
    Participerez vous les deux jours ? diff --git a/styles/Session.module.css b/styles/Session.module.css index 08ae997..63e5384 100644 --- a/styles/Session.module.css +++ b/styles/Session.module.css @@ -18,6 +18,18 @@ color:var(--secondary) } +.dayTitle{ + text-transform: uppercase; + font-weight: 700; + display: inline-block; + margin-bottom: 20px; + font-size: 1.25rem; + color:var(--primary); + background:#FFF; + padding: 10px 15px; + border-radius: 5px; +} + .Loading{ position: fixed; top:0; From c34a10ca9d45b988ccc22439d71a9ab1d6a7ecce Mon Sep 17 00:00:00 2001 From: AntonyKLINGER Date: Mon, 3 Jun 2024 10:21:51 +0200 Subject: [PATCH 009/100] maj visuel session --- pages/rencontres/[category]/[session].js | 3 +++ styles/Session.module.css | 9 ++++++++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/pages/rencontres/[category]/[session].js b/pages/rencontres/[category]/[session].js index 11d6ef8..f5bc93c 100644 --- a/pages/rencontres/[category]/[session].js +++ b/pages/rencontres/[category]/[session].js @@ -382,6 +382,9 @@ export default function Session({ data, user }){
    )}
    + {data.module.visuel != null && ( + visuel + )}
    diff --git a/styles/Session.module.css b/styles/Session.module.css index 63e5384..e6b522e 100644 --- a/styles/Session.module.css +++ b/styles/Session.module.css @@ -156,4 +156,11 @@ .Act{ display: block; -} \ No newline at end of file +} + +.visu{ + width: 100%; + aspect-ratio: 16/8; + object-fit: cover; + border-radius: 18px; +} From 3cfe8a8b0e1844d263ef7fb32be921e6332ac6be Mon Sep 17 00:00:00 2001 From: AntonyKLINGER Date: Mon, 3 Jun 2024 14:06:44 +0200 Subject: [PATCH 010/100] maj comptes DR --- components/AllSessions.jsx | 95 +++++--- components/Comptes.jsx | 423 ++++++++++++++++++++++++++++++---- components/Modules.jsx | 75 ++++-- components/SessionsModule.jsx | 89 ++++--- pages/admin.js | 2 +- pages/api/accounts/create.js | 6 +- pages/api/accounts/lib/jwt.js | 4 +- pages/api/accounts/update.js | 40 ++++ pages/connexion.js | 2 +- prisma/schema.prisma | 2 + styles/Admin.module.css | 16 +- 11 files changed, 632 insertions(+), 122 deletions(-) create mode 100644 pages/api/accounts/update.js diff --git a/components/AllSessions.jsx b/components/AllSessions.jsx index 912fb5a..eb1120b 100644 --- a/components/AllSessions.jsx +++ b/components/AllSessions.jsx @@ -166,34 +166,77 @@ export default function Modules({setPage, page, user}){
    - {sessions.length > 0 ? ( - sessions.map((session, index) => { - if(session.status == 'publish' || user.type == 'Administrateur' || user.id == 10){ - return ( -
    - deleteSession(session.id)} - status={session.status} - setActions={setActions} - session={session} - user={user} - /> -
    - ) - } - }) + {user.type == "Administrateur" ? ( + <> + {sessions.length > 0 ? ( + sessions.map((session, index) => { + if(session.status == 'publish' || user.type == 'Administrateur' || user.id == 10){ + return ( +
    + deleteSession(session.id)} + status={session.status} + setActions={setActions} + session={session} + user={user} + /> +
    + ) + } + }) + ) : ( + <> + Il n'y a aucun module pour le moment. + + )} + ) : ( <> - Il n'y a aucun module pour le moment. + {sessions.filter(session => + user.modules.includes(session.module.code) && + user.regions.includes(session.region) + ).length > 0 ? ( + sessions.filter(session => + user.modules.includes(session.module.code) && + user.regions.includes(session.region) + ).map((session, index) => { + if(session.status == 'publish' || user.type == 'Administrateur' || user.id == 10){ + return ( +
    + deleteSession(session.id)} + status={session.status} + setActions={setActions} + session={session} + user={user} + /> +
    + ) + } + }) + ) : ( + <> + Il n'y a aucun module pour le moment. + + )} )}
    diff --git a/components/Comptes.jsx b/components/Comptes.jsx index a721771..0dae467 100644 --- a/components/Comptes.jsx +++ b/components/Comptes.jsx @@ -3,14 +3,17 @@ import Alert from '@/components/Alert' import { Notif } from '@/components/Notif' import styles from '@/styles/Admin.module.css' -export default function Comptes(){ +export default function Comptes() { const [alert, setAlert] = useState(null) const [notif, setNotif] = useState(null) const [create, setCreate] = useState(false) const [actions, setActions] = useState(1) - const [account, setAccount] = useState({}) + const [account, setAccount] = useState({ regions: [], modules: [] }) + const [modules, setModules] = useState([]) const [listAccount, setListAccount] = useState([]) + const [openSettings, setOpenSettings] = useState(false) + const [selectedAccount, setSelectedAccount] = useState(null) useEffect(() => { const getAccounts = async () => { @@ -21,19 +24,40 @@ export default function Comptes(){ getAccounts() }, [alert, actions]) + useEffect(() => { + const getModules = async () => { + const geter = await fetch(`/api/modules`) + const json = await geter.json() + setModules(json) + } + getModules() + }, []) + const handleChange = (e) => { - const { name, type, value } = e.target - setAccount(prev => { - return { + const { name, type, value, checked } = e.target; + + if (type === 'checkbox') { + setAccount(prev => { + const group = name; // use the name as the group identifier (regions or modules) + const updatedGroup = checked + ? [...(prev[group] || []), value] + : (prev[group] || []).filter(item => item !== value); + return { + ...prev, + [group]: updatedGroup + }; + }); + } else { + setAccount(prev => ({ ...prev, [name]: value - } - }) - } + })); + } + }; const createAccount = async () => { - const { email, type } = account - if(email && type){ + const { email, type, modules, regions } = account + if (email && type) { const add = await fetch(`/api/accounts/create`, { method: 'POST', headers: { @@ -41,30 +65,32 @@ export default function Comptes(){ }, body: JSON.stringify({ email: email, - type: type + type: type, + modules: modules || [], + regions: regions || [] }) }) const json = await add.json() - if(json.status == "success"){ + if (json.status == "success") { //reset setCreate(false) - setAccount({}) - setActions(prev => prev+1) + setAccount({ regions: [], modules: [] }) + setActions(prev => prev + 1) setNotif({ text: 'Le compte a bien été créé !', icon: 'done' }); } - else{ + else { setNotif({ text: 'Cette adresse e-mail admin ou DR existe déjà !', icon: 'close' }); } } - else{ + else { setNotif({ text: 'Une information est manquante.', icon: 'close' @@ -87,15 +113,78 @@ export default function Comptes(){ 'Content-Type': 'application/json', }, }); - if(response.ok){ + if (response.ok) { setNotif({ text: 'Le compte a bien été supprimé.', icon: 'done' - }); + }); + setActions(prev => prev + 1); // Refresh the list of accounts } setAlert(null) } + const openAllSettings = (account) => { + setSelectedAccount(account); + setAccount({ + ...account, + regions: account.regions || [], + modules: account.modules || [] + }); // Pré-remplir le formulaire avec les valeurs du compte sélectionné + setOpenSettings(true); + } + + const updateAccount = async () => { + const { email, type, modules, regions, id } = account; + if (email && type) { + const update = await fetch(`/api/accounts/update`, { + method: 'PUT', + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + id: id, + email: email, + type: type, + modules: modules || [], + regions: regions || [] + }) + }) + const json = await update.json() + if (json.status == "success") { + + //reset + setOpenSettings(false) + setSelectedAccount(null) + setAccount({ regions: [], modules: [] }) + setActions(prev => prev + 1) + + setNotif({ + text: 'Le compte a bien été mis à jour !', + icon: 'done' + }); + } + else { + setNotif({ + text: 'Erreur lors de la mise à jour du compte !', + icon: 'close' + }); + } + } + else { + setNotif({ + text: 'Une information est manquante.', + icon: 'close' + }); + } + + } + + const closeSettings = () => { + setOpenSettings(false); + setSelectedAccount(null); + setAccount({ regions: [], modules: [] }); + } + return ( <>
    @@ -103,37 +192,285 @@ export default function Comptes(){
    {create && ( -
    -
    -
    - Adresse e-mail du compte - -
    -
    - Type de compte -
    - - expand_more -
    +
    +
    +
    + Adresse e-mail du compte + +
    +
    + Type de compte +
    + + expand_more +
    +
    + {account.type == "DR" && ( +
    +
    + Région +
    +
    + + +
    + +
    + + +
    + +
    + + +
    + +
    + + +
    + +
    + + +
    + +
    + + +
    + +
    + + +
    + +
    + + +
    + +
    + + +
    + +
    + + +
    + +
    + + +
    + +
    + + +
    + +
    + + +
    + +
    + + +
    + +
    + + +
    + +
    + + +
    + +
    + + +
    + +
    + + +
    +
    +
    +
    + Module(s) affecté(s) +
    + {modules.map((module, i) => { + return ( +
    + + +
    + ) + })} +
    +
    +
    + )} +
    - -
    )} {listAccount.length > 0 ? ( <> {listAccount.map((acc, i) => { return ( -
    -

    {acc.email}

    -
    - {acc.type} - +
    +
    +

    {acc.email}

    +
    + {acc.type} + + +
    + {openSettings && selectedAccount && selectedAccount.id === acc.id && ( +
    +
    +
    + Adresse e-mail du compte + +
    +
    + Type de compte +
    + + expand_more +
    +
    +
    + {account.type == "DR" && ( +
    +
    + Région +
    +
    + + +
    + +
    + + +
    + +
    + + +
    + +
    + + +
    + +
    + + +
    + +
    + + +
    + +
    + + +
    + +
    + + +
    + +
    + + +
    + +
    + + +
    + +
    + + +
    + +
    + + +
    + +
    + + +
    + +
    + + +
    + +
    + + +
    + +
    + + +
    + +
    + + +
    + +
    + + +
    +
    +
    +
    + Module(s) affecté(s) +
    + {modules.map((module, i) => { + return ( +
    + + +
    + ) + })} +
    +
    +
    + )} + + +
    + )}
    ) })} @@ -146,10 +483,10 @@ export default function Comptes(){ {alert != null && ( - )} + )} {notif != null && ( )} ) -} \ No newline at end of file +} diff --git a/components/Modules.jsx b/components/Modules.jsx index ff9aba9..c2d16af 100644 --- a/components/Modules.jsx +++ b/components/Modules.jsx @@ -146,29 +146,62 @@ export default function Modules({setPage, user}){
    - {modules.length > 0 ? ( - modules.map((module, index) => { - return ( -
    - deleteModule(module.id)} - user={user} - /> -
    - ) - }) + {user.type == "Administrateur" ? ( + <> + {modules.length > 0 ? ( + modules.map((module, index) => { + return ( +
    + deleteModule(module.id)} + user={user} + /> +
    + ) + }) + ) : ( + <> + Il n'y a aucun module pour le moment. + + )} + ) : ( <> - Il n'y a aucun module pour le moment. + {modules.filter(module => user.modules.includes(module.code)).length > 0 ? ( + modules.filter(module => user.modules.includes(module.code)).map((module, index) => { + const filteredSessions = module.sessions.filter(session => user.regions.includes(session.region)); + return ( +
    + deleteModule(module.id)} + user={user} + /> +
    + ) + }) + ) : ( + <> + Il n'y a aucun module pour le moment. + + )} )}
    diff --git a/components/SessionsModule.jsx b/components/SessionsModule.jsx index cdbd149..d2bd4f5 100644 --- a/components/SessionsModule.jsx +++ b/components/SessionsModule.jsx @@ -69,34 +69,71 @@ export default function SessionsModule({ id, setOpen, open, nom, user }){
    - {sessions.length > 0 ? ( - sessions.map((session, index) => { - if(session.status == "publish" || user.type == 'Administrateur' || user.id == 10){ - return ( -
    - deleteSession(session.id)} - status={session.status} - setActions={setActions} - session={session} - isModule="yes" - user={user} - /> -
    - ) - } - }) + {user.type == "Administrateur" ? ( + <> + {sessions.length > 0 ? ( + sessions.map((session, index) => { + if(session.status == "publish" || user.type == 'Administrateur' || user.id == 10){ + return ( +
    + deleteSession(session.id)} + status={session.status} + setActions={setActions} + session={session} + isModule="yes" + user={user} + /> +
    + ) + } + }) + ) : ( + <> + Il n'y a aucune session pour le moment. + + )} + ) : ( <> - Il n'y a aucune session pour le moment. + {sessions.filter(session => user.regions.includes(session.region)).length > 0 ? ( + sessions.filter(session => user.regions.includes(session.region)).map((session, index) => { + if(session.status == "publish" || user.type == 'Administrateur' || user.id == 10){ + return ( +
    + deleteSession(session.id)} + status={session.status} + setActions={setActions} + session={session} + isModule="yes" + user={user} + /> +
    + ) + } + }) + ) : ( + <> + Il n'y a aucune session pour le moment. + + )} )}
    diff --git a/pages/admin.js b/pages/admin.js index c5f5494..6b3d53a 100644 --- a/pages/admin.js +++ b/pages/admin.js @@ -13,7 +13,7 @@ export async function getServerSideProps(context) { const user = verifyToken(token); - if (!user || (user.id != 10 && user.type != 'Administrateur' && user.type != 'Moderateur')) { + if (!user || (user.id != 10 && user.type != 'Administrateur' && user.type != 'DR')) { return { redirect: { destination: '/connexion', diff --git a/pages/api/accounts/create.js b/pages/api/accounts/create.js index fbb69fe..85d02eb 100644 --- a/pages/api/accounts/create.js +++ b/pages/api/accounts/create.js @@ -15,7 +15,7 @@ function generatePassword(length) { export default async function handle(req, res) { if (req.method === 'POST') { - const { email, type } = req.body; + const { email, type, modules, regions } = req.body; try { // Vérifier si un compte avec cet email existe déjà @@ -37,6 +37,8 @@ export default async function handle(req, res) { email, type, password: hashedPassword, + modules, + regions }, }); @@ -49,6 +51,8 @@ export default async function handle(req, res) { email, type, password, + modules, + regions }), }); diff --git a/pages/api/accounts/lib/jwt.js b/pages/api/accounts/lib/jwt.js index 39b6520..a3f5e05 100644 --- a/pages/api/accounts/lib/jwt.js +++ b/pages/api/accounts/lib/jwt.js @@ -3,10 +3,10 @@ import jwt from 'jsonwebtoken'; export default async function handle(req, res) { if(req.method === 'POST') { - const { mail, id, type } = req.body + const { mail, id, type, regions, modules } = req.body const token = jwt.sign( - { mail: mail, id: id, type: type }, + { mail: mail, id: id, type: type, regions: regions, modules: modules }, process.env.JWT_SECRET, { expiresIn: '5h' } ); diff --git a/pages/api/accounts/update.js b/pages/api/accounts/update.js new file mode 100644 index 0000000..7fd7704 --- /dev/null +++ b/pages/api/accounts/update.js @@ -0,0 +1,40 @@ +import bcrypt from 'bcrypt'; +import prisma from '@/prisma'; +import fetch from 'node-fetch'; + +const SALT_ROUNDS = 10; + +export default async function handle(req, res) { + if (req.method === 'PUT') { + const { id, email, type, modules, regions } = req.body; + + try { + // Vérifier si un compte avec cet email existe déjà et ne pas autoriser la mise à jour si l'email appartient à un autre compte + const existingAccount = await prisma.account.findUnique({ + where: { email }, + }); + + if (existingAccount && existingAccount.id !== id) { + res.status(200).json({ status: 'already exist' }); + return; + } + + const updatedAccount = await prisma.account.update({ + where: { id }, + data: { + email, + type, + modules, + regions + }, + }); + + res.status(200).json({ status: 'success' }); + } catch (error) { + res.status(500).json({ error: `Impossible de mettre à jour le compte: ${error.message}` }); + } + } else { + res.setHeader('Allow', ['PUT']); + res.status(405).end(`Method ${req.method} Not Allowed`); + } +} diff --git a/pages/connexion.js b/pages/connexion.js index 7908d29..c4b4cc5 100644 --- a/pages/connexion.js +++ b/pages/connexion.js @@ -35,7 +35,7 @@ export default function Login(){ headers: { 'Content-Type': 'application/json', }, - body: JSON.stringify({ id: json.account.id, mail: json.account.mail, type: json.account.type }), + body: JSON.stringify({ id: json.account.id, mail: json.account.mail, type: json.account.type, modules: json.account.modules, regions: json.account.regions }), }); const jwtJson = await jwtResponse.json(); diff --git a/prisma/schema.prisma b/prisma/schema.prisma index edd9689..eed830b 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -126,4 +126,6 @@ model Account { email String @unique password String? type String? + regions Json? + modules Json? } diff --git a/styles/Admin.module.css b/styles/Admin.module.css index af363cf..3635657 100644 --- a/styles/Admin.module.css +++ b/styles/Admin.module.css @@ -313,4 +313,18 @@ border-radius: 8px; padding:10px 15px; cursor:pointer; -} \ No newline at end of file +} + +.accountSingle{ + position: relative; +} + +/* .accountSettings{ + position: absolute; + top:0; + left:0; + right: 0; + bottom:0; + background-color: #FFF; + z-index: 9; +} */ \ No newline at end of file From 97387e10c5039d6f814812241f39b45c98d689d1 Mon Sep 17 00:00:00 2001 From: AntonyKLINGER Date: Mon, 3 Jun 2024 14:12:18 +0200 Subject: [PATCH 011/100] maj session programme + dr --- pages/api/sessions/slug.js | 8 ++++++-- pages/rencontres/[category]/[session].js | 6 ++++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/pages/api/sessions/slug.js b/pages/api/sessions/slug.js index 9466521..46eb4fa 100644 --- a/pages/api/sessions/slug.js +++ b/pages/api/sessions/slug.js @@ -39,8 +39,12 @@ export default async function handle(req, res) { region: region, }, include: { - module: true, - metasSession: true, + module: { + include: { + metasModule: true, + }, + }, + metasSession: true }, }); diff --git a/pages/rencontres/[category]/[session].js b/pages/rencontres/[category]/[session].js index f5bc93c..81451f3 100644 --- a/pages/rencontres/[category]/[session].js +++ b/pages/rencontres/[category]/[session].js @@ -353,6 +353,8 @@ export default function Session({ data, user }){ const groupedData = groupByDay(data.metasSession.programmeSession); + console.log(data) + return ( <> @@ -468,7 +470,7 @@ export default function Session({ data, user }){
    {Object.keys(groupedData).map(day => (
    - {data.metasModule.duree == "2 jours" && ( + {data.module.metasModule.duree == "2 jours" && ( Jour {day} )}
    @@ -732,7 +734,7 @@ export default function Session({ data, user }){ )} {data.metasSession.mail_referent != undefined && data.metasSession.mail_referent != null && ( <> -

    Référent(e) DR Grand Est

    +

    Référent(e) DR {data.region}

    Une question concernant cette Rencontre ? Contactez le référent sur l’adresse mail suivante :
    {data.metasSession.mail_referent}

    )} From 33e022ede3634befb745ef03ce9841ddde6102fc Mon Sep 17 00:00:00 2001 From: AntonyKLINGER Date: Mon, 17 Jun 2024 10:26:03 +0200 Subject: [PATCH 012/100] maj emails --- pages/api/emails/newAccount.js | 9 ++- pages/api/emails/sessionAfterDays.js | 48 ++++++++++++++++ pages/api/workflow/workflowAfter.js | 75 +++++++++++++++++++++++++ views/emails/newaccount.hbs | 6 +- views/emails/newaccountdr.hbs | 78 ++++++++++++++++++++++++++ views/emails/session_after_day.hbs | 67 ++++++++++++++++++++++ views/emails/session_relance_weeks.hbs | 6 +- views/emails/welcome.hbs | 12 ++-- 8 files changed, 285 insertions(+), 16 deletions(-) create mode 100644 pages/api/emails/sessionAfterDays.js create mode 100644 pages/api/workflow/workflowAfter.js create mode 100644 views/emails/newaccountdr.hbs create mode 100644 views/emails/session_after_day.hbs diff --git a/pages/api/emails/newAccount.js b/pages/api/emails/newAccount.js index a6953ea..120a0ae 100644 --- a/pages/api/emails/newAccount.js +++ b/pages/api/emails/newAccount.js @@ -5,7 +5,10 @@ const path = require('path'); export default async function handler(req, res) { - const { email, password, type } = req.body + const { email, password, type, regions, modules } = req.body + + const formattedRegions = regions.join(', '); + const formattedModules = modules.join(', '); const transporter = nodemailer.createTransport({ host: 'smtp-relay.brevo.com', @@ -32,11 +35,13 @@ export default async function handler(req, res) { from: '"ADEME" ', to: email, subject: "Votre nouveau compte sur les Rencontres Territoire Engagé Transition écologique !", - template: 'newaccount', + template: type == 'DR' ? 'newaccountdr' : 'newaccount', context: { password: password, type: type, email: email, + regions: formattedRegions, + modules: formattedModules, siteUrl: process.env.WEBSITE_URL, } }; diff --git a/pages/api/emails/sessionAfterDays.js b/pages/api/emails/sessionAfterDays.js new file mode 100644 index 0000000..1d8e249 --- /dev/null +++ b/pages/api/emails/sessionAfterDays.js @@ -0,0 +1,48 @@ +import nodemailer from 'nodemailer'; +import hbs from 'nodemailer-express-handlebars'; +import path from 'path'; + +export default async function handler(req, res) { + const { prenom, email } = req.body; + + const transporter = nodemailer.createTransport({ + host: 'smtp-relay.brevo.com', + port: 587, + secure: false, + auth: { + user: 'contact@territoiresentransitions.fr', + pass: process.env.BREVO_KEY + }, + tls: { rejectUnauthorized: false } + }); + + transporter.use('compile', hbs({ + viewEngine: { + extName: '.hbs', + partialsDir: path.resolve('./views/emails'), + defaultLayout: false, + }, + viewPath: path.resolve('./views/emails'), + extName: '.hbs', + })); + + const mailOptions = { + from: '"ADEME" ', + to: email, + subject: "Merci pour votre présence à la Rencontre Territoire Engagé Transition Ecologique", + template: 'session_after_day', + context: { + prenom: prenom, + siteUrl: process.env.WEBSITE_URL, + } + }; + + transporter.sendMail(mailOptions, (error, info) => { + if (error) { + res.json(error); + return console.log(error); + } + console.log('Message sent: %s', info.messageId); + res.status(200).json({ status: 'sended' }); + }); +} diff --git a/pages/api/workflow/workflowAfter.js b/pages/api/workflow/workflowAfter.js new file mode 100644 index 0000000..8e9b68e --- /dev/null +++ b/pages/api/workflow/workflowAfter.js @@ -0,0 +1,75 @@ +import prisma from '@/prisma' +import fetch from 'node-fetch' + +export default async function handle(req, res) { + if (req.method !== 'GET') { + res.setHeader('Allow', ['GET']); + res.status(405).end(`Method ${req.method} Not Allowed`); + return; + } + + try { + const today = new Date(); + const oneDayBefore = new Date(today); + oneDayBefore.setDate(today.getDate() - 1); + + const pastSessions = await prisma.session.findMany({ + where: { + dateFin: { + equals: oneDayBefore, + }, + }, + include: { + registrations: { + include: { + user: true, + }, + }, + metasSession: true, + module: true, + }, + }); + + for (const session of pastSessions) { + const firstProgramme = session.metasSession.programmeSession[0]; + let firstDayStartTime; + + if (firstProgramme.horaires.includes('Jour')) { + firstDayStartTime = firstProgramme.horaires.split(' : ')[1].split(' - ')[0]; + } else { + firstDayStartTime = firstProgramme.horaires.split(' - ')[0].trim(); + } + + const dateDebut = new Date(session.dateDebut); + const formattedDateDebut = dateDebut.toLocaleDateString('fr-FR', { + day: '2-digit', + month: '2-digit', + year: 'numeric', + }); + + for (const registration of session.registrations) { + const userData = registration.user; + + const emailResponse = await fetch(`${process.env.WEBSITE_URL}/api/emails/sessionAfterDays`, { + method: 'POST', + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + prenom: userData.prenom, + email: userData.mail, + }) + }); + + if (!emailResponse.ok) { + throw new Error(`Email request failed with status ${emailResponse.status}`); + } + } + } + + res.status(200).json({ message: "Emails sent successfully" }); + } catch (error) { + console.error("Error fetching past sessions or sending emails: ", error); + res.status(500).json({ error: `Impossible de récupérer les enregistrements ou d'envoyer les emails : ${error.message}` }); + } +} diff --git a/views/emails/newaccount.hbs b/views/emails/newaccount.hbs index 995b60a..7ea0ec1 100644 --- a/views/emails/newaccount.hbs +++ b/views/emails/newaccount.hbs @@ -55,11 +55,11 @@ top email

    Votre compte {{type}} vient d'être créé !

    -

    Pour vous connecter, utilisez vos accès : votre adresse e-mail : {{email}} et votre nouveau mot de passe.

    +

    Vous pouvez dorénavant vous connecter à la plateforme Les Rencontres des Territoires Engagés avec les identifiants suivants :

    +

    Votre adresse e-mail : {{email}}

    Voici votre nouveau mot de passe :

    {{password}} -

    Attention à le garder secrètement de votre côté.

    -

    Vous pouvez vous connecter à partir de ce lien : Connexion.

    +

    Vous pourrez changer ce mot de passe dans votre espace personnel dès votre première connexion

    - Ressources :
    - {data?.metasSession?.explications && ( -
    - )} + {data?.metasSession?.explications && ( +
    + )}
      - {data?.metasSession?.urlsPDF.map((item, index) => { - return
    • {item.nom}
    • - })} + {data?.metasSession?.urlsPDF.map((item, index) => ( +
    • {item.nom}
    • + ))}
    ) : (
    Ressources : Pas de ressources disponibles. - {data?.metasSession?.mail_referent != null && data.metasSession.mail_referent != undefined && ( + {data?.metasSession?.mail_referent != null && data.metasSession.mail_referent !== undefined && ( <> Contact du référent : - {data.metasSession.mail_referent} + {data.metasSession.mail_referent} )}
    - )} - {passed && ( + )} + {passed && !hasResponded && ( <> Donnez votre avis sur la rencontre :
    @@ -261,7 +440,7 @@ export default function RencontreDetail({id, setOpen, userId, user}){ value={rating} size="small" onChange={(event, newValue) => { - setRating(newValue); + setRating(newValue); }} />
    @@ -271,19 +450,75 @@ export default function RencontreDetail({id, setOpen, userId, user}){
    )} + + Nous vous remercions de prendre 5 minutes pour répondre à ce questionnaire de satisfaction. Vos réponses permettront d’améliorer l’offre des Rencontres Territoire Engagé Transition Ecologique de l’ADEME. +
    + {questions.map((question) => ( +
    + {question.id}) {question.text} + {question.type === "textarea" ? ( +

    + +

    + ) : ( + question.options.map((option, index) => ( +
    +

    + handleOptionChange(question.id, option.value)} + /> + +

    + {option.value === 'autre' && otherInputs[question.id] && ( +

    + handleOtherInputChange(question.id, e.target.value)} + /> +

    + )} +
    + )) + )} +
    + ))} + +
    - )} + )} + {hasResponded && ( +
    + Vous avez déjà répondu à ce questionnaire. Merci pour votre participation. +
    + )} {alert != null && ( - )} + )} {notif != null && ( - )} + )} {loading && (
    loading
    )} - ) -} \ No newline at end of file + ); +} diff --git a/components/Reviews.jsx b/components/Reviews.jsx index 3434a60..854f0b0 100644 --- a/components/Reviews.jsx +++ b/components/Reviews.jsx @@ -7,6 +7,9 @@ export default function Reviews({ session, setOpen }){ const [number, setNumber] = useState(0) const [reviews, setReviews] = useState([]) const [moyenne, setMoyenne] = useState(0) + const [quizz, setQuizz] = useState([]) + + console.log(session) function formatDate(dateString) { const date = new Date(dateString); @@ -28,11 +31,33 @@ export default function Reviews({ session, setOpen }){ } } + const getQuizz = async () => { + const fetcher = await fetch(`/api/satisfaction/fromSession?sessionId=${session.id}`) + const json = await fetcher.json() + if(json.length > 0){ + setQuizz(json) + } + } + + const questionLabels = { + "1": "Qualité générale", + "2": "Qualité du contenu technique", + "3": "Pertinence des intervenant.e.s", + "4": "Qualité des formats participatifs", + "5": "Richesse des échanges", + "6": "Qualité de l'organisation", + "7": "Commentaires", + "8": "Comment avez-vous connu", + "9": "Nombre de participations", + "10": "Thématiques intéressantes" + }; + useEffect(() => { getParticipants() + getQuizz() }, []) - console.log(reviews) + console.log(quizz) return ( <> @@ -56,6 +81,34 @@ export default function Reviews({ session, setOpen }){ ) : ( Aucun avis pour cette session. )} + +

    Questionnaires de satisfaction :

    + + {quizz.length > 0 ? ( + <> + {quizz.map((question, index) => { + const responses = question.responses; + return ( + + + + + + + {Object.entries(responses).map(([questionId, response], idx) => ( + + + + + ))} + +
    Participant{question.User.nom} {question.User.prenom}
    {questionLabels[questionId] || `Question ${questionId}`}{response}
    + ); + })} + + ) : ( + Aucun questionnaire de satisfaction. + )}
    diff --git a/pages/api/satisfaction/add.js b/pages/api/satisfaction/add.js new file mode 100644 index 0000000..878a544 --- /dev/null +++ b/pages/api/satisfaction/add.js @@ -0,0 +1,38 @@ +import { PrismaClient } from '@prisma/client'; + +const prisma = new PrismaClient(); + +// Fonction pour sérialiser correctement les BigInt +function serializeBigIntFields(data) { + return JSON.parse( + JSON.stringify(data, (key, value) => + typeof value === 'bigint' ? value.toString() : value + ) + ); +} + +export default async function handler(req, res) { + if (req.method === 'POST') { + const { userId, sessionId, responses } = req.body; + + try { + console.log('Creating new satisfaction with data:', { userId, sessionId, responses }); + const newSatisfaction = await prisma.satisfaction.create({ + data: { + userId: userId ? parseInt(userId) : null, + sessionId: sessionId ? parseInt(sessionId) : null, + responses: responses ? responses : null, + }, + }); + + // Utilisez la fonction serializeBigIntFields pour convertir correctement les BigInt + res.status(201).json(serializeBigIntFields(newSatisfaction)); + } catch (error) { + console.error('Error creating satisfaction:', error); + res.status(500).json({ error: 'Erreur lors de la création de la satisfaction.' }); + } + } else { + res.setHeader('Allow', ['POST']); + res.status(405).end(`Method ${req.method} Not Allowed`); + } +} diff --git a/pages/api/satisfaction/checkSatisfaction.js b/pages/api/satisfaction/checkSatisfaction.js new file mode 100644 index 0000000..e921b13 --- /dev/null +++ b/pages/api/satisfaction/checkSatisfaction.js @@ -0,0 +1,29 @@ +import { PrismaClient } from '@prisma/client'; + +const prisma = new PrismaClient(); + +export default async function handler(req, res) { + if (req.method === 'GET') { + const { userId, sessionId } = req.query; + + try { + const satisfaction = await prisma.satisfaction.findFirst({ + where: { + userId: parseInt(userId), + sessionId: parseInt(sessionId), + }, + }); + if (satisfaction) { + res.status(200).json({ hasResponded: true }); + } else { + res.status(200).json({ hasResponded: false }); + } + } catch (error) { + console.error('Error checking satisfaction:', error); + res.status(500).json({ error: 'Erreur lors de la vérification de la satisfaction.' }); + } + } else { + res.setHeader('Allow', ['GET']); + res.status(405).end(`Method ${req.method} Not Allowed`); + } +} diff --git a/pages/api/satisfaction/fromSession.js b/pages/api/satisfaction/fromSession.js new file mode 100644 index 0000000..76cf9fc --- /dev/null +++ b/pages/api/satisfaction/fromSession.js @@ -0,0 +1,46 @@ +import { PrismaClient } from '@prisma/client'; + +const prisma = new PrismaClient(); + +// Fonction pour sérialiser correctement les BigInt +function serializeBigIntFields(data) { + return JSON.parse( + JSON.stringify(data, (key, value) => + typeof value === 'bigint' ? value.toString() : value + ) + ); +} + +export default async function handler(req, res) { + if (req.method === 'GET') { + const { sessionId } = req.query; + + try { + const satisfaction = await prisma.satisfaction.findMany({ + where: { + sessionId: sessionId ? parseInt(sessionId) : undefined, + }, + include: { + User: { + select: { + nom: true, + prenom: true, + }, + }, + }, + }); + if (satisfaction) { + // Utilisez la fonction serializeBigIntFields pour convertir correctement les BigInt + res.status(200).json(serializeBigIntFields(satisfaction)); + } else { + res.status(404).json({ error: 'Satisfaction non trouvée.' }); + } + } catch (error) { + console.error('Error fetching satisfaction:', error); + res.status(500).json({ error: 'Erreur lors de la récupération de la satisfaction.' }); + } + } else { + res.setHeader('Allow', ['GET']); + res.status(405).end(`Method ${req.method} Not Allowed`); + } +} diff --git a/pages/api/satisfaction/getSatisfaction.js b/pages/api/satisfaction/getSatisfaction.js new file mode 100644 index 0000000..f53e52e --- /dev/null +++ b/pages/api/satisfaction/getSatisfaction.js @@ -0,0 +1,39 @@ +import { PrismaClient } from '@prisma/client'; + +const prisma = new PrismaClient(); + +// Fonction pour sérialiser correctement les BigInt +function serializeBigIntFields(data) { + return JSON.parse( + JSON.stringify(data, (key, value) => + typeof value === 'bigint' ? value.toString() : value + ) + ); +} + +export default async function handler(req, res) { + if (req.method === 'GET') { + const { userId, sessionId } = req.query; + + try { + const satisfaction = await prisma.satisfaction.findFirst({ + where: { + userId: userId ? parseInt(userId) : undefined, + sessionId: sessionId ? parseInt(sessionId) : undefined, + }, + }); + if (satisfaction) { + // Utilisez la fonction serializeBigIntFields pour convertir correctement les BigInt + res.status(200).json(serializeBigIntFields(satisfaction)); + } else { + res.status(404).json({ error: 'Satisfaction non trouvée.' }); + } + } catch (error) { + console.error('Error fetching satisfaction:', error); + res.status(500).json({ error: 'Erreur lors de la récupération de la satisfaction.' }); + } + } else { + res.setHeader('Allow', ['GET']); + res.status(405).end(`Method ${req.method} Not Allowed`); + } +} diff --git a/pages/rencontres/index.js b/pages/rencontres/index.js index 37556ef..a577321 100644 --- a/pages/rencontres/index.js +++ b/pages/rencontres/index.js @@ -358,24 +358,24 @@ export default function Rencontres({ base, region, pilier, thematique }){
    Rechercher par région
      -
    • setFiltres(prev => { return { ...prev, nom: '', departement: '', region: 'Auvergne-Rhône-Alpes' } })}>roomAuvergne-Rhône-Alpes
    • -
    • setFiltres(prev => { return { ...prev, nom: '', departement: '', region: 'Bourgogne-Franche-Comté' } })}>roomBourgogne-Franche-Comté
    • -
    • setFiltres(prev => { return { ...prev, nom: '', departement: '', region: 'Bretagne' } })}>roomBretagne
    • -
    • setFiltres(prev => { return { ...prev, nom: '', departement: '', region: 'Centre-Val de Loire' } })}>roomCentre-Val de Loire
    • -
    • setFiltres(prev => { return { ...prev, nom: '', departement: '', region: 'Corse' } })}>roomCorse
    • -
    • setFiltres(prev => { return { ...prev, nom: '', departement: '', region: 'Normandie' } })}>roomNormandie
    • -
    • setFiltres(prev => { return { ...prev, nom: '', departement: '', region: 'Nouvelle-Aquitaine' } })}>roomNouvelle-Aquitaine
    • -
    • setFiltres(prev => { return { ...prev, nom: '', departement: '', region: 'Occitanie' } })}>roomOccitanie
    • -
    • setFiltres(prev => { return { ...prev, nom: '', departement: '', region: 'Grand-Est' } })}>roomGrand-Est
    • -
    • setFiltres(prev => { return { ...prev, nom: '', departement: '', region: 'Hauts-de-France' } })}>roomHauts-de-France
    • -
    • setFiltres(prev => { return { ...prev, nom: '', departement: '', region: 'Île-de-France' } })}>roomÎle-de-France
    • -
    • setFiltres(prev => { return { ...prev, nom: '', departement: '', region: 'Pays de la Loire' } })}>roomPays de la Loire
    • -
    • setFiltres(prev => { return { ...prev, nom: '', departement: '', region: "Provence-Alpes-Côte d'Azur" } })}>roomProvence-Alpes-Côte d'Azur
    • -
    • setFiltres(prev => { return { ...prev, nom: '', departement: '', region: "Guadeloupe" } })}>roomGuadeloupe
    • -
    • setFiltres(prev => { return { ...prev, nom: '', departement: '', region: "Martinique" } })}>roomMartinique
    • -
    • setFiltres(prev => { return { ...prev, nom: '', departement: '', region: "Guyane" } })}>roomGuyane
    • -
    • setFiltres(prev => { return { ...prev, nom: '', departement: '', region: "La Reunion" } })}>roomLa Reunion
    • -
    • setFiltres(prev => { return { ...prev, nom: '', departement: '', region: "Mayotte" } })}>roomMayotte
    • +
    • {setFiltres(prev => { return { ...prev, nom: '', departement: '', region: 'Auvergne-Rhône-Alpes' } });setSwitcher(true)}}>roomAuvergne-Rhône-Alpes
    • +
    • {setFiltres(prev => { return { ...prev, nom: '', departement: '', region: 'Bourgogne-Franche-Comté' } });setSwitcher(true)}}>roomBourgogne-Franche-Comté
    • +
    • {setFiltres(prev => { return { ...prev, nom: '', departement: '', region: 'Bretagne' } });setSwitcher(true)}}>roomBretagne
    • +
    • {setFiltres(prev => { return { ...prev, nom: '', departement: '', region: 'Centre-Val de Loire' } });setSwitcher(true)}}>roomCentre-Val de Loire
    • +
    • {setFiltres(prev => { return { ...prev, nom: '', departement: '', region: 'Corse' } });setSwitcher(true)}}>roomCorse
    • +
    • {setFiltres(prev => { return { ...prev, nom: '', departement: '', region: 'Normandie' } });setSwitcher(true)}}>roomNormandie
    • +
    • {setFiltres(prev => { return { ...prev, nom: '', departement: '', region: 'Nouvelle-Aquitaine' } });setSwitcher(true)}}>roomNouvelle-Aquitaine
    • +
    • {setFiltres(prev => { return { ...prev, nom: '', departement: '', region: 'Occitanie' } });setSwitcher(true)}}>roomOccitanie
    • +
    • {setFiltres(prev => { return { ...prev, nom: '', departement: '', region: 'Grand-Est' } });setSwitcher(true)}}>roomGrand-Est
    • +
    • {setFiltres(prev => { return { ...prev, nom: '', departement: '', region: 'Hauts-de-France' } });setSwitcher(true)}}>roomHauts-de-France
    • +
    • {setFiltres(prev => { return { ...prev, nom: '', departement: '', region: 'Île-de-France' } });setSwitcher(true)}}>roomÎle-de-France
    • +
    • {setFiltres(prev => { return { ...prev, nom: '', departement: '', region: 'Pays de la Loire' } });setSwitcher(true)}}>roomPays de la Loire
    • +
    • {setFiltres(prev => { return { ...prev, nom: '', departement: '', region: "Provence-Alpes-Côte d'Azur" } });setSwitcher(true)}}>roomProvence-Alpes-Côte d'Azur
    • +
    • {setFiltres(prev => { return { ...prev, nom: '', departement: '', region: "Guadeloupe" } });setSwitcher(true)}}>roomGuadeloupe
    • +
    • {setFiltres(prev => { return { ...prev, nom: '', departement: '', region: "Martinique" } });setSwitcher(true)}}>roomMartinique
    • +
    • {setFiltres(prev => { return { ...prev, nom: '', departement: '', region: "Guyane" } });setSwitcher(true)}}>roomGuyane
    • +
    • {setFiltres(prev => { return { ...prev, nom: '', departement: '', region: "La Reunion" } });setSwitcher(true)}}>roomLa Reunion
    • +
    • {setFiltres(prev => { return { ...prev, nom: '', departement: '', region: "Mayotte" } });setSwitcher(true)}}>roomMayotte
    diff --git a/prisma/schema.prisma b/prisma/schema.prisma index eed830b..e35ab3c 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -47,6 +47,7 @@ model User { organisation String? registrations Registration[] reviews Review[] + Satisfaction Satisfaction[] sessions Session[] @relation("UserSessions") } @@ -62,6 +63,7 @@ model Session { metasSession MetasSession? registrations Registration[] reviews Review[] + Satisfaction Satisfaction[] module Module @relation(fields: [moduleId], references: [id]) users User[] @relation("UserSessions") } @@ -129,3 +131,14 @@ model Account { regions Json? modules Json? } + +/// This model contains row level security and requires additional setup for migrations. Visit https://pris.ly/d/row-level-security for more info. +model Satisfaction { + id BigInt @id @default(autoincrement()) + userId Int? + sessionId Int? + created_at DateTime @default(now()) @db.Timestamptz(6) + responses Json? + Session Session? @relation(fields: [sessionId], references: [id], onDelete: NoAction, onUpdate: NoAction) + User User? @relation(fields: [userId], references: [id], onDelete: NoAction, onUpdate: NoAction) +} diff --git a/styles/Account.module.css b/styles/Account.module.css index d22c6a5..761fd4b 100644 --- a/styles/Account.module.css +++ b/styles/Account.module.css @@ -140,6 +140,39 @@ width: 50px; } +.askTitle{ + display: block; + margin:20px 0; + font-weight: 500; + font-size: 1.1rem; +} + +.asker{ + margin:10px 0; +} + +.asker label{ + margin-left: 5px; +} + +.textareaF{ + width: 100%; + height:100px; + border:2px solid rgba(0,0,0,.1); + padding:15px; + font-family: "Outfit", sans-serif; + font-size: 1rem; + font-weight: 300; +} + +.textF{ + width: 100%; + text-indent: 10px; + height: 40px; + border:2px solid rgba(0,0,0,.1); + font-weight: 300; +} + @media(max-width:810px){ .Box{ padding:30px; diff --git a/styles/Reviews.module.css b/styles/Reviews.module.css index 861f1bd..d6b4f9b 100644 --- a/styles/Reviews.module.css +++ b/styles/Reviews.module.css @@ -137,6 +137,21 @@ border-top:1px dotted var(--primary) } +.Quizzer{ + border-collapse: collapse; + width: 100%; + margin:20px 0; +} + +.Quizzer td{ + padding: 5px; + font-weight: 300; +} + +.Reviews h3{ + font-weight: 500; +} + @media(max-width:1280px){ .Number{ padding:10px 15px From f6c013ed748dd5f3a9eacd4ad382f7fee570375f Mon Sep 17 00:00:00 2001 From: lollybet_antony Date: Tue, 18 Jun 2024 10:01:55 +0200 Subject: [PATCH 015/100] maj questionnaire --- components/RencontreDetail.jsx | 18 +++++++++++++----- components/Rencontres.jsx | 2 +- pages/espace-personnel.js | 2 ++ pages/rencontres/index.js | 6 ++++++ 4 files changed, 22 insertions(+), 6 deletions(-) diff --git a/components/RencontreDetail.jsx b/components/RencontreDetail.jsx index b065bdb..c6b90f8 100644 --- a/components/RencontreDetail.jsx +++ b/components/RencontreDetail.jsx @@ -22,6 +22,18 @@ export default function RencontreDetail({ id, setOpen, userId, user }) { const [responses, setResponses] = useState({}); const [hasResponded, setHasResponded] = useState(false); + const [modules, setModules] = useState([]) + + const getModules = async () => { + const geter = await fetch(`/api/modules`) + const json = await geter.json() + setModules(json) + } + + useEffect(() => { + getModules() + }, []) + const questions = [ { id: 1, @@ -121,11 +133,7 @@ export default function RencontreDetail({ id, setOpen, userId, user }) { { id: 10, text: "Il existe d’autres Rencontres Territoire Engagé Transition Ecologique. Quelles sont les thématiques susceptibles de vous intéresser ?", - options: [ - { value: "Climat", label: "Climat" }, - { value: "Energie", label: "Energie" }, - { value: "Mobilité", label: "Mobilité" }, - ], + options: modules.map(module => ({ value: module.nom, label: module.nom })) } ]; diff --git a/components/Rencontres.jsx b/components/Rencontres.jsx index 2242e42..c4c374e 100644 --- a/components/Rencontres.jsx +++ b/components/Rencontres.jsx @@ -11,7 +11,7 @@ export default function Rencontres({ user }){ const [rencontres, setRencontres] = useState([]) const [status, setStatus] = useState('upcoming') const [load, setLoad] = useState(false) - + const getUserSessions = async () => { setLoad(true) diff --git a/pages/espace-personnel.js b/pages/espace-personnel.js index 74868ff..82373ed 100644 --- a/pages/espace-personnel.js +++ b/pages/espace-personnel.js @@ -6,6 +6,7 @@ import Alert from '@/components/Alert' import { verifyToken } from '@/utils/auth'; import { useState, useEffect } from 'react' import Rencontres from '/components/Rencontres' +import RencontreDetail from '@/components/RencontreDetail'; import Profil from '@/components/Profil' import styles from '@/styles/Account.module.css' @@ -61,6 +62,7 @@ export default function Account({ user }){
    +
    {page == 0 && ( diff --git a/pages/rencontres/index.js b/pages/rencontres/index.js index a577321..e7bfc26 100644 --- a/pages/rencontres/index.js +++ b/pages/rencontres/index.js @@ -92,6 +92,12 @@ export default function Rencontres({ base, region, pilier, thematique }){ return `${day}/${month}/${year}`; } + useEffect(() => { + if(region != ''){ + setSwitcher(true) + } + }, [region]) + const getModules = async () => { const { pilier, nom, region, departement, thematique, dateDebut } = filtres let url = '/api/modules/?' From 6fe8a654f78908fd85fcf3c0ead147b332636256 Mon Sep 17 00:00:00 2001 From: lollybet_antony Date: Tue, 18 Jun 2024 16:45:10 +0200 Subject: [PATCH 016/100] maj espace perso --- pages/espace-personnel.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/pages/espace-personnel.js b/pages/espace-personnel.js index 82373ed..74868ff 100644 --- a/pages/espace-personnel.js +++ b/pages/espace-personnel.js @@ -6,7 +6,6 @@ import Alert from '@/components/Alert' import { verifyToken } from '@/utils/auth'; import { useState, useEffect } from 'react' import Rencontres from '/components/Rencontres' -import RencontreDetail from '@/components/RencontreDetail'; import Profil from '@/components/Profil' import styles from '@/styles/Account.module.css' @@ -62,7 +61,6 @@ export default function Account({ user }){
    -
    {page == 0 && ( From 0c9a9a3a5ba7a3c99028fce280e02e552bc6c514 Mon Sep 17 00:00:00 2001 From: lollybet_antony Date: Tue, 18 Jun 2024 16:50:58 +0200 Subject: [PATCH 017/100] maj --- pages/espace-personnel.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pages/espace-personnel.js b/pages/espace-personnel.js index 74868ff..5784fd7 100644 --- a/pages/espace-personnel.js +++ b/pages/espace-personnel.js @@ -27,6 +27,8 @@ export async function getServerSideProps(context) { export default function Account({ user }){ + console.log("t") + const [page, setPage] = useState(0) const [alert, setAlert] = useState(null) From e6d7b9c42ed818d8221d32e3b42a435d0c4cd3c1 Mon Sep 17 00:00:00 2001 From: AntonyKLINGER Date: Tue, 18 Jun 2024 16:53:43 +0200 Subject: [PATCH 018/100] maj espace perso --- pages/espace-personnel.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/pages/espace-personnel.js b/pages/espace-personnel.js index 5784fd7..74868ff 100644 --- a/pages/espace-personnel.js +++ b/pages/espace-personnel.js @@ -27,8 +27,6 @@ export async function getServerSideProps(context) { export default function Account({ user }){ - console.log("t") - const [page, setPage] = useState(0) const [alert, setAlert] = useState(null) From 22a7367b0f554dc559ae2cf37b0272c2b3e57c47 Mon Sep 17 00:00:00 2001 From: lollybet_antony Date: Tue, 18 Jun 2024 17:04:22 +0200 Subject: [PATCH 019/100] maj espace perso --- pages/espace-personnel.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pages/espace-personnel.js b/pages/espace-personnel.js index 74868ff..5784fd7 100644 --- a/pages/espace-personnel.js +++ b/pages/espace-personnel.js @@ -27,6 +27,8 @@ export async function getServerSideProps(context) { export default function Account({ user }){ + console.log("t") + const [page, setPage] = useState(0) const [alert, setAlert] = useState(null) From a90d0c4c2c6f17f021c6fd73d81a5feb40d72696 Mon Sep 17 00:00:00 2001 From: Antony Klinger <40170587+AntonyKLINGER@users.noreply.github.com> Date: Tue, 18 Jun 2024 17:09:53 +0200 Subject: [PATCH 020/100] Espace perso (#17) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Maj questionnaire (#8) * maj comptes admin + dr * mise à jour 29/05 * maj * maj 29/05 * maj email style * mise à jour 29/05 * maj comptes admin + dr (#1) * maj 03/06 >> besoins + ajout titre par jour * maj visuel session * maj comptes DR * maj session programme + dr * maj emails * Update 3/06 - 14h14 (#4) (#5) * maj comptes admin + dr * mise à jour 29/05 * maj * maj 29/05 * maj email style * mise à jour 29/05 * maj comptes admin + dr (#1) * maj 03/06 >> besoins + ajout titre par jour * maj visuel session * maj comptes DR * maj session programme + dr --------- Co-authored-by: lollybet_antony * last maj 17/06 * maj questionnaire --------- Co-authored-by: lollybet_antony * Maj espace perso (#9) * maj comptes admin + dr * mise à jour 29/05 * maj * maj 29/05 * maj email style * mise à jour 29/05 * maj comptes admin + dr (#1) * maj 03/06 >> besoins + ajout titre par jour * maj visuel session * maj comptes DR * maj session programme + dr * maj emails * Update 3/06 - 14h14 (#4) (#5) * maj comptes admin + dr * mise à jour 29/05 * maj * maj 29/05 * maj email style * mise à jour 29/05 * maj comptes admin + dr (#1) * maj 03/06 >> besoins + ajout titre par jour * maj visuel session * maj comptes DR * maj session programme + dr --------- Co-authored-by: lollybet_antony * last maj 17/06 * maj questionnaire * maj espace perso --------- Co-authored-by: lollybet_antony * Maj espace perso (#10) * maj comptes admin + dr * mise à jour 29/05 * maj * maj 29/05 * maj email style * mise à jour 29/05 * maj comptes admin + dr (#1) * maj 03/06 >> besoins + ajout titre par jour * maj visuel session * maj comptes DR * maj session programme + dr * maj emails * Update 3/06 - 14h14 (#4) (#5) * maj comptes admin + dr * mise à jour 29/05 * maj * maj 29/05 * maj email style * mise à jour 29/05 * maj comptes admin + dr (#1) * maj 03/06 >> besoins + ajout titre par jour * maj visuel session * maj comptes DR * maj session programme + dr --------- Co-authored-by: lollybet_antony * last maj 17/06 * maj questionnaire * maj espace perso --------- Co-authored-by: lollybet_antony * Update espace perso (#12) * maj comptes admin + dr * mise à jour 29/05 * maj * maj 29/05 * maj email style * mise à jour 29/05 * maj comptes admin + dr (#1) * maj 03/06 >> besoins + ajout titre par jour * maj visuel session * maj comptes DR * maj session programme + dr * maj emails * Update 3/06 - 14h14 (#4) (#5) * maj comptes admin + dr * mise à jour 29/05 * maj * maj 29/05 * maj email style * mise à jour 29/05 * maj comptes admin + dr (#1) * maj 03/06 >> besoins + ajout titre par jour * maj visuel session * maj comptes DR * maj session programme + dr --------- Co-authored-by: lollybet_antony * last maj 17/06 * maj questionnaire * maj espace perso --------- Co-authored-by: lollybet_antony * Update from repo a (#13) * maj comptes admin + dr * mise à jour 29/05 * maj * maj 29/05 * maj email style * mise à jour 29/05 * maj comptes admin + dr (#1) * maj 03/06 >> besoins + ajout titre par jour * maj visuel session * maj comptes DR * maj session programme + dr * maj emails * Update 3/06 - 14h14 (#4) (#5) * maj comptes admin + dr * mise à jour 29/05 * maj * maj 29/05 * maj email style * mise à jour 29/05 * maj comptes admin + dr (#1) * maj 03/06 >> besoins + ajout titre par jour * maj visuel session * maj comptes DR * maj session programme + dr --------- Co-authored-by: lollybet_antony * last maj 17/06 * maj questionnaire * maj espace perso * maj --------- Co-authored-by: lollybet_antony * Maj test espace perso (#14) * maj comptes admin + dr * mise à jour 29/05 * maj * maj 29/05 * maj email style * mise à jour 29/05 * maj comptes admin + dr (#1) * maj 03/06 >> besoins + ajout titre par jour * maj visuel session * maj comptes DR * maj session programme + dr * maj emails * Update 3/06 - 14h14 (#4) (#5) * maj comptes admin + dr * mise à jour 29/05 * maj * maj 29/05 * maj email style * mise à jour 29/05 * maj comptes admin + dr (#1) * maj 03/06 >> besoins + ajout titre par jour * maj visuel session * maj comptes DR * maj session programme + dr --------- Co-authored-by: lollybet_antony * last maj 17/06 * maj questionnaire * maj espace perso * maj * maj espace perso --------- Co-authored-by: lollybet_antony * MAJ ESPACE PERSO (#15) * maj comptes admin + dr * mise à jour 29/05 * maj * maj 29/05 * maj email style * mise à jour 29/05 * maj comptes admin + dr (#1) * maj 03/06 >> besoins + ajout titre par jour * maj visuel session * maj comptes DR * maj session programme + dr * maj emails * Update 3/06 - 14h14 (#4) (#5) * maj comptes admin + dr * mise à jour 29/05 * maj * maj 29/05 * maj email style * mise à jour 29/05 * maj comptes admin + dr (#1) * maj 03/06 >> besoins + ajout titre par jour * maj visuel session * maj comptes DR * maj session programme + dr --------- Co-authored-by: lollybet_antony * last maj 17/06 * maj questionnaire * maj espace perso * maj * maj espace perso * maj espace perso --------- Co-authored-by: lollybet_antony * Update from repo a (#16) * maj comptes admin + dr * mise à jour 29/05 * maj * maj 29/05 * maj email style * mise à jour 29/05 * maj comptes admin + dr (#1) * maj 03/06 >> besoins + ajout titre par jour * maj visuel session * maj comptes DR * maj session programme + dr * maj emails * Update 3/06 - 14h14 (#4) (#5) * maj comptes admin + dr * mise à jour 29/05 * maj * maj 29/05 * maj email style * mise à jour 29/05 * maj comptes admin + dr (#1) * maj 03/06 >> besoins + ajout titre par jour * maj visuel session * maj comptes DR * maj session programme + dr --------- Co-authored-by: lollybet_antony * last maj 17/06 * maj questionnaire * maj espace perso * maj * maj espace perso * maj espace perso --------- Co-authored-by: lollybet_antony --------- Co-authored-by: lollybet_antony --- pages/espace-personnel.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pages/espace-personnel.js b/pages/espace-personnel.js index 5784fd7..63ec3a6 100644 --- a/pages/espace-personnel.js +++ b/pages/espace-personnel.js @@ -6,6 +6,7 @@ import Alert from '@/components/Alert' import { verifyToken } from '@/utils/auth'; import { useState, useEffect } from 'react' import Rencontres from '/components/Rencontres' +import RencontreDetail from '@/components/RencontreDetail'; import Profil from '@/components/Profil' import styles from '@/styles/Account.module.css' @@ -63,6 +64,7 @@ export default function Account({ user }){
    +
    {page == 0 && ( From 6559256de15dde29f77f49e5d16a82749c53d6eb Mon Sep 17 00:00:00 2001 From: lollybet_antony Date: Tue, 18 Jun 2024 17:10:56 +0200 Subject: [PATCH 021/100] update perso --- pages/espace-personnel.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/pages/espace-personnel.js b/pages/espace-personnel.js index 63ec3a6..5784fd7 100644 --- a/pages/espace-personnel.js +++ b/pages/espace-personnel.js @@ -6,7 +6,6 @@ import Alert from '@/components/Alert' import { verifyToken } from '@/utils/auth'; import { useState, useEffect } from 'react' import Rencontres from '/components/Rencontres' -import RencontreDetail from '@/components/RencontreDetail'; import Profil from '@/components/Profil' import styles from '@/styles/Account.module.css' @@ -64,7 +63,6 @@ export default function Account({ user }){
    -
    {page == 0 && ( From a75071e3c04802e3e5f773f4953902a0d11c9095 Mon Sep 17 00:00:00 2001 From: lollybet_antony Date: Tue, 18 Jun 2024 17:16:42 +0200 Subject: [PATCH 022/100] Ajout de console.log pour debug --- pages/espace-personnel.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pages/espace-personnel.js b/pages/espace-personnel.js index 5784fd7..514fc53 100644 --- a/pages/espace-personnel.js +++ b/pages/espace-personnel.js @@ -27,7 +27,7 @@ export async function getServerSideProps(context) { export default function Account({ user }){ - console.log("t") + console.log("ts") const [page, setPage] = useState(0) const [alert, setAlert] = useState(null) From dbc11d905dfbd5ce50acaf45b11d579491b14c50 Mon Sep 17 00:00:00 2001 From: lollybet_antony Date: Fri, 21 Jun 2024 11:57:00 +0200 Subject: [PATCH 023/100] maj admin + questionnaire --- components/Comptes.jsx | 5 +- components/RencontreDetail.jsx | 108 ++++++++++++++++++++++----------- components/Reviews.jsx | 33 ++++++---- pages/admin.js | 2 +- styles/globals.css | 2 +- 5 files changed, 101 insertions(+), 49 deletions(-) diff --git a/components/Comptes.jsx b/components/Comptes.jsx index ef88039..f012f52 100644 --- a/components/Comptes.jsx +++ b/components/Comptes.jsx @@ -3,7 +3,7 @@ import Alert from '@/components/Alert' import { Notif } from '@/components/Notif' import styles from '@/styles/Admin.module.css' -export default function Comptes() { +export default function Comptes({ user }) { const [alert, setAlert] = useState(null) const [notif, setNotif] = useState(null) @@ -179,6 +179,7 @@ export default function Comptes() { } + const closeSettings = () => { setOpenSettings(false); setSelectedAccount(null); @@ -334,7 +335,7 @@ export default function Comptes() {
    {acc.type} - {acc.type != 'DR' && ( + {user.type == 'Administrateur' && ( )}
    diff --git a/components/RencontreDetail.jsx b/components/RencontreDetail.jsx index 00916f5..f092e5b 100644 --- a/components/RencontreDetail.jsx +++ b/components/RencontreDetail.jsx @@ -7,7 +7,6 @@ import Rating from '@mui/material/Rating'; import styles from '@/styles/Account.module.css'; export default function RencontreDetail({ id, setOpen, userId, user }) { - console.log(id, setOpen, userId, user); const [alert, setAlert] = useState(null); const [notif, setNotif] = useState(null); @@ -22,7 +21,6 @@ export default function RencontreDetail({ id, setOpen, userId, user }) { const [responses, setResponses] = useState({}); const [hasResponded, setHasResponded] = useState(false); - const [modules, setModules] = useState([]) const getModules = async () => { @@ -31,6 +29,8 @@ export default function RencontreDetail({ id, setOpen, userId, user }) { setModules(json) } + console.log(responses) + useEffect(() => { getModules() }, []) @@ -134,20 +134,41 @@ export default function RencontreDetail({ id, setOpen, userId, user }) { { id: 10, text: "Il existe d’autres Rencontres Territoire Engagé Transition Ecologique. Quelles sont les thématiques susceptibles de vous intéresser ?", - options: modules.map(module => ({ value: module.nom, label: module.nom })) + options: modules.map(module => ({ value: module.nom, label: module.nom })), + type: "checkbox" } ]; - const handleOptionChange = (questionId, value) => { + const handleOptionChange = (questionId, value, checked) => { setOtherInputs(prevState => ({ ...prevState, [questionId]: value === 'autre', })); - setResponses(prevState => ({ - ...prevState, - [questionId]: value, - })); + + if (questions.find(q => q.id === questionId).type === 'checkbox') { + setResponses(prevState => { + const newValues = prevState[questionId] ? [...prevState[questionId]] : []; + if (checked) { + newValues.push(value); + } else { + const index = newValues.indexOf(value); + if (index > -1) { + newValues.splice(index, 1); + } + } + return { + ...prevState, + [questionId]: newValues, + }; + }); + } else { + setResponses(prevState => ({ + ...prevState, + [questionId]: value, + })); + } }; + const handleTextareaChange = (questionId, value) => { setResponses(prevState => ({ @@ -442,7 +463,7 @@ export default function RencontreDetail({ id, setOpen, userId, user }) { )} {passed && !hasResponded && ( <> - Donnez votre avis sur la rencontre : + {/* Donnez votre avis sur la rencontre :
    - )} + )} */} Nous vous remercions de prendre 5 minutes pour répondre à ce questionnaire de satisfaction. Vos réponses permettront d’améliorer l’offre des Rencontres Territoire Engagé Transition Ecologique de l’ADEME.
    @@ -478,43 +499,62 @@ export default function RencontreDetail({ id, setOpen, userId, user }) { >

    ) : ( - question.options.map((option, index) => ( -
    -

    - handleOptionChange(question.id, option.value)} - /> - -

    - {option.value === 'autre' && otherInputs[question.id] && ( + question.type === "checkbox" ? ( + question.options.map((option, index) => ( +
    +

    + handleOptionChange(question.id, option.value, e.target.checked)} + /> + +

    +
    + )) + ) : ( + question.options.map((option, index) => ( +

    handleOtherInputChange(question.id, e.target.value)} + type="radio" + name={`question_${question.id}`} + id={`question_${question.id}_${option.value}`} + value={option.value} + onChange={() => handleOptionChange(question.id, option.value)} /> +

    - )} -
    - )) + {option.value === 'autre' && otherInputs[question.id] && ( +

    + handleOtherInputChange(question.id, e.target.value)} + /> +

    + )} +
    + )) + ) )}
    ))} + )} {hasResponded && (
    - Vous avez déjà répondu à ce questionnaire. Merci pour votre participation. + Merci pour votre participation.
    )} {alert != null && ( diff --git a/components/Reviews.jsx b/components/Reviews.jsx index 854f0b0..0bd7296 100644 --- a/components/Reviews.jsx +++ b/components/Reviews.jsx @@ -1,4 +1,4 @@ -import { useState, useEffect } from 'react' +import React, { useState, useEffect } from 'react' import Review from '@/components/Review' import styles from '@/styles/Reviews.module.css' @@ -57,7 +57,7 @@ export default function Reviews({ session, setOpen }){ getQuizz() }, []) - console.log(quizz) + return ( <> @@ -65,14 +65,14 @@ export default function Reviews({ session, setOpen }){ setOpen(null)} className={styles.Back}>Retour aux sessions
    {session.moduleName}
    Avis sur la session du {formatDate(session.dateDebut)}, {session.region}
    -
    + {/*
    reviews{number} avis insights{moyenne > 0 ? moyenne : '-'}/5 de moyenne
    - + */}
    - {reviews.length > 0 ? ( + {/* {reviews.length > 0 ? ( <> {reviews.map((review, index) => { return @@ -80,10 +80,9 @@ export default function Reviews({ session, setOpen }){ ) : ( Aucun avis pour cette session. - )} + )} */}

    Questionnaires de satisfaction :

    - {quizz.length > 0 ? ( <> {quizz.map((question, index) => { @@ -96,10 +95,21 @@ export default function Reviews({ session, setOpen }){ {question.User.nom} {question.User.prenom} {Object.entries(responses).map(([questionId, response], idx) => ( - - {questionLabels[questionId] || `Question ${questionId}`} - {response} - + + {Array.isArray(response) ? ( + response.map((resp, respIdx) => ( + + {questionLabels[questionId] || `Question ${questionId}`} ({respIdx + 1}) + {resp} + + )) + ) : ( + + {questionLabels[questionId] || `Question ${questionId}`} + {response} + + )} + ))} @@ -109,6 +119,7 @@ export default function Reviews({ session, setOpen }){ ) : ( Aucun questionnaire de satisfaction. )} +
    diff --git a/pages/admin.js b/pages/admin.js index 6b3d53a..06bd616 100644 --- a/pages/admin.js +++ b/pages/admin.js @@ -62,7 +62,7 @@ export default function Admin({ user }){ )} {page == 1 && ( - + )} {page == 2 && ( diff --git a/styles/globals.css b/styles/globals.css index 0bf2353..575e5b4 100644 --- a/styles/globals.css +++ b/styles/globals.css @@ -124,7 +124,7 @@ p{ .btn__dark{ color:#FFF; - background: var(--primary); + background: var(--primary) !important; transition:.2s ease; } From 742e647da9d794fc4c33235b0cbb643fc459711f Mon Sep 17 00:00:00 2001 From: AntonyKLINGER Date: Thu, 27 Jun 2024 11:04:34 +0200 Subject: [PATCH 024/100] maj presence --- pages/_app.js | 15 +- pages/api/registrations/updatePresence.js | 32 +++++ pages/connexion.js | 5 +- pages/presence.js | 168 ++++++++++++++++++++++ prisma/schema.prisma | 1 + styles/Presence.module.css | 147 +++++++++++++++++++ styles/globals.css | 4 + 7 files changed, 365 insertions(+), 7 deletions(-) create mode 100644 pages/api/registrations/updatePresence.js create mode 100644 pages/presence.js create mode 100644 styles/Presence.module.css diff --git a/pages/_app.js b/pages/_app.js index 6f7f84e..1be86a0 100644 --- a/pages/_app.js +++ b/pages/_app.js @@ -1,4 +1,4 @@ -import Router from 'next/router'; +import Router, { useRouter } from 'next/router'; import NProgress from 'nprogress'; import 'nprogress/nprogress.css'; import Head from 'next/head' @@ -15,6 +15,9 @@ export default function App({ Component, pageProps }) { Router.events.on('routeChangeComplete', () => NProgress.done()); Router.events.on('routeChangeError', () => NProgress.done()); + const router = useRouter(); + const isPresencePage = router.pathname === '/presence'; + return ( <> @@ -22,11 +25,11 @@ export default function App({ Component, pageProps }) { -
    -
    - -
    -
    + {!isPresencePage &&
    } +
    + +
    + {!isPresencePage &&
    } ) } diff --git a/pages/api/registrations/updatePresence.js b/pages/api/registrations/updatePresence.js new file mode 100644 index 0000000..04a2864 --- /dev/null +++ b/pages/api/registrations/updatePresence.js @@ -0,0 +1,32 @@ +// pages/api/registrations/updatePresence.js +import { PrismaClient } from '@prisma/client'; + +const prisma = new PrismaClient(); + +export default async function handler(req, res) { + if (req.method === 'PUT') { + const { userId, sessionId, presence } = req.body; + + try { + const updatedRegistration = await prisma.registration.updateMany({ + where: { + userId: userId, + sessionId: sessionId, + }, + data: { + presence: presence, + }, + }); + + if (updatedRegistration.count === 0) { + return res.status(404).json({ message: 'Registration not found' }); + } + + res.status(200).json(updatedRegistration); + } catch (error) { + res.status(500).json({ message: 'Failed to update presence', error: error.message }); + } + } else { + res.status(405).json({ message: 'Method not allowed' }); + } +} diff --git a/pages/connexion.js b/pages/connexion.js index c4b4cc5..adca2a0 100644 --- a/pages/connexion.js +++ b/pages/connexion.js @@ -62,9 +62,12 @@ export default function Login(){ }); const jwtJson = await jwtResponse.json(); - if(jwtJson){ + if(jwtJson && json.user.id != 115){ router.push('/espace-personnel'); } + else{ + router.push('/presence'); + } } else { setNotif({ diff --git a/pages/presence.js b/pages/presence.js new file mode 100644 index 0000000..c262ceb --- /dev/null +++ b/pages/presence.js @@ -0,0 +1,168 @@ +import { useState, useEffect } from 'react'; +import nextCookies from 'next-cookies'; +import { verifyToken } from '@/utils/auth'; +import styles from '@/styles/Presence.module.css'; + +export async function getServerSideProps(context) { + const { auth: token } = nextCookies(context); + const user = verifyToken(token); + + if (!user && user != 115) { + return { + redirect: { + destination: '/connexion', + permanent: false, + }, + }; + } + + return { props: { user } }; +} + +export default function Presence() { + const [sessions, setSessions] = useState([]); + const [fiche, setFiche] = useState(0); + const [users, setUsers] = useState([]); + const [searchTerm, setSearchTerm] = useState(''); + + function formatDate(dateString) { + const date = new Date(dateString); + const day = date.getDate().toString().padStart(2, '0'); + const month = (date.getMonth() + 1).toString().padStart(2, '0'); + const year = date.getFullYear(); + return `${day}/${month}/${year}`; + } + + const openFiche = async (id_session) => { + const geter = await fetch(`/api/registrations/bySession?sessionId=${id_session}`); + const json = await geter.json(); + setUsers(json.sort((a, b) => a.nom.localeCompare(b.nom))); + setFiche(id_session); + }; + + const back = () => { + setUsers([]); + setFiche(0); + }; + + const updatePresence = async (userId, sessionId, isPresent) => { + const response = await fetch(`/api/registrations/updatePresence`, { + method: 'PUT', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ + userId, + sessionId, + presence: isPresent, + }), + }); + + if (!response.ok) { + console.error('Failed to update presence'); + } + }; + + const handleCheckboxChange = (userId, sessionId, event) => { + const isPresent = event.target.checked; + updatePresence(userId, sessionId, isPresent); + }; + + useEffect(() => { + const getSessions = async () => { + const geter = await fetch(`/api/sessions`); + const json = await geter.json(); + + // Filter sessions + const today = new Date(); + const minDate = new Date(today); + minDate.setDate(today.getDate() - 2); + const maxDate = new Date(today); + maxDate.setDate(today.getDate() + 2); + + const filteredSessions = json.filter(session => { + const sessionDate = new Date(session.dateDebut); + return sessionDate >= minDate && sessionDate <= maxDate; + }); + + setSessions(filteredSessions); + }; + getSessions(); + }, []); + + const handleSearchChange = (event) => { + setSearchTerm(event.target.value); + }; + + const filteredUsers = users.filter((user) => + user.nom.toLowerCase().includes(searchTerm.toLowerCase()) || + user.prenom.toLowerCase().includes(searchTerm.toLowerCase()) + ); + + return ( +
    +
    +

    Sélectionnez une session

    + {fiche == 0 && ( +
    + {sessions.length > 0 ? ( + <> + {sessions.map((session, i) => ( +
    +
    + {formatDate(session.dateDebut)} + {session.departement} {session.region} +
    +
    +
    + Module : + {session.module.nom} +
    + +
    +
    + ))} + + ) : ( + Pas de sessions en cours. + )} +
    + )} + {fiche != 0 && ( +
    + + + {filteredUsers.length > 0 ? ( + <> + {filteredUsers.map((u, i) => { + return ( +
    +
    + {u.nom} + {u.prenom} +
    + handleCheckboxChange(u.userId, fiche, e)} + /> +
    + ) + })} + + ) : ( + Pas de participants. + )} +
    + )} +
    +
    + ); +} diff --git a/prisma/schema.prisma b/prisma/schema.prisma index e35ab3c..39699e5 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -109,6 +109,7 @@ model Registration { regime String? deleted Boolean? hebergement String? + presence Boolean? session Session @relation(fields: [sessionId], references: [id]) user User @relation(fields: [userId], references: [id]) } diff --git a/styles/Presence.module.css b/styles/Presence.module.css new file mode 100644 index 0000000..eadb9ca --- /dev/null +++ b/styles/Presence.module.css @@ -0,0 +1,147 @@ +.all{ + width: 100%; + min-height: 100vh; + background-color: var(--primaryBack); + padding-top: 100px; +} + +.pres{ + max-width: 1000px; + margin-inline:auto; + padding:40px; + border-radius:15px; + background-color: #FFF; +} + +.pres h1{ + font-weight: 600; +} + +.session{ + padding: 20px; + border-radius: 10px; + background: var(--primaryBack); + cursor: pointer; + margin-bottom: 10px; +} + +.date{ + font-weight: 500; + font-size: 0.9rem; +} + +.region{ + color: #fff; + background: var(--orange); + font-weight: 500; + font-size: .9rem; + padding: 5px 10px; + border-radius: 5px; +} + +.module{ + font-size: 1.15rem; + color: var(--primary); + font-weight: 500; + display: block; + margin-top: 10px; +} + +.nom{ + font-size: 1.05rem; + color: var(--primary); + font-weight: 400; + display: block; +} + +.session button{ + color: var(--primary); + border: 2px solid var(--primary); + text-decoration: none; + font-weight: 500; + border-radius: 5px; + padding: 4px 15px; + display: inline-block; + cursor: pointer; + transition: .2s ease; +} + +.user{ + width: 100%; + display: flex; + align-items: center; + border:1.5px solid var(--primaryThird); + padding:15px; + border-radius: 10px; + font-weight: 500; + justify-content: space-between; +} + +.nom{ + font-weight: 500; + display: block; + margin-right: 5px; +} + +.back{ + border:0px; + font-weight: 500; + font-size: 1.1rem; + margin-bottom: 20px; + background-color:var(--primaryBack); + color:var(--primary); + padding: 8px 20px 9px; + border-radius: 10px; + cursor:pointer; +} + +.pres input[type=text]{ + width: 100%; + border-radius: 10px; + height: 40px; + border:2px solid rgba(0,0,0,.1); + margin-bottom: 20px; + text-indent: 10px; +} + +.pres input[type=text]:focus{ + outline: none; +} + +@media(max-width:810px){ + .all{ + padding-top:20px; + } + + .pres{ + max-width: 95%; + } + + .pres h1{ + font-size: 1.25rem; + } + + .pres{ + padding: 25px; + } + + .user{ + padding:10px; + } + + .back{ + font-size: 0.9rem; + } + + .nom{ + font-size: 0.9rem; + } + + .module{ + margin-bottom: 5px; + } + + .region{ + margin-top: 10px; + } +} \ No newline at end of file diff --git a/styles/globals.css b/styles/globals.css index 575e5b4..79bc96a 100644 --- a/styles/globals.css +++ b/styles/globals.css @@ -85,6 +85,10 @@ p{ cursor:pointer; } +.align-end{ + align-items: end; +} + .media{ object-fit: contain; } From ba54f44b43c5eb64ed48d248844771c8b02a0aef Mon Sep 17 00:00:00 2001 From: AntonyKLINGER Date: Thu, 27 Jun 2024 16:03:33 +0200 Subject: [PATCH 025/100] maj badge + mail --- components/Participant.jsx | 36 ++++++++++++++++++++++++-- pages/api/registrations/bySession.js | 5 ++-- views/emails/session_relance_days.hbs | 2 +- views/emails/session_relance_weeks.hbs | 2 +- 4 files changed, 39 insertions(+), 6 deletions(-) diff --git a/components/Participant.jsx b/components/Participant.jsx index 407b9e4..b674f5b 100644 --- a/components/Participant.jsx +++ b/components/Participant.jsx @@ -24,7 +24,38 @@ export default function Participant({ data, setActions, session }){ }); } - console.log(data.session.metasSession.nombreJours) + const generateBadge = async () => { + setNotif({ + text: 'Le badge se génère, veuillez patienter...', + icon: 'hourglass_top' + }) + const datas = { + nom: data.nom, + prenom: data.prenom, + program: data.session.metasSession.programmeSession, + organisation: data.user.organisation || '', + }; + + const response = await fetch('/api/generate-badge', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify(datas), + }); + + const blob = await response.blob(); + const url = window.URL.createObjectURL(blob); + + const a = document.createElement('a'); + a.href = url; + a.download = `badge_${data.nom}_${data.prenom}.pdf`; + document.body.appendChild(a); + a.click(); + + document.body.removeChild(a); + window.URL.revokeObjectURL(url); + }; return ( <> @@ -33,7 +64,8 @@ export default function Participant({ data, setActions, session }){ {data.deleted ? 'cancel' : 'person'}{data.nom} {data.prenom} {!data.deleted && ( - )} + )} +
    Nom{data.nom}
    diff --git a/pages/api/registrations/bySession.js b/pages/api/registrations/bySession.js index c72dc3a..404adce 100644 --- a/pages/api/registrations/bySession.js +++ b/pages/api/registrations/bySession.js @@ -14,9 +14,10 @@ export default async function handle(req, res) { session: { include: { reviews: true, - metasSession: true, + metasSession: true } - } + }, + user: true }, }); diff --git a/views/emails/session_relance_days.hbs b/views/emails/session_relance_days.hbs index 5d22511..ebe63fb 100644 --- a/views/emails/session_relance_days.hbs +++ b/views/emails/session_relance_days.hbs @@ -53,7 +53,7 @@ Date de la Rencontre : {{dateRencontre}}, {{firstDayStartTime}}
    Durée : {{nbJours}} jour(s)
    Lieu de la Rencontre : {{lieuRencontre}}

    -

    N'oubliez pas que des ressources ont été mises à disposition sur votre Espace personnel, elles vous permettront de vous préparer au mieux pour les échanges à venir.
    Nous tenons également à vous rappeler qu'il est essentiel de générer votre badge sur votre espace personnel avant la rencontre et de l’imprimer pour permettre votre accès à l’évènement.

    +

    N'oubliez pas que des ressources ont été mises à disposition sur votre Espace personnel, elles vous permettront de vous préparer au mieux pour les échanges à venir.

    Pour information, il est possible que des photos soient prises durant cette Rencontre afin que l’ADEME puisse communiquer sur ces événements.

    Pour toute question supplémentaire, vous pouvez contacter le référent de cette rencontre : {{mail_referent}}.

    Nous sommes impatients de vous y rencontrer !

    diff --git a/views/emails/session_relance_weeks.hbs b/views/emails/session_relance_weeks.hbs index c95740e..5973890 100644 --- a/views/emails/session_relance_weeks.hbs +++ b/views/emails/session_relance_weeks.hbs @@ -55,7 +55,7 @@ Durée : {{nbJours}} jour(s)
    Lieu de la Rencontre : {{lieuRencontre}}

    En vous inscrivant à cette Rencontre, vous vous êtes engagé à y participer. Il est primordial pour nous que vous honoriez votre engagement car le nombre d’inscrits permet non seulement de réserver une salle adaptée mais également de prévoir le nombre exact de repas nécessaire afin d’éviter tout gaspillage alimentaire. Si toutefois il n’est vraiment plus possible pour vous d’être présent ce jour, merci d'annuler au plus vite votre inscription dans votre {{siteUrl}}/espace-personnel

    -

    Vous retrouverez également dans votre espace personnel :
    - Toutes les informations pratiques relatives à la Rencontre
    - Des ressources pour vous préparer au mieux aux échanges à venir
    - Un badge à générer vous permettant d’accéder à l’événement le jour J

    +

    Vous retrouverez également dans votre espace personnel :
    - Toutes les informations pratiques relatives à la Rencontre
    - Des ressources pour vous préparer au mieux aux échanges à venir.

    En cas de question, vous pouvez contacter le référent de cette rencontre : {{mail_referent}}.

    Nous sommes impatients de vous retrouver lors de cette Rencontre !

    Bien cordialement,

    From 07dc7e5b8880a3c90699da8f22a2d879ad644359 Mon Sep 17 00:00:00 2001 From: AntonyKLINGER Date: Thu, 4 Jul 2024 14:38:57 +0200 Subject: [PATCH 026/100] maj email after 1 day --- .../one-day-after-reminder-email-task.yml | 28 +++++++++++++++++++ .../workflows/scripts/fetchDataDayAfter.js | 10 +++++++ 2 files changed, 38 insertions(+) create mode 100644 .github/workflows/one-day-after-reminder-email-task.yml create mode 100644 .github/workflows/scripts/fetchDataDayAfter.js diff --git a/.github/workflows/one-day-after-reminder-email-task.yml b/.github/workflows/one-day-after-reminder-email-task.yml new file mode 100644 index 0000000..ae97619 --- /dev/null +++ b/.github/workflows/one-day-after-reminder-email-task.yml @@ -0,0 +1,28 @@ +name: One Day After Reminder Email Task + +on: + schedule: + - cron: '0 0 * * *' + workflow_dispatch: + +jobs: + run-daily-task: + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v2 + + - name: Set up Node.js + uses: actions/setup-node@v2 + with: + node-version: '16' + + - name: Install dependencies + run: npm install + + - name: Run daily task + env: + DATABASE_URL: ${{ secrets.DATABASE_URL }} + WEBSITE_URL: ${{ secrets.WEBSITE_URL }} + run: node .github/workflows/scripts/fetchDataDayAfter.js diff --git a/.github/workflows/scripts/fetchDataDayAfter.js b/.github/workflows/scripts/fetchDataDayAfter.js new file mode 100644 index 0000000..f747e77 --- /dev/null +++ b/.github/workflows/scripts/fetchDataDayAfter.js @@ -0,0 +1,10 @@ +(async () => { + const fetch = await import('node-fetch').then(module => module.default); + + const res = await fetch(`https://rencontres.territoiresentransitions.fr/api/workflow/workflowAfter`, { + method: 'GET' + }); + const data = await res.json(); + console.log(data); + })(); + \ No newline at end of file From 2487f052984fd2db098801abd4776bc4df613ec6 Mon Sep 17 00:00:00 2001 From: AntonyKLINGER Date: Thu, 4 Jul 2024 14:40:11 +0200 Subject: [PATCH 027/100] maj presence --- pages/presence.js | 2 +- styles/Presence.module.css | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/pages/presence.js b/pages/presence.js index c262ceb..154d68d 100644 --- a/pages/presence.js +++ b/pages/presence.js @@ -78,7 +78,7 @@ export default function Presence() { const minDate = new Date(today); minDate.setDate(today.getDate() - 2); const maxDate = new Date(today); - maxDate.setDate(today.getDate() + 2); + maxDate.setDate(today.getDate() + 6); const filteredSessions = json.filter(session => { const sessionDate = new Date(session.dateDebut); diff --git a/styles/Presence.module.css b/styles/Presence.module.css index eadb9ca..1e48f07 100644 --- a/styles/Presence.module.css +++ b/styles/Presence.module.css @@ -75,6 +75,7 @@ border-radius: 10px; font-weight: 500; justify-content: space-between; + margin-bottom:5px; } .nom{ From d3a9e688b8127638a28368af56ecb8713088ec15 Mon Sep 17 00:00:00 2001 From: AntonyKLINGER Date: Thu, 4 Jul 2024 14:52:44 +0200 Subject: [PATCH 028/100] maj 5 mn --- views/emails/session_after_day.hbs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/views/emails/session_after_day.hbs b/views/emails/session_after_day.hbs index f549804..f31067a 100644 --- a/views/emails/session_after_day.hbs +++ b/views/emails/session_after_day.hbs @@ -48,7 +48,7 @@

    Cher {{prenom}},

    Nous tenons à vous remercier chaleureusement pour votre participation d’hier à la Rencontre Territoire Engagé Transition Ecologique. Votre présence et votre engagement ont grandement contribué au succès de cet événement.

    -

    Afin de continuer à améliorer nos événements, nous souhaitons recueillir votre avis. Merci de prendre quelques instants (5 minutes environ) pour remplir notre questionnaire de satisfaction également présent dans votre Espace personnel.

    +

    Afin de continuer à améliorer nos événements, nous souhaitons recueillir votre avis. Merci de prendre quelques instants pour remplir notre questionnaire de satisfaction également présent dans votre Espace personnel.

    Nous espérons que vous avez trouvé ces moments d'échange et de partage enrichissants, et que vous repartez avec de nouvelles perspectives et des idées inspirantes pour votre territoires.

    Vous pouvez retrouver les informations de la session (des ressources mises à disposition, les coordonnées des intervenants, ...) dans votre Espace personnel, onglet Mes rencontres puis Mes rencontres passées.

    Nous vous remercions encore une fois pour votre participation et espérons vous retrouver lors de nos prochains événements.

    From f7512ff2b7f719194caee2904226ee5355b5cf3c Mon Sep 17 00:00:00 2001 From: AntonyKLINGER Date: Thu, 4 Jul 2024 15:58:22 +0200 Subject: [PATCH 029/100] maj export excel questionnaires --- components/Reviews.jsx | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/components/Reviews.jsx b/components/Reviews.jsx index 0bd7296..4857456 100644 --- a/components/Reviews.jsx +++ b/components/Reviews.jsx @@ -1,5 +1,6 @@ import React, { useState, useEffect } from 'react' import Review from '@/components/Review' +import * as XLSX from 'xlsx'; import styles from '@/styles/Reviews.module.css' export default function Reviews({ session, setOpen }){ @@ -8,6 +9,7 @@ export default function Reviews({ session, setOpen }){ const [reviews, setReviews] = useState([]) const [moyenne, setMoyenne] = useState(0) const [quizz, setQuizz] = useState([]) + console.log(session) @@ -57,6 +59,27 @@ export default function Reviews({ session, setOpen }){ getQuizz() }, []) + const exportToExcel = () => { + const data = quizz.map((question) => { + const responses = question.responses; + const participant = `${question.User.nom} ${question.User.prenom}`; + const row = { Participant: participant }; + Object.entries(responses).forEach(([questionId, response]) => { + if (Array.isArray(response)) { + row[questionLabels[questionId] || `Question ${questionId}`] = response.join(', '); + } else { + row[questionLabels[questionId] || `Question ${questionId}`] = response; + } + }); + return row; + }); + + const worksheet = XLSX.utils.json_to_sheet(data); + const workbook = XLSX.utils.book_new(); + XLSX.utils.book_append_sheet(workbook, worksheet, 'Quizz'); + + XLSX.writeFile(workbook, `questionnaires_session_${session.id}.xlsx`); + }; return ( @@ -85,6 +108,7 @@ export default function Reviews({ session, setOpen }){

    Questionnaires de satisfaction :

    {quizz.length > 0 ? ( <> + {quizz.map((question, index) => { const responses = question.responses; return ( From 06ebf3ae30534074989c19a7d4f3c2240464cb72 Mon Sep 17 00:00:00 2001 From: AntonyKLINGER Date: Mon, 8 Jul 2024 11:19:01 +0200 Subject: [PATCH 030/100] maj workflow emails --- pages/api/workflow/workflowAfter.js | 18 +++++++++++++----- pages/api/workflow/workflowDays.js | 19 ++++++++++++++----- pages/api/workflow/workflowWeeks.js | 16 ++++++++++++---- 3 files changed, 39 insertions(+), 14 deletions(-) diff --git a/pages/api/workflow/workflowAfter.js b/pages/api/workflow/workflowAfter.js index 8e9b68e..8ddfae5 100644 --- a/pages/api/workflow/workflowAfter.js +++ b/pages/api/workflow/workflowAfter.js @@ -10,13 +10,21 @@ export default async function handle(req, res) { try { const today = new Date(); - const oneDayBefore = new Date(today); - oneDayBefore.setDate(today.getDate() - 1); - + const oneDayafter = new Date(today); + oneDayafter.setDate(today.getDate() - 1); + oneDayafter.setHours(0, 0, 0, 0); + + const startOfDay = new Date(oneDayafter); + startOfDay.setHours(0, 0, 0, 0); + + const endOfDay = new Date(oneDayafter); + endOfDay.setHours(23, 59, 59, 999); + const pastSessions = await prisma.session.findMany({ where: { - dateFin: { - equals: oneDayBefore, + dateDebut: { + gte: startOfDay, + lt: endOfDay, }, }, include: { diff --git a/pages/api/workflow/workflowDays.js b/pages/api/workflow/workflowDays.js index d3965ca..e6533e8 100644 --- a/pages/api/workflow/workflowDays.js +++ b/pages/api/workflow/workflowDays.js @@ -10,13 +10,21 @@ export default async function handle(req, res) { try { const today = new Date(); - const twoWeeksLater = new Date(today); - twoWeeksLater.setDate(today.getDate() + 3); - + const threeDaysLater = new Date(today); + threeDaysLater.setDate(today.getDate() + 3); + threeDaysLater.setHours(0, 0, 0, 0); + + const startOfDay = new Date(threeDaysLater); + startOfDay.setHours(0, 0, 0, 0); + + const endOfDay = new Date(threeDaysLater); + endOfDay.setHours(23, 59, 59, 999); + const upcomingSessions = await prisma.session.findMany({ where: { dateDebut: { - equals: twoWeeksLater, + gte: startOfDay, + lt: endOfDay, }, }, include: { @@ -30,6 +38,7 @@ export default async function handle(req, res) { }, }); + for (const session of upcomingSessions) { const firstProgramme = session.metasSession.programmeSession[0]; let firstDayStartTime; @@ -73,7 +82,7 @@ export default async function handle(req, res) { } } - res.status(200).json({ message: "Emails sent successfully" }); + res.status(200).json({ message: "Emails sended" }); } catch (error) { console.error("Error fetching upcoming sessions or sending emails: ", error); res.status(500).json({ error: `Impossible de récupérer les enregistrements ou d'envoyer les emails : ${error.message}` }); diff --git a/pages/api/workflow/workflowWeeks.js b/pages/api/workflow/workflowWeeks.js index 934c1cd..5ea6e2d 100644 --- a/pages/api/workflow/workflowWeeks.js +++ b/pages/api/workflow/workflowWeeks.js @@ -10,13 +10,21 @@ export default async function handle(req, res) { try { const today = new Date(); - const twoWeeksLater = new Date(today); - twoWeeksLater.setDate(today.getDate() + 14); - + const threeDaysLater = new Date(today); + threeDaysLater.setDate(today.getDate() + 14); + threeDaysLater.setHours(0, 0, 0, 0); + + const startOfDay = new Date(threeDaysLater); + startOfDay.setHours(0, 0, 0, 0); + + const endOfDay = new Date(threeDaysLater); + endOfDay.setHours(23, 59, 59, 999); + const upcomingSessions = await prisma.session.findMany({ where: { dateDebut: { - equals: twoWeeksLater, + gte: startOfDay, + lt: endOfDay, }, }, include: { From 4b84da7dc924657c0757aa66724d315b153c785d Mon Sep 17 00:00:00 2001 From: AntonyKLINGER Date: Tue, 9 Jul 2024 12:12:43 +0200 Subject: [PATCH 031/100] maj presents --- components/SessionsBack.jsx | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/components/SessionsBack.jsx b/components/SessionsBack.jsx index b3113ba..0ad01e5 100644 --- a/components/SessionsBack.jsx +++ b/components/SessionsBack.jsx @@ -15,12 +15,17 @@ export default function SessionsBack({isModule, date, session, code, region, tit const startDate = formatDate(date); const [number, setNumber] = useState(0) + const [presentNumber, setPresentNumber] = useState(0) const getParticipants = async () => { const fetcher = await fetch(`/api/registrations/bySession?sessionId=${session.id}`) const json = await fetcher.json() if(json.length > 0){ - setNumber(json.filter((item) => !item.deleted).length) + const activeParticipants = json.filter((item) => !item.deleted); + setNumber(activeParticipants.length); + + const presentParticipants = activeParticipants.filter((item) => item.presence === true).length; + setPresentNumber(presentParticipants); } } @@ -60,7 +65,7 @@ export default function SessionsBack({isModule, date, session, code, region, tit
    - {startDate} - {joursRestants >= 0 ? `${joursRestants} jour${joursRestants > 1 ? 's': ''} restant${joursRestants > 1 ? 's': ''}` : 'Terminée'} - {number} participant{number > 1 && 's'} + {startDate} - {joursRestants >= 0 ? `${joursRestants} jour${joursRestants > 1 ? 's': ''} restant${joursRestants > 1 ? 's': ''}` : 'Terminée'} - {number} participant{number > 1 && 's'} - {presentNumber} présent{number > 1 && 's'}
    {dept} - {region}
    From 73f9b1325fa4a3998728e1befd6ecace71b5d607 Mon Sep 17 00:00:00 2001 From: AntonyKLINGER Date: Wed, 10 Jul 2024 11:12:28 +0200 Subject: [PATCH 032/100] maj espace perso ressources --- components/RencontreDetail.jsx | 40 +++++++++++++++++++++++++++------- 1 file changed, 32 insertions(+), 8 deletions(-) diff --git a/components/RencontreDetail.jsx b/components/RencontreDetail.jsx index f092e5b..acdd807 100644 --- a/components/RencontreDetail.jsx +++ b/components/RencontreDetail.jsx @@ -384,6 +384,28 @@ export default function RencontreDetail({ id, setOpen, userId, user }) { setOpen(null); }; + const transformLinks = (html) => { + // Cette regex trouve les liens et capture l'URL + const urlRegex = /(.*?)<\/a>/g; + + return html.replace(urlRegex, (match, url, linkText) => { + // Remplacez "Cliquez ici" par le texte que vous voulez montrer comme lien + const clickableText = "Lien externe"; + + // Retourne le HTML modifié avec le texte cliquable qui garde l'URL comme destination + return `${clickableText}`; + }); + }; + + const [transformedHTML, setTransformedHTML] = useState('') + + useEffect(() => { + if(data?.metasSession?.explications){ + setTransformedHTML(transformLinks(data?.metasSession?.explications)) + } + }, [data]) + + return ( <> setOpen(null)} className={styles.Back}>Retour à mes rencontres @@ -435,20 +457,22 @@ export default function RencontreDetail({ id, setOpen, userId, user }) { En savoir plus sur ce module :

    {data.module !== undefined ? data.module.description : 'Chargement...'}

    - {data?.metasSession?.urlsPDF.length > 0 ? ( - <> + {(data?.metasSession?.urlsPDF.length > 0 || data?.metasSession?.explications) ? ( +
    Ressources :
    {data?.metasSession?.explications && (
    )}
    -
      - {data?.metasSession?.urlsPDF.map((item, index) => ( -
    • {item.nom}
    • - ))} -
    - + {data?.metasSession?.urlsPDF.length > 0 && ( +
      + {data?.metasSession?.urlsPDF.map((item, index) => ( +
    • {item.nom}
    • + ))} +
    + )} +
    ) : (
    Ressources : From fcf9a108184f4a545b2307c84dd5e596096ee09a Mon Sep 17 00:00:00 2001 From: AntonyKLINGER Date: Wed, 17 Jul 2024 11:32:24 +0200 Subject: [PATCH 033/100] maj upload test --- pages/api/upload.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pages/api/upload.js b/pages/api/upload.js index 3f31a3d..52c61f7 100644 --- a/pages/api/upload.js +++ b/pages/api/upload.js @@ -94,5 +94,5 @@ export default async function handler(req, res) { } } - res.status(200).json({ urlsPDF }); + res.status(200).json({ urlsPDF, env1:supabaseUrl, env2:supabaseKey}); } From 73285b267d6fdeaf4bbf20af4f17a190f792312e Mon Sep 17 00:00:00 2001 From: AntonyKLINGER Date: Wed, 17 Jul 2024 14:29:33 +0200 Subject: [PATCH 034/100] maj upload --- pages/api/upload.js | 4 ++-- pages/api/uploadVisuel.js | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pages/api/upload.js b/pages/api/upload.js index 52c61f7..f7d453f 100644 --- a/pages/api/upload.js +++ b/pages/api/upload.js @@ -10,7 +10,7 @@ export const config = { }; const supabaseUrl = process.env.NEXT_PUBLIC_SUPABASE_URL; -const supabaseKey = process.env.NEXT_PUBLIC_SUPABASE_KEY; +const supabaseKey = process.env.SUPABASE_KEY; const supabase = createClient(supabaseUrl, supabaseKey); export default async function handler(req, res) { @@ -94,5 +94,5 @@ export default async function handler(req, res) { } } - res.status(200).json({ urlsPDF, env1:supabaseUrl, env2:supabaseKey}); + res.status(200).json({ urlsPDF, env1:supabaseUrl}); } diff --git a/pages/api/uploadVisuel.js b/pages/api/uploadVisuel.js index 1811532..bcf34d5 100644 --- a/pages/api/uploadVisuel.js +++ b/pages/api/uploadVisuel.js @@ -10,7 +10,7 @@ export const config = { }; const supabaseUrl = process.env.NEXT_PUBLIC_SUPABASE_URL; -const supabaseKey = process.env.NEXT_PUBLIC_SUPABASE_KEY; +const supabaseKey = process.env.SUPABASE_KEY; const supabase = createClient(supabaseUrl, supabaseKey); // Fonction utilitaire pour nettoyer et encoder le nom de fichier From a4981a9adc818ca3f58d0ea8922328575ab3b4f6 Mon Sep 17 00:00:00 2001 From: AntonyKLINGER Date: Thu, 29 Aug 2024 09:58:46 +0200 Subject: [PATCH 035/100] maj api session slug --- pages/api/sessions/slug.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/pages/api/sessions/slug.js b/pages/api/sessions/slug.js index 46eb4fa..8892cd0 100644 --- a/pages/api/sessions/slug.js +++ b/pages/api/sessions/slug.js @@ -14,6 +14,11 @@ const regionSlugs = { 'nouvelle-aquitaine': 'Nouvelle-Aquitaine', 'occitanie': 'Occitanie', 'pays-de-la-loire': 'Pays de la Loire', + 'guyane': 'Guyane', + 'martinique': 'Martinique', + 'reunion': 'La Reunion', + 'guadeloupe': 'Guadeloupe', + 'mayotte': 'Mayotte', 'provence-alpes-cote-d-azur': 'Provence-Alpes-Côte d\'Azur' }; From ea35f237825aaf764d1f3a059f6f44334cd666d9 Mon Sep 17 00:00:00 2001 From: AntonyKLINGER Date: Thu, 29 Aug 2024 10:03:00 +0200 Subject: [PATCH 036/100] maj slug url sessions --- pages/api/modules/add.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pages/api/modules/add.js b/pages/api/modules/add.js index 14878de..a5789f6 100644 --- a/pages/api/modules/add.js +++ b/pages/api/modules/add.js @@ -74,7 +74,7 @@ export default async function handle(req, res) { let slug = moduleData.nom .normalize("NFD") .replace(/[\u0300-\u036f]/g, "") - .replace(/[.,]/g, "") + .replace(/[.,?]/g, "") .replace(/\s+/g, '-') .toLowerCase() From d31eeb57ed058a20bd8b17c84cbb7fb582397d5f Mon Sep 17 00:00:00 2001 From: AntonyKLINGER Date: Thu, 29 Aug 2024 10:22:36 +0200 Subject: [PATCH 037/100] maj affichage modules et sessions --- pages/rencontres/index.js | 47 ++++++++++++++++++++++++++++++--------- 1 file changed, 36 insertions(+), 11 deletions(-) diff --git a/pages/rencontres/index.js b/pages/rencontres/index.js index e7bfc26..515f5af 100644 --- a/pages/rencontres/index.js +++ b/pages/rencontres/index.js @@ -258,17 +258,42 @@ export default function Rencontres({ base, region, pilier, thematique }){ )} {modules.length > 0 ? (
    - {modules.map((module, index) => ( -
    - -
    - ))} + {!switcher ? + modules.map((module, index) => ( + <> +
    + +
    + + )) : modules.map((module, index) => { + const publishedUpcomingSessions = module.sessions.filter(session => { + const isPublished = session.status === "publish"; + const isUpcoming = new Date(session.dateDebut) > new Date(); + return isPublished && isUpcoming; + }); + + if (publishedUpcomingSessions.length > 0) { + return ( +
    + +
    + ); + } + return null; + }) + }
    ) : (
    From 03ce753a89d8f715595cfa34049faee9ff6a7700 Mon Sep 17 00:00:00 2001 From: AntonyKLINGER Date: Wed, 4 Sep 2024 10:03:39 +0200 Subject: [PATCH 038/100] maj accounts + users --- components/Header.jsx | 5 +- components/Participant.jsx | 4 +- components/Profil.jsx | 138 ++++++++++++++------ components/RencontreDetail.jsx | 107 +++++++++++---- components/Rencontres.jsx | 18 ++- components/Reviews.jsx | 2 +- pages/api/accounts/[id].js | 17 +++ pages/api/emails/toParticipants.js | 23 +++- pages/api/registrations/add.js | 135 +++++++++++++------ pages/api/registrations/bySession.js | 38 +++++- pages/api/registrations/byUser.js | 23 +++- pages/api/registrations/byUserSession.js | 44 +++++-- pages/api/registrations/cancel.js | 58 +++++--- pages/api/registrations/delete.js | 32 +++-- pages/api/registrations/updatePresence.js | 39 ++++-- pages/api/reviews/add.js | 34 +++-- pages/api/reviews/bySession.js | 33 ++++- pages/api/reviews/check.js | 36 +++-- pages/api/satisfaction/add.js | 33 +++-- pages/api/satisfaction/checkSatisfaction.js | 50 ++++--- pages/api/satisfaction/fromSession.js | 39 +++++- pages/api/satisfaction/getSatisfaction.js | 28 +++- pages/presence.js | 14 +- pages/rencontres/[category]/[session].js | 76 +++++++---- prisma/schema.prisma | 93 ++++++++++--- 25 files changed, 823 insertions(+), 296 deletions(-) create mode 100644 pages/api/accounts/[id].js diff --git a/components/Header.jsx b/components/Header.jsx index 99fb35f..74777ca 100644 --- a/components/Header.jsx +++ b/components/Header.jsx @@ -46,7 +46,10 @@ export default function Header(){ {user?.id ? ( <> {(user.id == 10 || user.type == 'Administrateur' || user.type == 'DR') ? ( -
  • setActiveMenu(prev => !prev)} className={styles.pf}>Administration
  • + <> +
  • setActiveMenu(prev => !prev)} className={styles.pf}>Administration
  • +
  • setActiveMenu(prev => !prev)} className={styles.pf}>Espace personnel
  • + ) : (
  • setActiveMenu(prev => !prev)} className={styles.pf}>Espace personnel
  • )} diff --git a/components/Participant.jsx b/components/Participant.jsx index b674f5b..518003b 100644 --- a/components/Participant.jsx +++ b/components/Participant.jsx @@ -10,7 +10,7 @@ export default function Participant({ data, setActions, session }){ const deleteUser = async () => { setAlert(null) - const fetcher = await fetch(`/api/registrations/delete?userId=${data.userId}&sessionId=${data.sessionId}`, { method: 'DELETE' }) + const fetcher = await fetch(`/api/registrations/delete?userId=${data.userId ? data.userId : data.accountId}&sessionId=${data.sessionId}&${!data.userId && 'specialAccount=true'}`, { method: 'DELETE' }) // const json = await fetcher.json() setActions(prev => prev+1) } @@ -33,7 +33,7 @@ export default function Participant({ data, setActions, session }){ nom: data.nom, prenom: data.prenom, program: data.session.metasSession.programmeSession, - organisation: data.user.organisation || '', + organisation: data.user !== undefined && data.user.organisation || '', }; const response = await fetch('/api/generate-badge', { diff --git a/components/Profil.jsx b/components/Profil.jsx index 6c75481..04b437a 100644 --- a/components/Profil.jsx +++ b/components/Profil.jsx @@ -13,9 +13,15 @@ export default function Profil({ user }){ const [rgpd, setRgpd] = useState(false) const getUserInfos = async () => { - const geter = await fetch(`/api/users/${user.id}`) - const json = await geter.json() - setUserData(json[0]) + if(user.type == "Administrateur" || user.type == "DR"){ + const geter = await fetch(`/api/accounts/${user.id}`) + const json = await geter.json() + setUserData(json[0]) + } else { + const geter = await fetch(`/api/users/${user.id}`) + const json = await geter.json() + setUserData(json[0]) + } } const handleChange = async (event) => { @@ -42,22 +48,42 @@ export default function Profil({ user }){ const { motDePasse, motDePasse2 } = passw if(motDePasse && motDePasse2){ if(motDePasse.length > 5){ - const fetcher = await fetch('/api/users/lib/update-password', { - method: 'POST', - headers: { - 'Content-Type': 'application/json' - }, - body: JSON.stringify({ - motDePasse: motDePasse, - userId: user.id + if(user.type == "Administrateur" || user.type == "DR"){ + // const fetcher = await fetch('/api/accounts/lib/update-password', { + // method: 'POST', + // headers: { + // 'Content-Type': 'application/json' + // }, + // body: JSON.stringify({ + // motDePasse: motDePasse, + // userId: user.id + // }) + // }) + // const json = await fetcher.json(); + // if(json.id){ + // setNotif({ + // text: 'Le mot de passe a bien été modififé !', + // icon: 'done' + // }) + // } + } else { + const fetcher = await fetch('/api/users/lib/update-password', { + method: 'POST', + headers: { + 'Content-Type': 'application/json' + }, + body: JSON.stringify({ + motDePasse: motDePasse, + userId: user.id + }) }) - }) - const json = await fetcher.json(); - if(json.id){ - setNotif({ - text: 'Le mot de passe a bien été modififé !', - icon: 'done' - }) + const json = await fetcher.json(); + if(json.id){ + setNotif({ + text: 'Le mot de passe a bien été modififé !', + icon: 'done' + }) + } } } else{ @@ -78,21 +104,39 @@ export default function Profil({ user }){ const deleteAccount = async () => { if(rgpd){ try { - const response = await fetch(`/api/users/delete/?id=${user.id}`, { - method: 'DELETE', - headers: { - 'Content-Type': 'application/json', - }, - }); - - if (!response.ok) { - throw new Error(`Erreur HTTP: ${response.status}`); + if(user.type == "Administrateur" || user.type == "DR"){ + // const response = await fetch(`/api/accounts/delete/?id=${user.id}`, { + // method: 'DELETE', + // headers: { + // 'Content-Type': 'application/json', + // }, + // }); + + // if (!response.ok) { + // throw new Error(`Erreur HTTP: ${response.status}`); + // } + + // const result = await response.json(); + // const unlog = await fetch('/api/logout') + + // window.location.href = "/" + } else { + const response = await fetch(`/api/users/delete/?id=${user.id}`, { + method: 'DELETE', + headers: { + 'Content-Type': 'application/json', + }, + }); + + if (!response.ok) { + throw new Error(`Erreur HTTP: ${response.status}`); + } + + const result = await response.json(); + const unlog = await fetch('/api/logout') + + window.location.href = "/" } - - const result = await response.json(); - const unlog = await fetch('/api/logout') - - window.location.href = "/" } catch (error) { console.error('Erreur lors de la suppression de la session:', error.message); @@ -115,16 +159,26 @@ export default function Profil({ user }){ <>
    Vos informations personnelles -
    -
    - - -
    -
    - - -
    -
    + {user.type != "Administrateur" && user.type != "DR" ? ( + <> +
    +
    + + +
    +
    + + +
    +
    + + ) : ( +
    +
    + +
    +
    + )} Vous souhaitez modifier votre mot de passe ?
    diff --git a/components/RencontreDetail.jsx b/components/RencontreDetail.jsx index acdd807..9099138 100644 --- a/components/RencontreDetail.jsx +++ b/components/RencontreDetail.jsx @@ -198,6 +198,8 @@ export default function RencontreDetail({ id, setOpen, userId, user }) { return; } + const typeUser = user.type == "Administrateur" || user.type == "DR" ? "special" : "user" + const response = await fetch('/api/satisfaction/add', { method: 'POST', headers: { @@ -206,7 +208,8 @@ export default function RencontreDetail({ id, setOpen, userId, user }) { body: JSON.stringify({ userId: userId, sessionId: data.id, - responses: responses + responses: responses, + type: typeUser }), }); @@ -240,6 +243,7 @@ export default function RencontreDetail({ id, setOpen, userId, user }) { const registerReview = async () => { setAlert(null); + const typeUser = user.type == "Administrateur" || user.type == "DR" ? "special" : "user" const fetcher = await fetch('/api/reviews/add', { method: 'POST', headers: { @@ -250,6 +254,7 @@ export default function RencontreDetail({ id, setOpen, userId, user }) { commentaire: commentaires, userId: userId, sessionId: data.id, + type: typeUser }), }); const json = await fetcher.json(); @@ -278,21 +283,39 @@ export default function RencontreDetail({ id, setOpen, userId, user }) { }; const checkReview = async () => { - const fetcher = await fetch(`/api/reviews/check?userId=${userId}&sessionId=${data.id}`); - const json = await fetcher.json(); - setReviewDisabled(true); - if (json.length > 0) { - setRating(json[0].note); - setCommentaires(json[0].commentaire); + if(user.type == "Administrateur" || user.type == "DR") { + const fetcher = await fetch(`/api/reviews/check?userId=${userId}&sessionId=${data.id}&specialAccount=true`); + const json = await fetcher.json(); + setReviewDisabled(true); + if (json.length > 0) { + setRating(json[0].note); + setCommentaires(json[0].commentaire); + } else { + setReviewDisabled(false); + } } else { - setReviewDisabled(false); + const fetcher = await fetch(`/api/reviews/check?userId=${userId}&sessionId=${data.id}`); + const json = await fetcher.json(); + setReviewDisabled(true); + if (json.length > 0) { + setRating(json[0].note); + setCommentaires(json[0].commentaire); + } else { + setReviewDisabled(false); + } } }; const checkSatisfaction = async () => { - const fetcher = await fetch(`/api/satisfaction/checkSatisfaction?userId=${userId}&sessionId=${data.id}`); - const json = await fetcher.json(); - setHasResponded(json.hasResponded); + if(user.type == "Administrateur" || user.type == "DR"){ + const fetcher = await fetch(`/api/satisfaction/checkSatisfaction?userId=${userId}&sessionId=${data.id}&specialAccount=true`); + const json = await fetcher.json(); + setHasResponded(json.hasResponded); + } else { + const fetcher = await fetch(`/api/satisfaction/checkSatisfaction?userId=${userId}&sessionId=${data.id}`); + const json = await fetcher.json(); + setHasResponded(json.hasResponded); + } }; useEffect(() => { @@ -321,12 +344,21 @@ export default function RencontreDetail({ id, setOpen, userId, user }) { useEffect(() => { if (user) { - const getUserIn = async () => { - const fetcher = await fetch(`/api/users/${user.id}`); - const json = await fetcher.json(); - setUserData(json[0]); - }; - getUserIn(); + if(user.type == "Administrateur" || user.type == "DR"){ + const getUserIn = async () => { + const fetcher = await fetch(`/api/accounts/${user.id}`); + const json = await fetcher.json(); + setUserData(json[0]); + }; + getUserIn(); + } else { + const getUserIn = async () => { + const fetcher = await fetch(`/api/users/${user.id}`); + const json = await fetcher.json(); + setUserData(json[0]); + }; + getUserIn(); + } } }, [user]); @@ -370,18 +402,35 @@ export default function RencontreDetail({ id, setOpen, userId, user }) { }; const cancel = async () => { - const fetcher = await fetch('/api/registrations/cancel', { - method: 'POST', - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - userId: userId, - sessionId: id, - }), - }); - const json = await fetcher.json(); - setOpen(null); + if(user.type == "Administrateur" || user.type == "DR"){ + const fetcher = await fetch('/api/registrations/cancel', { + method: 'POST', + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + userId: userId, + sessionId: id, + type: "special" + }), + }); + const json = await fetcher.json(); + setOpen(null); + } else { + const fetcher = await fetch('/api/registrations/cancel', { + method: 'POST', + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + userId: userId, + sessionId: id, + type: "user" + }), + }); + const json = await fetcher.json(); + setOpen(null); + } }; const transformLinks = (html) => { diff --git a/components/Rencontres.jsx b/components/Rencontres.jsx index c4c374e..b421346 100644 --- a/components/Rencontres.jsx +++ b/components/Rencontres.jsx @@ -14,11 +14,19 @@ export default function Rencontres({ user }){ const getUserSessions = async () => { - setLoad(true) - const fetcher = await fetch(`/api/registrations/byUser/?userId=${user.id}&status=${status}`) - const json = await fetcher.json() - setRencontres(json) - setLoad(false) + if(user.type == "Administrateur" || user.type == "DR"){ + setLoad(true) + const fetcher = await fetch(`/api/registrations/byUser/?userId=${user.id}&status=${status}&specialAccount=true`) + const json = await fetcher.json() + setRencontres(json) + setLoad(false) + } else { + setLoad(true) + const fetcher = await fetch(`/api/registrations/byUser/?userId=${user.id}&status=${status}`) + const json = await fetcher.json() + setRencontres(json) + setLoad(false) + } } useEffect(() => { diff --git a/components/Reviews.jsx b/components/Reviews.jsx index 4857456..525efae 100644 --- a/components/Reviews.jsx +++ b/components/Reviews.jsx @@ -116,7 +116,7 @@ export default function Reviews({ session, setOpen }){ Participant - {question.User.nom} {question.User.prenom} + {question.User.nom || question.Account.email} {question.User.prenom || question.Account.type} {Object.entries(responses).map(([questionId, response], idx) => ( diff --git a/pages/api/accounts/[id].js b/pages/api/accounts/[id].js new file mode 100644 index 0000000..a25d77c --- /dev/null +++ b/pages/api/accounts/[id].js @@ -0,0 +1,17 @@ +import prisma from '@/prisma' + +export default async function handle(req, res) { + const { id } = req.query; + + let queryOptions = {} + + if (id) { + queryOptions.where = { + id: parseInt(id), + }; + } + + const user = await prisma.account.findMany(queryOptions); + + res.json(user); +} diff --git a/pages/api/emails/toParticipants.js b/pages/api/emails/toParticipants.js index 021c3f4..2478b01 100644 --- a/pages/api/emails/toParticipants.js +++ b/pages/api/emails/toParticipants.js @@ -8,18 +8,33 @@ const prisma = new PrismaClient(); export default async function handler(req, res) { const { sujet, content, sessionId } = req.body; - // Récupérer les emails des participants à la session try { + // Récupérer les inscriptions des utilisateurs standards const registrations = await prisma.registration.findMany({ where: { - sessionId: sessionId, + sessionId: parseInt(sessionId), }, include: { - user: true, // Assuming there's a relation to a user table containing email + user: true, // Relation avec la table user pour obtenir l'email }, }); - const emails = registrations.map(registration => registration.user.mail); + // Récupérer les inscriptions des comptes spéciaux + const accountRegistrations = await prisma.accountRegistration.findMany({ + where: { + sessionId: parseInt(sessionId), + }, + include: { + account: true, // Relation avec la table account pour obtenir l'email + }, + }); + + // Extraire les emails des utilisateurs standards et des comptes spéciaux + const userEmails = registrations.map(registration => registration.user.mail); + const accountEmails = accountRegistrations.map(registration => registration.account.email); + + // Combiner les deux listes d'emails + const emails = [...userEmails, ...accountEmails]; const transporter = nodemailer.createTransport({ host: 'smtp-relay.brevo.com', diff --git a/pages/api/registrations/add.js b/pages/api/registrations/add.js index 6e44ea5..66c979e 100644 --- a/pages/api/registrations/add.js +++ b/pages/api/registrations/add.js @@ -8,15 +8,11 @@ export default async function handle(req, res) { return; } - const { inscriptionData, userId, sessionId } = req.body; + const { inscriptionData, userId, sessionId, type } = req.body; try { const now = new Date(); - const userData = await prisma.user.findUnique({ - where: { id: parseInt(userId) }, - }); - const sessionData = await prisma.session.findUnique({ where: { id: parseInt(sessionId) }, include: { @@ -25,18 +21,48 @@ export default async function handle(req, res) { } }); - const newRegistration = await prisma.registration.create({ - data: { - ...inscriptionData, - deleted: false, - user: { - connect: { id: parseInt(userId) }, - }, - session: { - connect: { id: parseInt(sessionId) }, + let userData; + let newRegistration; + + if (type === 'special') { + // Récupération des données du compte pour type "special" + userData = await prisma.account.findUnique({ + where: { id: parseInt(userId) }, + }); + + // Création de l'inscription dans accountRegistration + newRegistration = await prisma.accountRegistration.create({ + data: { + ...inscriptionData, + deleted: false, + account: { + connect: { id: parseInt(userId) }, + }, + session: { + connect: { id: parseInt(sessionId) }, + } } - } - }); + }); + } else { + // Récupération des données de l'utilisateur pour les types autres que "special" + userData = await prisma.user.findUnique({ + where: { id: parseInt(userId) }, + }); + + // Création de l'inscription dans registration + newRegistration = await prisma.registration.create({ + data: { + ...inscriptionData, + deleted: false, + user: { + connect: { id: parseInt(userId) }, + }, + session: { + connect: { id: parseInt(sessionId) }, + } + } + }); + } const firstProgramme = sessionData.metasSession.programmeSession[0]; let firstDayStartTime; @@ -54,32 +80,61 @@ export default async function handle(req, res) { year: 'numeric', }); - const emailResponse = await fetch(`${process.env.WEBSITE_URL}/api/emails/sessionRegister`, { - method: 'POST', - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - prenom: userData.prenom, - email: userData.mail, - nomRencontre: sessionData.module.nom, - dateRencontre: formattedDateDebut, - lieuRencontre: sessionData.metasSession.lieuRencontre || 'Lieu', - nbJours: sessionData.metasSession.nombreJours, - mail_referent: sessionData.metasSession.mail_referent, - firstDayStartTime: firstDayStartTime - }) - }); - - - if (!emailResponse.ok) { - throw new Error(`Email request failed with status ${emailResponse.status}`); + if(type == "special"){ + const emailResponse = await fetch(`${process.env.WEBSITE_URL}/api/emails/sessionRegister`, { + method: 'POST', + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + prenom: inscriptionData.prenom, + email: userData.email, + nomRencontre: sessionData.module.nom, + dateRencontre: formattedDateDebut, + lieuRencontre: sessionData.metasSession.lieuRencontre || 'Lieu', + nbJours: sessionData.metasSession.nombreJours, + mail_referent: sessionData.metasSession.mail_referent, + firstDayStartTime: firstDayStartTime + }) + }); + + if (!emailResponse.ok) { + throw new Error(`Email request failed with status ${emailResponse.status}`); + } + + res.json({ + registration: newRegistration, + session: sessionData + }); + } + else{ + const emailResponse = await fetch(`${process.env.WEBSITE_URL}/api/emails/sessionRegister`, { + method: 'POST', + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + prenom: userData.prenom, + email: userData.mail, + nomRencontre: sessionData.module.nom, + dateRencontre: formattedDateDebut, + lieuRencontre: sessionData.metasSession.lieuRencontre || 'Lieu', + nbJours: sessionData.metasSession.nombreJours, + mail_referent: sessionData.metasSession.mail_referent, + firstDayStartTime: firstDayStartTime + }) + }); + + if (!emailResponse.ok) { + throw new Error(`Email request failed with status ${emailResponse.status}`); + } + + res.json({ + registration: newRegistration, + session: sessionData + }); } - res.json({ - registration: newRegistration, - session: sessionData - }); } catch (error) { console.error("Error creating registration: ", error); res.status(500).json({ error: `Impossible de créer l'enregistrement : ${error.message}` }); diff --git a/pages/api/registrations/bySession.js b/pages/api/registrations/bySession.js index 404adce..b534f0c 100644 --- a/pages/api/registrations/bySession.js +++ b/pages/api/registrations/bySession.js @@ -6,6 +6,7 @@ export default async function handle(req, res) { const parsedSessionId = parseInt(sessionId); try { + // Requête pour récupérer les registrations (utilisateurs) const registrations = await prisma.registration.findMany({ where: { sessionId: parsedSessionId, @@ -14,14 +15,43 @@ export default async function handle(req, res) { session: { include: { reviews: true, - metasSession: true - } + metasSession: true, + }, }, - user: true + user: true, }, }); - res.json(registrations); + // Requête pour récupérer les accountRegistrations (administrateurs/DR) + const accountRegistrations = await prisma.accountRegistration.findMany({ + where: { + sessionId: parsedSessionId, + }, + include: { + session: { + include: { + reviews: true, + metasSession: true, + }, + }, + account: true, // Include the account data associated with the registration + }, + }); + + // Combiner les deux résultats + const combinedRegistrations = [ + ...registrations.map(registration => ({ + ...registration, + type: 'userRegistration', // Pour différencier les types + })), + ...accountRegistrations.map(accountRegistration => ({ + ...accountRegistration, + type: 'accountRegistration', // Pour différencier les types + })), + ]; + + // Retourner la réponse avec les données combinées + res.json(combinedRegistrations); } catch (error) { console.error(error); res.status(500).json({ error: 'Une erreur est survenue lors de la récupération des inscriptions' }); diff --git a/pages/api/registrations/byUser.js b/pages/api/registrations/byUser.js index 48b9e74..c3209d0 100644 --- a/pages/api/registrations/byUser.js +++ b/pages/api/registrations/byUser.js @@ -1,7 +1,7 @@ import prisma from '@/prisma'; export default async function handle(req, res) { - const { userId, status } = req.query; + const { userId, status, specialAccount } = req.query; let dateCondition = {}; let now = new Date(); @@ -24,22 +24,31 @@ export default async function handle(req, res) { let queryOptions = { where: { - userId: parseInt(userId), - // Supposons ici que chaque inscription a une session directement liée + deleted: false, session: dateCondition, - deleted: false }, include: { session: { include: { - module: true // Inclure le module via la session - } + module: true, // Inclure le module via la session + }, }, }, }; + // Modifier la requête en fonction de specialAccount + if (specialAccount === 'true') { + queryOptions.where.accountId = parseInt(userId); // Utiliser accountId si specialAccount est vrai + } else { + queryOptions.where.userId = parseInt(userId); // Utiliser userId sinon + } + try { - const registrations = await prisma.registration.findMany(queryOptions); + // Exécution de la requête en fonction de l'utilisateur ou du compte + const registrations = specialAccount === 'true' + ? await prisma.accountRegistration.findMany(queryOptions) + : await prisma.registration.findMany(queryOptions); + res.json(registrations); } catch (error) { console.error(error); diff --git a/pages/api/registrations/byUserSession.js b/pages/api/registrations/byUserSession.js index 887a063..7b1c1e4 100644 --- a/pages/api/registrations/byUserSession.js +++ b/pages/api/registrations/byUserSession.js @@ -1,20 +1,38 @@ import prisma from '@/prisma'; export default async function handle(req, res) { - const { userId, sessionId } = req.query; + const { userId, sessionId, specialAccount } = req.query; - let queryOptions = { - where: { - userId: parseInt(userId), - sessionId: parseInt(sessionId) + if(specialAccount){ + let queryOptions = { + where: { + accountId: parseInt(userId), + sessionId: parseInt(sessionId) + } + }; + + try { + const registrations = await prisma.accountRegistration.findMany(queryOptions); + res.json(registrations); + } catch (error) { + console.error(error); + res.status(500).json({ error: 'Une erreur est survenue lors de la récupération des modules' }); + } + } else { + let queryOptions = { + where: { + userId: parseInt(userId), + sessionId: parseInt(sessionId) + } + }; + + try { + const registrations = await prisma.registration.findMany(queryOptions); + res.json(registrations); + } catch (error) { + console.error(error); + res.status(500).json({ error: 'Une erreur est survenue lors de la récupération des modules' }); } - }; - - try { - const registrations = await prisma.registration.findMany(queryOptions); - res.json(registrations); - } catch (error) { - console.error(error); - res.status(500).json({ error: 'Une erreur est survenue lors de la récupération des modules' }); } + } diff --git a/pages/api/registrations/cancel.js b/pages/api/registrations/cancel.js index 51a3de0..eb3b488 100644 --- a/pages/api/registrations/cancel.js +++ b/pages/api/registrations/cancel.js @@ -7,7 +7,7 @@ export default async function handle(req, res) { return; } - const { userId, sessionId } = req.body; + const { userId, sessionId, type } = req.body; if (!userId || !sessionId) { return res.status(400).send("userId et sessionId sont requis."); @@ -22,25 +22,51 @@ export default async function handle(req, res) { } try { - const registration = await prisma.registration.findFirst({ - where: { - userId: parsedUserId, - sessionId: parsedSessionId - } - }); - - if (registration) { - const updatedRegistration = await prisma.registration.update({ + let registration; + if (type === 'special') { + // Recherche et suppression dans accountRegistration + registration = await prisma.accountRegistration.findFirst({ where: { - id: registration.id - }, - data: { - deleted: true + accountId: parsedUserId, + sessionId: parsedSessionId } }); - res.json(updatedRegistration); + + if (registration) { + const updatedRegistration = await prisma.accountRegistration.update({ + where: { + id: registration.id + }, + data: { + deleted: true + } + }); + res.json(updatedRegistration); + } else { + res.status(404).send("Account registration not found."); + } } else { - res.status(404).send("Registration not found."); + // Recherche et suppression dans registration + registration = await prisma.registration.findFirst({ + where: { + userId: parsedUserId, + sessionId: parsedSessionId + } + }); + + if (registration) { + const updatedRegistration = await prisma.registration.update({ + where: { + id: registration.id + }, + data: { + deleted: true + } + }); + res.json(updatedRegistration); + } else { + res.status(404).send("Registration not found."); + } } } catch (error) { console.error("Erreur lors de la mise à jour de la session:", error.message); diff --git a/pages/api/registrations/delete.js b/pages/api/registrations/delete.js index f0c0ed3..8d72963 100644 --- a/pages/api/registrations/delete.js +++ b/pages/api/registrations/delete.js @@ -7,17 +7,31 @@ export default async function handle(req, res) { return; } - const { userId, sessionId } = req.query; + const { userId, sessionId, specialAccount } = req.query; - try { + if(specialAccount){ + try { - await prisma.registration.deleteMany({ - where: { userId: parseInt(userId), sessionId: parseInt(sessionId) }, - }); + await prisma.accountRegistration.deleteMany({ + where: { accountId: parseInt(userId), sessionId: parseInt(sessionId) }, + }); + + res.json({ message: 'User supprimé avec succès' }); + } catch (error) { + console.error(error); + res.status(500).json({ error: `Impossible de supprimer le user : ${error.message}` }); + } + } else { + try { - res.json({ message: 'User supprimé avec succès' }); - } catch (error) { - console.error(error); - res.status(500).json({ error: `Impossible de supprimer le user : ${error.message}` }); + await prisma.registration.deleteMany({ + where: { userId: parseInt(userId), sessionId: parseInt(sessionId) }, + }); + + res.json({ message: 'User supprimé avec succès' }); + } catch (error) { + console.error(error); + res.status(500).json({ error: `Impossible de supprimer le user : ${error.message}` }); + } } } diff --git a/pages/api/registrations/updatePresence.js b/pages/api/registrations/updatePresence.js index 04a2864..12db6ce 100644 --- a/pages/api/registrations/updatePresence.js +++ b/pages/api/registrations/updatePresence.js @@ -1,22 +1,39 @@ -// pages/api/registrations/updatePresence.js import { PrismaClient } from '@prisma/client'; const prisma = new PrismaClient(); export default async function handler(req, res) { if (req.method === 'PUT') { - const { userId, sessionId, presence } = req.body; + const { userId, accountId, sessionId, presence } = req.body; try { - const updatedRegistration = await prisma.registration.updateMany({ - where: { - userId: userId, - sessionId: sessionId, - }, - data: { - presence: presence, - }, - }); + let updatedRegistration; + + if (userId) { + // Mettre à jour dans la table registration pour les utilisateurs standards + updatedRegistration = await prisma.registration.updateMany({ + where: { + userId: parseInt(userId), + sessionId: parseInt(sessionId), + }, + data: { + presence: presence, + }, + }); + } else if (accountId) { + // Mettre à jour dans la table accountRegistration pour les comptes spéciaux + updatedRegistration = await prisma.accountRegistration.updateMany({ + where: { + accountId: parseInt(accountId), + sessionId: parseInt(sessionId), + }, + data: { + presence: presence, + }, + }); + } else { + return res.status(400).json({ message: 'Either userId or accountId is required' }); + } if (updatedRegistration.count === 0) { return res.status(404).json({ message: 'Registration not found' }); diff --git a/pages/api/reviews/add.js b/pages/api/reviews/add.js index 35dbbb9..fdd1263 100644 --- a/pages/api/reviews/add.js +++ b/pages/api/reviews/add.js @@ -9,7 +9,7 @@ export default async function handle(req, res) { } // Extraire les données reçues du corps de la requête - const { note, commentaire, userId, sessionId } = req.body; + const { note, commentaire, userId, sessionId, type } = req.body; // Valider les données reçues if (!note || !commentaire || !userId || !sessionId) { @@ -18,15 +18,29 @@ export default async function handle(req, res) { } try { - // Créer la nouvelle review - const newReview = await prisma.review.create({ - data: { - note, - commentaire, - userId, - sessionId - } - }); + let newReview; + + if (type === 'special') { + // Créer une nouvelle review dans AccountReview si le type est "special" + newReview = await prisma.accountReview.create({ + data: { + note, + commentaire, + accountId: userId, // Utiliser accountId au lieu de userId + sessionId + } + }); + } else { + // Créer une nouvelle review dans Review pour tous les autres types + newReview = await prisma.review.create({ + data: { + note, + commentaire, + userId, + sessionId + } + }); + } // Retourner la review créée res.status(201).json(newReview); diff --git a/pages/api/reviews/bySession.js b/pages/api/reviews/bySession.js index c66b25f..2e9ef34 100644 --- a/pages/api/reviews/bySession.js +++ b/pages/api/reviews/bySession.js @@ -6,18 +6,41 @@ export default async function handle(req, res) { const parsedSessionId = parseInt(sessionId); try { - const reviews = await prisma.review.findMany({ + // Requête pour récupérer les reviews des utilisateurs + const userReviews = await prisma.review.findMany({ where: { sessionId: parsedSessionId, }, include: { - user: true - } + user: true, // Inclure les informations de l'utilisateur + }, }); - res.json(reviews); + // Requête pour récupérer les reviews des comptes spéciaux + const accountReviews = await prisma.accountReview.findMany({ + where: { + sessionId: parsedSessionId, + }, + include: { + account: true, // Inclure les informations du compte + }, + }); + + // Combiner les deux résultats + const combinedReviews = [ + ...userReviews.map((review) => ({ + ...review, + type: 'userReview', // Indiquer qu'il s'agit d'une review d'utilisateur + })), + ...accountReviews.map((review) => ({ + ...review, + type: 'accountReview', // Indiquer qu'il s'agit d'une review de compte + })), + ]; + + res.json(combinedReviews); } catch (error) { console.error(error); - res.status(500).json({ error: 'Une erreur est survenue lors de la récupération des inscriptions' }); + res.status(500).json({ error: 'Une erreur est survenue lors de la récupération des reviews' }); } } diff --git a/pages/api/reviews/check.js b/pages/api/reviews/check.js index f7b71ae..274fa10 100644 --- a/pages/api/reviews/check.js +++ b/pages/api/reviews/check.js @@ -1,18 +1,36 @@ import prisma from '@/prisma' export default async function handle(req, res) { - const { userId, sessionId } = req.query; + const { userId, sessionId, specialAccount } = req.query; let queryOptions = {}; - if (userId && sessionId) { - queryOptions.where = { - userId: parseInt(userId), - sessionId: parseInt(sessionId) - }; - } + if(specialAccount){ + + if (userId && sessionId) { + queryOptions.where = { + accountId: parseInt(userId), + sessionId: parseInt(sessionId) + }; + } + + const review = await prisma.accountReview.findMany(queryOptions); + + res.json(review); + + } else { - const review = await prisma.review.findMany(queryOptions); + if (userId && sessionId) { + queryOptions.where = { + userId: parseInt(userId), + sessionId: parseInt(sessionId) + }; + } + + const review = await prisma.review.findMany(queryOptions); + + res.json(review); + + } - res.json(review); } diff --git a/pages/api/satisfaction/add.js b/pages/api/satisfaction/add.js index 878a544..e0cde3d 100644 --- a/pages/api/satisfaction/add.js +++ b/pages/api/satisfaction/add.js @@ -13,17 +13,32 @@ function serializeBigIntFields(data) { export default async function handler(req, res) { if (req.method === 'POST') { - const { userId, sessionId, responses } = req.body; + const { userId, sessionId, responses, type } = req.body; try { - console.log('Creating new satisfaction with data:', { userId, sessionId, responses }); - const newSatisfaction = await prisma.satisfaction.create({ - data: { - userId: userId ? parseInt(userId) : null, - sessionId: sessionId ? parseInt(sessionId) : null, - responses: responses ? responses : null, - }, - }); + console.log('Creating new satisfaction with data:', { userId, sessionId, responses, type }); + + let newSatisfaction; + + if (type === 'special') { + // Création dans accountSatisfaction si type == "special" + newSatisfaction = await prisma.accountSatisfaction.create({ + data: { + accountId: userId ? parseInt(userId) : null, + sessionId: sessionId ? parseInt(sessionId) : null, + responses: responses ? responses : null, + }, + }); + } else { + // Création dans satisfaction pour tous les autres types + newSatisfaction = await prisma.satisfaction.create({ + data: { + userId: userId ? parseInt(userId) : null, + sessionId: sessionId ? parseInt(sessionId) : null, + responses: responses ? responses : null, + }, + }); + } // Utilisez la fonction serializeBigIntFields pour convertir correctement les BigInt res.status(201).json(serializeBigIntFields(newSatisfaction)); diff --git a/pages/api/satisfaction/checkSatisfaction.js b/pages/api/satisfaction/checkSatisfaction.js index e921b13..dac56be 100644 --- a/pages/api/satisfaction/checkSatisfaction.js +++ b/pages/api/satisfaction/checkSatisfaction.js @@ -4,24 +4,44 @@ const prisma = new PrismaClient(); export default async function handler(req, res) { if (req.method === 'GET') { - const { userId, sessionId } = req.query; + const { userId, sessionId, specialAccount } = req.query; - try { - const satisfaction = await prisma.satisfaction.findFirst({ - where: { - userId: parseInt(userId), - sessionId: parseInt(sessionId), - }, - }); - if (satisfaction) { - res.status(200).json({ hasResponded: true }); - } else { - res.status(200).json({ hasResponded: false }); + if(specialAccount){ + try { + const satisfaction = await prisma.accountSatisfaction.findFirst({ + where: { + accountId: parseInt(userId), + sessionId: parseInt(sessionId), + }, + }); + if (satisfaction) { + res.status(200).json({ hasResponded: true }); + } else { + res.status(200).json({ hasResponded: false }); + } + } catch (error) { + console.error('Error checking satisfaction:', error); + res.status(500).json({ error: 'Erreur lors de la vérification de la satisfaction.' }); + } + } else { + try { + const satisfaction = await prisma.satisfaction.findFirst({ + where: { + userId: parseInt(userId), + sessionId: parseInt(sessionId), + }, + }); + if (satisfaction) { + res.status(200).json({ hasResponded: true }); + } else { + res.status(200).json({ hasResponded: false }); + } + } catch (error) { + console.error('Error checking satisfaction:', error); + res.status(500).json({ error: 'Erreur lors de la vérification de la satisfaction.' }); } - } catch (error) { - console.error('Error checking satisfaction:', error); - res.status(500).json({ error: 'Erreur lors de la vérification de la satisfaction.' }); } + } else { res.setHeader('Allow', ['GET']); res.status(405).end(`Method ${req.method} Not Allowed`); diff --git a/pages/api/satisfaction/fromSession.js b/pages/api/satisfaction/fromSession.js index 76cf9fc..6c67d08 100644 --- a/pages/api/satisfaction/fromSession.js +++ b/pages/api/satisfaction/fromSession.js @@ -16,6 +16,7 @@ export default async function handler(req, res) { const { sessionId } = req.query; try { + // Récupération des satisfactions des utilisateurs const satisfaction = await prisma.satisfaction.findMany({ where: { sessionId: sessionId ? parseInt(sessionId) : undefined, @@ -29,13 +30,37 @@ export default async function handler(req, res) { }, }, }); - if (satisfaction) { - // Utilisez la fonction serializeBigIntFields pour convertir correctement les BigInt - res.status(200).json(serializeBigIntFields(satisfaction)); - } else { - res.status(404).json({ error: 'Satisfaction non trouvée.' }); - } - } catch (error) { + + // Récupération des satisfactions des comptes spéciaux + const accountSatisfaction = await prisma.accountSatisfaction.findMany({ + where: { + sessionId: sessionId ? parseInt(sessionId) : undefined, + }, + include: { + Account: { + select: { + email: true, + type: true, + }, + }, + }, + }); + + // Combinaison des résultats + const combinedSatisfaction = [ + ...satisfaction.map(item => ({ + ...item, + source: 'user', // Identifier la source de la satisfaction + })), + ...accountSatisfaction.map(item => ({ + ...item, + source: 'account', // Identifier la source de la satisfaction + })), + ]; + + // Utilisation de la fonction serializeBigIntFields pour convertir correctement les BigInt + res.status(200).json(serializeBigIntFields(combinedSatisfaction)); + } catch (error) { console.error('Error fetching satisfaction:', error); res.status(500).json({ error: 'Erreur lors de la récupération de la satisfaction.' }); } diff --git a/pages/api/satisfaction/getSatisfaction.js b/pages/api/satisfaction/getSatisfaction.js index f53e52e..c0d83b4 100644 --- a/pages/api/satisfaction/getSatisfaction.js +++ b/pages/api/satisfaction/getSatisfaction.js @@ -13,15 +13,29 @@ function serializeBigIntFields(data) { export default async function handler(req, res) { if (req.method === 'GET') { - const { userId, sessionId } = req.query; + const { userId, sessionId, type } = req.query; try { - const satisfaction = await prisma.satisfaction.findFirst({ - where: { - userId: userId ? parseInt(userId) : undefined, - sessionId: sessionId ? parseInt(sessionId) : undefined, - }, - }); + let satisfaction; + + if (type === 'special') { + // Recherche dans la table accountSatisfaction si type == "special" + satisfaction = await prisma.accountSatisfaction.findFirst({ + where: { + accountId: userId ? parseInt(userId) : undefined, + sessionId: sessionId ? parseInt(sessionId) : undefined, + }, + }); + } else { + // Recherche dans la table satisfaction pour tous les autres types + satisfaction = await prisma.satisfaction.findFirst({ + where: { + userId: userId ? parseInt(userId) : undefined, + sessionId: sessionId ? parseInt(sessionId) : undefined, + }, + }); + } + if (satisfaction) { // Utilisez la fonction serializeBigIntFields pour convertir correctement les BigInt res.status(200).json(serializeBigIntFields(satisfaction)); diff --git a/pages/presence.js b/pages/presence.js index 154d68d..1906426 100644 --- a/pages/presence.js +++ b/pages/presence.js @@ -45,14 +45,14 @@ export default function Presence() { setFiche(0); }; - const updatePresence = async (userId, sessionId, isPresent) => { + const updatePresence = async (id, sessionId, isPresent, idType) => { const response = await fetch(`/api/registrations/updatePresence`, { method: 'PUT', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ - userId, + [idType]: id, // Envoyer soit userId soit accountId sessionId, presence: isPresent, }), @@ -63,9 +63,9 @@ export default function Presence() { } }; - const handleCheckboxChange = (userId, sessionId, event) => { + const handleCheckboxChange = (id, sessionId, idType, event) => { const isPresent = event.target.checked; - updatePresence(userId, sessionId, isPresent); + updatePresence(id, sessionId, isPresent, idType); // Passer le type d'ID }; useEffect(() => { @@ -141,6 +141,8 @@ export default function Presence() { {filteredUsers.length > 0 ? ( <> {filteredUsers.map((u, i) => { + const idType = u.userId ? 'userId' : 'accountId'; // Identifier le type d'ID + const id = u.userId || u.accountId; // Récupérer l'ID correct return (
    @@ -151,10 +153,10 @@ export default function Presence() { type="checkbox" name="participe" defaultChecked={u.presence} - onChange={(e) => handleCheckboxChange(u.userId, fiche, e)} + onChange={(e) => handleCheckboxChange(id, fiche, idType, e)} // Passer l'ID et le type d'ID />
    - ) + ); })} ) : ( diff --git a/pages/rencontres/[category]/[session].js b/pages/rencontres/[category]/[session].js index 81451f3..f1adeae 100644 --- a/pages/rencontres/[category]/[session].js +++ b/pages/rencontres/[category]/[session].js @@ -122,6 +122,8 @@ export default function Session({ data, user }){ days: inscription.days } + const userType = user.type == "Administrateur" || user.type == "DR" ? "special" : "user" + const registering = await fetch('/api/registrations/add', { method: 'POST', headers: { @@ -130,7 +132,8 @@ export default function Session({ data, user }){ body: JSON.stringify({ inscriptionData: inscriptionData, userId: inscription.userId, - sessionId: data.id + sessionId: data.id, + type: userType }) }) @@ -213,20 +216,33 @@ export default function Session({ data, user }){ useEffect(() => { const getUserInfo = async () => { - const fetcher = await fetch(`/api/users/${user.id}`) - const json = await fetcher.json() - let userDetail = await json[0] - setInscription(prev => { - return { - ...prev, - userId: userDetail.id, - nom: userDetail.nom, - prenom: userDetail.prenom, - mail: userDetail.mail, - telephone: userDetail.telephone, - fonction:userDetail.fonction - } - }) + if(user.type == "Administrateur" || user.type == "DR"){ + const fetcher = await fetch(`/api/accounts/${user.id}`) + const json = await fetcher.json() + let userDetail = await json[0] + setInscription(prev => { + return { + ...prev, + userId: userDetail.id, + mail: userDetail.email, + } + }) + } else { + const fetcher = await fetch(`/api/users/${user.id}`) + const json = await fetcher.json() + let userDetail = await json[0] + setInscription(prev => { + return { + ...prev, + userId: userDetail.id, + nom: userDetail.nom, + prenom: userDetail.prenom, + mail: userDetail.mail, + telephone: userDetail.telephone, + fonction:userDetail.fonction + } + }) + } } if(user != null){ @@ -253,15 +269,28 @@ export default function Session({ data, user }){ } useEffect(() => { - const checker = async () => { - const fetcher = await fetch(`/api/registrations/byUserSession?userId=${user.id}&sessionId=${data.id}`) - const json = await fetcher.json() - if(json.length > 0 && json[0].deleted == false){ - setCheck(true) + if(user.type == "Administrateur" || user.type == "DR"){ + const checker = async () => { + const fetcher = await fetch(`/api/registrations/byUserSession?userId=${user.id}&sessionId=${data.id}&specialAccount=true`) + const json = await fetcher.json() + if(json.length > 0 && json[0].deleted == false){ + setCheck(true) + } + } + if(user != null){ + checker() + } + } else { + const checker = async () => { + const fetcher = await fetch(`/api/registrations/byUserSession?userId=${user.id}&sessionId=${data.id}`) + const json = await fetcher.json() + if(json.length > 0 && json[0].deleted == false){ + setCheck(true) + } + } + if(user != null){ + checker() } - } - if(user != null){ - checker() } }, [data, alert, user]) @@ -353,7 +382,6 @@ export default function Session({ data, user }){ const groupedData = groupByDay(data.metasSession.programmeSession); - console.log(data) return ( <> diff --git a/prisma/schema.prisma b/prisma/schema.prisma index 39699e5..76aefd1 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -52,20 +52,23 @@ model User { } model Session { - id Int @id @default(autoincrement()) - dateDebut DateTime - moduleId Int - departement String - region String - datePublication DateTime? - lastUpdate DateTime? - status String - metasSession MetasSession? - registrations Registration[] - reviews Review[] - Satisfaction Satisfaction[] - module Module @relation(fields: [moduleId], references: [id]) - users User[] @relation("UserSessions") + id Int @id @default(autoincrement()) + dateDebut DateTime + moduleId Int + departement String + region String + datePublication DateTime? + lastUpdate DateTime? + status String + accountRegistrations AccountRegistration[] + AccountReview AccountReview[] + AccountSatisfaction AccountSatisfaction[] + metasSession MetasSession? + registrations Registration[] + reviews Review[] + Satisfaction Satisfaction[] + module Module @relation(fields: [moduleId], references: [id]) + users User[] @relation("UserSessions") } model MetasSession { @@ -125,12 +128,15 @@ model Review { } model Account { - id Int @id @default(autoincrement()) @db.SmallInt - email String @unique - password String? - type String? - regions Json? - modules Json? + id Int @id @default(autoincrement()) @db.SmallInt + email String @unique + password String? + type String? + regions Json? + modules Json? + accountRegistrations AccountRegistration[] + AccountReview AccountReview[] + AccountSatisfaction AccountSatisfaction[] } /// This model contains row level security and requires additional setup for migrations. Visit https://pris.ly/d/row-level-security for more info. @@ -143,3 +149,50 @@ model Satisfaction { Session Session? @relation(fields: [sessionId], references: [id], onDelete: NoAction, onUpdate: NoAction) User User? @relation(fields: [userId], references: [id], onDelete: NoAction, onUpdate: NoAction) } + +model AccountRegistration { + id Int @id @default(autoincrement()) + civilite String? + nom String? + prenom String? + mail String? + structure String? + fonction String? + typeFonction String? + ville String? + telephone String? + transport String? + besoins String? + repas Boolean? + accountId Int + sessionId Int + region String? + repas2 Boolean? + days Boolean? + regime String? + deleted Boolean? + hebergement String? + presence Boolean? + account Account @relation(fields: [accountId], references: [id], onDelete: Cascade, onUpdate: NoAction) + session Session @relation(fields: [sessionId], references: [id], onDelete: Cascade, onUpdate: NoAction) +} + +model AccountReview { + id Int @id @default(autoincrement()) + note Int + commentaire String + accountId Int + sessionId Int + Account Account @relation(fields: [accountId], references: [id], onDelete: Cascade, onUpdate: NoAction) + Session Session @relation(fields: [sessionId], references: [id], onDelete: Cascade, onUpdate: NoAction) +} + +model AccountSatisfaction { + id BigInt @id @default(autoincrement()) + accountId Int? + sessionId Int? + created_at DateTime? @default(now()) @db.Timestamptz(6) + responses Json? + Account Account? @relation(fields: [accountId], references: [id], onDelete: NoAction, onUpdate: NoAction) + Session Session? @relation(fields: [sessionId], references: [id], onDelete: NoAction, onUpdate: NoAction) +} From c26ce26cc5128b08c57943050ef9d8174cd800ac Mon Sep 17 00:00:00 2001 From: AntonyKLINGER Date: Wed, 4 Sep 2024 11:11:00 +0200 Subject: [PATCH 039/100] maj type --- pages/rencontres/[category]/[session].js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/pages/rencontres/[category]/[session].js b/pages/rencontres/[category]/[session].js index f1adeae..8fad137 100644 --- a/pages/rencontres/[category]/[session].js +++ b/pages/rencontres/[category]/[session].js @@ -122,7 +122,9 @@ export default function Session({ data, user }){ days: inscription.days } - const userType = user.type == "Administrateur" || user.type == "DR" ? "special" : "user" + const userType = (user.type == "Administrateur" || user.type == "DR") ? "special" : "user" + + console.log("TYPE => ", userType) const registering = await fetch('/api/registrations/add', { method: 'POST', From dbb0d652012f9f51ea380281c844df2c130b1cf5 Mon Sep 17 00:00:00 2001 From: AntonyKLINGER Date: Wed, 4 Sep 2024 11:24:44 +0200 Subject: [PATCH 040/100] maj add js --- pages/api/registrations/add.js | 104 +++++++++++++++------------------ 1 file changed, 48 insertions(+), 56 deletions(-) diff --git a/pages/api/registrations/add.js b/pages/api/registrations/add.js index 66c979e..3062e49 100644 --- a/pages/api/registrations/add.js +++ b/pages/api/registrations/add.js @@ -1,5 +1,5 @@ -import prisma from '@/prisma' -import fetch from 'node-fetch' +import prisma from '@/prisma'; +import fetch from 'node-fetch'; export default async function handle(req, res) { if (req.method !== 'POST') { @@ -11,6 +11,7 @@ export default async function handle(req, res) { const { inscriptionData, userId, sessionId, type } = req.body; try { + console.log("Début de la requête"); const now = new Date(); const sessionData = await prisma.session.findUnique({ @@ -21,6 +22,12 @@ export default async function handle(req, res) { } }); + if (!sessionData) { + throw new Error('Session non trouvée'); + } + + console.log("Session trouvée :", sessionData); + let userData; let newRegistration; @@ -30,6 +37,10 @@ export default async function handle(req, res) { where: { id: parseInt(userId) }, }); + if (!userData) { + throw new Error('Compte non trouvé'); + } + // Création de l'inscription dans accountRegistration newRegistration = await prisma.accountRegistration.create({ data: { @@ -49,6 +60,10 @@ export default async function handle(req, res) { where: { id: parseInt(userId) }, }); + if (!userData) { + throw new Error('Utilisateur non trouvé'); + } + // Création de l'inscription dans registration newRegistration = await prisma.registration.create({ data: { @@ -64,6 +79,8 @@ export default async function handle(req, res) { }); } + console.log("Nouvelle inscription créée :", newRegistration); + const firstProgramme = sessionData.metasSession.programmeSession[0]; let firstDayStartTime; @@ -80,63 +97,38 @@ export default async function handle(req, res) { year: 'numeric', }); - if(type == "special"){ - const emailResponse = await fetch(`${process.env.WEBSITE_URL}/api/emails/sessionRegister`, { - method: 'POST', - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - prenom: inscriptionData.prenom, - email: userData.email, - nomRencontre: sessionData.module.nom, - dateRencontre: formattedDateDebut, - lieuRencontre: sessionData.metasSession.lieuRencontre || 'Lieu', - nbJours: sessionData.metasSession.nombreJours, - mail_referent: sessionData.metasSession.mail_referent, - firstDayStartTime: firstDayStartTime - }) - }); - - if (!emailResponse.ok) { - throw new Error(`Email request failed with status ${emailResponse.status}`); - } - - res.json({ - registration: newRegistration, - session: sessionData - }); - } - else{ - const emailResponse = await fetch(`${process.env.WEBSITE_URL}/api/emails/sessionRegister`, { - method: 'POST', - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - prenom: userData.prenom, - email: userData.mail, - nomRencontre: sessionData.module.nom, - dateRencontre: formattedDateDebut, - lieuRencontre: sessionData.metasSession.lieuRencontre || 'Lieu', - nbJours: sessionData.metasSession.nombreJours, - mail_referent: sessionData.metasSession.mail_referent, - firstDayStartTime: firstDayStartTime - }) - }); - - if (!emailResponse.ok) { - throw new Error(`Email request failed with status ${emailResponse.status}`); - } - - res.json({ - registration: newRegistration, - session: sessionData - }); + // Envoi d'email + const emailResponse = await fetch(`${process.env.WEBSITE_URL}/api/emails/sessionRegister`, { + method: 'POST', + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + prenom: type === 'special' ? inscriptionData.prenom : userData.prenom, + email: type === 'special' ? userData.email : userData.mail, + nomRencontre: sessionData.module.nom, + dateRencontre: formattedDateDebut, + lieuRencontre: sessionData.metasSession.lieuRencontre || 'Lieu', + nbJours: sessionData.metasSession.nombreJours, + mail_referent: sessionData.metasSession.mail_referent, + firstDayStartTime: firstDayStartTime + }) + }); + + if (!emailResponse.ok) { + throw new Error(`Email request failed with status ${emailResponse.status}`); } + console.log("Email envoyé avec succès"); + + res.json({ + registration: newRegistration, + session: sessionData + }); + } catch (error) { - console.error("Error creating registration: ", error); + console.error("Error creating registration:", error.message); + console.error("Stack trace:", error.stack); res.status(500).json({ error: `Impossible de créer l'enregistrement : ${error.message}` }); } } From 73044ec374aeb1b5c5afa93ad0c524dd93258c1e Mon Sep 17 00:00:00 2001 From: AntonyKLINGER Date: Wed, 4 Sep 2024 11:31:07 +0200 Subject: [PATCH 041/100] maj add sans mail --- pages/api/registrations/add.js | 44 +++++++++++++++++----------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/pages/api/registrations/add.js b/pages/api/registrations/add.js index 3062e49..1f5f67d 100644 --- a/pages/api/registrations/add.js +++ b/pages/api/registrations/add.js @@ -98,28 +98,28 @@ export default async function handle(req, res) { }); // Envoi d'email - const emailResponse = await fetch(`${process.env.WEBSITE_URL}/api/emails/sessionRegister`, { - method: 'POST', - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - prenom: type === 'special' ? inscriptionData.prenom : userData.prenom, - email: type === 'special' ? userData.email : userData.mail, - nomRencontre: sessionData.module.nom, - dateRencontre: formattedDateDebut, - lieuRencontre: sessionData.metasSession.lieuRencontre || 'Lieu', - nbJours: sessionData.metasSession.nombreJours, - mail_referent: sessionData.metasSession.mail_referent, - firstDayStartTime: firstDayStartTime - }) - }); - - if (!emailResponse.ok) { - throw new Error(`Email request failed with status ${emailResponse.status}`); - } - - console.log("Email envoyé avec succès"); + // const emailResponse = await fetch(`${process.env.WEBSITE_URL}/api/emails/sessionRegister`, { + // method: 'POST', + // headers: { + // "Content-Type": "application/json", + // }, + // body: JSON.stringify({ + // prenom: type === 'special' ? inscriptionData.prenom : userData.prenom, + // email: type === 'special' ? userData.email : userData.mail, + // nomRencontre: sessionData.module.nom, + // dateRencontre: formattedDateDebut, + // lieuRencontre: sessionData.metasSession.lieuRencontre || 'Lieu', + // nbJours: sessionData.metasSession.nombreJours, + // mail_referent: sessionData.metasSession.mail_referent, + // firstDayStartTime: firstDayStartTime + // }) + // }); + + // if (!emailResponse.ok) { + // throw new Error(`Email request failed with status ${emailResponse.status}`); + // } + + // console.log("Email envoyé avec succès"); res.json({ registration: newRegistration, From b4b6427b881913480d1a1680ed22fd0cb830e995 Mon Sep 17 00:00:00 2001 From: AntonyKLINGER Date: Wed, 4 Sep 2024 11:44:06 +0200 Subject: [PATCH 042/100] maj add --- pages/api/registrations/add.js | 47 +++++++++++++++++----------------- 1 file changed, 23 insertions(+), 24 deletions(-) diff --git a/pages/api/registrations/add.js b/pages/api/registrations/add.js index a04e6db..319b55f 100644 --- a/pages/api/registrations/add.js +++ b/pages/api/registrations/add.js @@ -97,30 +97,29 @@ export default async function handle(req, res) { year: 'numeric', }); - // Envoi d'email - - // const emailResponse = await fetch(`${process.env.WEBSITE_URL}/api/emails/sessionRegister`, { - // method: 'POST', - // headers: { - // "Content-Type": "application/json", - // }, - // body: JSON.stringify({ - // prenom: type === 'special' ? inscriptionData.prenom : userData.prenom, - // email: type === 'special' ? userData.email : userData.mail, - // nomRencontre: sessionData.module.nom, - // dateRencontre: formattedDateDebut, - // lieuRencontre: sessionData.metasSession.lieuRencontre || 'Lieu', - // nbJours: sessionData.metasSession.nombreJours, - // mail_referent: sessionData.metasSession.mail_referent, - // firstDayStartTime: firstDayStartTime - // }) - // }); - - // if (!emailResponse.ok) { - // throw new Error(`Email request failed with status ${emailResponse.status}`); - // } - - // console.log("Email envoyé avec succès"); + + const emailResponse = await fetch(`${process.env.WEBSITE_URL}/api/emails/sessionRegister`, { + method: 'POST', + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + prenom: type === 'special' ? inscriptionData.prenom : userData.prenom, + email: type === 'special' ? userData.email : userData.mail, + nomRencontre: sessionData.module.nom, + dateRencontre: formattedDateDebut, + lieuRencontre: sessionData.metasSession.lieuRencontre || 'Lieu', + nbJours: sessionData.metasSession.nombreJours, + mail_referent: sessionData.metasSession.mail_referent, + firstDayStartTime: firstDayStartTime + }) + }); + + if (!emailResponse.ok) { + throw new Error(`Email request failed with status ${emailResponse.status}`); + } + + console.log("Email envoyé avec succès"); res.json({ registration: newRegistration, From 1662af97ab69e281aa1708bf1dc6b3cfffe7fc87 Mon Sep 17 00:00:00 2001 From: AntonyKLINGER Date: Wed, 4 Sep 2024 11:48:59 +0200 Subject: [PATCH 043/100] maj add --- pages/api/registrations/add.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/pages/api/registrations/add.js b/pages/api/registrations/add.js index 8b5a170..6d173b5 100644 --- a/pages/api/registrations/add.js +++ b/pages/api/registrations/add.js @@ -113,6 +113,7 @@ export default async function handle(req, res) { mail_referent: sessionData.metasSession.mail_referent, firstDayStartTime: firstDayStartTime }) + }) res.json({ @@ -120,8 +121,6 @@ export default async function handle(req, res) { session: sessionData }); - console.log("Email envoyé avec succès"); - } catch (error) { console.error("Error creating registration:", error.message); From 632d73ccc08d24ba441e8207233cf829989f284c Mon Sep 17 00:00:00 2001 From: AntonyKLINGER Date: Wed, 4 Sep 2024 11:49:20 +0200 Subject: [PATCH 044/100] maj add --- pages/api/registrations/add.js | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/pages/api/registrations/add.js b/pages/api/registrations/add.js index 6d173b5..3062e49 100644 --- a/pages/api/registrations/add.js +++ b/pages/api/registrations/add.js @@ -97,7 +97,7 @@ export default async function handle(req, res) { year: 'numeric', }); - + // Envoi d'email const emailResponse = await fetch(`${process.env.WEBSITE_URL}/api/emails/sessionRegister`, { method: 'POST', headers: { @@ -113,15 +113,19 @@ export default async function handle(req, res) { mail_referent: sessionData.metasSession.mail_referent, firstDayStartTime: firstDayStartTime }) - }) + }); + if (!emailResponse.ok) { + throw new Error(`Email request failed with status ${emailResponse.status}`); + } + + console.log("Email envoyé avec succès"); res.json({ registration: newRegistration, session: sessionData }); - } catch (error) { console.error("Error creating registration:", error.message); console.error("Stack trace:", error.stack); From da25c89f4858bdffeed5087ced573f7f6353f434 Mon Sep 17 00:00:00 2001 From: AntonyKLINGER Date: Wed, 4 Sep 2024 12:11:27 +0200 Subject: [PATCH 045/100] maj log add --- pages/api/registrations/add.js | 37 ++++++++++++++++++---------------- 1 file changed, 20 insertions(+), 17 deletions(-) diff --git a/pages/api/registrations/add.js b/pages/api/registrations/add.js index 3062e49..551f78b 100644 --- a/pages/api/registrations/add.js +++ b/pages/api/registrations/add.js @@ -4,16 +4,19 @@ import fetch from 'node-fetch'; export default async function handle(req, res) { if (req.method !== 'POST') { res.setHeader('Allow', ['POST']); - res.status(405).end(`Method ${req.method} Not Allowed`); - return; + return res.status(405).json({ error: `Method ${req.method} not allowed` }); } - + const { inscriptionData, userId, sessionId, type } = req.body; + if (!userId || !sessionId || !inscriptionData || !type) { + return res.status(400).json({ error: 'Missing required fields: userId, sessionId, inscriptionData, or type' }); + } + try { console.log("Début de la requête"); - const now = new Date(); - + + // Récupérer les données de la session const sessionData = await prisma.session.findUnique({ where: { id: parseInt(sessionId) }, include: { @@ -23,7 +26,7 @@ export default async function handle(req, res) { }); if (!sessionData) { - throw new Error('Session non trouvée'); + return res.status(404).json({ error: 'Session non trouvée' }); } console.log("Session trouvée :", sessionData); @@ -31,17 +34,16 @@ export default async function handle(req, res) { let userData; let newRegistration; + // Traiter en fonction du type (special ou normal) if (type === 'special') { - // Récupération des données du compte pour type "special" userData = await prisma.account.findUnique({ where: { id: parseInt(userId) }, }); if (!userData) { - throw new Error('Compte non trouvé'); + return res.status(404).json({ error: 'Compte non trouvé' }); } - // Création de l'inscription dans accountRegistration newRegistration = await prisma.accountRegistration.create({ data: { ...inscriptionData, @@ -55,16 +57,14 @@ export default async function handle(req, res) { } }); } else { - // Récupération des données de l'utilisateur pour les types autres que "special" userData = await prisma.user.findUnique({ where: { id: parseInt(userId) }, }); if (!userData) { - throw new Error('Utilisateur non trouvé'); + return res.status(404).json({ error: 'Utilisateur non trouvé' }); } - // Création de l'inscription dans registration newRegistration = await prisma.registration.create({ data: { ...inscriptionData, @@ -116,19 +116,22 @@ export default async function handle(req, res) { }); if (!emailResponse.ok) { - throw new Error(`Email request failed with status ${emailResponse.status}`); + const emailErrorText = await emailResponse.text(); + return res.status(500).json({ error: `Échec de l'envoi de l'email`, details: emailErrorText }); } console.log("Email envoyé avec succès"); - res.json({ + return res.status(200).json({ registration: newRegistration, session: sessionData }); } catch (error) { - console.error("Error creating registration:", error.message); - console.error("Stack trace:", error.stack); - res.status(500).json({ error: `Impossible de créer l'enregistrement : ${error.message}` }); + // Log plus détaillé dans la réponse JSON + return res.status(500).json({ + error: `Impossible de créer l'enregistrement : ${error.message}`, + stack: error.stack, // Inclure la trace de l'erreur pour plus de détails + }); } } From 0005dca82e8835a3bc5f29aac050e5be21a97028 Mon Sep 17 00:00:00 2001 From: AntonyKLINGER Date: Wed, 4 Sep 2024 12:19:12 +0200 Subject: [PATCH 046/100] maj without mails add --- pages/api/registrations/add.js | 84 +++++++++++++++++----------------- 1 file changed, 42 insertions(+), 42 deletions(-) diff --git a/pages/api/registrations/add.js b/pages/api/registrations/add.js index 551f78b..815788a 100644 --- a/pages/api/registrations/add.js +++ b/pages/api/registrations/add.js @@ -79,48 +79,48 @@ export default async function handle(req, res) { }); } - console.log("Nouvelle inscription créée :", newRegistration); - - const firstProgramme = sessionData.metasSession.programmeSession[0]; - let firstDayStartTime; - - if (firstProgramme.horaires.includes('Jour')) { - firstDayStartTime = firstProgramme.horaires.split(' : ')[1].split(' - ')[0]; - } else { - firstDayStartTime = firstProgramme.horaires.split(' - ')[0].trim(); - } - - const dateDebut = new Date(sessionData.dateDebut); - const formattedDateDebut = dateDebut.toLocaleDateString('fr-FR', { - day: '2-digit', - month: '2-digit', - year: 'numeric', - }); - - // Envoi d'email - const emailResponse = await fetch(`${process.env.WEBSITE_URL}/api/emails/sessionRegister`, { - method: 'POST', - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - prenom: type === 'special' ? inscriptionData.prenom : userData.prenom, - email: type === 'special' ? userData.email : userData.mail, - nomRencontre: sessionData.module.nom, - dateRencontre: formattedDateDebut, - lieuRencontre: sessionData.metasSession.lieuRencontre || 'Lieu', - nbJours: sessionData.metasSession.nombreJours, - mail_referent: sessionData.metasSession.mail_referent, - firstDayStartTime: firstDayStartTime - }) - }); - - if (!emailResponse.ok) { - const emailErrorText = await emailResponse.text(); - return res.status(500).json({ error: `Échec de l'envoi de l'email`, details: emailErrorText }); - } - - console.log("Email envoyé avec succès"); + // console.log("Nouvelle inscription créée :", newRegistration); + + // const firstProgramme = sessionData.metasSession.programmeSession[0]; + // let firstDayStartTime; + + // if (firstProgramme.horaires.includes('Jour')) { + // firstDayStartTime = firstProgramme.horaires.split(' : ')[1].split(' - ')[0]; + // } else { + // firstDayStartTime = firstProgramme.horaires.split(' - ')[0].trim(); + // } + + // const dateDebut = new Date(sessionData.dateDebut); + // const formattedDateDebut = dateDebut.toLocaleDateString('fr-FR', { + // day: '2-digit', + // month: '2-digit', + // year: 'numeric', + // }); + + // // Envoi d'email + // const emailResponse = await fetch(`${process.env.WEBSITE_URL}/api/emails/sessionRegister`, { + // method: 'POST', + // headers: { + // "Content-Type": "application/json", + // }, + // body: JSON.stringify({ + // prenom: type === 'special' ? inscriptionData.prenom : userData.prenom, + // email: type === 'special' ? userData.email : userData.mail, + // nomRencontre: sessionData.module.nom, + // dateRencontre: formattedDateDebut, + // lieuRencontre: sessionData.metasSession.lieuRencontre || 'Lieu', + // nbJours: sessionData.metasSession.nombreJours, + // mail_referent: sessionData.metasSession.mail_referent, + // firstDayStartTime: firstDayStartTime + // }) + // }); + + // if (!emailResponse.ok) { + // const emailErrorText = await emailResponse.text(); + // return res.status(500).json({ error: `Échec de l'envoi de l'email`, details: emailErrorText }); + // } + + // console.log("Email envoyé avec succès"); return res.status(200).json({ registration: newRegistration, From a94ee8792931c6090f46bf31b9ddfabdc661619c Mon Sep 17 00:00:00 2001 From: AntonyKLINGER Date: Wed, 4 Sep 2024 12:28:13 +0200 Subject: [PATCH 047/100] maj add juste first day --- pages/api/registrations/add.js | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/pages/api/registrations/add.js b/pages/api/registrations/add.js index 815788a..a1b79d4 100644 --- a/pages/api/registrations/add.js +++ b/pages/api/registrations/add.js @@ -79,16 +79,16 @@ export default async function handle(req, res) { }); } - // console.log("Nouvelle inscription créée :", newRegistration); + console.log("Nouvelle inscription créée :", newRegistration); - // const firstProgramme = sessionData.metasSession.programmeSession[0]; - // let firstDayStartTime; + const firstProgramme = sessionData.metasSession.programmeSession[0]; + let firstDayStartTime; - // if (firstProgramme.horaires.includes('Jour')) { - // firstDayStartTime = firstProgramme.horaires.split(' : ')[1].split(' - ')[0]; - // } else { - // firstDayStartTime = firstProgramme.horaires.split(' - ')[0].trim(); - // } + if (firstProgramme.horaires.includes('Jour')) { + firstDayStartTime = firstProgramme.horaires.split(' : ')[1].split(' - ')[0]; + } else { + firstDayStartTime = firstProgramme.horaires.split(' - ')[0].trim(); + } // const dateDebut = new Date(sessionData.dateDebut); // const formattedDateDebut = dateDebut.toLocaleDateString('fr-FR', { From 6b59c2c4fdfeea9a532879fcb2dc1b3a5659dbec Mon Sep 17 00:00:00 2001 From: Antony Klinger <40170587+AntonyKLINGER@users.noreply.github.com> Date: Wed, 4 Sep 2024 12:31:54 +0200 Subject: [PATCH 048/100] maj first day (#44) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Maj without mail (#41) * maj comptes admin + dr * mise à jour 29/05 * maj * maj 29/05 * maj email style * mise à jour 29/05 * maj comptes admin + dr (#1) * maj 03/06 >> besoins + ajout titre par jour * maj visuel session * maj comptes DR * maj session programme + dr * maj emails * Update 3/06 - 14h14 (#4) (#5) * maj comptes admin + dr * mise à jour 29/05 * maj * maj 29/05 * maj email style * mise à jour 29/05 * maj comptes admin + dr (#1) * maj 03/06 >> besoins + ajout titre par jour * maj visuel session * maj comptes DR * maj session programme + dr --------- Co-authored-by: lollybet_antony * last maj 17/06 * maj questionnaire * maj espace perso * maj * maj espace perso * maj espace perso * Espace perso (#17) * Maj questionnaire (#8) * maj comptes admin + dr * mise à jour 29/05 * maj * maj 29/05 * maj email style * mise à jour 29/05 * maj comptes admin + dr (#1) * maj 03/06 >> besoins + ajout titre par jour * maj visuel session * maj comptes DR * maj session programme + dr * maj emails * Update 3/06 - 14h14 (#4) (#5) * maj comptes admin + dr * mise à jour 29/05 * maj * maj 29/05 * maj email style * mise à jour 29/05 * maj comptes admin + dr (#1) * maj 03/06 >> besoins + ajout titre par jour * maj visuel session * maj comptes DR * maj session programme + dr --------- Co-authored-by: lollybet_antony * last maj 17/06 * maj questionnaire --------- Co-authored-by: lollybet_antony * Maj espace perso (#9) * maj comptes admin + dr * mise à jour 29/05 * maj * maj 29/05 * maj email style * mise à jour 29/05 * maj comptes admin + dr (#1) * maj 03/06 >> besoins + ajout titre par jour * maj visuel session * maj comptes DR * maj session programme + dr * maj emails * Update 3/06 - 14h14 (#4) (#5) * maj comptes admin + dr * mise à jour 29/05 * maj * maj 29/05 * maj email style * mise à jour 29/05 * maj comptes admin + dr (#1) * maj 03/06 >> besoins + ajout titre par jour * maj visuel session * maj comptes DR * maj session programme + dr --------- Co-authored-by: lollybet_antony * last maj 17/06 * maj questionnaire * maj espace perso --------- Co-authored-by: lollybet_antony * Maj espace perso (#10) * maj comptes admin + dr * mise à jour 29/05 * maj * maj 29/05 * maj email style * mise à jour 29/05 * maj comptes admin + dr (#1) * maj 03/06 >> besoins + ajout titre par jour * maj visuel session * maj comptes DR * maj session programme + dr * maj emails * Update 3/06 - 14h14 (#4) (#5) * maj comptes admin + dr * mise à jour 29/05 * maj * maj 29/05 * maj email style * mise à jour 29/05 * maj comptes admin + dr (#1) * maj 03/06 >> besoins + ajout titre par jour * maj visuel session * maj comptes DR * maj session programme + dr --------- Co-authored-by: lollybet_antony * last maj 17/06 * maj questionnaire * maj espace perso --------- Co-authored-by: lollybet_antony * Update espace perso (#12) * maj comptes admin + dr * mise à jour 29/05 * maj * maj 29/05 * maj email style * mise à jour 29/05 * maj comptes admin + dr (#1) * maj 03/06 >> besoins + ajout titre par jour * maj visuel session * maj comptes DR * maj session programme + dr * maj emails * Update 3/06 - 14h14 (#4) (#5) * maj comptes admin + dr * mise à jour 29/05 * maj * maj 29/05 * maj email style * mise à jour 29/05 * maj comptes admin + dr (#1) * maj 03/06 >> besoins + ajout titre par jour * maj visuel session * maj comptes DR * maj session programme + dr --------- Co-authored-by: lollybet_antony * last maj 17/06 * maj questionnaire * maj espace perso --------- Co-authored-by: lollybet_antony * Update from repo a (#13) * maj comptes admin + dr * mise à jour 29/05 * maj * maj 29/05 * maj email style * mise à jour 29/05 * maj comptes admin + dr (#1) * maj 03/06 >> besoins + ajout titre par jour * maj visuel session * maj comptes DR * maj session programme + dr * maj emails * Update 3/06 - 14h14 (#4) (#5) * maj comptes admin + dr * mise à jour 29/05 * maj * maj 29/05 * maj email style * mise à jour 29/05 * maj comptes admin + dr (#1) * maj 03/06 >> besoins + ajout titre par jour * maj visuel session * maj comptes DR * maj session programme + dr --------- Co-authored-by: lollybet_antony * last maj 17/06 * maj questionnaire * maj espace perso * maj --------- Co-authored-by: lollybet_antony * Maj test espace perso (#14) * maj comptes admin + dr * mise à jour 29/05 * maj * maj 29/05 * maj email style * mise à jour 29/05 * maj comptes admin + dr (#1) * maj 03/06 >> besoins + ajout titre par jour * maj visuel session * maj comptes DR * maj session programme + dr * maj emails * Update 3/06 - 14h14 (#4) (#5) * maj comptes admin + dr * mise à jour 29/05 * maj * maj 29/05 * maj email style * mise à jour 29/05 * maj comptes admin + dr (#1) * maj 03/06 >> besoins + ajout titre par jour * maj visuel session * maj comptes DR * maj session programme + dr --------- Co-authored-by: lollybet_antony * last maj 17/06 * maj questionnaire * maj espace perso * maj * maj espace perso --------- Co-authored-by: lollybet_antony * MAJ ESPACE PERSO (#15) * maj comptes admin + dr * mise à jour 29/05 * maj * maj 29/05 * maj email style * mise à jour 29/05 * maj comptes admin + dr (#1) * maj 03/06 >> besoins + ajout titre par jour * maj visuel session * maj comptes DR * maj session programme + dr * maj emails * Update 3/06 - 14h14 (#4) (#5) * maj comptes admin + dr * mise à jour 29/05 * maj * maj 29/05 * maj email style * mise à jour 29/05 * maj comptes admin + dr (#1) * maj 03/06 >> besoins + ajout titre par jour * maj visuel session * maj comptes DR * maj session programme + dr --------- Co-authored-by: lollybet_antony * last maj 17/06 * maj questionnaire * maj espace perso * maj * maj espace perso * maj espace perso --------- Co-authored-by: lollybet_antony * Update from repo a (#16) * maj comptes admin + dr * mise à jour 29/05 * maj * maj 29/05 * maj email style * mise à jour 29/05 * maj comptes admin + dr (#1) * maj 03/06 >> besoins + ajout titre par jour * maj visuel session * maj comptes DR * maj session programme + dr * maj emails * Update 3/06 - 14h14 (#4) (#5) * maj comptes admin + dr * mise à jour 29/05 * maj * maj 29/05 * maj email style * mise à jour 29/05 * maj comptes admin + dr (#1) * maj 03/06 >> besoins + ajout titre par jour * maj visuel session * maj comptes DR * maj session programme + dr --------- Co-authored-by: lollybet_antony * last maj 17/06 * maj questionnaire * maj espace perso * maj * maj espace perso * maj espace perso --------- Co-authored-by: lollybet_antony --------- Co-authored-by: lollybet_antony * update perso * Ajout de console.log pour debug * maj admin + questionnaire * maj presence * maj badge + mail * maj email after 1 day * maj presence * maj 5 mn * maj export excel questionnaires * maj workflow emails * maj presents * maj espace perso ressources * maj upload test * maj upload * maj api session slug * maj slug url sessions * maj affichage modules et sessions * maj accounts + users * maj type * maj add js * maj add sans mail * maj add * maj add * maj add * maj log add * maj without mails add --------- Co-authored-by: lollybet_antony * Maj just aded first time (#42) * maj comptes admin + dr * mise à jour 29/05 * maj * maj 29/05 * maj email style * mise à jour 29/05 * maj comptes admin + dr (#1) * maj 03/06 >> besoins + ajout titre par jour * maj visuel session * maj comptes DR * maj session programme + dr * maj emails * Update 3/06 - 14h14 (#4) (#5) * maj comptes admin + dr * mise à jour 29/05 * maj * maj 29/05 * maj email style * mise à jour 29/05 * maj comptes admin + dr (#1) * maj 03/06 >> besoins + ajout titre par jour * maj visuel session * maj comptes DR * maj session programme + dr --------- Co-authored-by: lollybet_antony * last maj 17/06 * maj questionnaire * maj espace perso * maj * maj espace perso * maj espace perso * Espace perso (#17) * Maj questionnaire (#8) * maj comptes admin + dr * mise à jour 29/05 * maj * maj 29/05 * maj email style * mise à jour 29/05 * maj comptes admin + dr (#1) * maj 03/06 >> besoins + ajout titre par jour * maj visuel session * maj comptes DR * maj session programme + dr * maj emails * Update 3/06 - 14h14 (#4) (#5) * maj comptes admin + dr * mise à jour 29/05 * maj * maj 29/05 * maj email style * mise à jour 29/05 * maj comptes admin + dr (#1) * maj 03/06 >> besoins + ajout titre par jour * maj visuel session * maj comptes DR * maj session programme + dr --------- Co-authored-by: lollybet_antony * last maj 17/06 * maj questionnaire --------- Co-authored-by: lollybet_antony * Maj espace perso (#9) * maj comptes admin + dr * mise à jour 29/05 * maj * maj 29/05 * maj email style * mise à jour 29/05 * maj comptes admin + dr (#1) * maj 03/06 >> besoins + ajout titre par jour * maj visuel session * maj comptes DR * maj session programme + dr * maj emails * Update 3/06 - 14h14 (#4) (#5) * maj comptes admin + dr * mise à jour 29/05 * maj * maj 29/05 * maj email style * mise à jour 29/05 * maj comptes admin + dr (#1) * maj 03/06 >> besoins + ajout titre par jour * maj visuel session * maj comptes DR * maj session programme + dr --------- Co-authored-by: lollybet_antony * last maj 17/06 * maj questionnaire * maj espace perso --------- Co-authored-by: lollybet_antony * Maj espace perso (#10) * maj comptes admin + dr * mise à jour 29/05 * maj * maj 29/05 * maj email style * mise à jour 29/05 * maj comptes admin + dr (#1) * maj 03/06 >> besoins + ajout titre par jour * maj visuel session * maj comptes DR * maj session programme + dr * maj emails * Update 3/06 - 14h14 (#4) (#5) * maj comptes admin + dr * mise à jour 29/05 * maj * maj 29/05 * maj email style * mise à jour 29/05 * maj comptes admin + dr (#1) * maj 03/06 >> besoins + ajout titre par jour * maj visuel session * maj comptes DR * maj session programme + dr --------- Co-authored-by: lollybet_antony * last maj 17/06 * maj questionnaire * maj espace perso --------- Co-authored-by: lollybet_antony * Update espace perso (#12) * maj comptes admin + dr * mise à jour 29/05 * maj * maj 29/05 * maj email style * mise à jour 29/05 * maj comptes admin + dr (#1) * maj 03/06 >> besoins + ajout titre par jour * maj visuel session * maj comptes DR * maj session programme + dr * maj emails * Update 3/06 - 14h14 (#4) (#5) * maj comptes admin + dr * mise à jour 29/05 * maj * maj 29/05 * maj email style * mise à jour 29/05 * maj comptes admin + dr (#1) * maj 03/06 >> besoins + ajout titre par jour * maj visuel session * maj comptes DR * maj session programme + dr --------- Co-authored-by: lollybet_antony * last maj 17/06 * maj questionnaire * maj espace perso --------- Co-authored-by: lollybet_antony * Update from repo a (#13) * maj comptes admin + dr * mise à jour 29/05 * maj * maj 29/05 * maj email style * mise à jour 29/05 * maj comptes admin + dr (#1) * maj 03/06 >> besoins + ajout titre par jour * maj visuel session * maj comptes DR * maj session programme + dr * maj emails * Update 3/06 - 14h14 (#4) (#5) * maj comptes admin + dr * mise à jour 29/05 * maj * maj 29/05 * maj email style * mise à jour 29/05 * maj comptes admin + dr (#1) * maj 03/06 >> besoins + ajout titre par jour * maj visuel session * maj comptes DR * maj session programme + dr --------- Co-authored-by: lollybet_antony * last maj 17/06 * maj questionnaire * maj espace perso * maj --------- Co-authored-by: lollybet_antony * Maj test espace perso (#14) * maj comptes admin + dr * mise à jour 29/05 * maj * maj 29/05 * maj email style * mise à jour 29/05 * maj comptes admin + dr (#1) * maj 03/06 >> besoins + ajout titre par jour * maj visuel session * maj comptes DR * maj session programme + dr * maj emails * Update 3/06 - 14h14 (#4) (#5) * maj comptes admin + dr * mise à jour 29/05 * maj * maj 29/05 * maj email style * mise à jour 29/05 * maj comptes admin + dr (#1) * maj 03/06 >> besoins + ajout titre par jour * maj visuel session * maj comptes DR * maj session programme + dr --------- Co-authored-by: lollybet_antony * last maj 17/06 * maj questionnaire * maj espace perso * maj * maj espace perso --------- Co-authored-by: lollybet_antony * MAJ ESPACE PERSO (#15) * maj comptes admin + dr * mise à jour 29/05 * maj * maj 29/05 * maj email style * mise à jour 29/05 * maj comptes admin + dr (#1) * maj 03/06 >> besoins + ajout titre par jour * maj visuel session * maj comptes DR * maj session programme + dr * maj emails * Update 3/06 - 14h14 (#4) (#5) * maj comptes admin + dr * mise à jour 29/05 * maj * maj 29/05 * maj email style * mise à jour 29/05 * maj comptes admin + dr (#1) * maj 03/06 >> besoins + ajout titre par jour * maj visuel session * maj comptes DR * maj session programme + dr --------- Co-authored-by: lollybet_antony * last maj 17/06 * maj questionnaire * maj espace perso * maj * maj espace perso * maj espace perso --------- Co-authored-by: lollybet_antony * Update from repo a (#16) * maj comptes admin + dr * mise à jour 29/05 * maj * maj 29/05 * maj email style * mise à jour 29/05 * maj comptes admin + dr (#1) * maj 03/06 >> besoins + ajout titre par jour * maj visuel session * maj comptes DR * maj session programme + dr * maj emails * Update 3/06 - 14h14 (#4) (#5) * maj comptes admin + dr * mise à jour 29/05 * maj * maj 29/05 * maj email style * mise à jour 29/05 * maj comptes admin + dr (#1) * maj 03/06 >> besoins + ajout titre par jour * maj visuel session * maj comptes DR * maj session programme + dr --------- Co-authored-by: lollybet_antony * last maj 17/06 * maj questionnaire * maj espace perso * maj * maj espace perso * maj espace perso --------- Co-authored-by: lollybet_antony --------- Co-authored-by: lollybet_antony * update perso * Ajout de console.log pour debug * maj admin + questionnaire * maj presence * maj badge + mail * maj email after 1 day * maj presence * maj 5 mn * maj export excel questionnaires * maj workflow emails * maj presents * maj espace perso ressources * maj upload test * maj upload * maj api session slug * maj slug url sessions * maj affichage modules et sessions * maj accounts + users * maj type * maj add js * maj add sans mail * maj add * maj add * maj add * maj log add * maj without mails add * maj add juste first day --------- Co-authored-by: lollybet_antony * Maj mail inscription (#43) * maj comptes admin + dr * mise à jour 29/05 * maj * maj 29/05 * maj email style * mise à jour 29/05 * maj comptes admin + dr (#1) * maj 03/06 >> besoins + ajout titre par jour * maj visuel session * maj comptes DR * maj session programme + dr * maj emails * Update 3/06 - 14h14 (#4) (#5) * maj comptes admin + dr * mise à jour 29/05 * maj * maj 29/05 * maj email style * mise à jour 29/05 * maj comptes admin + dr (#1) * maj 03/06 >> besoins + ajout titre par jour * maj visuel session * maj comptes DR * maj session programme + dr --------- Co-authored-by: lollybet_antony * last maj 17/06 * maj questionnaire * maj espace perso * maj * maj espace perso * maj espace perso * Espace perso (#17) * Maj questionnaire (#8) * maj comptes admin + dr * mise à jour 29/05 * maj * maj 29/05 * maj email style * mise à jour 29/05 * maj comptes admin + dr (#1) * maj 03/06 >> besoins + ajout titre par jour * maj visuel session * maj comptes DR * maj session programme + dr * maj emails * Update 3/06 - 14h14 (#4) (#5) * maj comptes admin + dr * mise à jour 29/05 * maj * maj 29/05 * maj email style * mise à jour 29/05 * maj comptes admin + dr (#1) * maj 03/06 >> besoins + ajout titre par jour * maj visuel session * maj comptes DR * maj session programme + dr --------- Co-authored-by: lollybet_antony * last maj 17/06 * maj questionnaire --------- Co-authored-by: lollybet_antony * Maj espace perso (#9) * maj comptes admin + dr * mise à jour 29/05 * maj * maj 29/05 * maj email style * mise à jour 29/05 * maj comptes admin + dr (#1) * maj 03/06 >> besoins + ajout titre par jour * maj visuel session * maj comptes DR * maj session programme + dr * maj emails * Update 3/06 - 14h14 (#4) (#5) * maj comptes admin + dr * mise à jour 29/05 * maj * maj 29/05 * maj email style * mise à jour 29/05 * maj comptes admin + dr (#1) * maj 03/06 >> besoins + ajout titre par jour * maj visuel session * maj comptes DR * maj session programme + dr --------- Co-authored-by: lollybet_antony * last maj 17/06 * maj questionnaire * maj espace perso --------- Co-authored-by: lollybet_antony * Maj espace perso (#10) * maj comptes admin + dr * mise à jour 29/05 * maj * maj 29/05 * maj email style * mise à jour 29/05 * maj comptes admin + dr (#1) * maj 03/06 >> besoins + ajout titre par jour * maj visuel session * maj comptes DR * maj session programme + dr * maj emails * Update 3/06 - 14h14 (#4) (#5) * maj comptes admin + dr * mise à jour 29/05 * maj * maj 29/05 * maj email style * mise à jour 29/05 * maj comptes admin + dr (#1) * maj 03/06 >> besoins + ajout titre par jour * maj visuel session * maj comptes DR * maj session programme + dr --------- Co-authored-by: lollybet_antony * last maj 17/06 * maj questionnaire * maj espace perso --------- Co-authored-by: lollybet_antony * Update espace perso (#12) * maj comptes admin + dr * mise à jour 29/05 * maj * maj 29/05 * maj email style * mise à jour 29/05 * maj comptes admin + dr (#1) * maj 03/06 >> besoins + ajout titre par jour * maj visuel session * maj comptes DR * maj session programme + dr * maj emails * Update 3/06 - 14h14 (#4) (#5) * maj comptes admin + dr * mise à jour 29/05 * maj * maj 29/05 * maj email style * mise à jour 29/05 * maj comptes admin + dr (#1) * maj 03/06 >> besoins + ajout titre par jour * maj visuel session * maj comptes DR * maj session programme + dr --------- Co-authored-by: lollybet_antony * last maj 17/06 * maj questionnaire * maj espace perso --------- Co-authored-by: lollybet_antony * Update from repo a (#13) * maj comptes admin + dr * mise à jour 29/05 * maj * maj 29/05 * maj email style * mise à jour 29/05 * maj comptes admin + dr (#1) * maj 03/06 >> besoins + ajout titre par jour * maj visuel session * maj comptes DR * maj session programme + dr * maj emails * Update 3/06 - 14h14 (#4) (#5) * maj comptes admin + dr * mise à jour 29/05 * maj * maj 29/05 * maj email style * mise à jour 29/05 * maj comptes admin + dr (#1) * maj 03/06 >> besoins + ajout titre par jour * maj visuel session * maj comptes DR * maj session programme + dr --------- Co-authored-by: lollybet_antony * last maj 17/06 * maj questionnaire * maj espace perso * maj --------- Co-authored-by: lollybet_antony * Maj test espace perso (#14) * maj comptes admin + dr * mise à jour 29/05 * maj * maj 29/05 * maj email style * mise à jour 29/05 * maj comptes admin + dr (#1) * maj 03/06 >> besoins + ajout titre par jour * maj visuel session * maj comptes DR * maj session programme + dr * maj emails * Update 3/06 - 14h14 (#4) (#5) * maj comptes admin + dr * mise à jour 29/05 * maj * maj 29/05 * maj email style * mise à jour 29/05 * maj comptes admin + dr (#1) * maj 03/06 >> besoins + ajout titre par jour * maj visuel session * maj comptes DR * maj session programme + dr --------- Co-authored-by: lollybet_antony * last maj 17/06 * maj questionnaire * maj espace perso * maj * maj espace perso --------- Co-authored-by: lollybet_antony * MAJ ESPACE PERSO (#15) * maj comptes admin + dr * mise à jour 29/05 * maj * maj 29/05 * maj email style * mise à jour 29/05 * maj comptes admin + dr (#1) * maj 03/06 >> besoins + ajout titre par jour * maj visuel session * maj comptes DR * maj session programme + dr * maj emails * Update 3/06 - 14h14 (#4) (#5) * maj comptes admin + dr * mise à jour 29/05 * maj * maj 29/05 * maj email style * mise à jour 29/05 * maj comptes admin + dr (#1) * maj 03/06 >> besoins + ajout titre par jour * maj visuel session * maj comptes DR * maj session programme + dr --------- Co-authored-by: lollybet_antony * last maj 17/06 * maj questionnaire * maj espace perso * maj * maj espace perso * maj espace perso --------- Co-authored-by: lollybet_antony * Update from repo a (#16) * maj comptes admin + dr * mise à jour 29/05 * maj * maj 29/05 * maj email style * mise à jour 29/05 * maj comptes admin + dr (#1) * maj 03/06 >> besoins + ajout titre par jour * maj visuel session * maj comptes DR * maj session programme + dr * maj emails * Update 3/06 - 14h14 (#4) (#5) * maj comptes admin + dr * mise à jour 29/05 * maj * maj 29/05 * maj email style * mise à jour 29/05 * maj comptes admin + dr (#1) * maj 03/06 >> besoins + ajout titre par jour * maj visuel session * maj comptes DR * maj session programme + dr --------- Co-authored-by: lollybet_antony * last maj 17/06 * maj questionnaire * maj espace perso * maj * maj espace perso * maj espace perso --------- Co-authored-by: lollybet_antony --------- Co-authored-by: lollybet_antony * update perso * Ajout de console.log pour debug * maj admin + questionnaire * maj presence * maj badge + mail * maj email after 1 day * maj presence * maj 5 mn * maj export excel questionnaires * maj workflow emails * maj presents * maj espace perso ressources * maj upload test * maj upload * maj api session slug * maj slug url sessions * maj affichage modules et sessions * maj accounts + users * maj type * maj add js * maj add sans mail * maj add * maj add * maj add * maj log add * maj without mails add * maj add juste first day --------- Co-authored-by: lollybet_antony --------- Co-authored-by: lollybet_antony --- pages/api/registrations/add.js | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/pages/api/registrations/add.js b/pages/api/registrations/add.js index a1b79d4..815788a 100644 --- a/pages/api/registrations/add.js +++ b/pages/api/registrations/add.js @@ -79,16 +79,16 @@ export default async function handle(req, res) { }); } - console.log("Nouvelle inscription créée :", newRegistration); + // console.log("Nouvelle inscription créée :", newRegistration); - const firstProgramme = sessionData.metasSession.programmeSession[0]; - let firstDayStartTime; + // const firstProgramme = sessionData.metasSession.programmeSession[0]; + // let firstDayStartTime; - if (firstProgramme.horaires.includes('Jour')) { - firstDayStartTime = firstProgramme.horaires.split(' : ')[1].split(' - ')[0]; - } else { - firstDayStartTime = firstProgramme.horaires.split(' - ')[0].trim(); - } + // if (firstProgramme.horaires.includes('Jour')) { + // firstDayStartTime = firstProgramme.horaires.split(' : ')[1].split(' - ')[0]; + // } else { + // firstDayStartTime = firstProgramme.horaires.split(' - ')[0].trim(); + // } // const dateDebut = new Date(sessionData.dateDebut); // const formattedDateDebut = dateDebut.toLocaleDateString('fr-FR', { From 1a4faf44fa3b5ec6af1685f49333d4135fa36e54 Mon Sep 17 00:00:00 2001 From: AntonyKLINGER Date: Wed, 4 Sep 2024 12:32:52 +0200 Subject: [PATCH 049/100] maj first day added --- pages/api/registrations/add.js | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/pages/api/registrations/add.js b/pages/api/registrations/add.js index 815788a..a1b79d4 100644 --- a/pages/api/registrations/add.js +++ b/pages/api/registrations/add.js @@ -79,16 +79,16 @@ export default async function handle(req, res) { }); } - // console.log("Nouvelle inscription créée :", newRegistration); + console.log("Nouvelle inscription créée :", newRegistration); - // const firstProgramme = sessionData.metasSession.programmeSession[0]; - // let firstDayStartTime; + const firstProgramme = sessionData.metasSession.programmeSession[0]; + let firstDayStartTime; - // if (firstProgramme.horaires.includes('Jour')) { - // firstDayStartTime = firstProgramme.horaires.split(' : ')[1].split(' - ')[0]; - // } else { - // firstDayStartTime = firstProgramme.horaires.split(' - ')[0].trim(); - // } + if (firstProgramme.horaires.includes('Jour')) { + firstDayStartTime = firstProgramme.horaires.split(' : ')[1].split(' - ')[0]; + } else { + firstDayStartTime = firstProgramme.horaires.split(' - ')[0].trim(); + } // const dateDebut = new Date(sessionData.dateDebut); // const formattedDateDebut = dateDebut.toLocaleDateString('fr-FR', { From 621b736b449c4033ae047b19c09c1068acddbdfe Mon Sep 17 00:00:00 2001 From: AntonyKLINGER Date: Wed, 4 Sep 2024 13:41:30 +0200 Subject: [PATCH 050/100] maj adder --- pages/api/registrations/add.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pages/api/registrations/add.js b/pages/api/registrations/add.js index a1b79d4..f362113 100644 --- a/pages/api/registrations/add.js +++ b/pages/api/registrations/add.js @@ -81,8 +81,8 @@ export default async function handle(req, res) { console.log("Nouvelle inscription créée :", newRegistration); - const firstProgramme = sessionData.metasSession.programmeSession[0]; let firstDayStartTime; + const firstProgramme = sessionData.metasSession.programmeSession[0]; if (firstProgramme.horaires.includes('Jour')) { firstDayStartTime = firstProgramme.horaires.split(' : ')[1].split(' - ')[0]; From a121590fbc2fb2e7153f4df7264b507374659951 Mon Sep 17 00:00:00 2001 From: AntonyKLINGER Date: Wed, 4 Sep 2024 13:52:11 +0200 Subject: [PATCH 051/100] maj with email --- pages/api/registrations/add.js | 54 +++++++++++++++++----------------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/pages/api/registrations/add.js b/pages/api/registrations/add.js index f362113..2b63946 100644 --- a/pages/api/registrations/add.js +++ b/pages/api/registrations/add.js @@ -90,35 +90,35 @@ export default async function handle(req, res) { firstDayStartTime = firstProgramme.horaires.split(' - ')[0].trim(); } - // const dateDebut = new Date(sessionData.dateDebut); - // const formattedDateDebut = dateDebut.toLocaleDateString('fr-FR', { - // day: '2-digit', - // month: '2-digit', - // year: 'numeric', - // }); + const dateDebut = new Date(sessionData.dateDebut); + const formattedDateDebut = dateDebut.toLocaleDateString('fr-FR', { + day: '2-digit', + month: '2-digit', + year: 'numeric', + }); // // Envoi d'email - // const emailResponse = await fetch(`${process.env.WEBSITE_URL}/api/emails/sessionRegister`, { - // method: 'POST', - // headers: { - // "Content-Type": "application/json", - // }, - // body: JSON.stringify({ - // prenom: type === 'special' ? inscriptionData.prenom : userData.prenom, - // email: type === 'special' ? userData.email : userData.mail, - // nomRencontre: sessionData.module.nom, - // dateRencontre: formattedDateDebut, - // lieuRencontre: sessionData.metasSession.lieuRencontre || 'Lieu', - // nbJours: sessionData.metasSession.nombreJours, - // mail_referent: sessionData.metasSession.mail_referent, - // firstDayStartTime: firstDayStartTime - // }) - // }); - - // if (!emailResponse.ok) { - // const emailErrorText = await emailResponse.text(); - // return res.status(500).json({ error: `Échec de l'envoi de l'email`, details: emailErrorText }); - // } + const emailResponse = await fetch(`${process.env.WEBSITE_URL}/api/emails/sessionRegister`, { + method: 'POST', + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + prenom: type == 'special' ? inscriptionData.prenom : userData.prenom, + email: type == 'special' ? userData.email : userData.mail, + nomRencontre: sessionData.module.nom, + dateRencontre: formattedDateDebut, + lieuRencontre: sessionData.metasSession.lieuRencontre || 'Lieu', + nbJours: sessionData.metasSession.nombreJours, + mail_referent: sessionData.metasSession.mail_referent, + firstDayStartTime: firstDayStartTime + }) + }); + + if (!emailResponse.ok) { + const emailErrorText = await emailResponse.text(); + return res.status(500).json({ error: `Échec de l'envoi de l'email`, details: emailErrorText }); + } // console.log("Email envoyé avec succès"); From 9f7ec30b05beabab1983bb2506a5d3a72f7a40e1 Mon Sep 17 00:00:00 2001 From: AntonyKLINGER Date: Wed, 4 Sep 2024 13:59:12 +0200 Subject: [PATCH 052/100] maj without mail --- pages/api/registrations/add.js | 42 +++++++++++++++++----------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/pages/api/registrations/add.js b/pages/api/registrations/add.js index 2b63946..ffca5b1 100644 --- a/pages/api/registrations/add.js +++ b/pages/api/registrations/add.js @@ -98,27 +98,27 @@ export default async function handle(req, res) { }); // // Envoi d'email - const emailResponse = await fetch(`${process.env.WEBSITE_URL}/api/emails/sessionRegister`, { - method: 'POST', - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - prenom: type == 'special' ? inscriptionData.prenom : userData.prenom, - email: type == 'special' ? userData.email : userData.mail, - nomRencontre: sessionData.module.nom, - dateRencontre: formattedDateDebut, - lieuRencontre: sessionData.metasSession.lieuRencontre || 'Lieu', - nbJours: sessionData.metasSession.nombreJours, - mail_referent: sessionData.metasSession.mail_referent, - firstDayStartTime: firstDayStartTime - }) - }); - - if (!emailResponse.ok) { - const emailErrorText = await emailResponse.text(); - return res.status(500).json({ error: `Échec de l'envoi de l'email`, details: emailErrorText }); - } + // const emailResponse = await fetch(`${process.env.WEBSITE_URL}/api/emails/sessionRegister`, { + // method: 'POST', + // headers: { + // "Content-Type": "application/json", + // }, + // body: JSON.stringify({ + // prenom: type == 'special' ? inscriptionData.prenom : userData.prenom, + // email: type == 'special' ? userData.email : userData.mail, + // nomRencontre: sessionData.module.nom, + // dateRencontre: formattedDateDebut, + // lieuRencontre: sessionData.metasSession.lieuRencontre || 'Lieu', + // nbJours: sessionData.metasSession.nombreJours, + // mail_referent: sessionData.metasSession.mail_referent, + // firstDayStartTime: firstDayStartTime + // }) + // }); + + // if (!emailResponse.ok) { + // const emailErrorText = await emailResponse.text(); + // return res.status(500).json({ error: `Échec de l'envoi de l'email`, details: emailErrorText }); + // } // console.log("Email envoyé avec succès"); From e7105f0c56890fd2354849a654858c7bef879365 Mon Sep 17 00:00:00 2001 From: AntonyKLINGER Date: Wed, 4 Sep 2024 14:06:55 +0200 Subject: [PATCH 053/100] maj with sending --- pages/api/registrations/add.js | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/pages/api/registrations/add.js b/pages/api/registrations/add.js index ffca5b1..22de0d3 100644 --- a/pages/api/registrations/add.js +++ b/pages/api/registrations/add.js @@ -97,6 +97,17 @@ export default async function handle(req, res) { year: 'numeric', }); + const sending = { + prenom: type == 'special' ? inscriptionData.prenom : userData.prenom, + email: type == 'special' ? userData.email : userData.mail, + nomRencontre: sessionData.module.nom, + dateRencontre: formattedDateDebut, + lieuRencontre: sessionData.metasSession.lieuRencontre || 'Lieu', + nbJours: sessionData.metasSession.nombreJours, + mail_referent: sessionData.metasSession.mail_referent, + firstDayStartTime: firstDayStartTime + } + // // Envoi d'email // const emailResponse = await fetch(`${process.env.WEBSITE_URL}/api/emails/sessionRegister`, { // method: 'POST', @@ -124,7 +135,8 @@ export default async function handle(req, res) { return res.status(200).json({ registration: newRegistration, - session: sessionData + session: sessionData, + sending: sending }); } catch (error) { From 17a5e278bb882c211f2aba4ae6d6f4eeb803415c Mon Sep 17 00:00:00 2001 From: AntonyKLINGER Date: Wed, 4 Sep 2024 14:20:53 +0200 Subject: [PATCH 054/100] maj session register --- pages/api/emails/sessionRegister.js | 91 ++++++++++++++++------------- 1 file changed, 50 insertions(+), 41 deletions(-) diff --git a/pages/api/emails/sessionRegister.js b/pages/api/emails/sessionRegister.js index e5f47d6..5b803e0 100644 --- a/pages/api/emails/sessionRegister.js +++ b/pages/api/emails/sessionRegister.js @@ -3,52 +3,61 @@ import hbs from 'nodemailer-express-handlebars'; import path from 'path'; export default async function handler(req, res) { + // Extraction des données du corps de la requête const { prenom, email, nomRencontre, dateRencontre, lieuRencontre, nbJours, mail_referent, firstDayStartTime } = req.body; - const transporter = nodemailer.createTransport({ - host: 'smtp-relay.brevo.com', - port: 587, - secure: false, - auth: { - user: 'contact@territoiresentransitions.fr', - pass: process.env.BREVO_KEY - }, - tls: { rejectUnauthorized: false } - }); + try { + // Configuration du transporteur SMTP + const transporter = nodemailer.createTransport({ + host: 'smtp-relay.brevo.com', + port: 587, + secure: false, + auth: { + user: 'contact@territoiresentransitions.fr', + pass: process.env.BREVO_KEY + }, + tls: { rejectUnauthorized: false } + }); - transporter.use('compile', hbs({ - viewEngine: { + // Utilisation de Handlebars pour les templates d'e-mails + transporter.use('compile', hbs({ + viewEngine: { + extName: '.hbs', + partialsDir: path.resolve('./views/emails'), + defaultLayout: false, + }, + viewPath: path.resolve('./views/emails'), extName: '.hbs', - partialsDir: path.resolve('./views/emails'), - defaultLayout: false, - }, - viewPath: path.resolve('./views/emails'), - extName: '.hbs', - })); + })); - const mailOptions = { - from: '"ADEME" ', - to: email, - subject: "Inscription à une Rencontre Territoire Engagé Transition Ecologique", - template: 'session_register', - context: { - prenom: prenom, - siteUrl: process.env.WEBSITE_URL, - nomRencontre: nomRencontre, - lieuRencontre: lieuRencontre, - nbJours: nbJours, - dateRencontre: dateRencontre, - mail_referent: mail_referent, - firstDayStartTime: firstDayStartTime - } - }; + // Options de l'e-mail + const mailOptions = { + from: '"ADEME" ', + to: email, + subject: "Inscription à une Rencontre Territoire Engagé Transition Ecologique", + template: 'session_register', + context: { + prenom: prenom, + siteUrl: process.env.WEBSITE_URL, + nomRencontre: nomRencontre, + lieuRencontre: lieuRencontre, + nbJours: nbJours, + dateRencontre: dateRencontre, + mail_referent: mail_referent, + firstDayStartTime: firstDayStartTime + } + }; - transporter.sendMail(mailOptions, (error, info) => { - if (error) { - res.json(error); - return console.log(error); - } + // Envoi de l'e-mail + const info = await transporter.sendMail(mailOptions); + + // Si l'envoi est réussi, réponse avec un statut 200 console.log('Message sent: %s', info.messageId); - res.status(200).json({ status: 'sended' }); - }); + res.status(200).json({ status: 'sended', messageId: info.messageId }); + + } catch (error) { + // Gestion des erreurs et réponse avec un statut 500 + console.error('Erreur lors de l\'envoi de l\'e-mail:', error); + res.status(500).json({ error: 'Erreur lors de l\'envoi de l\'e-mail', details: error }); + } } From 5dbfede94733337935a1301f0f6480348e18da61 Mon Sep 17 00:00:00 2001 From: AntonyKLINGER Date: Wed, 4 Sep 2024 14:30:33 +0200 Subject: [PATCH 055/100] maj testeur --- pages/api/emails/gets.js | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 pages/api/emails/gets.js diff --git a/pages/api/emails/gets.js b/pages/api/emails/gets.js new file mode 100644 index 0000000..d97e568 --- /dev/null +++ b/pages/api/emails/gets.js @@ -0,0 +1,9 @@ +import nodemailer from 'nodemailer'; +import hbs from 'nodemailer-express-handlebars'; +import path from 'path'; + +export default async function handler(req, res) { + + res.status(200).json({ a: process.env.WEBSITE_URL, b: process.env.BREVO_KEY }); + +} From ddf4c9ffd39fa8f714f0287792166c41c3c4a38c Mon Sep 17 00:00:00 2001 From: AntonyKLINGER Date: Wed, 4 Sep 2024 14:42:09 +0200 Subject: [PATCH 056/100] new maj test --- pages/api/emails/gets.js | 9 --- pages/api/emails/sessionRegister.js | 91 +++++++++++++---------------- 2 files changed, 41 insertions(+), 59 deletions(-) delete mode 100644 pages/api/emails/gets.js diff --git a/pages/api/emails/gets.js b/pages/api/emails/gets.js deleted file mode 100644 index d97e568..0000000 --- a/pages/api/emails/gets.js +++ /dev/null @@ -1,9 +0,0 @@ -import nodemailer from 'nodemailer'; -import hbs from 'nodemailer-express-handlebars'; -import path from 'path'; - -export default async function handler(req, res) { - - res.status(200).json({ a: process.env.WEBSITE_URL, b: process.env.BREVO_KEY }); - -} diff --git a/pages/api/emails/sessionRegister.js b/pages/api/emails/sessionRegister.js index 5b803e0..176713c 100644 --- a/pages/api/emails/sessionRegister.js +++ b/pages/api/emails/sessionRegister.js @@ -3,61 +3,52 @@ import hbs from 'nodemailer-express-handlebars'; import path from 'path'; export default async function handler(req, res) { - // Extraction des données du corps de la requête const { prenom, email, nomRencontre, dateRencontre, lieuRencontre, nbJours, mail_referent, firstDayStartTime } = req.body; - try { - // Configuration du transporteur SMTP - const transporter = nodemailer.createTransport({ - host: 'smtp-relay.brevo.com', - port: 587, - secure: false, - auth: { - user: 'contact@territoiresentransitions.fr', - pass: process.env.BREVO_KEY - }, - tls: { rejectUnauthorized: false } - }); + const transporter = nodemailer.createTransport({ + host: 'smtp-relay.brevo.com', + port: 587, + secure: false, + auth: { + user: 'contact@territoiresentransitions.fr', + pass: process.env.BREVO_KEY + }, + // tls: { rejectUnauthorized: false } + }); - // Utilisation de Handlebars pour les templates d'e-mails - transporter.use('compile', hbs({ - viewEngine: { - extName: '.hbs', - partialsDir: path.resolve('./views/emails'), - defaultLayout: false, - }, - viewPath: path.resolve('./views/emails'), + transporter.use('compile', hbs({ + viewEngine: { extName: '.hbs', - })); + partialsDir: path.resolve('./views/emails'), + defaultLayout: false, + }, + viewPath: path.resolve('./views/emails'), + extName: '.hbs', + })); - // Options de l'e-mail - const mailOptions = { - from: '"ADEME" ', - to: email, - subject: "Inscription à une Rencontre Territoire Engagé Transition Ecologique", - template: 'session_register', - context: { - prenom: prenom, - siteUrl: process.env.WEBSITE_URL, - nomRencontre: nomRencontre, - lieuRencontre: lieuRencontre, - nbJours: nbJours, - dateRencontre: dateRencontre, - mail_referent: mail_referent, - firstDayStartTime: firstDayStartTime - } - }; + const mailOptions = { + from: '"ADEME" ', + to: email, + subject: "Inscription à une Rencontre Territoire Engagé Transition Ecologique", + template: 'session_register', + context: { + prenom: prenom, + siteUrl: process.env.WEBSITE_URL, + nomRencontre: nomRencontre, + lieuRencontre: lieuRencontre, + nbJours: nbJours, + dateRencontre: dateRencontre, + mail_referent: mail_referent, + firstDayStartTime: firstDayStartTime + } + }; - // Envoi de l'e-mail - const info = await transporter.sendMail(mailOptions); - - // Si l'envoi est réussi, réponse avec un statut 200 + transporter.sendMail(mailOptions, (error, info) => { + if (error) { + res.json(error); + return console.log(error); + } console.log('Message sent: %s', info.messageId); - res.status(200).json({ status: 'sended', messageId: info.messageId }); - - } catch (error) { - // Gestion des erreurs et réponse avec un statut 500 - console.error('Erreur lors de l\'envoi de l\'e-mail:', error); - res.status(500).json({ error: 'Erreur lors de l\'envoi de l\'e-mail', details: error }); - } + res.status(200).json({ status: 'sended' }); + }); } From 37baed5cbe9b39475aac25be4ee6e1bc9d83291a Mon Sep 17 00:00:00 2001 From: AntonyKLINGER Date: Wed, 4 Sep 2024 14:47:34 +0200 Subject: [PATCH 057/100] maj with logs --- pages/api/emails/sessionRegister.js | 97 ++++++++++++++++------------- 1 file changed, 55 insertions(+), 42 deletions(-) diff --git a/pages/api/emails/sessionRegister.js b/pages/api/emails/sessionRegister.js index 176713c..33235be 100644 --- a/pages/api/emails/sessionRegister.js +++ b/pages/api/emails/sessionRegister.js @@ -3,52 +3,65 @@ import hbs from 'nodemailer-express-handlebars'; import path from 'path'; export default async function handler(req, res) { - const { prenom, email, nomRencontre, dateRencontre, lieuRencontre, nbJours, mail_referent, firstDayStartTime } = req.body; + try { + // Étape 1: Vérifier si la requête contient le body attendu + const { prenom, email, nomRencontre, dateRencontre, lieuRencontre, nbJours, mail_referent, firstDayStartTime } = req.body; - const transporter = nodemailer.createTransport({ - host: 'smtp-relay.brevo.com', - port: 587, - secure: false, - auth: { - user: 'contact@territoiresentransitions.fr', - pass: process.env.BREVO_KEY - }, - // tls: { rejectUnauthorized: false } - }); + if (!prenom || !email || !nomRencontre || !dateRencontre) { + return res.status(400).json({ error: "Données manquantes dans la requête", body: req.body }); + } + + // Étape 2: Configurer le transporteur Nodemailer + const transporter = nodemailer.createTransport({ + host: 'smtp-relay.brevo.com', + port: 587, + secure: false, + auth: { + user: 'contact@territoiresentransitions.fr', + pass: process.env.BREVO_KEY + }, + tls: { rejectUnauthorized: false } + }); - transporter.use('compile', hbs({ - viewEngine: { + // Étape 3: Configurer Handlebars pour les templates + transporter.use('compile', hbs({ + viewEngine: { + extName: '.hbs', + partialsDir: path.resolve('./views/emails'), + defaultLayout: false, + }, + viewPath: path.resolve('./views/emails'), extName: '.hbs', - partialsDir: path.resolve('./views/emails'), - defaultLayout: false, - }, - viewPath: path.resolve('./views/emails'), - extName: '.hbs', - })); + })); - const mailOptions = { - from: '"ADEME" ', - to: email, - subject: "Inscription à une Rencontre Territoire Engagé Transition Ecologique", - template: 'session_register', - context: { - prenom: prenom, - siteUrl: process.env.WEBSITE_URL, - nomRencontre: nomRencontre, - lieuRencontre: lieuRencontre, - nbJours: nbJours, - dateRencontre: dateRencontre, - mail_referent: mail_referent, - firstDayStartTime: firstDayStartTime - } - }; + // Étape 4: Préparer les options d'email + const mailOptions = { + from: '"ADEME" ', + to: email, + subject: "Inscription à une Rencontre Territoire Engagé Transition Ecologique", + template: 'session_register', + context: { + prenom: prenom, + siteUrl: process.env.WEBSITE_URL, + nomRencontre: nomRencontre, + lieuRencontre: lieuRencontre, + nbJours: nbJours, + dateRencontre: dateRencontre, + mail_referent: mail_referent, + firstDayStartTime: firstDayStartTime + } + }; - transporter.sendMail(mailOptions, (error, info) => { - if (error) { - res.json(error); - return console.log(error); + // Étape 5: Essayer d'envoyer l'email + try { + const info = await transporter.sendMail(mailOptions); + return res.status(200).json({ status: 'sended', messageId: info.messageId }); + } catch (error) { + return res.status(500).json({ error: 'Erreur lors de l\'envoi de l\'e-mail', details: error.message }); } - console.log('Message sent: %s', info.messageId); - res.status(200).json({ status: 'sended' }); - }); + + } catch (error) { + // Gestion générale des erreurs + return res.status(500).json({ error: 'Erreur serveur', details: error.message }); + } } From 2bf98cc062b860fb3d766f0336862eb24cd0cc99 Mon Sep 17 00:00:00 2001 From: AntonyKLINGER Date: Wed, 4 Sep 2024 14:59:08 +0200 Subject: [PATCH 058/100] maj epp --- pages/rencontres/[category]/[session].js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pages/rencontres/[category]/[session].js b/pages/rencontres/[category]/[session].js index 6e26efe..53c161e 100644 --- a/pages/rencontres/[category]/[session].js +++ b/pages/rencontres/[category]/[session].js @@ -220,7 +220,7 @@ export default function Session({ data, user }){ useEffect(() => { const getUserInfo = async () => { - if(user.type == "Administrateur" || user.type == "DR"){ + if(user != null && (user.type == "Administrateur" || user.type == "DR")){ const fetcher = await fetch(`/api/accounts/${user.id}`) const json = await fetcher.json() let userDetail = await json[0] @@ -273,7 +273,7 @@ export default function Session({ data, user }){ } useEffect(() => { - if(user.type == "Administrateur" || user.type == "DR"){ + if(user != null && (user.type == "Administrateur" || user.type == "DR")){ const checker = async () => { const fetcher = await fetch(`/api/registrations/byUserSession?userId=${user.id}&sessionId=${data.id}&specialAccount=true`) const json = await fetcher.json() From c2ac57e446627f50b817978732d98c4705ba1a43 Mon Sep 17 00:00:00 2001 From: AntonyKLINGER Date: Wed, 4 Sep 2024 15:05:28 +0200 Subject: [PATCH 059/100] maj gets --- pages/api/emails/gets.js | 55 +++++++++++++++++++++++++++++++++++----- 1 file changed, 49 insertions(+), 6 deletions(-) diff --git a/pages/api/emails/gets.js b/pages/api/emails/gets.js index d97e568..9304e5e 100644 --- a/pages/api/emails/gets.js +++ b/pages/api/emails/gets.js @@ -1,9 +1,52 @@ -import nodemailer from 'nodemailer'; -import hbs from 'nodemailer-express-handlebars'; -import path from 'path'; +const nodemailer = require('nodemailer'); +const hbs = require('nodemailer-express-handlebars'); +const path = require('path'); export default async function handler(req, res) { - - res.status(200).json({ a: process.env.WEBSITE_URL, b: process.env.BREVO_KEY }); -} + const { prenom, email } = req.body + + res.status(200).json({ prenom: prenom }) + +// const transporter = nodemailer.createTransport({ +// host: 'smtp-relay.brevo.com', +// port: 587, +// secure: false, +// auth: { +// user: 'contact@territoiresentransitions.fr', +// pass: process.env.BREVO_KEY +// }, +// tls: {rejectUnauthorized: false} +// }); + +// transporter.use('compile', hbs({ +// viewEngine: { +// extName: '.hbs', +// partialsDir: path.resolve('./views/emails'), +// defaultLayout: false, +// }, +// viewPath: path.resolve('./views/emails'), +// extName: '.hbs', +// })); + +// const mailOptions = { +// from: '"ADEME" ', +// to: email, +// subject: "Bienvenue sur la plateforme des Rencontres Territoire Engagé Transition Ecologique !", +// template: 'welcome', +// context: { +// prenom: prenom, +// siteUrl: process.env.WEBSITE_URL, +// } +// }; + +// transporter.sendMail(mailOptions, (error, info) => { +// if (error) { +// res.json(error) +// // return console.log(error); +// } +// console.log('Message sent: %s', info.messageId); +// res.status(200).json({ status: 'sended' }) +// }); + +} \ No newline at end of file From 8e39a32f480d4298aa025957445709efde169ffa Mon Sep 17 00:00:00 2001 From: AntonyKLINGER Date: Wed, 4 Sep 2024 15:11:02 +0200 Subject: [PATCH 060/100] maj step 1 --- pages/api/emails/gets.js | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/pages/api/emails/gets.js b/pages/api/emails/gets.js index 9304e5e..78f890c 100644 --- a/pages/api/emails/gets.js +++ b/pages/api/emails/gets.js @@ -8,16 +8,16 @@ export default async function handler(req, res) { res.status(200).json({ prenom: prenom }) -// const transporter = nodemailer.createTransport({ -// host: 'smtp-relay.brevo.com', -// port: 587, -// secure: false, -// auth: { -// user: 'contact@territoiresentransitions.fr', -// pass: process.env.BREVO_KEY -// }, -// tls: {rejectUnauthorized: false} -// }); + const transporter = nodemailer.createTransport({ + host: 'smtp-relay.brevo.com', + port: 587, + secure: false, + auth: { + user: 'contact@territoiresentransitions.fr', + pass: process.env.BREVO_KEY + }, + tls: {rejectUnauthorized: false} + }); // transporter.use('compile', hbs({ // viewEngine: { From 882602130cb0dc261c3e34126265f234aaa21459 Mon Sep 17 00:00:00 2001 From: AntonyKLINGER Date: Wed, 4 Sep 2024 15:12:15 +0200 Subject: [PATCH 061/100] maj step 2 --- pages/api/emails/gets.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/pages/api/emails/gets.js b/pages/api/emails/gets.js index 78f890c..56ae6ef 100644 --- a/pages/api/emails/gets.js +++ b/pages/api/emails/gets.js @@ -6,8 +6,6 @@ export default async function handler(req, res) { const { prenom, email } = req.body - res.status(200).json({ prenom: prenom }) - const transporter = nodemailer.createTransport({ host: 'smtp-relay.brevo.com', port: 587, @@ -19,6 +17,9 @@ export default async function handler(req, res) { tls: {rejectUnauthorized: false} }); + + res.status(200).json({ prenom: prenom }) + // transporter.use('compile', hbs({ // viewEngine: { // extName: '.hbs', From 8f000d9c65f7282c3de37270a157ab738c2107b3 Mon Sep 17 00:00:00 2001 From: AntonyKLINGER Date: Wed, 4 Sep 2024 15:19:53 +0200 Subject: [PATCH 062/100] maj step 3 --- pages/api/emails/gets.js | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/pages/api/emails/gets.js b/pages/api/emails/gets.js index 56ae6ef..a719c03 100644 --- a/pages/api/emails/gets.js +++ b/pages/api/emails/gets.js @@ -17,18 +17,17 @@ export default async function handler(req, res) { tls: {rejectUnauthorized: false} }); + transporter.use('compile', hbs({ + viewEngine: { + extName: '.hbs', + partialsDir: path.resolve('./views/emails'), + defaultLayout: false, + }, + viewPath: path.resolve('./views/emails'), + extName: '.hbs', + })); - res.status(200).json({ prenom: prenom }) - -// transporter.use('compile', hbs({ -// viewEngine: { -// extName: '.hbs', -// partialsDir: path.resolve('./views/emails'), -// defaultLayout: false, -// }, -// viewPath: path.resolve('./views/emails'), -// extName: '.hbs', -// })); + res.status(200).json({ prenom: prenom, maj: "ok" }) // const mailOptions = { // from: '"ADEME" ', From 8ce459dd2865ff26ae766f55fc025a3f5b231f10 Mon Sep 17 00:00:00 2001 From: AntonyKLINGER Date: Wed, 4 Sep 2024 15:25:02 +0200 Subject: [PATCH 063/100] maj step 4 --- pages/api/emails/gets.js | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/pages/api/emails/gets.js b/pages/api/emails/gets.js index a719c03..bbae31f 100644 --- a/pages/api/emails/gets.js +++ b/pages/api/emails/gets.js @@ -27,18 +27,20 @@ export default async function handler(req, res) { extName: '.hbs', })); - res.status(200).json({ prenom: prenom, maj: "ok" }) - -// const mailOptions = { -// from: '"ADEME" ', -// to: email, -// subject: "Bienvenue sur la plateforme des Rencontres Territoire Engagé Transition Ecologique !", -// template: 'welcome', -// context: { -// prenom: prenom, -// siteUrl: process.env.WEBSITE_URL, -// } -// }; + const mailOptions = { + from: '"ADEME" ', + to: email, + subject: "Bienvenue sur la plateforme des Rencontres Territoire Engagé Transition Ecologique !", + template: 'welcome', + context: { + prenom: prenom, + siteUrl: process.env.WEBSITE_URL, + } + }; + + res.status(200).json({ prenom: prenom, mailOptions: mailOptions }) + + // transporter.sendMail(mailOptions, (error, info) => { // if (error) { From 536ea1d9cb2d74961a4ac38c0677afe29ad2be8b Mon Sep 17 00:00:00 2001 From: AntonyKLINGER Date: Wed, 4 Sep 2024 15:31:35 +0200 Subject: [PATCH 064/100] maj step 5 --- pages/api/emails/gets.js | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/pages/api/emails/gets.js b/pages/api/emails/gets.js index bbae31f..ac12173 100644 --- a/pages/api/emails/gets.js +++ b/pages/api/emails/gets.js @@ -38,17 +38,13 @@ export default async function handler(req, res) { } }; - res.status(200).json({ prenom: prenom, mailOptions: mailOptions }) - - - -// transporter.sendMail(mailOptions, (error, info) => { -// if (error) { -// res.json(error) -// // return console.log(error); -// } -// console.log('Message sent: %s', info.messageId); -// res.status(200).json({ status: 'sended' }) -// }); + transporter.sendMail(mailOptions, (error, info) => { + if (error) { + res.json(error) + // return console.log(error); + } + console.log('Message sent: %s', info.messageId); + res.status(200).json({ status: 'sended' }) + }); } \ No newline at end of file From a1a4c7f9bbc8ad52cb70f8da0581fe5e6d666cbb Mon Sep 17 00:00:00 2001 From: AntonyKLINGER Date: Wed, 4 Sep 2024 15:43:53 +0200 Subject: [PATCH 065/100] maj step 6 --- pages/api/emails/gets.js | 83 +++++++++++++++++++++++----------------- 1 file changed, 48 insertions(+), 35 deletions(-) diff --git a/pages/api/emails/gets.js b/pages/api/emails/gets.js index ac12173..5190f1f 100644 --- a/pages/api/emails/gets.js +++ b/pages/api/emails/gets.js @@ -3,48 +3,61 @@ const hbs = require('nodemailer-express-handlebars'); const path = require('path'); export default async function handler(req, res) { + try { + // Extraction des données du corps de la requête + const { prenom, email } = req.body; - const { prenom, email } = req.body + if (!prenom || !email) { + return res.status(400).json({ error: 'Données manquantes' }); + } - const transporter = nodemailer.createTransport({ - host: 'smtp-relay.brevo.com', - port: 587, - secure: false, - auth: { - user: 'contact@territoiresentransitions.fr', - pass: process.env.BREVO_KEY - }, - tls: {rejectUnauthorized: false} - }); + // Configuration du transporteur Nodemailer + const transporter = nodemailer.createTransport({ + host: 'smtp-relay.brevo.com', + port: 587, + secure: false, + auth: { + user: 'contact@territoiresentransitions.fr', + pass: process.env.BREVO_KEY + }, + tls: { rejectUnauthorized: false } + }); - transporter.use('compile', hbs({ - viewEngine: { + // Configuration de Handlebars pour les templates + transporter.use('compile', hbs({ + viewEngine: { + extName: '.hbs', + partialsDir: path.resolve('./views/emails'), + defaultLayout: false, + }, + viewPath: path.resolve('./views/emails'), extName: '.hbs', - partialsDir: path.resolve('./views/emails'), - defaultLayout: false, - }, - viewPath: path.resolve('./views/emails'), - extName: '.hbs', - })); + })); - const mailOptions = { - from: '"ADEME" ', - to: email, - subject: "Bienvenue sur la plateforme des Rencontres Territoire Engagé Transition Ecologique !", - template: 'welcome', - context: { + // Options d'e-mail + const mailOptions = { + from: '"ADEME" ', + to: email, + subject: "Bienvenue sur la plateforme des Rencontres Territoire Engagé Transition Ecologique !", + template: 'welcome', + context: { prenom: prenom, siteUrl: process.env.WEBSITE_URL, - } - }; + } + }; - transporter.sendMail(mailOptions, (error, info) => { - if (error) { - res.json(error) - // return console.log(error); + // Tentative d'envoi de l'e-mail + try { + const info = await transporter.sendMail(mailOptions); // Utilisation d'await + console.log('Message sent: %s', info.messageId); + return res.status(200).json({ status: 'sended', messageId: info.messageId }); + } catch (error) { + console.error('Erreur lors de l\'envoi de l\'e-mail:', error); + return res.status(500).json({ error: 'Erreur lors de l\'envoi de l\'e-mail', details: error.message }); } - console.log('Message sent: %s', info.messageId); - res.status(200).json({ status: 'sended' }) - }); -} \ No newline at end of file + } catch (error) { + console.error('Erreur générale:', error); + return res.status(500).json({ error: 'Erreur générale', details: error.message }); + } +} From fa67aee32393fb5043d5ab7aa8702f8c26651dfd Mon Sep 17 00:00:00 2001 From: AntonyKLINGER Date: Wed, 4 Sep 2024 15:49:18 +0200 Subject: [PATCH 066/100] maj step 8 --- pages/api/emails/gets.js | 58 +++++++++------------------------------- 1 file changed, 13 insertions(+), 45 deletions(-) diff --git a/pages/api/emails/gets.js b/pages/api/emails/gets.js index 5190f1f..0049c2d 100644 --- a/pages/api/emails/gets.js +++ b/pages/api/emails/gets.js @@ -1,17 +1,8 @@ -const nodemailer = require('nodemailer'); -const hbs = require('nodemailer-express-handlebars'); -const path = require('path'); +import nodemailer from 'nodemailer'; export default async function handler(req, res) { try { - // Extraction des données du corps de la requête - const { prenom, email } = req.body; - - if (!prenom || !email) { - return res.status(400).json({ error: 'Données manquantes' }); - } - - // Configuration du transporteur Nodemailer + // Configuration du transporteur SMTP const transporter = nodemailer.createTransport({ host: 'smtp-relay.brevo.com', port: 587, @@ -23,41 +14,18 @@ export default async function handler(req, res) { tls: { rejectUnauthorized: false } }); - // Configuration de Handlebars pour les templates - transporter.use('compile', hbs({ - viewEngine: { - extName: '.hbs', - partialsDir: path.resolve('./views/emails'), - defaultLayout: false, - }, - viewPath: path.resolve('./views/emails'), - extName: '.hbs', - })); - - // Options d'e-mail - const mailOptions = { - from: '"ADEME" ', - to: email, - subject: "Bienvenue sur la plateforme des Rencontres Territoire Engagé Transition Ecologique !", - template: 'welcome', - context: { - prenom: prenom, - siteUrl: process.env.WEBSITE_URL, + // Test de la connexion SMTP + transporter.verify(function(error, success) { + if (error) { + console.log('Erreur de connexion SMTP:', error); + return res.status(500).json({ status: 'error', message: 'Connexion au serveur SMTP échouée', details: error.message }); + } else { + console.log('Connexion au serveur SMTP réussie'); + return res.status(200).json({ status: 'success', message: 'Connexion au serveur SMTP réussie' }); } - }; - - // Tentative d'envoi de l'e-mail - try { - const info = await transporter.sendMail(mailOptions); // Utilisation d'await - console.log('Message sent: %s', info.messageId); - return res.status(200).json({ status: 'sended', messageId: info.messageId }); - } catch (error) { - console.error('Erreur lors de l\'envoi de l\'e-mail:', error); - return res.status(500).json({ error: 'Erreur lors de l\'envoi de l\'e-mail', details: error.message }); - } - + }); } catch (error) { - console.error('Erreur générale:', error); - return res.status(500).json({ error: 'Erreur générale', details: error.message }); + console.error('Erreur:', error); + res.status(500).json({ status: 'error', message: 'Erreur lors de la tentative de connexion', details: error.message }); } } From 7d47c4fdc87053de857e3815d353dc74562f27aa Mon Sep 17 00:00:00 2001 From: AntonyKLINGER Date: Wed, 4 Sep 2024 15:55:25 +0200 Subject: [PATCH 067/100] maj step 9 --- pages/api/emails/gets.js | 65 ++++++++++++++++++++++------------------ 1 file changed, 36 insertions(+), 29 deletions(-) diff --git a/pages/api/emails/gets.js b/pages/api/emails/gets.js index 0049c2d..d6d5f0f 100644 --- a/pages/api/emails/gets.js +++ b/pages/api/emails/gets.js @@ -1,31 +1,38 @@ -import nodemailer from 'nodemailer'; - export default async function handler(req, res) { - try { - // Configuration du transporteur SMTP - const transporter = nodemailer.createTransport({ - host: 'smtp-relay.brevo.com', - port: 587, - secure: false, - auth: { - user: 'contact@territoiresentransitions.fr', - pass: process.env.BREVO_KEY - }, - tls: { rejectUnauthorized: false } - }); - - // Test de la connexion SMTP - transporter.verify(function(error, success) { - if (error) { - console.log('Erreur de connexion SMTP:', error); - return res.status(500).json({ status: 'error', message: 'Connexion au serveur SMTP échouée', details: error.message }); - } else { - console.log('Connexion au serveur SMTP réussie'); - return res.status(200).json({ status: 'success', message: 'Connexion au serveur SMTP réussie' }); - } - }); - } catch (error) { - console.error('Erreur:', error); - res.status(500).json({ status: 'error', message: 'Erreur lors de la tentative de connexion', details: error.message }); + try { + // Retourner des informations dans la réponse pour les consulter + const logs = []; + + // Ajouter des logs pour inspecter la requête + logs.push({ message: 'Requête reçue', body: req.body }); + + // Vérification de la clé BREVO_KEY + logs.push({ message: 'Clé BREVO_KEY', value: process.env.BREVO_KEY }); + + const transporter = nodemailer.createTransport({ + host: 'smtp-relay.brevo.com', + port: 587, + secure: false, + auth: { + user: 'contact@territoiresentransitions.fr', + pass: process.env.BREVO_KEY + }, + tls: { rejectUnauthorized: false } + }); + + // Test de la connexion SMTP + transporter.verify(function(error, success) { + if (error) { + logs.push({ message: 'Erreur de connexion SMTP', error: error.message }); + return res.status(500).json({ status: 'error', logs: logs, message: 'Connexion au serveur SMTP échouée', details: error.message }); + } else { + logs.push({ message: 'Connexion au serveur SMTP réussie' }); + return res.status(200).json({ status: 'success', logs: logs, message: 'Connexion au serveur SMTP réussie' }); + } + }); + } catch (error) { + // Capturer et retourner l'erreur + res.status(500).json({ status: 'error', message: 'Erreur lors de la tentative de connexion', details: error.message }); + } } -} + \ No newline at end of file From ff795b1ccff8b0117f81f43f7614dd368fa97e41 Mon Sep 17 00:00:00 2001 From: AntonyKLINGER Date: Wed, 4 Sep 2024 16:01:21 +0200 Subject: [PATCH 068/100] maj step 10 --- pages/api/emails/gets.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pages/api/emails/gets.js b/pages/api/emails/gets.js index d6d5f0f..1264046 100644 --- a/pages/api/emails/gets.js +++ b/pages/api/emails/gets.js @@ -1,3 +1,5 @@ +import nodemailer from 'nodemailer'; + export default async function handler(req, res) { try { // Retourner des informations dans la réponse pour les consulter From 13d273603a60f1e90252afe11b0a373b433734a6 Mon Sep 17 00:00:00 2001 From: AntonyKLINGER Date: Wed, 4 Sep 2024 16:13:34 +0200 Subject: [PATCH 069/100] maj all steps --- pages/api/emails/gets.js | 2 +- pages/api/emails/sessionRegister.js | 97 +++++++++++++---------------- pages/api/registrations/add.js | 48 +++++++------- 3 files changed, 67 insertions(+), 80 deletions(-) diff --git a/pages/api/emails/gets.js b/pages/api/emails/gets.js index 1264046..14143e9 100644 --- a/pages/api/emails/gets.js +++ b/pages/api/emails/gets.js @@ -1,4 +1,4 @@ -import nodemailer from 'nodemailer'; +const nodemailer = require('nodemailer'); export default async function handler(req, res) { try { diff --git a/pages/api/emails/sessionRegister.js b/pages/api/emails/sessionRegister.js index 33235be..e5f47d6 100644 --- a/pages/api/emails/sessionRegister.js +++ b/pages/api/emails/sessionRegister.js @@ -3,65 +3,52 @@ import hbs from 'nodemailer-express-handlebars'; import path from 'path'; export default async function handler(req, res) { - try { - // Étape 1: Vérifier si la requête contient le body attendu - const { prenom, email, nomRencontre, dateRencontre, lieuRencontre, nbJours, mail_referent, firstDayStartTime } = req.body; + const { prenom, email, nomRencontre, dateRencontre, lieuRencontre, nbJours, mail_referent, firstDayStartTime } = req.body; - if (!prenom || !email || !nomRencontre || !dateRencontre) { - return res.status(400).json({ error: "Données manquantes dans la requête", body: req.body }); - } - - // Étape 2: Configurer le transporteur Nodemailer - const transporter = nodemailer.createTransport({ - host: 'smtp-relay.brevo.com', - port: 587, - secure: false, - auth: { - user: 'contact@territoiresentransitions.fr', - pass: process.env.BREVO_KEY - }, - tls: { rejectUnauthorized: false } - }); + const transporter = nodemailer.createTransport({ + host: 'smtp-relay.brevo.com', + port: 587, + secure: false, + auth: { + user: 'contact@territoiresentransitions.fr', + pass: process.env.BREVO_KEY + }, + tls: { rejectUnauthorized: false } + }); - // Étape 3: Configurer Handlebars pour les templates - transporter.use('compile', hbs({ - viewEngine: { - extName: '.hbs', - partialsDir: path.resolve('./views/emails'), - defaultLayout: false, - }, - viewPath: path.resolve('./views/emails'), + transporter.use('compile', hbs({ + viewEngine: { extName: '.hbs', - })); + partialsDir: path.resolve('./views/emails'), + defaultLayout: false, + }, + viewPath: path.resolve('./views/emails'), + extName: '.hbs', + })); - // Étape 4: Préparer les options d'email - const mailOptions = { - from: '"ADEME" ', - to: email, - subject: "Inscription à une Rencontre Territoire Engagé Transition Ecologique", - template: 'session_register', - context: { - prenom: prenom, - siteUrl: process.env.WEBSITE_URL, - nomRencontre: nomRencontre, - lieuRencontre: lieuRencontre, - nbJours: nbJours, - dateRencontre: dateRencontre, - mail_referent: mail_referent, - firstDayStartTime: firstDayStartTime - } - }; - - // Étape 5: Essayer d'envoyer l'email - try { - const info = await transporter.sendMail(mailOptions); - return res.status(200).json({ status: 'sended', messageId: info.messageId }); - } catch (error) { - return res.status(500).json({ error: 'Erreur lors de l\'envoi de l\'e-mail', details: error.message }); + const mailOptions = { + from: '"ADEME" ', + to: email, + subject: "Inscription à une Rencontre Territoire Engagé Transition Ecologique", + template: 'session_register', + context: { + prenom: prenom, + siteUrl: process.env.WEBSITE_URL, + nomRencontre: nomRencontre, + lieuRencontre: lieuRencontre, + nbJours: nbJours, + dateRencontre: dateRencontre, + mail_referent: mail_referent, + firstDayStartTime: firstDayStartTime } + }; - } catch (error) { - // Gestion générale des erreurs - return res.status(500).json({ error: 'Erreur serveur', details: error.message }); - } + transporter.sendMail(mailOptions, (error, info) => { + if (error) { + res.json(error); + return console.log(error); + } + console.log('Message sent: %s', info.messageId); + res.status(200).json({ status: 'sended' }); + }); } diff --git a/pages/api/registrations/add.js b/pages/api/registrations/add.js index 22de0d3..37857aa 100644 --- a/pages/api/registrations/add.js +++ b/pages/api/registrations/add.js @@ -108,30 +108,30 @@ export default async function handle(req, res) { firstDayStartTime: firstDayStartTime } - // // Envoi d'email - // const emailResponse = await fetch(`${process.env.WEBSITE_URL}/api/emails/sessionRegister`, { - // method: 'POST', - // headers: { - // "Content-Type": "application/json", - // }, - // body: JSON.stringify({ - // prenom: type == 'special' ? inscriptionData.prenom : userData.prenom, - // email: type == 'special' ? userData.email : userData.mail, - // nomRencontre: sessionData.module.nom, - // dateRencontre: formattedDateDebut, - // lieuRencontre: sessionData.metasSession.lieuRencontre || 'Lieu', - // nbJours: sessionData.metasSession.nombreJours, - // mail_referent: sessionData.metasSession.mail_referent, - // firstDayStartTime: firstDayStartTime - // }) - // }); - - // if (!emailResponse.ok) { - // const emailErrorText = await emailResponse.text(); - // return res.status(500).json({ error: `Échec de l'envoi de l'email`, details: emailErrorText }); - // } - - // console.log("Email envoyé avec succès"); + // Envoi d'email + const emailResponse = await fetch(`${process.env.WEBSITE_URL}/api/emails/sessionRegister`, { + method: 'POST', + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + prenom: type == 'special' ? inscriptionData.prenom : userData.prenom, + email: type == 'special' ? userData.email : userData.mail, + nomRencontre: sessionData.module.nom, + dateRencontre: formattedDateDebut, + lieuRencontre: sessionData.metasSession.lieuRencontre || 'Lieu', + nbJours: sessionData.metasSession.nombreJours, + mail_referent: sessionData.metasSession.mail_referent, + firstDayStartTime: firstDayStartTime + }) + }); + + if (!emailResponse.ok) { + const emailErrorText = await emailResponse.text(); + return res.status(500).json({ error: `Échec de l'envoi de l'email`, details: emailErrorText }); + } + + console.log("Email envoyé avec succès"); return res.status(200).json({ registration: newRegistration, From aa6e350b2b5aee82125db7aa5c67c14b287355a6 Mon Sep 17 00:00:00 2001 From: AntonyKLINGER Date: Wed, 4 Sep 2024 16:40:17 +0200 Subject: [PATCH 070/100] maj package test --- package-lock.json | 120 ---------------------------------------------- 1 file changed, 120 deletions(-) diff --git a/package-lock.json b/package-lock.json index 0b9ec49..35f22d6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -611,21 +611,6 @@ "resolved": "https://registry.npmjs.org/@next/env/-/env-14.1.0.tgz", "integrity": "sha512-Py8zIo+02ht82brwwhTg36iogzFqGLPXlRGKQw5s+qP/kMNc4MAyDeEwBKDijk6zTIbegEgu8Qy7C1LboslQAw==" }, - "node_modules/@next/swc-darwin-arm64": { - "version": "14.1.0", - "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-14.1.0.tgz", - "integrity": "sha512-nUDn7TOGcIeyQni6lZHfzNoo9S0euXnu0jhsbMOmMJUBfgsnESdjN97kM7cBqQxZa8L/bM9om/S5/1dzCrW6wQ==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 10" - } - }, "node_modules/@next/swc-darwin-x64": { "version": "14.1.0", "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-14.1.0.tgz", @@ -641,111 +626,6 @@ "node": ">= 10" } }, - "node_modules/@next/swc-linux-arm64-gnu": { - "version": "14.1.0", - "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-14.1.0.tgz", - "integrity": "sha512-RHo7Tcj+jllXUbK7xk2NyIDod3YcCPDZxj1WLIYxd709BQ7WuRYl3OWUNG+WUfqeQBds6kvZYlc42NJJTNi4tQ==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@next/swc-linux-arm64-musl": { - "version": "14.1.0", - "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-14.1.0.tgz", - "integrity": "sha512-v6kP8sHYxjO8RwHmWMJSq7VZP2nYCkRVQ0qolh2l6xroe9QjbgV8siTbduED4u0hlk0+tjS6/Tuy4n5XCp+l6g==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@next/swc-linux-x64-gnu": { - "version": "14.1.0", - "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-14.1.0.tgz", - "integrity": "sha512-zJ2pnoFYB1F4vmEVlb/eSe+VH679zT1VdXlZKX+pE66grOgjmKJHKacf82g/sWE4MQ4Rk2FMBCRnX+l6/TVYzQ==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@next/swc-linux-x64-musl": { - "version": "14.1.0", - "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-14.1.0.tgz", - "integrity": "sha512-rbaIYFt2X9YZBSbH/CwGAjbBG2/MrACCVu2X0+kSykHzHnYH5FjHxwXLkcoJ10cX0aWCEynpu+rP76x0914atg==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@next/swc-win32-arm64-msvc": { - "version": "14.1.0", - "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-14.1.0.tgz", - "integrity": "sha512-o1N5TsYc8f/HpGt39OUQpQ9AKIGApd3QLueu7hXk//2xq5Z9OxmV6sQfNp8C7qYmiOlHYODOGqNNa0e9jvchGQ==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@next/swc-win32-ia32-msvc": { - "version": "14.1.0", - "resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-14.1.0.tgz", - "integrity": "sha512-XXIuB1DBRCFwNO6EEzCTMHT5pauwaSj4SWs7CYnME57eaReAKBXCnkUE80p/pAZcewm7hs+vGvNqDPacEXHVkw==", - "cpu": [ - "ia32" - ], - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@next/swc-win32-x64-msvc": { - "version": "14.1.0", - "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-14.1.0.tgz", - "integrity": "sha512-9WEbVRRAqJ3YFVqEZIxUqkiO8l1nool1LmNxygr5HWF8AcSYsEpneUDhmjUVJEzO2A04+oPtZdombzzPPkTtgg==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10" - } - }, "node_modules/@pdf-lib/standard-fonts": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/@pdf-lib/standard-fonts/-/standard-fonts-1.0.0.tgz", From 2df1f01657c088529ee89a49fa2389ab6683e858 Mon Sep 17 00:00:00 2001 From: AntonyKLINGER Date: Thu, 5 Sep 2024 11:25:35 +0200 Subject: [PATCH 071/100] delete log gets --- pages/api/emails/gets.js | 40 ---------------------------------------- 1 file changed, 40 deletions(-) delete mode 100644 pages/api/emails/gets.js diff --git a/pages/api/emails/gets.js b/pages/api/emails/gets.js deleted file mode 100644 index 14143e9..0000000 --- a/pages/api/emails/gets.js +++ /dev/null @@ -1,40 +0,0 @@ -const nodemailer = require('nodemailer'); - -export default async function handler(req, res) { - try { - // Retourner des informations dans la réponse pour les consulter - const logs = []; - - // Ajouter des logs pour inspecter la requête - logs.push({ message: 'Requête reçue', body: req.body }); - - // Vérification de la clé BREVO_KEY - logs.push({ message: 'Clé BREVO_KEY', value: process.env.BREVO_KEY }); - - const transporter = nodemailer.createTransport({ - host: 'smtp-relay.brevo.com', - port: 587, - secure: false, - auth: { - user: 'contact@territoiresentransitions.fr', - pass: process.env.BREVO_KEY - }, - tls: { rejectUnauthorized: false } - }); - - // Test de la connexion SMTP - transporter.verify(function(error, success) { - if (error) { - logs.push({ message: 'Erreur de connexion SMTP', error: error.message }); - return res.status(500).json({ status: 'error', logs: logs, message: 'Connexion au serveur SMTP échouée', details: error.message }); - } else { - logs.push({ message: 'Connexion au serveur SMTP réussie' }); - return res.status(200).json({ status: 'success', logs: logs, message: 'Connexion au serveur SMTP réussie' }); - } - }); - } catch (error) { - // Capturer et retourner l'erreur - res.status(500).json({ status: 'error', message: 'Erreur lors de la tentative de connexion', details: error.message }); - } - } - \ No newline at end of file From 830d5ec7502810f7e4fcaffd8f201d6b10153aa0 Mon Sep 17 00:00:00 2001 From: AntonyKLINGER Date: Thu, 5 Sep 2024 11:32:19 +0200 Subject: [PATCH 072/100] maj gets --- pages/api/emails/gets.js | 40 ++-------------------------------------- 1 file changed, 2 insertions(+), 38 deletions(-) diff --git a/pages/api/emails/gets.js b/pages/api/emails/gets.js index 9be3931..f85ea51 100644 --- a/pages/api/emails/gets.js +++ b/pages/api/emails/gets.js @@ -1,40 +1,4 @@ -const nodemailer = require('nodemailer'); - export default async function handler(req, res) { - try { - // Retourner des informations dans la réponse pour les consulter - const logs = []; - - // Ajouter des logs pour inspecter la requête - logs.push({ message: 'Requête reçue', body: req.body }); - - // Vérification de la clé BREVO_KEY - logs.push({ message: 'Clé BREVO_KEY', value: process.env.BREVO_KEY }); - - const transporter = nodemailer.createTransport({ - host: 'smtp-relay.brevo.com', - port: 587, - secure: false, - auth: { - user: 'contact@territoiresentransitions.fr', - pass: process.env.BREVO_KEY - }, - tls: { rejectUnauthorized: false } - }); - - // Test de la connexion SMTP - transporter.verify(function(error, success) { - if (error) { - logs.push({ message: 'Erreur de connexion SMTP', error: error.message }); - return res.status(500).json({ status: 'error', logs: logs, message: 'Connexion au serveur SMTP échouée', details: error.message }); - } else { - logs.push({ message: 'Connexion au serveur SMTP réussie' }); - return res.status(200).json({ status: 'success', logs: logs, message: 'Connexion au serveur SMTP réussie' }); - } - }); - } catch (error) { - // Capturer et retourner l'erreur - res.status(500).json({ status: 'error', message: 'Erreur lors de la tentative de connexion', details: error.message }); - } - } + res.json({ status: 'access' }) +} From 61cee563d6212a648f1db5252bd4f87aaa2f01a5 Mon Sep 17 00:00:00 2001 From: AntonyKLINGER Date: Thu, 5 Sep 2024 11:38:49 +0200 Subject: [PATCH 073/100] maj workflow mail j+2 --- pages/api/workflow/workflowAfter.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pages/api/workflow/workflowAfter.js b/pages/api/workflow/workflowAfter.js index 8ddfae5..bd0546b 100644 --- a/pages/api/workflow/workflowAfter.js +++ b/pages/api/workflow/workflowAfter.js @@ -11,7 +11,7 @@ export default async function handle(req, res) { try { const today = new Date(); const oneDayafter = new Date(today); - oneDayafter.setDate(today.getDate() - 1); + oneDayafter.setDate(today.getDate() - 2); oneDayafter.setHours(0, 0, 0, 0); const startOfDay = new Date(oneDayafter); From 281a167764491a7e7607591fc9d5304925921b2a Mon Sep 17 00:00:00 2001 From: AntonyKLINGER Date: Mon, 16 Sep 2024 09:51:30 +0200 Subject: [PATCH 074/100] maj password changes --- components/Profil.jsx | 38 ++++++++------- pages/api/users/lib/forgot-password.js | 66 +++++++++++++++++++++----- pages/api/users/lib/update-password.js | 30 ++++++++---- 3 files changed, 94 insertions(+), 40 deletions(-) diff --git a/components/Profil.jsx b/components/Profil.jsx index 04b437a..6011715 100644 --- a/components/Profil.jsx +++ b/components/Profil.jsx @@ -49,23 +49,24 @@ export default function Profil({ user }){ if(motDePasse && motDePasse2){ if(motDePasse.length > 5){ if(user.type == "Administrateur" || user.type == "DR"){ - // const fetcher = await fetch('/api/accounts/lib/update-password', { - // method: 'POST', - // headers: { - // 'Content-Type': 'application/json' - // }, - // body: JSON.stringify({ - // motDePasse: motDePasse, - // userId: user.id - // }) - // }) - // const json = await fetcher.json(); - // if(json.id){ - // setNotif({ - // text: 'Le mot de passe a bien été modififé !', - // icon: 'done' - // }) - // } + const fetcher = await fetch('/api/users/lib/update-password', { + method: 'POST', + headers: { + 'Content-Type': 'application/json' + }, + body: JSON.stringify({ + motDePasse: motDePasse, + userId: user.id, + type: 'special' + }) + }) + const json = await fetcher.json(); + if(json.id){ + setNotif({ + text: 'Le mot de passe a bien été modififé !', + icon: 'done' + }) + } } else { const fetcher = await fetch('/api/users/lib/update-password', { method: 'POST', @@ -74,7 +75,8 @@ export default function Profil({ user }){ }, body: JSON.stringify({ motDePasse: motDePasse, - userId: user.id + userId: user.id, + type: 'user' }) }) const json = await fetcher.json(); diff --git a/pages/api/users/lib/forgot-password.js b/pages/api/users/lib/forgot-password.js index 3d84de6..a33a45f 100644 --- a/pages/api/users/lib/forgot-password.js +++ b/pages/api/users/lib/forgot-password.js @@ -1,7 +1,7 @@ import bcrypt from 'bcrypt'; import prisma from '@/prisma'; const crypto = require('crypto'); -import fetch from 'node-fetch' +import fetch from 'node-fetch'; function generatePassword(length = 10) { return crypto.randomBytes(length) @@ -18,18 +18,55 @@ export default async function handle(req, res) { const { mail } = req.body; try { - const newPassword = generatePassword(); const hashedPassword = await bcrypt.hash(newPassword, SALT_ROUNDS); - - const updatedUser = await prisma.user.update({ - where: { mail: mail }, - data: { - motDePasse: hashedPassword - }, - }); - // envoyer mail avec le nouveau mdp : newPassword + // Chercher d'abord dans la table user + let updatedUser; + try { + updatedUser = await prisma.user.update({ + where: { mail: mail }, + data: { + motDePasse: hashedPassword + }, + }); + } catch (userError) { + // Si l'email n'est pas trouvé dans user, chercher dans account + let updatedAccount; + try { + updatedAccount = await prisma.account.update({ + where: { email: mail }, + data: { + password: hashedPassword + }, + }); + + if (!updatedAccount) { + // Si l'email n'est pas trouvé dans account non plus + throw new Error('Email not found in both user and account.'); + } + + // Envoyer le mail avec le nouveau mot de passe + await fetch(`${process.env.WEBSITE_URL}/api/emails/newPassword`, { + method: 'POST', + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + email: mail, + password: newPassword + }) + }); + + // Retourner la réponse avec l'updatedAccount + return res.json(updatedAccount); + } catch (accountError) { + // Gérer les erreurs liées à la table account + return res.status(500).json({ error: accountError.message }); + } + } + + // Envoyer le mail avec le nouveau mot de passe await fetch(`${process.env.WEBSITE_URL}/api/emails/newPassword`, { method: 'POST', headers: { @@ -39,11 +76,14 @@ export default async function handle(req, res) { email: mail, password: newPassword }) - }) + }); + + // Retourner la réponse avec l'updatedUser + return res.json(updatedUser); - res.json(updatedUser); } catch (error) { - res.status(500).json({ error: error.message }); + // Gérer les autres erreurs + return res.status(500).json({ error: error.message }); } } else { res.setHeader('Allow', ['POST']); diff --git a/pages/api/users/lib/update-password.js b/pages/api/users/lib/update-password.js index e2575f8..3eca810 100644 --- a/pages/api/users/lib/update-password.js +++ b/pages/api/users/lib/update-password.js @@ -5,20 +5,32 @@ const SALT_ROUNDS = 10; export default async function handle(req, res) { if (req.method === 'POST') { - const { motDePasse, userId } = req.body; + const { motDePasse, userId, type } = req.body; try { const hashedPassword = await bcrypt.hash(motDePasse, SALT_ROUNDS); - - const updatedUser = await prisma.user.update({ - where: { id: parseInt(userId) }, - data: { - motDePasse: hashedPassword - }, - }); - res.json(updatedUser); + if(type == "special"){ + const updatedUser = await prisma.account.update({ + where: { id: parseInt(userId) }, + data: { + password: hashedPassword + }, + }); + + res.json(updatedUser); + } else { + const updatedUser = await prisma.user.update({ + where: { id: parseInt(userId) }, + data: { + motDePasse: hashedPassword + }, + }); + + res.json(updatedUser); + } + } catch (error) { res.status(500).json({ error: error.message }); } From 2a6b239b9347ddf98b41b459ce0fcbba79f27ce2 Mon Sep 17 00:00:00 2001 From: AntonyKLINGER Date: Mon, 16 Sep 2024 09:58:11 +0200 Subject: [PATCH 075/100] maj forgot password --- pages/api/users/lib/forgot-password.js | 72 +++++++++++++------------- 1 file changed, 36 insertions(+), 36 deletions(-) diff --git a/pages/api/users/lib/forgot-password.js b/pages/api/users/lib/forgot-password.js index a33a45f..e2f61f2 100644 --- a/pages/api/users/lib/forgot-password.js +++ b/pages/api/users/lib/forgot-password.js @@ -21,32 +21,49 @@ export default async function handle(req, res) { const newPassword = generatePassword(); const hashedPassword = await bcrypt.hash(newPassword, SALT_ROUNDS); - // Chercher d'abord dans la table user - let updatedUser; - try { - updatedUser = await prisma.user.update({ + // Vérifier si le mail existe dans `user` + const user = await prisma.user.findUnique({ + where: { mail: mail } + }); + + if (user) { + // Si l'utilisateur existe, mettre à jour le mot de passe + const updatedUser = await prisma.user.update({ where: { mail: mail }, data: { motDePasse: hashedPassword }, }); - } catch (userError) { - // Si l'email n'est pas trouvé dans user, chercher dans account - let updatedAccount; - try { - updatedAccount = await prisma.account.update({ + + // Envoyer un email avec le nouveau mot de passe + await fetch(`${process.env.WEBSITE_URL}/api/emails/newPassword`, { + method: 'POST', + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + email: mail, + password: newPassword + }) + }); + + return res.json(updatedUser); + } else { + // Si l'utilisateur n'existe pas dans `user`, chercher dans `account` + const account = await prisma.account.findUnique({ + where: { email: mail } + }); + + if (account) { + // Si un compte existe, mettre à jour le mot de passe + const updatedAccount = await prisma.account.update({ where: { email: mail }, data: { password: hashedPassword }, }); - if (!updatedAccount) { - // Si l'email n'est pas trouvé dans account non plus - throw new Error('Email not found in both user and account.'); - } - - // Envoyer le mail avec le nouveau mot de passe + // Envoyer un email avec le nouveau mot de passe await fetch(`${process.env.WEBSITE_URL}/api/emails/newPassword`, { method: 'POST', headers: { @@ -58,31 +75,14 @@ export default async function handle(req, res) { }) }); - // Retourner la réponse avec l'updatedAccount return res.json(updatedAccount); - } catch (accountError) { - // Gérer les erreurs liées à la table account - return res.status(500).json({ error: accountError.message }); + } else { + // Si aucun utilisateur ou compte n'est trouvé + throw new Error('Email not found in both user and account.'); } } - - // Envoyer le mail avec le nouveau mot de passe - await fetch(`${process.env.WEBSITE_URL}/api/emails/newPassword`, { - method: 'POST', - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - email: mail, - password: newPassword - }) - }); - - // Retourner la réponse avec l'updatedUser - return res.json(updatedUser); - } catch (error) { - // Gérer les autres erreurs + // Gérer les erreurs return res.status(500).json({ error: error.message }); } } else { From 4231b9aee736a07694ad9f1dfa5b17d435472cbc Mon Sep 17 00:00:00 2001 From: AntonyKLINGER Date: Mon, 16 Sep 2024 10:07:56 +0200 Subject: [PATCH 076/100] maj export --- components/Participants.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/Participants.jsx b/components/Participants.jsx index e11c0b9..e6f7612 100644 --- a/components/Participants.jsx +++ b/components/Participants.jsx @@ -128,7 +128,7 @@ export default function Participants({ session, setOpen }){ expand_more
    - +
    {isMail && ( From 5045b38e00896cc9a1efbc4815d0d5befd5389c2 Mon Sep 17 00:00:00 2001 From: AntonyKLINGER Date: Mon, 16 Sep 2024 10:21:58 +0200 Subject: [PATCH 077/100] =?UTF-8?q?ajout=20polyn=C3=A9sie?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- components/AddSession.jsx | 6 ++++++ components/AllSessions.jsx | 1 + components/Comptes.jsx | 10 ++++++++++ pages/api/sessions/slug.js | 1 + pages/index.js | 2 ++ pages/rencontres/[category]/[session].js | 1 + pages/rencontres/[category]/index.js | 1 + pages/rencontres/index.js | 2 ++ 8 files changed, 24 insertions(+) diff --git a/components/AddSession.jsx b/components/AddSession.jsx index 64e4910..5a55cc8 100644 --- a/components/AddSession.jsx +++ b/components/AddSession.jsx @@ -459,6 +459,7 @@ export default function AddSession({setOpen, id, nom}){ + expand_more
    @@ -638,6 +639,11 @@ export default function AddSession({setOpen, id, nom}){ )} + {datas?.region == "Polynésie Française" && ( + <> + + + )} expand_more
    diff --git a/components/AllSessions.jsx b/components/AllSessions.jsx index eb1120b..3d1905d 100644 --- a/components/AllSessions.jsx +++ b/components/AllSessions.jsx @@ -145,6 +145,7 @@ export default function Modules({setPage, page, user}){ + expand_more
    diff --git a/components/Comptes.jsx b/components/Comptes.jsx index f012f52..14cea01 100644 --- a/components/Comptes.jsx +++ b/components/Comptes.jsx @@ -305,6 +305,11 @@ export default function Comptes({ user }) {
    + +
    + + +
    @@ -453,6 +458,11 @@ export default function Comptes({ user }) {
    + +
    + + +
    diff --git a/pages/api/sessions/slug.js b/pages/api/sessions/slug.js index 8892cd0..22c7b6a 100644 --- a/pages/api/sessions/slug.js +++ b/pages/api/sessions/slug.js @@ -19,6 +19,7 @@ const regionSlugs = { 'reunion': 'La Reunion', 'guadeloupe': 'Guadeloupe', 'mayotte': 'Mayotte', + 'polynesie-francaise': 'Polynésie Française', 'provence-alpes-cote-d-azur': 'Provence-Alpes-Côte d\'Azur' }; diff --git a/pages/index.js b/pages/index.js index 5d48875..8a39b49 100644 --- a/pages/index.js +++ b/pages/index.js @@ -30,6 +30,7 @@ export default function Home() { trad["GUY"] = "Guyane" trad["REU"] = "La Reunion" trad["MAY"] = "Mayotte" + trad["POL"] = "Polynésie Française" const getModules = async (nom) => { const fetcher = await fetch(`/api/modules/?nom=${nom}`) @@ -124,6 +125,7 @@ export default function Home() {
  • setRegion('GUY')} onMouseOut={() => setRegion('')}>roomGuyane
  • setRegion('REU')} onMouseOut={() => setRegion('')}>roomLa Reunion
  • setRegion('MAY')} onMouseOut={() => setRegion('')}>roomMayotte
  • +
  • setRegion('POL')} onMouseOut={() => setRegion('')}>roomPolynésie Française
  • Voir toutes les rencontres
    diff --git a/pages/rencontres/[category]/[session].js b/pages/rencontres/[category]/[session].js index 53c161e..02dbfcf 100644 --- a/pages/rencontres/[category]/[session].js +++ b/pages/rencontres/[category]/[session].js @@ -664,6 +664,7 @@ export default function Session({ data, user }){ + expand_more
    diff --git a/pages/rencontres/[category]/index.js b/pages/rencontres/[category]/index.js index 5da6031..8ca65d3 100644 --- a/pages/rencontres/[category]/index.js +++ b/pages/rencontres/[category]/index.js @@ -250,6 +250,7 @@ export default function Module({ data }){ + expand_more
    diff --git a/pages/rencontres/index.js b/pages/rencontres/index.js index 515f5af..c8213ec 100644 --- a/pages/rencontres/index.js +++ b/pages/rencontres/index.js @@ -407,6 +407,7 @@ export default function Rencontres({ base, region, pilier, thematique }){
  • {setFiltres(prev => { return { ...prev, nom: '', departement: '', region: "Guyane" } });setSwitcher(true)}}>roomGuyane
  • {setFiltres(prev => { return { ...prev, nom: '', departement: '', region: "La Reunion" } });setSwitcher(true)}}>roomLa Reunion
  • {setFiltres(prev => { return { ...prev, nom: '', departement: '', region: "Mayotte" } });setSwitcher(true)}}>roomMayotte
  • +
  • {setFiltres(prev => { return { ...prev, nom: '', departement: '', region: "Polynésie Française" } });setSwitcher(true)}}>roomPolynésie Française
  • @@ -515,6 +516,7 @@ export default function Rencontres({ base, region, pilier, thematique }){ + expand_more
    From abb5ebf7520d34a5e12bde22049b020af5e6bfce Mon Sep 17 00:00:00 2001 From: AntonyKLINGER Date: Mon, 16 Sep 2024 14:52:41 +0200 Subject: [PATCH 078/100] maj reunion --- pages/api/sessions/slug.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pages/api/sessions/slug.js b/pages/api/sessions/slug.js index 22c7b6a..e738bd6 100644 --- a/pages/api/sessions/slug.js +++ b/pages/api/sessions/slug.js @@ -16,7 +16,7 @@ const regionSlugs = { 'pays-de-la-loire': 'Pays de la Loire', 'guyane': 'Guyane', 'martinique': 'Martinique', - 'reunion': 'La Reunion', + 'la-reunion': 'La Reunion', 'guadeloupe': 'Guadeloupe', 'mayotte': 'Mayotte', 'polynesie-francaise': 'Polynésie Française', From 45a8e207e9f9f5d36cafb6615c2975581b06e3eb Mon Sep 17 00:00:00 2001 From: AntonyKLINGER Date: Tue, 17 Sep 2024 09:06:46 +0200 Subject: [PATCH 079/100] published sessions only --- pages/rencontres/index.js | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/pages/rencontres/index.js b/pages/rencontres/index.js index c8213ec..198e2ac 100644 --- a/pages/rencontres/index.js +++ b/pages/rencontres/index.js @@ -259,19 +259,27 @@ export default function Rencontres({ base, region, pilier, thematique }){ {modules.length > 0 ? (
    {!switcher ? - modules.map((module, index) => ( - <> + modules.map((module, index) => { + + const publishedUpcomingSessions = module.sessions.filter(session => { + const isPublished = session.status === "publish"; + const isUpcoming = new Date(session.dateDebut) > new Date(); + return isPublished && isUpcoming; + }); + + return (
    - - )) : modules.map((module, index) => { + ); + + }) : modules.map((module, index) => { const publishedUpcomingSessions = module.sessions.filter(session => { const isPublished = session.status === "publish"; const isUpcoming = new Date(session.dateDebut) > new Date(); From 7ac4f46217e216256601abe2385ca986740ee70c Mon Sep 17 00:00:00 2001 From: AntonyKLINGER Date: Wed, 18 Sep 2024 15:37:25 +0200 Subject: [PATCH 080/100] maj regions inscription --- pages/inscription.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/pages/inscription.js b/pages/inscription.js index 5881268..6f3b7aa 100644 --- a/pages/inscription.js +++ b/pages/inscription.js @@ -165,6 +165,12 @@ export default function Register(){ + + + + + + expand_more
    From e1e75c6f23e36f3a6430ef8f2da3ab1901bc8026 Mon Sep 17 00:00:00 2001 From: AntonyKLINGER Date: Thu, 26 Sep 2024 15:31:07 +0200 Subject: [PATCH 081/100] Maj GMT --- components/SessionBox.jsx | 8 +++----- components/SessionsBack.jsx | 10 ++++------ pages/rencontres/[category]/[session].js | 8 +++----- pages/rencontres/[category]/index.js | 8 +++----- pages/rencontres/index.js | 8 +++----- 5 files changed, 16 insertions(+), 26 deletions(-) diff --git a/components/SessionBox.jsx b/components/SessionBox.jsx index 6e3bd45..1277a17 100644 --- a/components/SessionBox.jsx +++ b/components/SessionBox.jsx @@ -4,12 +4,10 @@ import styles from '@/styles/SessionBox.module.css' export default function SessionBox({date, region, title, link, data, register, dept, see, detail, displayDept}){ function formatDate(dateString) { - const date = new Date(dateString); - const day = date.getDate().toString().padStart(2, '0'); - const month = (date.getMonth() + 1).toString().padStart(2, '0'); - const year = date.getFullYear(); + const base = dateString.split('T'); + const [year, month, day] = base[0].split('-') return `${day}/${month}/${year}`; - } + } return ( <> diff --git a/components/SessionsBack.jsx b/components/SessionsBack.jsx index 0ad01e5..716f5c6 100644 --- a/components/SessionsBack.jsx +++ b/components/SessionsBack.jsx @@ -5,13 +5,11 @@ import styles from '@/styles/SessionsBack.module.css' export default function SessionsBack({isModule, date, session, code, region, title, id, setOpen, setAlert, setActions, action, status, moduleId, dept, user}){ function formatDate(dateString) { - const date = new Date(dateString); - const day = date.getDate().toString().padStart(2, '0'); - const month = (date.getMonth() + 1).toString().padStart(2, '0'); - const year = date.getFullYear(); + const base = dateString.split('T'); + const [year, month, day] = base[0].split('-') return `${day}/${month}/${year}`; - } - + } + const startDate = formatDate(date); const [number, setNumber] = useState(0) diff --git a/pages/rencontres/[category]/[session].js b/pages/rencontres/[category]/[session].js index 02dbfcf..e437c2a 100644 --- a/pages/rencontres/[category]/[session].js +++ b/pages/rencontres/[category]/[session].js @@ -50,12 +50,10 @@ export async function getServerSideProps(context) { export default function Session({ data, user }){ function formatDate(dateString) { - const date = new Date(dateString); - const day = date.getDate().toString().padStart(2, '0'); - const month = (date.getMonth() + 1).toString().padStart(2, '0'); - const year = date.getFullYear(); + const base = dateString.split('T'); + const [year, month, day] = base[0].split('-') return `${day}/${month}/${year}`; - } + } const [alert, setAlert] = useState(null) const [notif, setNotif] = useState(null) diff --git a/pages/rencontres/[category]/index.js b/pages/rencontres/[category]/index.js index 8ca65d3..4e85ad7 100644 --- a/pages/rencontres/[category]/index.js +++ b/pages/rencontres/[category]/index.js @@ -37,12 +37,10 @@ export async function getServerSideProps(context) { export default function Module({ data }){ function formatDate(dateString) { - const date = new Date(dateString); - const day = date.getDate().toString().padStart(2, '0'); - const month = (date.getMonth() + 1).toString().padStart(2, '0'); - const year = date.getFullYear(); + const base = dateString.split('T'); + const [year, month, day] = base[0].split('-') return `${day}/${month}/${year}`; - } + } const lastUpdate = formatDate(data.lastUpdate); diff --git a/pages/rencontres/index.js b/pages/rencontres/index.js index 198e2ac..56b9812 100644 --- a/pages/rencontres/index.js +++ b/pages/rencontres/index.js @@ -85,12 +85,10 @@ export default function Rencontres({ base, region, pilier, thematique }){ const [switcher, setSwitcher] = useState(false) function formatDate(dateString) { - const date = new Date(dateString); - const day = date.getDate().toString().padStart(2, '0'); - const month = (date.getMonth() + 1).toString().padStart(2, '0'); - const year = date.getFullYear(); + const base = dateString.split('T'); + const [year, month, day] = base[0].split('-') return `${day}/${month}/${year}`; - } + } useEffect(() => { if(region != ''){ From 3921f154bc112b47ef62964dd5ba7f5fec4ee090 Mon Sep 17 00:00:00 2001 From: AntonyKLINGER Date: Mon, 30 Sep 2024 10:35:49 +0200 Subject: [PATCH 082/100] =?UTF-8?q?maj=20ajout=20des=20r=C3=A9gions=20manq?= =?UTF-8?q?uantes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- components/AddSession.jsx | 18 +++++++ components/Comptes.jsx | 33 ++++++++++++ components/EditSession.jsx | 24 +++++++++ components/Inscriptions.jsx | 4 ++ pages/api/sessions/slug.js | 5 +- pages/index.js | 16 ++++-- pages/inscription.js | 3 ++ pages/rencontres/[category]/[session].js | 3 ++ pages/rencontres/[category]/index.js | 3 ++ pages/rencontres/index.js | 6 +++ public/medias/map/nouvelle-caledonie.png | Bin 0 -> 2297 bytes public/medias/map/nouvelle-caledonie.svg | 14 +++++ public/medias/map/ocean-indien.png | Bin 0 -> 3795 bytes public/medias/map/ocean-indien.svg | 63 ++++++++++++++++++++++ public/medias/map/polynesie-francaise.png | Bin 0 -> 2178 bytes public/medias/map/polynesie-francaise.svg | 18 +++++++ public/medias/map/st-pierre-miquelon.png | Bin 0 -> 2785 bytes public/medias/map/st-pierre-miquelon.svg | 10 ++++ styles/globals.css | 5 +- 19 files changed, 218 insertions(+), 7 deletions(-) create mode 100644 public/medias/map/nouvelle-caledonie.png create mode 100644 public/medias/map/nouvelle-caledonie.svg create mode 100644 public/medias/map/ocean-indien.png create mode 100644 public/medias/map/ocean-indien.svg create mode 100644 public/medias/map/polynesie-francaise.png create mode 100644 public/medias/map/polynesie-francaise.svg create mode 100644 public/medias/map/st-pierre-miquelon.png create mode 100644 public/medias/map/st-pierre-miquelon.svg diff --git a/components/AddSession.jsx b/components/AddSession.jsx index 5a55cc8..9a831cc 100644 --- a/components/AddSession.jsx +++ b/components/AddSession.jsx @@ -460,6 +460,9 @@ export default function AddSession({setOpen, id, nom}){ + + + expand_more
    @@ -644,6 +647,21 @@ export default function AddSession({setOpen, id, nom}){ )} + {datas?.region == "Saint-Pierre et Miquelon" && ( + <> + + + )} + {datas?.region == "Océan Indien" && ( + <> + + + )} + {datas?.region == "Nouvelle Calédonie" && ( + <> + + + )} expand_more
    diff --git a/components/Comptes.jsx b/components/Comptes.jsx index 14cea01..7e1d63f 100644 --- a/components/Comptes.jsx +++ b/components/Comptes.jsx @@ -310,6 +310,23 @@ export default function Comptes({ user }) {
    + + +
    + + +
    + + +
    + + +
    + +
    + + +
    @@ -463,6 +480,22 @@ export default function Comptes({ user }) {
    + +
    + + +
    + + +
    + + +
    + +
    + + +
    diff --git a/components/EditSession.jsx b/components/EditSession.jsx index 3aee0b4..8c6667b 100644 --- a/components/EditSession.jsx +++ b/components/EditSession.jsx @@ -485,6 +485,10 @@ export default function EditSession({setOpen, id, nom, moduleId, page}){ + + + + expand_more
    @@ -664,6 +668,26 @@ export default function EditSession({setOpen, id, nom, moduleId, page}){ )} + {datas?.region == "Polynésie Française" && ( + <> + + + )} + {datas?.region == "Saint-Pierre et Miquelon" && ( + <> + + + )} + {datas?.region == "Océan Indien" && ( + <> + + + )} + {datas?.region == "Nouvelle Calédonie" && ( + <> + + + )} expand_more
    diff --git a/components/Inscriptions.jsx b/components/Inscriptions.jsx index 24a8f84..2bc6daf 100644 --- a/components/Inscriptions.jsx +++ b/components/Inscriptions.jsx @@ -87,6 +87,10 @@ export default function Inscriptions(){ + + + + expand_more diff --git a/pages/api/sessions/slug.js b/pages/api/sessions/slug.js index e738bd6..16982e5 100644 --- a/pages/api/sessions/slug.js +++ b/pages/api/sessions/slug.js @@ -20,7 +20,10 @@ const regionSlugs = { 'guadeloupe': 'Guadeloupe', 'mayotte': 'Mayotte', 'polynesie-francaise': 'Polynésie Française', - 'provence-alpes-cote-d-azur': 'Provence-Alpes-Côte d\'Azur' + 'provence-alpes-cote-d-azur': 'Provence-Alpes-Côte d\'Azur', + 'saint-pierre-et-miquelon': 'Saint-Pierre et Miquelon', + 'ocean-indien': 'Océan Indien', + 'nouvelle-caledonie': "Nouvelle Calédonie" }; export default async function handle(req, res) { diff --git a/pages/index.js b/pages/index.js index 8a39b49..d904bc5 100644 --- a/pages/index.js +++ b/pages/index.js @@ -31,6 +31,9 @@ export default function Home() { trad["REU"] = "La Reunion" trad["MAY"] = "Mayotte" trad["POL"] = "Polynésie Française" + trad["SPM"] = "Saint-Pierre et Miquelon" + trad["OIN"] = "Océan Indien" + trad["NCA"] = "Nouvelle Calédonie" const getModules = async (nom) => { const fetcher = await fetch(`/api/modules/?nom=${nom}`) @@ -75,7 +78,7 @@ export default function Home() {
    -
    +
    window.location.href = `/rencontres?region=Corse`} onMouseOver={() => setRegion('COR')} onMouseOut={() => setRegion('')} className={`map corse ${region == "COR" && styles.RegionLight}`} /> @@ -99,12 +102,14 @@ export default function Home() { window.location.href = `/rencontres?region=Guadeloupe`} onMouseOver={() => setRegion('GUA')} onMouseOut={() => setRegion('')} className={`${region == "GUA" && styles.RegionLight}`} /> window.location.href = `/rencontres?region=Martinique`} onMouseOver={() => setRegion('MART')} onMouseOut={() => setRegion('')} className={`${region == "MART" && styles.RegionLight}`} /> window.location.href = `/rencontres?region=Guyane`} onMouseOver={() => setRegion('GUY')} onMouseOut={() => setRegion('')} className={`${region == "GUY" && styles.RegionLight}`} /> - window.location.href = `/rencontres?region=La Reunion`} onMouseOver={() => setRegion('REU')} onMouseOut={() => setRegion('')} className={`${region == "REU" && styles.RegionLight}`} /> - window.location.href = `/rencontres?region=Mayotte`} onMouseOver={() => setRegion('MAY')} onMouseOut={() => setRegion('')} className={`${region == "MAY" && styles.RegionLight}`} /> + window.location.href = `/rencontres?region=Nouvelle Calédonie`} onMouseOver={() => setRegion('NCA')} onMouseOut={() => setRegion('')} className={`${region == "NCA" && styles.RegionLight}`} /> + window.location.href = `/rencontres?region=Océan Indien`} onMouseOver={() => setRegion('OIN')} onMouseOut={() => setRegion('')} className={`${region == "OIN" && styles.RegionLight}`} /> + window.location.href = `/rencontres?region=Polynésie Française`} onMouseOver={() => setRegion('POL')} onMouseOut={() => setRegion('')} className={`${region == "POL" && styles.RegionLight}`} /> + window.location.href = `/rencontres?region=Saint-Pierre et Miquelon`} onMouseOver={() => setRegion('SPM')} onMouseOut={() => setRegion('')} className={`${region == "SPM" && styles.RegionLight}`} />
    Carte des régions de France
    -
    +

    Découvrez les rencontres à venir dans votre région.

    • setRegion('ARA')} onMouseOut={() => setRegion('')}>roomAuvergne-Rhône-Alpes
    • @@ -126,6 +131,9 @@ export default function Home() {
    • setRegion('REU')} onMouseOut={() => setRegion('')}>roomLa Reunion
    • setRegion('MAY')} onMouseOut={() => setRegion('')}>roomMayotte
    • setRegion('POL')} onMouseOut={() => setRegion('')}>roomPolynésie Française
    • +
    • setRegion('SPM')} onMouseOut={() => setRegion('')}>roomSaint-Pierre et Miquelon
    • +
    • setRegion('OIN')} onMouseOut={() => setRegion('')}>roomOcéan Indien
    • +
    • setRegion('NCA')} onMouseOut={() => setRegion('')}>roomNouvelle Calédonie
    Voir toutes les rencontres
    diff --git a/pages/inscription.js b/pages/inscription.js index 6f3b7aa..9f34e57 100644 --- a/pages/inscription.js +++ b/pages/inscription.js @@ -171,6 +171,9 @@ export default function Register(){ + + + expand_more
    diff --git a/pages/rencontres/[category]/[session].js b/pages/rencontres/[category]/[session].js index e437c2a..362fd71 100644 --- a/pages/rencontres/[category]/[session].js +++ b/pages/rencontres/[category]/[session].js @@ -663,6 +663,9 @@ export default function Session({ data, user }){ + + + expand_more
    diff --git a/pages/rencontres/[category]/index.js b/pages/rencontres/[category]/index.js index 4e85ad7..92e1b69 100644 --- a/pages/rencontres/[category]/index.js +++ b/pages/rencontres/[category]/index.js @@ -249,6 +249,9 @@ export default function Module({ data }){ + + + expand_more
    diff --git a/pages/rencontres/index.js b/pages/rencontres/index.js index 56b9812..f7f98b9 100644 --- a/pages/rencontres/index.js +++ b/pages/rencontres/index.js @@ -414,6 +414,9 @@ export default function Rencontres({ base, region, pilier, thematique }){
  • {setFiltres(prev => { return { ...prev, nom: '', departement: '', region: "La Reunion" } });setSwitcher(true)}}>roomLa Reunion
  • {setFiltres(prev => { return { ...prev, nom: '', departement: '', region: "Mayotte" } });setSwitcher(true)}}>roomMayotte
  • {setFiltres(prev => { return { ...prev, nom: '', departement: '', region: "Polynésie Française" } });setSwitcher(true)}}>roomPolynésie Française
  • +
  • {setFiltres(prev => { return { ...prev, nom: '', departement: '', region: "Saint-Pierre et Miquelon" } });setSwitcher(true)}}>roomSaint-Pierre et Miquelon
  • +
  • {setFiltres(prev => { return { ...prev, nom: '', departement: '', region: "Océan Indien" } });setSwitcher(true)}}>roomOcéan Indien
  • +
  • {setFiltres(prev => { return { ...prev, nom: '', departement: '', region: "Nouvelle Calédonie" } });setSwitcher(true)}}>roomNouvelle Calédonie
  • @@ -523,6 +526,9 @@ export default function Rencontres({ base, region, pilier, thematique }){ + + + expand_more
    diff --git a/public/medias/map/nouvelle-caledonie.png b/public/medias/map/nouvelle-caledonie.png new file mode 100644 index 0000000000000000000000000000000000000000..fa324c67cb8e0c9e291a47a675c8b38b80fd6c13 GIT binary patch literal 2297 zcmVr#!QEo_Bl_(#(NDa*>0D|6l7TLfN+6LB3L!vi?5(GfL3E{iZFybQ0#UU(ah z6kmv03`Y0t*v!zHV<`&Z3hXiZdB&Vo9E`ntiLlfj4a>}lfTj2U-z-b*jd)kn186Hn zh43uhe2yL`9tS-OC?bTT@W|-;BTg6Jv|XzkRuY!sO_rV&oQNWm#ZS%qcl(U4Y@&59 zuEe#t8n@%=l4Goj`Qz+aKoKF#n0rGPzOgH?93LIMegf-o4Xz(ue=pEy6+EY*emg-C zA?&co-{+g&?Qs|mo%j0>;U@+9Ez464^w}AT2w|6;_Ycfjj#-?AOYm@kzRPemeuy^+ zQ9O!GWA1wjch@+sR!~F;FDcRA0DIyO_y}$)(NTP%5#Q8X@h|)nYsH7wHQtWjF8JLnet}PGxghci;WZWYo6Q&Y!b^p9$oLjc zsi>bi*=Nk}26zwNjE~{xHI642dDqk_X5I_O@JSI4o)(69E`EkH8Xn7L$t#4rl8oY+ z>?*!N(?m8|K2eCGb>tPo&A35YH|-4Gov{5T*&4?*J&17>aksutxRz5f#9I=!-y}15 zZ_|SqM-d_X75n1?F)L2NJ|eI+Z47a^7REb@4rm77l+JfQRNV@tZS07Bn;yhM$|&<* zk>{7nD(s)A-8OJQ(*syYSrc`UG*)2-uS?Kw8<;WP=g=r+g>bPn7Ga1tCTO<}WS-Sl zQC0{K;`h=lC->9-WS99|iH#P2F9srozExB)dp)h9b`~wF3o+a|dOc1MGx&F11DcdUp8XNFQ1Z4dF2}*DwGLU` z!NXW1%#@;tA>nG#1M^On3-B?KbR;7=kjm1-ri zn8@zMD~wM#SyD7v`*^>|Rh<7J%&KlxG09k02p4!yPO2_>TO*QJ4iO%-SBhump~7W6 z$+x-;GgzgWoXAd-qW19tA&B{GkE3y_Fx{ybigd9QCVlukBn3wG=D!q>qOZr^Y9R+(*nC_JQ z4n?SUuY`Rx#nJe(u&|7O9|yv*m5V0Ap^w+p&lhUyr%v`W+2lL-1ic9%JS1JjGGice zA6w_jEy<*Fx<~Ui+>{W$JNh}LAhyBD3EOXiT}(E=`d{9Lo63~=ERHvq@|I%qm|2Cz zO7yzKE+%u~^^k^8z?KnZiEKV~QR4Ox%7~=K#V7Z~ShDi#L2Rig<*b?jU z6}$+aQNYYCU{*L^4ldbF8@S)%kIzE!oi+*~<8hpeTS~Sw5T3VdL~+hJBBi{GTMHhI z%SJ!X&b#LCO0$(HCeB3{-i&*Mc`s8BnF)TS@Xdb?_lbhr)w&b5UN1HYJw#N4tq>F9 zheQbeZ=>tFybX6j2vsL=WTMy;=ZR(PvACn+eo}Jn=&Fo1KN>O~mZmy7TaWKA_G&mH zK_8u=D?&)gP?*=>i2a_HBwY}~xZK3583>p3FHL9Ea#4CA%rV4H_#K{CQ=hG&3qr`f z6e__`ScD&2Vw-bzK?wKM+}}WKj5TeM%PrCcAv~zOcd-bkiS_!DpbLHkBI)%E>9e5c zGZ2%<)xwvtNr>_?;lPXAcn#^T`6tBPHl8m2pRvy_eFH_0I~k39zhJmhF`bfYr+}TS-LKS`P_^T z#-YDw|f!{0_^0`D!#^>b~@kwbBc5X3p|va(A#8~=M4DQvxx`RdqBSDl zu$A;e2upDoemZ)cs{C#sj`cY(LHniYg%E5I#}FQF&N)@Jg&2yRPS)b(6}MfQUI@?R z3gMhOMw;#KvMi{pv~2hJUI^n^BV5O4i$_J3kBgyL#oQq3E4Hh!?ZWgz*gPBYMX~g& z`ox;dBYBR<$-F?rsd2p!7UxDW!8=LBHmaUXZikNx(KSXdgvr>1Zwp7%C5ietOSq;R z*|578LO%Y2cZj0e6sO)FFV4)mK+Vg{UI@ilAj0vip)Nr6Y$kKI_k;CZR*dH{CvvBdm$8K1AbL=pF4^DmXpv6 zp*Sb2FReZ!*-o;(5Q=k$*wbipc@8OfcB+PZA(Ue+UMu#8tV0mV<|Vxl%5xt+A$CPw zF1GQzc=Wdo75A0w;Idu_)v-y4;(EMaD=bsTfq;3>RFdM~w ziBB5ur?^|f$!RZyv|K2x#3N&_x|~uIk?Y*Yp6R8ZBlMsbLeGd^2tDY9&@ + + + + + + + + + + + + + diff --git a/public/medias/map/ocean-indien.png b/public/medias/map/ocean-indien.png new file mode 100644 index 0000000000000000000000000000000000000000..8bcfa65600b3989cf531a04238135965d46bf30f GIT binary patch literal 3795 zcmV;^4lMDBP){b?)b;o zm!9qInYrD4duAj3Rc$5n=-YR?zkBXE-#zDcu3RpYAwx^EJCI>!AR|HsAR|Hs4;c|M z02vW7c*uy50mz7u!9zxb3_wPN3?5onu3XvdK5R=k9=IO(HgGZUeKhOyr2z;-(-EoJE2==%K*a=MwW5^#C51`+lHmI8~Ahh1rP+JK({r=Ss%1NH`nf#*`_OSADw z@83Ld46h&}oCaJ5%&PI76VV)7Lf-cvBE$f&9L4E>M+BM+Y-HPv*WZW+0_b|21Iznv;n^d76#rw2Y3j$1&!YJi03!cgRNy6N0#GT zz!fNrn`t;5xElSgFpL0a1J^XHM;5S+8ctz42>_NMg3LoC7>;=U649ooR$vZr5wHnZ z3*3xUznOvq5n-#L11XbfJL-{OON2!=j_*!z{$kAII=u6~2KWfji>9f03HlNjdEf)c zN&W`#VPrvTVMpLUXd0Ojgs|zvQ^4+)?G@2H*lGFwNpvBTq8nMPe*gyqs~xmyi=%)W zkjZbw&PVF>{;ou%xjMDpS;EF5yozXZzpa%S#tjL|$cfA$2kilT{h|?Aj0V7VKu^SD zODIxmI_llDw-L{Dm0}zd7bAh!I|0vA-#oiO0ZGkq(F%OjQC||F9udxBdI(ex9n^M~ z43fsuvkG87y2{yi^Y`!+b5WLB*MIpWo@5BAe+BGe;7T(%dfA18OjY#aQWT}0DX zCkiD;&?qecUm$(w@nAG1_0{`g6_kP7s(jWBJP15O^uZVz^>l=_$TN41N#ZSdnefym z+9;!y!gFJsCkk4DPXON``sghoac&v#I9i>25G{3I4lF^}X&s7;#!%QighaImfoGF- zUr37x6Vx`D!$c1qN6Eh3yuebZ!%R%9+KBZWyskU?}IE3JeHKg~spt3alW zx1irqz|LBAps;on`+;DC*(lV%75Ey}El*X15h0Hjb-qh7`8cdy&;>9T!zgiW=;jX~ zLKqF8)(EpbXPTB|A2dhzBj;_vvQGtM>4tH;B;A9YGPom!|J9TK_A~(1XIdol`u=Aj*|^3HY-2XG;cM3~oXfrIFa5#tLG+f!AwLUg<2t1A#kRkjV^6z}3)#2vI~1$tWU*4UFH> zOzc4I`7tmeE$j3$Gpo}4lQ7eJ9Ky%Z$ zjdOffgU{QCJoQ%6C&I<3KsSiZD1Tx@;QcMYEk^%7iuknxIpm+@`kOc^f z7;N(!(?APS9WQIp`5r*Bu1h=_^SI}L-H^rsgpY<_p{m`aPTe?DR}!nCgT{w*21Qh4 zvI&{Yv~vUZa@5Wc(nCI_NW5 z5ok?fkCe{yCfudiuR_l58b|F_oge$q2#Jd_(FK%}cT5lRuJiZ{D`xpRP2_=H&`7&A zh4$Z$J3(y?j;}{8N2!1qR;i+_tydy)x>OxBa>1$_rIfow3sUx0qTdq7NghGbo$G6BwLe1K zl=exa6S&gYN0}~#mvL7}8^mT5V!FUARD-YwZl;HIIIcHIGln*8yAq8G_^DXn7r&+z ze!3*rX7)WHfOmy20jk>u_Q4*@42)z+1|xEsp4N>YveGU^dwKFLQ$o^;j}#+h0$ z;&O@@LIoo(aT~gMr{RVSMO4tz>!7W=L~zmJ5!^d-C4Ak%q|>>|{uxChEiK#x`~r7_ zqa8W6iKfSTM0lKdxe5lO=tj9F!X#6tESGr>&r^HP0v9*~=>aa#gK9hK`2s~`_UEGO zyAJtTYk_A%zW;Bu^7%*X>oiL!7hx%I7Y-JnqI%lbpiLnbV@C#4@EXLp_kNt4Wn;yL ziC4sXSBztV=tdihn`>*To?B5qLbaviQ-MEWmlH9B%GEX}>S+byC{yQQzi&^D=_7a? z5hPE%j9#1QAdbH>2rP?DmJc#GqEG%JhXP<3~`C@MKnkCA!b$!FM}oa zW{;sl#pkAiw;s$Ew>GPprroHRALE!XY()77L2GzGo#WP^#~)N1WTS{EU1%EFB|#sj zATAO5QDyNCC?a4H_&PNyqK7&M(GSO~CJ5!TX z!)hU-AdbVhuKrgdVFju=T!^0P(vR;v9*1^XIR;;bKO8+vGDw0Ew3BQqB!KkFwD&|F z@F7GC5evkxwhkiB?ks84Wp2dJ2oJWuGgEznNy4X%4rEco`dYb%Jq#xYvtakx4lL$e~Mo(-z z3vGGt!f7<|dnL-qe=*ODcno+y)5V{p*a`R)%26yLAK|yCz@?tT7={hN`*5F23Ct`a z803)pc0T@%G#NfFQUi&#X&z(7Z>BW#C|3c z!61*smm|>ycm|d1?~QLQ2GMA1!LOX2MDlAp@=2B;C(u<|SQ2cHeuvF-B>E7EyP0ks z`;p&pwyTcKh=)&B!2}w~cT~K$06m6yKeSEEDx}OE3;Yz#p{wvm`4tW7t1S*d*Sv)P zV6w1uz5z6)EJxExu*RYdx4zVjCPEm>OyA+;H^@|O3pfmkYtN!b2R}_X5sWlnMtdV2 zil3Xx`V&PGw9e|w6O=#!V-n2T_XdU5|j$V{Q zU>3KoN9zY~#m_hzKnqkWyw`)?F}-PaY$iL4uQcq59yY!K)mAhVxpKLg`($UBDafXV z3_wPN3?4EfWB@WEWblv?Ap?*RA%lmE2pNEk2pK$NM92WZ{{X#ME6eYc)W84$002ov JPDHLkV1iHw)x`h+ literal 0 HcmV?d00001 diff --git a/public/medias/map/ocean-indien.svg b/public/medias/map/ocean-indien.svg new file mode 100644 index 0000000..45f1458 --- /dev/null +++ b/public/medias/map/ocean-indien.svg @@ -0,0 +1,63 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/medias/map/polynesie-francaise.png b/public/medias/map/polynesie-francaise.png new file mode 100644 index 0000000000000000000000000000000000000000..89644bd9bc6a42d101b0fb771884d63057c1f1d9 GIT binary patch literal 2178 zcma);`#%$k8^>2sHj-(Zdl?cl*OY7Pw5-VLn3{VucP5wIBT6IYeo4dJCJ}QlcPWNb z$0ey&?wc}~BU=kYa-8p9@crTQeBRIVdVPNWJV{npFC7NSf&c)(VGDCJ>phR#le5Ud zy}7zO_-xOBf#&wX0D$Px|FjQ~Pn8A$MD#7p&R>t9u1rM@%Hw4Qcq9InZn&>(BCgEl zD-Eo1nH&c~fK>a5r`2RXoa+=8{=iUcaKbXYX*hj2JN{n81&qWAFr5rO|D1A1-O5j{ zQ>a|6+1ygIv*R~!aD8g(`(3Z_uog~1XJmMo*E}_kU%)ZtP&rg}d^JAFtZhL|MfHIS zNhnJ~QpQ3Ar~+5f+e34-x%(bwkTU+-Lq#AwGn16@ha_4_83^A8V+PP~bc8{C{z-0O zM>vsOQk62zcIi%Sw>LO_3hQz?-wY3q^z#Gv=a!HSW(|M&3oWW9lsu9U?@JQEe}7?p zE;p2_ppoi428!}`oZr0E_LwL~b_KA618KHe4Q3Gc)u z0*c`N5W**-?yciJN6ZRcMxv)03f1NSofZw~h|{&NlpTIG%g-=m*hRl?rEDTddm$OQ z`tE*ojRB7_<}@mRtSQCGF7w`?)<+7IxwmRCRwF^5Q(U~ZZ5p5^NV~sQSx<2uAx`?D ztYe~o#+=N@ywiX>X;Axb9FQ-T;)ouvkb)&6>Y>nR0FfIEuN~_3tQB#9&ZExC+b+Gd zocL*@VIyS8&8H6IJ7Q0==Xy3aso!%w+1@8er_qar(q<)iRI#5ad$H`?+eVDkPd`Jtc3b}zZ?#t1v=+bZyJ zVC*o*ug`jP%Lrn^1BrgRN&RrF5fhQ`{fyodN!#2xbJSgZ9LR#{q5|7mlOn~gJ~Eq# zzHW+(*x;}hWgXAW!Om+eRhQec5G?nrLWLlKTtud~#*tI!8=O0F8E=H2Ol2g+v;r?J*0@zF4Nk9a z4}Adq!lL5sa^fjcX^{l6_sGe6wytiEcbbz*r-MvAOt{xJ!{btuF|LZW#o$RNndh-3 zlFF#cKs|9o)4z>Z! z6VP>rhLzy&XCRLRNFd?C;>)7l*?F2|@w^;!uvhbC!SmenCcbCucMLn)^eoYajz4c< z$GO4UIT&e|QW*-g$`x|k0n}YosATh8$J0W@jJc7HEgloxlkQbdu|K-MbLJB3GpxX@^?2Q6w4y23r@gsRI^>RhrVIsBd#X?Y`==U$We?pC_Aqc_B_wJ$aNzXg|a*1CY;&qnM zb^&)B#PJOYcz959lNRX;NK9k}-BgZ9YRJ+Q>`(h>=-+r9n{6VSp3M(UbuH|(V5iYe zy-V0Cf0*CP5trnf&75=q8-OY{R8mX*jwIQCT+O}UK1O#W6+jp6g_ca*t=oyIw`=_e z64ig|yYka7Gg|YNwJn!L7WN%)InP5$68Hd1$Axb*?sj&IMhz27R`j?S}V{48sg z-5~q&oCt(kiBDykO&c9hSejPXpQVFt#YL1biXVvLHKRA4;g6BAm=%XGFL%Y{x1 z=T0jMvDMog22rSs$R|M*>8-PuDPK%$Fn9=hNQD_4w;~|ft%Ra1cL%9sS}lUkVoI$5 zrmNU;C@NXP*RR=Yb&9H%vXK~??pr-5?yHID(Ra~u066yDe18$%zY@9~UXWei;*)Uvrt=rQ@@JVz4}0X@PtVZWKl-*vz6&99L^cXjDB;<4!6#o(Pa&YR*6U`>(G>Y+(QY@Vrb5|+b6FCq$(nB1>epK; za4c*<)+JA$f%*@_Ws93yJ7biAghoTl$FED}+gkp&e2!=S9j;Ra-AHB{eOCn%eo&<9 zETlaSjTO31RZs0DwK$3M?$g(~$@ALT5~>AbNHKd3l;qfRV#q}mjy==C1@pwoj!mmo z3Ckf{bP;}lV(Mw^p@KfHfQShk%I<5=8tE%*yxShn#$#5$8P&vK(UfChWT})-*Ca=6 zP9{q|R47@i&LhH!0nD!|pUm;SA=jX|K`F9YC0; + + + + + + + + + + + + + + + + + diff --git a/public/medias/map/st-pierre-miquelon.png b/public/medias/map/st-pierre-miquelon.png new file mode 100644 index 0000000000000000000000000000000000000000..9a2b5c5e610c30560f7a56191a573f70cb0c5a32 GIT binary patch literal 2785 zcmV<73Lf=|P) z_=pNf0a7T6QYk5{vO=kpTCtQ+pjapmA1Eb?q9T?=qDE0LUIZ!P)LIf-WJ`5~Het3|s0iX`N$bwxe@I?rx0iOnrKz?v&3V_`4 z<`QjEg?1rK1-=Tr7071B+I4pc@HgOVCE2A8&G!iV0Y3xIOpl{B=QM!bz-NJDfL-O7 zrVq_6!l#f?L2DO~k+l$K0e6*Rkz%yA2s429(^&)w@C3?q zwTUYbfmEbu>>5BOj#dGC#yKwrCeysmsmNs1gTSn!jMIo#A%OgM|B&`Kj$;u62c@6g z$Fxye(JTajd+6;NV#Iyzd%zTv25CjR5H`|&`FSGLfK!k~sb?FrNGaNd@Mxc(uK_0^ za}!7QZ;oEH3t@+WGGgEmWO%s}ad-(1?LydVsGJxXN?(bzG8Y5;8!B4`+J#`62zWkl z9k30!5qKjo&8AUhpj`-^Je2w+LRy6L5a*U%z$V}}-~+&O3#!)|+J!K);PNw}MZlrJ z+kk5jkLU{uuDet!A#_KSKK4Zxzs@hY{=(2Mgn5?hzYchwWgCp3T?j7*hAq}V1-WNX zj}JnyNsR29P>*&YycGLO>GSC9KBorlLg;qou_)AgMQIm8FU!zHFx|ER{i0n6zoWQG zrEaj@J@t)tAq?6!Amu-{4d@r`LU@Aaen*?A-)^s62nn#$wh>f9aDwd?>uw+}@>?z1 zU<4n8u+w7Q5%6(~^&7(nA^g)~-H!v`w^+Y1d=SDPv9sP#2dEV zRtxnOf)7Ht8;O@xHX9HJ6)*5X2z!w2Z)G;o3Gkf~>nj`|gaGgvU_IrnJH*I3hd1~l zguO@{=I^G*Mc+I=0X$rA9i`%n5J0+!<-iFPD})5Nqrmd5;FAzCeuLy_$hwIHiMTez z#MULoJ10g`0Cv7g7g) z4V;XbSPahMyAbNgXd&a$miK2P|K;m|e;~q{jw~qEk$8^Fkb48K@m&Z2U!l1u^8YE!G;fQcd1>2tT6zHOIg$CEMZ@p$TCV z?GuGRn7$V*p$P$GLrUJaahNJmXplnq6(dIvlYq6BY;lGVg|MOJcrQ)Ag2w8$8yh~?s!%}gervHx#u>6dOJg?LddrQLFI1hM5sc@JEP99W`#q9 zDunz5QmgZ7kc29PJcrvhzy(4T!sOiZS6H*cAwm^G{s!>~s@%}Q3ZXS`<60ywaIl0b zgadQWBjDvoOr*D4vBm*H6hZ`?%}6KK80jv)i3H^GB86W!geZi|5Ftbz-aifTQMi!i z_p={xA`)q()8|wZnh<6n8(hcwF=J#$^bNotkm&2%fL|i1gC1dYG!^xPCWLn)NjoRX zVZarP%oaZf*%7q@kG?-|E@Xn7OLy0t<$}&rOCPI|*5MW;Rlsr+2HGMde}sLI@HZwo z1b87LjJbx(E|rj4goPB78Zaw!Spj92Mo2 zB7|v3(_N$xV&D>BYJqhWMkqqKlbBXx)SO!P6$F+0(_Kmu5}oAO$qfF$5$al z$WZZ0;HQ*#os*DdZFTrIk5EGobB+LYR-F-#ae%TG=81IM_m+ zedCJ|mLOqqTyRadA-=xxK?p|yKS8FDUAX6Y%C-T$;KCQz4+kS5bzKob9i;&~UHI~P zWq%|K>`dIbjtHgsAYJ(ayCp_4u`a-^K6yKEyKN(SLF+xjwMdjy*WAV~1O98>55~+kh4tNcx}iEZfl+8ig=z{8LIJ6Tw-Om!P~5Gz!6$ zP`M2x0f>4LfKDN-rTN9zX>L?0%KNAjtAPvfKm?#u2;V}6j19z#_#)ullp8(ua%6;{ zD~;|LXdE>>jHKvmAY0nAFgQ0OqWEG#^=4V;FGlg`pc5K}0OEhRhtUzyzJx45y#w*~Qw}x***j8}) zTM91U8omkP9!B3In3(;mBSXja2Fh|0--K`#;xo7rcr)-8Br!)nH;@V9Y_c4Wrj%RJ zI+gtL*jNha1FVq~-JfT8l7!&f290={6l%q&K;myz3j6~Zc{IUkR1W*ieF zk95)N8CLLB2)81RB!g|<%m4TrfiuS_Crb`mM*?vy#nWkK-=>%|)})UWz+K3O*{p9L zLUJ$cK-}S{AU|||UqlTN%m}Oy~S4{WHgYhEU!%b=wkK~MD#QW$B + + + + + + + + + diff --git a/styles/globals.css b/styles/globals.css index 79bc96a..ac9e78e 100644 --- a/styles/globals.css +++ b/styles/globals.css @@ -270,8 +270,9 @@ p{ } .map__image{ - width:100%; + width:91%; position: relative; + margin-left: auto; } .map__image .france{ @@ -421,7 +422,7 @@ p{ display: flex; justify-content: center; flex-direction: column; - transform:translateY(-350px); + transform:scale(0.9) translateY(-100%); position: absolute; } From 9ac65ce9de8e2dff1638ebabb87553e55f728477 Mon Sep 17 00:00:00 2001 From: AntonyKLINGER Date: Mon, 30 Sep 2024 10:52:01 +0200 Subject: [PATCH 083/100] ajout informations export --- components/Participants.jsx | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/components/Participants.jsx b/components/Participants.jsx index e6f7612..dc6f35f 100644 --- a/components/Participants.jsx +++ b/components/Participants.jsx @@ -20,10 +20,27 @@ export default function Participants({ session, setOpen }){ const [subject, setSubject] = useState('') const [isMail, setIsMail] = useState(false) - const exportToExcel = (jsonArray, sheetName) => { + const flattenJson = (jsonArray) => { + return jsonArray.map(item => { + const flattenedItem = { ...item }; + + if (item.user) { + flattenedItem.userOrganisation = item.user.organisation || ''; + flattenedItem.userFonction = item.user.fonction || ''; + delete flattenedItem.user; + } + + + return flattenedItem; + }); + }; + + const exportToExcel = (jsonArray, sheetName) => { + + const flattenedData = flattenJson(jsonArray); + const workbook = XLSX.utils.book_new(); - - const worksheet = XLSX.utils.json_to_sheet(jsonArray); + const worksheet = XLSX.utils.json_to_sheet(flattenedData); XLSX.utils.book_append_sheet(workbook, worksheet, sheetName); @@ -36,9 +53,10 @@ export default function Participants({ session, setOpen }){ document.body.appendChild(link); link.click(); - + document.body.removeChild(link); }; + function formatDate(dateString) { const date = new Date(dateString); From 538e14e64d2b16a267e6d9fcadcea7a40a1d7088 Mon Sep 17 00:00:00 2001 From: AntonyKLINGER Date: Mon, 30 Sep 2024 11:18:06 +0200 Subject: [PATCH 084/100] maj ajout champs formulaire --- components/SessionBox.jsx | 10 ++- pages/rencontres/[category]/[session].js | 49 +++++++---- prisma/schema.prisma | 100 ++++++++++++----------- 3 files changed, 91 insertions(+), 68 deletions(-) diff --git a/components/SessionBox.jsx b/components/SessionBox.jsx index 1277a17..9ad90d5 100644 --- a/components/SessionBox.jsx +++ b/components/SessionBox.jsx @@ -4,9 +4,13 @@ import styles from '@/styles/SessionBox.module.css' export default function SessionBox({date, region, title, link, data, register, dept, see, detail, displayDept}){ function formatDate(dateString) { - const base = dateString.split('T'); - const [year, month, day] = base[0].split('-') - return `${day}/${month}/${year}`; + if(dateString){ + const base = dateString.split('T'); + const [year, month, day] = base[0].split('-') + return `${day}/${month}/${year}`; + } else{ + return '---' + } } return ( diff --git a/pages/rencontres/[category]/[session].js b/pages/rencontres/[category]/[session].js index 362fd71..c0b4be9 100644 --- a/pages/rencontres/[category]/[session].js +++ b/pages/rencontres/[category]/[session].js @@ -82,6 +82,8 @@ export default function Session({ data, user }){ besoins: '', hebergement: '', regime: 'Omnivore', + programmeTETE: '', + participationUlterieure: false, days: true, repas: false, repas2: false, @@ -117,6 +119,8 @@ export default function Session({ data, user }){ repas2: inscription.repas2, besoins: inscription.besoins, regime: inscription.regime, + programmeTETE: inscription.programmeTETE, + participationUlterieure: inscription.participationUlterieure, days: inscription.days } @@ -164,6 +168,8 @@ export default function Session({ data, user }){ besoins: '', hebergement: '', regime: 'Omnivore', + programmeTETE: '', + participationUlterieure: false, repas: false, repas2: false, days: true, @@ -174,8 +180,8 @@ export default function Session({ data, user }){ } const register = async () => { - const { civilite, nom, prenom, mail, structure, fonction, type_fonction, ville, region, telephone, transport, besoins, hebergement, repas, rgpd, rgpd2 } = inscription - if(civilite && nom && prenom && mail && structure && fonction && type_fonction && region && transport){ + const { civilite, nom, prenom, mail, structure, fonction, type_fonction, ville, region, telephone, transport, besoins, hebergement, programmeTETE, repas, rgpd, rgpd2 } = inscription + if(civilite && nom && prenom && mail && structure && fonction && type_fonction && region && programmeTETE && transport){ if(rgpd && rgpd2){ if(mail.includes('@') && mail.includes('.')){ setAlert({ @@ -321,8 +327,8 @@ export default function Session({ data, user }){ }, [data]); const nextStep = () => { - const { civilite, nom, prenom, mail, structure, fonction, type_fonction, ville, region, telephone } = inscription - if(civilite && nom && prenom && mail && structure && fonction && type_fonction && region){ + const { civilite, nom, prenom, mail, structure, fonction, type_fonction, ville, region, programmeTETE, telephone } = inscription + if(civilite && nom && prenom && mail && structure && fonction && type_fonction && region && programmeTETE){ setReg(1) } else{ @@ -611,20 +617,22 @@ export default function Session({ data, user }){
    -
    - - expand_more -
    +
    - {other && ( -
    - setOtherSave(event.target.value)} value={otherSave} className="input-text" placeholder="Indiquez le type de structure" /> +
    +
    +

    Votre organisation est-elle engagée dans le programme Territoire Engagé Transition Ecologique (TETE) de l’ADEME ?

    +
    + + expand_more +
    - )} +
    @@ -734,7 +742,7 @@ export default function Session({ data, user }){ )} Besoins spécifiques complémentaires -
    +
    Participerez vous les deux jours ?
    @@ -743,6 +751,13 @@ export default function Session({ data, user }){
    +
    + Avez-vous déjà participé à un événement organisé par l'ADEME ? +
    + Oui + Non +
    +
    J’ai lu et j’accepte que l’ADEME collecte mes données afin de garantir la bonne utilisation des services offerts et reconnais avoir pris connaissance de sa politique de protection des données personnelles. diff --git a/prisma/schema.prisma b/prisma/schema.prisma index 76aefd1..17901fc 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -91,30 +91,32 @@ model MetasSession { } model Registration { - id Int @id @default(autoincrement()) - civilite String - nom String - prenom String - mail String - structure String - fonction String? - typeFonction String - ville String? - telephone String? - transport String? - besoins String? - repas Boolean - userId Int - sessionId Int - region String - repas2 Boolean? - days Boolean? - regime String? - deleted Boolean? - hebergement String? - presence Boolean? - session Session @relation(fields: [sessionId], references: [id]) - user User @relation(fields: [userId], references: [id]) + id Int @id @default(autoincrement()) + civilite String + nom String + prenom String + mail String + structure String + fonction String? + typeFonction String + ville String? + telephone String? + transport String? + besoins String? + repas Boolean + userId Int + sessionId Int + region String + repas2 Boolean? + days Boolean? + regime String? + deleted Boolean? + hebergement String? + presence Boolean? + programmeTETE String? + participationUlterieure Boolean? + session Session @relation(fields: [sessionId], references: [id]) + user User @relation(fields: [userId], references: [id]) } model Review { @@ -151,30 +153,32 @@ model Satisfaction { } model AccountRegistration { - id Int @id @default(autoincrement()) - civilite String? - nom String? - prenom String? - mail String? - structure String? - fonction String? - typeFonction String? - ville String? - telephone String? - transport String? - besoins String? - repas Boolean? - accountId Int - sessionId Int - region String? - repas2 Boolean? - days Boolean? - regime String? - deleted Boolean? - hebergement String? - presence Boolean? - account Account @relation(fields: [accountId], references: [id], onDelete: Cascade, onUpdate: NoAction) - session Session @relation(fields: [sessionId], references: [id], onDelete: Cascade, onUpdate: NoAction) + id Int @id @default(autoincrement()) + civilite String? + nom String? + prenom String? + mail String? + structure String? + fonction String? + typeFonction String? + ville String? + telephone String? + transport String? + besoins String? + repas Boolean? + accountId Int + sessionId Int + region String? + repas2 Boolean? + days Boolean? + regime String? + deleted Boolean? + hebergement String? + presence Boolean? + programmeTETE String? + participationUlterieure Boolean? + account Account @relation(fields: [accountId], references: [id], onDelete: Cascade, onUpdate: NoAction) + session Session @relation(fields: [sessionId], references: [id], onDelete: Cascade, onUpdate: NoAction) } model AccountReview { From fe669009db1cb24f378c6258f73fb47034e4a23e Mon Sep 17 00:00:00 2001 From: AntonyKLINGER Date: Mon, 30 Sep 2024 12:05:18 +0200 Subject: [PATCH 085/100] git test infos quizz --- components/Reviews.jsx | 106 +++++++++++++------------- pages/api/satisfaction/fromSession.js | 79 +++++++++++++++---- 2 files changed, 117 insertions(+), 68 deletions(-) diff --git a/components/Reviews.jsx b/components/Reviews.jsx index 525efae..8224925 100644 --- a/components/Reviews.jsx +++ b/components/Reviews.jsx @@ -1,17 +1,15 @@ -import React, { useState, useEffect } from 'react' -import Review from '@/components/Review' +import React, { useState, useEffect } from 'react'; +import Review from '@/components/Review'; import * as XLSX from 'xlsx'; -import styles from '@/styles/Reviews.module.css' +import styles from '@/styles/Reviews.module.css'; -export default function Reviews({ session, setOpen }){ +export default function Reviews({ session, setOpen }) { + const [number, setNumber] = useState(0); + const [reviews, setReviews] = useState([]); + const [moyenne, setMoyenne] = useState(0); + const [quizz, setQuizz] = useState([]); - const [number, setNumber] = useState(0) - const [reviews, setReviews] = useState([]) - const [moyenne, setMoyenne] = useState(0) - const [quizz, setQuizz] = useState([]) - - - console.log(session) + console.log(session); function formatDate(dateString) { const date = new Date(dateString); @@ -21,25 +19,35 @@ export default function Reviews({ session, setOpen }){ return `${day}/${month}/${year}`; } - const getParticipants = async () => { - const fetcher = await fetch(`/api/reviews/bySession?sessionId=${session.id}`) - const json = await fetcher.json() - if(json.length > 0){ - setNumber(json.length) - setReviews(json) - const sommeNotes = json.reduce((acc, review) => acc + review.note, 0); - const moyenneNotes = sommeNotes / json.length; - setMoyenne(moyenneNotes) - } - } + // const getParticipants = async () => { + // const fetcher = await fetch(`/api/reviews/bySession?sessionId=${session.id}`); + // const json = await fetcher.json(); + // if (json.length > 0) { + // setNumber(json.length); + // setReviews(json); + // const sommeNotes = json.reduce((acc, review) => acc + review.note, 0); + // const moyenneNotes = sommeNotes / json.length; + // setMoyenne(moyenneNotes); + // console.log("JSON => ", json); + // } + // }; const getQuizz = async () => { - const fetcher = await fetch(`/api/satisfaction/fromSession?sessionId=${session.id}`) - const json = await fetcher.json() - if(json.length > 0){ - setQuizz(json) + try { + const fetcher = await fetch(`/api/satisfaction/fromSession?sessionId=${session.id}`); + const json = await fetcher.json(); + console.log("Récupéré depuis l'API: ", json); // Vérifier les données + + if (json.length > 0) { + setQuizz(json); + } else { + console.log("Aucune donnée de satisfaction récupérée."); + } + } catch (error) { + console.error("Erreur lors de la récupération des questionnaires : ", error); } - } + }; + const questionLabels = { "1": "Qualité générale", @@ -55,14 +63,16 @@ export default function Reviews({ session, setOpen }){ }; useEffect(() => { - getParticipants() - getQuizz() - }, []) + console.log("Session info: ", session); // Vérifie que la session est bien définie + getQuizz(); + }, []); const exportToExcel = () => { const data = quizz.map((question) => { const responses = question.responses; - const participant = `${question.User.nom} ${question.User.prenom}`; + const participant = question.User + ? `${question.User.nom} ${question.User.prenom}` + : `${question.Account.email} (${question.Account.type})`; const row = { Participant: participant }; Object.entries(responses).forEach(([questionId, response]) => { if (Array.isArray(response)) { @@ -81,42 +91,33 @@ export default function Reviews({ session, setOpen }){ XLSX.writeFile(workbook, `questionnaires_session_${session.id}.xlsx`); }; - return ( - <> + <>
    setOpen(null)} className={styles.Back}>Retour aux sessions
    - {session.moduleName}
    Avis sur la session du {formatDate(session.dateDebut)}, {session.region}
    - {/*
    - reviews{number} avis - insights{moyenne > 0 ? moyenne : '-'}/5 de moyenne -
    - */} + + {session.moduleName}
    + Avis sur la session du {formatDate(session.dateDebut)}, {session.region} +
    - {/* {reviews.length > 0 ? ( - <> - {reviews.map((review, index) => { - return - })} - - ) : ( - Aucun avis pour cette session. - )} */} -

    Questionnaires de satisfaction :

    {quizz.length > 0 ? ( <> {quizz.map((question, index) => { const responses = question.responses; + const participant = question.User + ? `${question.User.nom} ${question.User.prenom}` + : `${question.Account.email} (${question.Account.type})`; + return ( - + {Object.entries(responses).map(([questionId, response], idx) => ( @@ -143,9 +144,8 @@ export default function Reviews({ session, setOpen }){ ) : ( Aucun questionnaire de satisfaction. )} - - ) -} \ No newline at end of file + ); +} diff --git a/pages/api/satisfaction/fromSession.js b/pages/api/satisfaction/fromSession.js index 6c67d08..bd01bda 100644 --- a/pages/api/satisfaction/fromSession.js +++ b/pages/api/satisfaction/fromSession.js @@ -16,51 +16,100 @@ export default async function handler(req, res) { const { sessionId } = req.query; try { - // Récupération des satisfactions des utilisateurs - const satisfaction = await prisma.satisfaction.findMany({ + console.log("Session ID reçu : ", sessionId); + + // Récupérer les satisfactions des utilisateurs + const userSatisfaction = await prisma.satisfaction.findMany({ where: { sessionId: sessionId ? parseInt(sessionId) : undefined, }, include: { - User: { + User: { // Inclure les informations de l'utilisateur select: { nom: true, prenom: true, }, }, + Session: true, // Inclure la session si nécessaire }, }); - // Récupération des satisfactions des comptes spéciaux + // Récupérer les satisfactions des comptes const accountSatisfaction = await prisma.accountSatisfaction.findMany({ where: { sessionId: sessionId ? parseInt(sessionId) : undefined, }, include: { - Account: { + Account: { // Inclure les informations du compte select: { email: true, type: true, }, }, + Session: true, // Inclure la session si nécessaire }, }); - // Combinaison des résultats + // Récupérer les informations d'inscription associées pour chaque utilisateur + const userSatisfactionWithRegistration = await Promise.all( + userSatisfaction.map(async (satisfactionItem) => { + const registration = await prisma.registration.findFirst({ + where: { + sessionId: parseInt(sessionId), + userId: satisfactionItem.userId, // Utiliser le userId pour obtenir les infos d'inscription + }, + select: { + mail: true, + structure: true, + fonction: true, + typeFonction: true, + ville: true, + }, + }); + + return { + ...satisfactionItem, + registration, // Ajouter les informations d'inscription + }; + }) + ); + + + // Récupérer les informations d'inscription associées pour chaque compte + const accountSatisfactionWithRegistration = await Promise.all( + accountSatisfaction.map(async (satisfactionItem) => { + const registration = await prisma.accountRegistration.findFirst({ + where: { + sessionId: parseInt(sessionId), + accountId: satisfactionItem.accountId, // Utiliser le accountId pour obtenir les infos d'inscription + }, + select: { + mail: true, + structure: true, + fonction: true, + typeFonction: true, + ville: true, + }, + }); + + return { + ...satisfactionItem, + registration, // Ajouter les informations d'inscription + }; + }) + ); + + // Combiner les résultats des deux sources (utilisateurs et comptes) const combinedSatisfaction = [ - ...satisfaction.map(item => ({ - ...item, - source: 'user', // Identifier la source de la satisfaction - })), - ...accountSatisfaction.map(item => ({ - ...item, - source: 'account', // Identifier la source de la satisfaction - })), + ...userSatisfactionWithRegistration, + ...accountSatisfactionWithRegistration, ]; + console.log("Satisfactions récupérées : ", satisfaction); + // Utilisation de la fonction serializeBigIntFields pour convertir correctement les BigInt res.status(200).json(serializeBigIntFields(combinedSatisfaction)); - } catch (error) { + } catch (error) { console.error('Error fetching satisfaction:', error); res.status(500).json({ error: 'Erreur lors de la récupération de la satisfaction.' }); } From 49846d6c525076e45244c295e945c050cd218907 Mon Sep 17 00:00:00 2001 From: AntonyKLINGER Date: Mon, 30 Sep 2024 12:12:54 +0200 Subject: [PATCH 086/100] maj from session quizz --- pages/api/satisfaction/fromSession.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/pages/api/satisfaction/fromSession.js b/pages/api/satisfaction/fromSession.js index bd01bda..059369f 100644 --- a/pages/api/satisfaction/fromSession.js +++ b/pages/api/satisfaction/fromSession.js @@ -105,8 +105,6 @@ export default async function handler(req, res) { ...accountSatisfactionWithRegistration, ]; - console.log("Satisfactions récupérées : ", satisfaction); - // Utilisation de la fonction serializeBigIntFields pour convertir correctement les BigInt res.status(200).json(serializeBigIntFields(combinedSatisfaction)); } catch (error) { From 957122e33cabf2aacb3ef0d828fc06de6dc8cc99 Mon Sep 17 00:00:00 2001 From: AntonyKLINGER Date: Mon, 30 Sep 2024 12:34:30 +0200 Subject: [PATCH 087/100] maj test reviews --- components/Reviews.jsx | 93 +++++++++++---------------- pages/api/satisfaction/fromSession.js | 61 ++++++++++-------- 2 files changed, 72 insertions(+), 82 deletions(-) diff --git a/components/Reviews.jsx b/components/Reviews.jsx index 8224925..3996703 100644 --- a/components/Reviews.jsx +++ b/components/Reviews.jsx @@ -1,15 +1,15 @@ -import React, { useState, useEffect } from 'react'; -import Review from '@/components/Review'; +import React, { useState, useEffect } from 'react' +import Review from '@/components/Review' import * as XLSX from 'xlsx'; -import styles from '@/styles/Reviews.module.css'; +import styles from '@/styles/Reviews.module.css' -export default function Reviews({ session, setOpen }) { - const [number, setNumber] = useState(0); - const [reviews, setReviews] = useState([]); - const [moyenne, setMoyenne] = useState(0); - const [quizz, setQuizz] = useState([]); +export default function Reviews({ session, setOpen }){ - console.log(session); + const [number, setNumber] = useState(0) + const [reviews, setReviews] = useState([]) + const [moyenne, setMoyenne] = useState(0) + const [quizz, setQuizz] = useState([]) + function formatDate(dateString) { const date = new Date(dateString); @@ -19,35 +19,13 @@ export default function Reviews({ session, setOpen }) { return `${day}/${month}/${year}`; } - // const getParticipants = async () => { - // const fetcher = await fetch(`/api/reviews/bySession?sessionId=${session.id}`); - // const json = await fetcher.json(); - // if (json.length > 0) { - // setNumber(json.length); - // setReviews(json); - // const sommeNotes = json.reduce((acc, review) => acc + review.note, 0); - // const moyenneNotes = sommeNotes / json.length; - // setMoyenne(moyenneNotes); - // console.log("JSON => ", json); - // } - // }; - const getQuizz = async () => { - try { - const fetcher = await fetch(`/api/satisfaction/fromSession?sessionId=${session.id}`); - const json = await fetcher.json(); - console.log("Récupéré depuis l'API: ", json); // Vérifier les données - - if (json.length > 0) { - setQuizz(json); - } else { - console.log("Aucune donnée de satisfaction récupérée."); - } - } catch (error) { - console.error("Erreur lors de la récupération des questionnaires : ", error); + const fetcher = await fetch(`/api/satisfaction/fromSession?sessionId=${session.id}`) + const json = await fetcher.json() + if(json.length > 0){ + setQuizz(json) } - }; - + } const questionLabels = { "1": "Qualité générale", @@ -63,16 +41,13 @@ export default function Reviews({ session, setOpen }) { }; useEffect(() => { - console.log("Session info: ", session); // Vérifie que la session est bien définie - getQuizz(); - }, []); + getQuizz() + }, []) const exportToExcel = () => { const data = quizz.map((question) => { const responses = question.responses; - const participant = question.User - ? `${question.User.nom} ${question.User.prenom}` - : `${question.Account.email} (${question.Account.type})`; + const participant = `${question.User.nom} ${question.User.prenom}`; const row = { Participant: participant }; Object.entries(responses).forEach(([questionId, response]) => { if (Array.isArray(response)) { @@ -91,33 +66,42 @@ export default function Reviews({ session, setOpen }) { XLSX.writeFile(workbook, `questionnaires_session_${session.id}.xlsx`); }; + return ( - <> + <>
    setOpen(null)} className={styles.Back}>Retour aux sessions
    - - {session.moduleName}
    - Avis sur la session du {formatDate(session.dateDebut)}, {session.region} -
    + {session.moduleName}
    Avis sur la session du {formatDate(session.dateDebut)}, {session.region}
    + {/*
    + reviews{number} avis + insights{moyenne > 0 ? moyenne : '-'}/5 de moyenne +
    + */}
    + {/* {reviews.length > 0 ? ( + <> + {reviews.map((review, index) => { + return + })} + + ) : ( + Aucun avis pour cette session. + )} */} +

    Questionnaires de satisfaction :

    {quizz.length > 0 ? ( <> {quizz.map((question, index) => { const responses = question.responses; - const participant = question.User - ? `${question.User.nom} ${question.User.prenom}` - : `${question.Account.email} (${question.Account.type})`; - return (
    Participant{question.User.nom || question.Account.email} {question.User.prenom || question.Account.type}{participant}
    - + {Object.entries(responses).map(([questionId, response], idx) => ( @@ -144,8 +128,9 @@ export default function Reviews({ session, setOpen }) { ) : ( Aucun questionnaire de satisfaction. )} + - ); -} + ) +} \ No newline at end of file diff --git a/pages/api/satisfaction/fromSession.js b/pages/api/satisfaction/fromSession.js index 059369f..54a4f16 100644 --- a/pages/api/satisfaction/fromSession.js +++ b/pages/api/satisfaction/fromSession.js @@ -16,43 +16,23 @@ export default async function handler(req, res) { const { sessionId } = req.query; try { - console.log("Session ID reçu : ", sessionId); - - // Récupérer les satisfactions des utilisateurs - const userSatisfaction = await prisma.satisfaction.findMany({ + // Récupération des satisfactions des utilisateurs + const satisfaction = await prisma.satisfaction.findMany({ where: { sessionId: sessionId ? parseInt(sessionId) : undefined, }, include: { - User: { // Inclure les informations de l'utilisateur + User: { select: { nom: true, prenom: true, }, }, - Session: true, // Inclure la session si nécessaire }, }); - // Récupérer les satisfactions des comptes - const accountSatisfaction = await prisma.accountSatisfaction.findMany({ - where: { - sessionId: sessionId ? parseInt(sessionId) : undefined, - }, - include: { - Account: { // Inclure les informations du compte - select: { - email: true, - type: true, - }, - }, - Session: true, // Inclure la session si nécessaire - }, - }); - - // Récupérer les informations d'inscription associées pour chaque utilisateur const userSatisfactionWithRegistration = await Promise.all( - userSatisfaction.map(async (satisfactionItem) => { + satisfaction.map(async (satisfactionItem) => { const registration = await prisma.registration.findFirst({ where: { sessionId: parseInt(sessionId), @@ -73,9 +53,23 @@ export default async function handler(req, res) { }; }) ); - - // Récupérer les informations d'inscription associées pour chaque compte + // Récupération des satisfactions des comptes spéciaux + const accountSatisfaction = await prisma.accountSatisfaction.findMany({ + where: { + sessionId: sessionId ? parseInt(sessionId) : undefined, + }, + include: { + Account: { + select: { + email: true, + type: true, + }, + }, + }, + }); + + const accountSatisfactionWithRegistration = await Promise.all( accountSatisfaction.map(async (satisfactionItem) => { const registration = await prisma.accountRegistration.findFirst({ @@ -99,15 +93,26 @@ export default async function handler(req, res) { }) ); - // Combiner les résultats des deux sources (utilisateurs et comptes) const combinedSatisfaction = [ ...userSatisfactionWithRegistration, ...accountSatisfactionWithRegistration, ]; + // Combinaison des résultats + // const combinedSatisfaction = [ + // ...satisfaction.map(item => ({ + // ...item, + // source: 'user', // Identifier la source de la satisfaction + // })), + // ...accountSatisfaction.map(item => ({ + // ...item, + // source: 'account', // Identifier la source de la satisfaction + // })), + // ]; + // Utilisation de la fonction serializeBigIntFields pour convertir correctement les BigInt res.status(200).json(serializeBigIntFields(combinedSatisfaction)); - } catch (error) { + } catch (error) { console.error('Error fetching satisfaction:', error); res.status(500).json({ error: 'Erreur lors de la récupération de la satisfaction.' }); } From 37610a636d3bd7a5fc076e8bb487a57832ca9e04 Mon Sep 17 00:00:00 2001 From: AntonyKLINGER Date: Mon, 30 Sep 2024 14:35:35 +0200 Subject: [PATCH 088/100] maj quizz admin --- pages/api/satisfaction/fromSession.js | 103 +++----------------------- 1 file changed, 10 insertions(+), 93 deletions(-) diff --git a/pages/api/satisfaction/fromSession.js b/pages/api/satisfaction/fromSession.js index 4169b50..029d2b8 100644 --- a/pages/api/satisfaction/fromSession.js +++ b/pages/api/satisfaction/fromSession.js @@ -19,7 +19,7 @@ export default async function handler(req, res) { console.log("Session ID reçu : ", sessionId); // Récupérer les satisfactions des utilisateurs - const userSatisfaction = await prisma.satisfaction.findMany({ + const satisfaction = await prisma.satisfaction.findMany({ where: { sessionId: sessionId ? parseInt(sessionId) : undefined, }, @@ -35,31 +35,7 @@ export default async function handler(req, res) { }); - const userSatisfactionWithRegistration = await Promise.all( - satisfaction.map(async (satisfactionItem) => { - const registration = await prisma.registration.findFirst({ - where: { - sessionId: parseInt(sessionId), - userId: satisfactionItem.userId, // Utiliser le userId pour obtenir les infos d'inscription - }, - select: { - mail: true, - structure: true, - fonction: true, - typeFonction: true, - ville: true, - }, - }); - - return { - ...satisfactionItem, - registration, // Ajouter les informations d'inscription - }; - }) - ); - // Récupération des satisfactions des comptes spéciaux - const accountSatisfaction = await prisma.accountSatisfaction.findMany({ where: { sessionId: sessionId ? parseInt(sessionId) : undefined, @@ -76,78 +52,19 @@ export default async function handler(req, res) { }); - // Récupérer les informations d'inscription associées pour chaque utilisateur - const userSatisfactionWithRegistration = await Promise.all( - userSatisfaction.map(async (satisfactionItem) => { - const registration = await prisma.registration.findFirst({ - where: { - sessionId: parseInt(sessionId), - userId: satisfactionItem.userId, // Utiliser le userId pour obtenir les infos d'inscription - }, - select: { - mail: true, - structure: true, - fonction: true, - typeFonction: true, - ville: true, - }, - }); - - return { - ...satisfactionItem, - registration, // Ajouter les informations d'inscription - }; - }) - ); - - - // Récupérer les informations d'inscription associées pour chaque compte - - const accountSatisfactionWithRegistration = await Promise.all( - accountSatisfaction.map(async (satisfactionItem) => { - const registration = await prisma.accountRegistration.findFirst({ - where: { - sessionId: parseInt(sessionId), - accountId: satisfactionItem.accountId, // Utiliser le accountId pour obtenir les infos d'inscription - }, - select: { - mail: true, - structure: true, - fonction: true, - typeFonction: true, - ville: true, - }, - }); - - return { - ...satisfactionItem, - registration, // Ajouter les informations d'inscription - }; - }) - ); - - - // Combiner les résultats des deux sources (utilisateurs et comptes) + // Combinaison des résultats const combinedSatisfaction = [ - ...userSatisfactionWithRegistration, - ...accountSatisfactionWithRegistration, + ...satisfaction.map(item => ({ + ...item, + source: 'user', // Identifier la source de la satisfaction + })), + ...accountSatisfaction.map(item => ({ + ...item, + source: 'account', // Identifier la source de la satisfaction + })), ]; - // Combinaison des résultats - // const combinedSatisfaction = [ - // ...satisfaction.map(item => ({ - // ...item, - // source: 'user', // Identifier la source de la satisfaction - // })), - // ...accountSatisfaction.map(item => ({ - // ...item, - // source: 'account', // Identifier la source de la satisfaction - // })), - // ]; - - console.log("Satisfactions récupérées : ", satisfaction); - // Utilisation de la fonction serializeBigIntFields pour convertir correctement les BigInt res.status(200).json(serializeBigIntFields(combinedSatisfaction)); } catch (error) { From 46d98961503efa95efcac143c5de623d35888198 Mon Sep 17 00:00:00 2001 From: AntonyKLINGER Date: Mon, 30 Sep 2024 14:40:54 +0200 Subject: [PATCH 089/100] maj questions satisfactions --- components/RencontreDetail.jsx | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) diff --git a/components/RencontreDetail.jsx b/components/RencontreDetail.jsx index 9099138..5ce598a 100644 --- a/components/RencontreDetail.jsx +++ b/components/RencontreDetail.jsx @@ -71,7 +71,7 @@ export default function RencontreDetail({ id, setOpen, userId, user }) { }, { id: 4, - text: "*De 1 à 5, comment évaluez-vous la qualité des formats participatifs qui ont eu lieu durant la Rencontre ?", + text: "*De 1 à 5, comment évaluez-vous la richesse des échanges avec les autres participant.e.s durant la Rencontre ?", options: [ { value: 5, label: "5/5 - Très satisfaisant" }, { value: 4, label: "4/5 - Satisfaisant" }, @@ -82,7 +82,7 @@ export default function RencontreDetail({ id, setOpen, userId, user }) { }, { id: 5, - text: "*De 1 à 5, comment évaluez-vous la richesse des échanges avec les autres participant.e.s durant la Rencontre ?", + text: "*De 1 à 5, comment évaluez-vous la qualité de l’animation (formats participatifs, dynamisme de l’animateur, etc.) de la Rencontre ?", options: [ { value: 5, label: "5/5 - Très satisfaisant" }, { value: 4, label: "4/5 - Satisfaisant" }, @@ -111,8 +111,7 @@ export default function RencontreDetail({ id, setOpen, userId, user }) { id: 8, text: "*Comment avez-vous connu les Rencontres Territoire Engagé Transition Ecologique ?", options: [ - { value: "Via la Direction Régionale de l’ADEME", label: "Via la Direction Régionale de l’ADEME" }, - { value: "Via un emailing ADEME", label: "Via un emailing ADEME" }, + { value: "Via un emailing de la Direction Régionale de l'ADEME", label: "Via un emailing de la Direction Régionale de l'ADEME" }, { value: "Via des articles de presse", label: "Via des articles de presse" }, { value: "Via des post sur les réseaux sociaux comme LinkedIn ou X", label: "Via des post sur les réseaux sociaux comme LinkedIn ou X" }, { value: "Via un des partenaires de l’ADEME", label: "Via un des partenaires de l’ADEME" }, @@ -124,16 +123,7 @@ export default function RencontreDetail({ id, setOpen, userId, user }) { }, { id: 9, - text: "*À combien de Rencontres avez-vous participé ?", - options: [ - { value: "Il s'agit de la première", label: "Il s'agit de la première" }, - { value: "2 à 3", label: "2 à 3" }, - { value: "4 ou plus", label: "4 ou plus" }, - ], - }, - { - id: 10, - text: "Il existe d’autres Rencontres Territoire Engagé Transition Ecologique. Quelles sont les thématiques susceptibles de vous intéresser ?", + text: "Il existe d’autres Rencontres Territoire Engagé Transition Ecologique. Quelles sont les thématiques susceptibles de vous intéresser ? (max. 5 réponses)", options: modules.map(module => ({ value: module.nom, label: module.nom })), type: "checkbox" } From 50d3c6b1edc1c0ea226adfa954618ca09e3461c4 Mon Sep 17 00:00:00 2001 From: AntonyKLINGER Date: Mon, 30 Sep 2024 14:52:41 +0200 Subject: [PATCH 090/100] maj telechargement badges --- components/Participants.jsx | 43 ++++++++ package-lock.json | 198 ++++++++++++++++++++++++++++++++++++ package.json | 2 + 3 files changed, 243 insertions(+) diff --git a/components/Participants.jsx b/components/Participants.jsx index dc6f35f..ab54c1f 100644 --- a/components/Participants.jsx +++ b/components/Participants.jsx @@ -1,6 +1,8 @@ import { useState, useEffect } from 'react' import Participant from '@/components/Participant' import * as XLSX from 'xlsx'; +import * as JSZip from 'jszip'; // Importer JSZip +import { saveAs } from 'file-saver'; // Importer file-saver pour gérer le téléchargement import Alert from '@/components/Alert' import { Notif } from '@/components/Notif' import styles from '@/styles/Participants.module.css' @@ -19,6 +21,7 @@ export default function Participants({ session, setOpen }){ const [editContent, setEditContent] = useState(''); const [subject, setSubject] = useState('') const [isMail, setIsMail] = useState(false) + const [loading, setLoading] = useState(false); const flattenJson = (jsonArray) => { return jsonArray.map(item => { @@ -66,6 +69,40 @@ export default function Participants({ session, setOpen }){ return `${day}/${month}/${year}`; } + // Fonction pour télécharger tous les badges + const downloadAllBadges = async () => { + setLoading(true); + const zip = new JSZip(); + + for (const participant of users) { + const datas = { + nom: participant.nom, + prenom: participant.prenom, + program: participant.session.metasSession.programmeSession, + organisation: participant.organisation || '', + }; + + const response = await fetch('/api/generate-badge', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify(datas), + }); + + const blob = await response.blob(); + zip.file(`badge_${participant.nom}_${participant.prenom}.pdf`, blob); + } + + zip.generateAsync({ type: 'blob' }).then((content) => { + saveAs(content, 'badges_participants.zip'); + setLoading(false); + }).catch(error => { + console.error('Erreur lors de la génération du fichier ZIP:', error); + setLoading(false); + }); + }; + const getParticipants = async () => { const fetcher = await fetch(`/api/registrations/bySession?sessionId=${session.id}`) const json = await fetcher.json() @@ -149,6 +186,12 @@ export default function Participants({ session, setOpen }){ +
    + + {loading &&

    Le téléchargement peut prendre du temps si le nombre de participants est élevé, veuillez patienter...

    } +
    {isMail && (

    Envoyer un mail aux participants

    diff --git a/package-lock.json b/package-lock.json index 9f48503..c79d0a0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16,10 +16,12 @@ "bcrypt": "^5.1.1", "crypto": "^1.0.1", "express": "^4.18.2", + "file-saver": "^2.0.5", "formidable": "^3.5.1", "fs": "^0.0.1-security", "js-cookie": "^3.0.5", "jsonwebtoken": "^9.0.2", + "jszip": "^3.10.1", "next": "14.1.0", "next-cookies": "^2.0.3", "node-fetch": "^3.3.2", @@ -1230,6 +1232,11 @@ "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" }, + "node_modules/core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" + }, "node_modules/cosmiconfig": { "version": "7.1.0", "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz", @@ -1642,6 +1649,11 @@ "node": "^12.20 || >= 14.13" } }, + "node_modules/file-saver": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/file-saver/-/file-saver-2.0.5.tgz", + "integrity": "sha512-P9bmyZ3h/PRG+Nzga+rbdI4OEpNDzAVyy74uVO9ATgzLK6VtAsYybF/+TOCvrc0MO793d6+42lLyZTw7/ArVzA==" + }, "node_modules/finalhandler": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", @@ -2033,6 +2045,11 @@ "node": ">=0.10.0" } }, + "node_modules/immediate": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz", + "integrity": "sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==" + }, "node_modules/import-fresh": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", @@ -2138,6 +2155,11 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" + }, "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", @@ -2201,6 +2223,44 @@ "npm": ">=6" } }, + "node_modules/jszip": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/jszip/-/jszip-3.10.1.tgz", + "integrity": "sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g==", + "dependencies": { + "lie": "~3.3.0", + "pako": "~1.0.2", + "readable-stream": "~2.3.6", + "setimmediate": "^1.0.5" + } + }, + "node_modules/jszip/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/jszip/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "node_modules/jszip/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, "node_modules/jwa": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz", @@ -2220,6 +2280,14 @@ "safe-buffer": "^5.0.1" } }, + "node_modules/lie": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/lie/-/lie-3.3.0.tgz", + "integrity": "sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==", + "dependencies": { + "immediate": "~3.0.5" + } + }, "node_modules/lines-and-columns": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", @@ -2846,6 +2914,11 @@ "node": ">= 0.6.0" } }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" + }, "node_modules/prop-types": { "version": "15.8.1", "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", @@ -3200,6 +3273,11 @@ "node": ">= 0.4" } }, + "node_modules/setimmediate": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", + "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==" + }, "node_modules/setprototypeof": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", @@ -3777,6 +3855,126 @@ "engines": { "node": ">= 6" } + }, + "node_modules/@next/swc-darwin-arm64": { + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-14.1.0.tgz", + "integrity": "sha512-nUDn7TOGcIeyQni6lZHfzNoo9S0euXnu0jhsbMOmMJUBfgsnESdjN97kM7cBqQxZa8L/bM9om/S5/1dzCrW6wQ==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-arm64-gnu": { + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-14.1.0.tgz", + "integrity": "sha512-RHo7Tcj+jllXUbK7xk2NyIDod3YcCPDZxj1WLIYxd709BQ7WuRYl3OWUNG+WUfqeQBds6kvZYlc42NJJTNi4tQ==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-arm64-musl": { + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-14.1.0.tgz", + "integrity": "sha512-v6kP8sHYxjO8RwHmWMJSq7VZP2nYCkRVQ0qolh2l6xroe9QjbgV8siTbduED4u0hlk0+tjS6/Tuy4n5XCp+l6g==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-x64-gnu": { + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-14.1.0.tgz", + "integrity": "sha512-zJ2pnoFYB1F4vmEVlb/eSe+VH679zT1VdXlZKX+pE66grOgjmKJHKacf82g/sWE4MQ4Rk2FMBCRnX+l6/TVYzQ==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-x64-musl": { + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-14.1.0.tgz", + "integrity": "sha512-rbaIYFt2X9YZBSbH/CwGAjbBG2/MrACCVu2X0+kSykHzHnYH5FjHxwXLkcoJ10cX0aWCEynpu+rP76x0914atg==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-win32-arm64-msvc": { + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-14.1.0.tgz", + "integrity": "sha512-o1N5TsYc8f/HpGt39OUQpQ9AKIGApd3QLueu7hXk//2xq5Z9OxmV6sQfNp8C7qYmiOlHYODOGqNNa0e9jvchGQ==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-win32-ia32-msvc": { + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-14.1.0.tgz", + "integrity": "sha512-XXIuB1DBRCFwNO6EEzCTMHT5pauwaSj4SWs7CYnME57eaReAKBXCnkUE80p/pAZcewm7hs+vGvNqDPacEXHVkw==", + "cpu": [ + "ia32" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-win32-x64-msvc": { + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-14.1.0.tgz", + "integrity": "sha512-9WEbVRRAqJ3YFVqEZIxUqkiO8l1nool1LmNxygr5HWF8AcSYsEpneUDhmjUVJEzO2A04+oPtZdombzzPPkTtgg==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } } } } diff --git a/package.json b/package.json index f48d013..c49c85e 100644 --- a/package.json +++ b/package.json @@ -17,10 +17,12 @@ "bcrypt": "^5.1.1", "crypto": "^1.0.1", "express": "^4.18.2", + "file-saver": "^2.0.5", "formidable": "^3.5.1", "fs": "^0.0.1-security", "js-cookie": "^3.0.5", "jsonwebtoken": "^9.0.2", + "jszip": "^3.10.1", "next": "14.1.0", "next-cookies": "^2.0.3", "node-fetch": "^3.3.2", From 33eca2517fb9d93f6e95d17a6f02723472d5b28b Mon Sep 17 00:00:00 2001 From: AntonyKLINGER Date: Mon, 30 Sep 2024 16:01:00 +0200 Subject: [PATCH 091/100] maj ajout participant manuellement --- components/Participants.jsx | 107 ++++++++++++++++++++++++++++++++- pages/api/users/findUser.js | 39 ++++++++++++ styles/Participants.module.css | 51 ++++++++++++++++ 3 files changed, 194 insertions(+), 3 deletions(-) create mode 100644 pages/api/users/findUser.js diff --git a/components/Participants.jsx b/components/Participants.jsx index ab54c1f..a901f2e 100644 --- a/components/Participants.jsx +++ b/components/Participants.jsx @@ -21,6 +21,10 @@ export default function Participants({ session, setOpen }){ const [editContent, setEditContent] = useState(''); const [subject, setSubject] = useState('') const [isMail, setIsMail] = useState(false) + const [openAdd, setOpenAdd] = useState(false) + const [openList, setOpenList] = useState(false) + const [searchUsers, setSearchUsers] = useState([]) + const [userAdded, setUserAdded] = useState(null) const [loading, setLoading] = useState(false); const flattenJson = (jsonArray) => { @@ -164,6 +168,75 @@ export default function Participants({ session, setOpen }){ } } + const chercherInscrit = async (nom) => { + if(nom.length >= 3){ + const getUsers = await fetch(`/api/users/findUser?search=${nom}`) + const get = await getUsers.json() + setSearchUsers(get) + setOpenList(true) + } + else{ + setOpenList(false) + } + } + + const addUserFromList = async (user) => { + setUserAdded(user) + setOpenList(false) + setSearchUsers([]) + } + + const ajouterInscrit = async () => { + let inscriptionData = { + civilite: '-', + mail: userAdded.mail, + nom: userAdded.nom, + prenom: userAdded.prenom, + structure: userAdded.organisation, + fonction: userAdded.fonction, + typeFonction: '-', + ville: '-', + region: userAdded.region, + telephone: '-', + transport: '-', + repas: false, + repas2: false, + besoins: null, + regime: 'Omnivore', + programmeTETE: null, + participationUlterieure: null, + days: false + } + + const registering = await fetch('/api/registrations/add', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ + inscriptionData: inscriptionData, + userId: userAdded.id, + sessionId: session.id, + type: 'user' + }) + }) + + const json = await registering.json() + + setUserAdded(null) + setOpenList(false) + setSearchUsers([]) + + setAlert(null) + setNotif({ + text: 'Le nouveau participant a été ajouté !', + icon: 'done' + }) + + getParticipants() + } + + useEffect(() => { getParticipants() }, [actions]) @@ -187,9 +260,12 @@ export default function Participants({ session, setOpen }){
    - +
    + + +
    {loading &&

    Le téléchargement peut prendre du temps si le nombre de participants est élevé, veuillez patienter...

    }
    {isMail && ( @@ -202,6 +278,31 @@ export default function Participants({ session, setOpen }){ )} + {openAdd && ( +
    +

    Ajouter un participant

    + {userAdded == null ? ( + <> + chercherInscrit(event.target.value)} name="rechercheInscrit" className="input-text" placeholder="Chercher un inscrit..." /> + {openList && ( + <> +
    + {searchUsers.map((user, i) => { + return + })} +
    + + )} + + ) : ( +
    + {userAdded.nom} {userAdded.prenom} - {userAdded.mail} + + +
    + )} +
    + )} {users.filter(user => selectedFonction === '' || user.fonction === selectedFonction).map((user, index) => { return diff --git a/pages/api/users/findUser.js b/pages/api/users/findUser.js new file mode 100644 index 0000000..f55ccb7 --- /dev/null +++ b/pages/api/users/findUser.js @@ -0,0 +1,39 @@ +import prisma from '@/prisma'; + +export default async function handle(req, res) { + const { search } = req.query; + + if (!search || search.trim() === '') { + return res.status(400).json({ error: 'Le paramètre de recherche est requis' }); + } + + try { + const users = await prisma.user.findMany({ + where: { + OR: [ + { + nom: { + contains: search, // Recherche partielle sur le nom + mode: 'insensitive', // Recherche insensible à la casse + }, + }, + { + mail: { + contains: search, // Recherche partielle sur l'email + mode: 'insensitive', // Recherche insensible à la casse + }, + }, + ], + }, + }); + + if (users.length === 0) { + return res.status(404).json({ message: 'Aucun utilisateur trouvé' }); + } + + res.json(users); + } catch (error) { + console.error(error); + res.status(500).json({ error: 'Erreur du serveur' }); + } +} diff --git a/styles/Participants.module.css b/styles/Participants.module.css index 20b7448..dbc3009 100644 --- a/styles/Participants.module.css +++ b/styles/Participants.module.css @@ -27,6 +27,57 @@ border-radius: 5px; } +.ListSearch{ + max-width: 500px; + margin-top:20px; +} + +.ListSearch button{ + width: 100%; + display: block; + text-align: left; + padding:10px; + box-sizing: border-box; + border:1px solid rgba(0,0,0,.1); + margin:5px 0; + cursor:pointer; +} + +.ListSearch button:hover{ + background-color: var(--primaryBack); +} + +.toAdd{ + border:0px; + background-color: var(--primary); + color:#FFF; + padding:7px 15px; + font-weight: 500; + box-sizing: border-box; + border-radius: 35px; + margin-left: 10px; + cursor:pointer; +} + +.toRem{ + border:0px; + cursor:pointer; +} + +.toRem span{ + border:0px; + background-color: var(--primaryBack); + color:var(--primary); + font-size: .9rem !important; + width:35px; + height: 35px; + border-radius: 50%; + display: inline-flex; + justify-content: center; + align-items: center; + margin-left: 10px; +} + .Title{ font-size: 1.15rem; color: var(--primary); From e17979c374b7b0b0247f0403df0b227310d5a50f Mon Sep 17 00:00:00 2001 From: AntonyKLINGER Date: Mon, 30 Sep 2024 16:19:48 +0200 Subject: [PATCH 092/100] maj informations perso --- components/Profil.jsx | 67 +++++++++++++++++++++++++++++++++- pages/api/users/updateInfos.js | 57 +++++++++++++++++++++++++++++ 2 files changed, 123 insertions(+), 1 deletion(-) create mode 100644 pages/api/users/updateInfos.js diff --git a/components/Profil.jsx b/components/Profil.jsx index 6011715..4a1275d 100644 --- a/components/Profil.jsx +++ b/components/Profil.jsx @@ -153,6 +153,29 @@ export default function Profil({ user }){ } } + const updateInfosUser = async () => { + const go = await fetch('/api/users/updateInfos', { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + id: user.id, + telephone: userData.telephone, + fonction: userData.fonction, + organisation: userData.organisation, + region: userData.region + }) + }) + const json = await go.json() + + setNotif({ + text: 'Vos informations ont été modifiées !', + icon: 'done' + }) + setAlert(null) + } + useEffect(() => { getUserInfos() }, []) @@ -170,7 +193,49 @@ export default function Profil({ user }){
    - + +
    + +
    +
    + +
    + + expand_more +
    +
    +
    +
    + + expand_more +
    +
    diff --git a/pages/api/users/updateInfos.js b/pages/api/users/updateInfos.js new file mode 100644 index 0000000..fe916b6 --- /dev/null +++ b/pages/api/users/updateInfos.js @@ -0,0 +1,57 @@ +import prisma from '@/prisma'; + +export default async function handle(req, res) { + + const { id, telephone, fonction, organisation, region } = req.body; // Les nouvelles informations envoyées par le client + + if (!id) { + return res.status(400).json({ error: 'L\'ID de l\'utilisateur est requis' }); + } + + try { + // Recherche de l'utilisateur existant par son ID + const user = await prisma.user.findUnique({ + where: { + id: parseInt(id), + }, + }); + + if (!user) { + return res.status(404).json({ error: 'Utilisateur non trouvé' }); + } + + // Préparation de l'objet de mise à jour, en comparant les nouvelles informations + const updatedData = {}; + + if (organisation && organisation !== user.organisation) { + updatedData.organisation = organisation; + } + if (region && region !== user.region) { + updatedData.region = region; + } + if (telephone && telephone !== user.telephone) { + updatedData.telephone = telephone; + } + if (fonction && fonction !== user.fonction) { + updatedData.fonction = fonction; + } + + // Si aucune donnée n'est à mettre à jour + if (Object.keys(updatedData).length === 0) { + return res.status(400).json({ message: 'Aucune modification détectée' }); + } + + // Mise à jour de l'utilisateur dans la base de données + const updatedUser = await prisma.user.update({ + where: { + id: parseInt(id), + }, + data: updatedData, + }); + + res.json(updatedUser); + } catch (error) { + console.error(error); + res.status(500).json({ error: 'Erreur du serveur' }); + } +} From 59387472abc5838d6e6defae0803594d456af26b Mon Sep 17 00:00:00 2001 From: AntonyKLINGER Date: Mon, 30 Sep 2024 16:24:03 +0200 Subject: [PATCH 093/100] maj duree module --- pages/rencontres/[category]/[session].js | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/pages/rencontres/[category]/[session].js b/pages/rencontres/[category]/[session].js index c0b4be9..763e34d 100644 --- a/pages/rencontres/[category]/[session].js +++ b/pages/rencontres/[category]/[session].js @@ -432,10 +432,19 @@ export default function Session({ data, user }){ icon
    - Date et horaires : + Date : {formatDate(data.metasSession.dateHoraires)}
    +
    +
    + icon +
    +
    + Durée du module : + {data.metasSession.nombreJours} jour{data.metasSession.nombreJour > 1 ? 's' : ''} +
    +
    icon From fd2e068d83335f1e20b98c9c9e029865ed06aec4 Mon Sep 17 00:00:00 2001 From: AntonyKLINGER Date: Mon, 30 Sep 2024 16:52:37 +0200 Subject: [PATCH 094/100] maj export questionnaire --- components/RencontreDetail.jsx | 1 + components/Reviews.jsx | 54 ++++++++++++++++++++++++--- pages/api/satisfaction/add.js | 4 +- pages/api/satisfaction/fromSession.js | 26 +++++++++++-- prisma/schema.prisma | 46 +++++++++++++---------- 5 files changed, 101 insertions(+), 30 deletions(-) diff --git a/components/RencontreDetail.jsx b/components/RencontreDetail.jsx index 5ce598a..4da0825 100644 --- a/components/RencontreDetail.jsx +++ b/components/RencontreDetail.jsx @@ -198,6 +198,7 @@ export default function RencontreDetail({ id, setOpen, userId, user }) { body: JSON.stringify({ userId: userId, sessionId: data.id, + registrationId: id, responses: responses, type: typeUser }), diff --git a/components/Reviews.jsx b/components/Reviews.jsx index ca59d93..be3cf33 100644 --- a/components/Reviews.jsx +++ b/components/Reviews.jsx @@ -70,10 +70,48 @@ export default function Reviews({ session, setOpen }) { const exportToExcel = () => { const data = quizz.map((question) => { const responses = question.responses; - const participant = question.User - ? `${question.User.nom} ${question.User.prenom}` - : `${question.Account.email} (${question.Account.type})`; - const row = { Participant: participant }; + let participant; + let registrationData = {}; + + // Identifier si c'est un utilisateur normal ou un compte spécial et inclure Registration ou AccountRegistration + if (question.User) { + participant = `${question.User.nom} ${question.User.prenom}`; + + // Inclure les informations de Registration s'il s'agit d'un User + const registration = question.User.registrations && question.User.registrations.length > 0 + ? question.User.registrations[0] // Assume we take the first registration if multiple + : null; + + if (registration) { + registrationData = { + Ville: registration.ville || '-', + Structure: registration.structure || '-', + Fonction: registration.fonction || '-', + Type_Fonction: registration.typeFonction || '-', + }; + } + } else if (question.Account) { + participant = `${question.Account.email} (${question.Account.type})`; + + // Inclure les informations de AccountRegistration s'il s'agit d'un Account + const accountRegistration = question.Account.accountRegistrations && question.Account.accountRegistrations.length > 0 + ? question.Account.accountRegistrations[0] + : null; + + if (accountRegistration) { + registrationData = { + Ville: accountRegistration.ville || '-', + Structure: accountRegistration.structure || '-', + Fonction: accountRegistration.fonction || '-', + Type_Fonction: registration.typeFonction || '-', + }; + } + } + + // Créer une ligne avec toutes les données + const row = { Participant: participant, ...registrationData }; + + // Ajouter les réponses aux questions dans la ligne Object.entries(responses).forEach(([questionId, response]) => { if (Array.isArray(response)) { row[questionLabels[questionId] || `Question ${questionId}`] = response.join(', '); @@ -81,15 +119,19 @@ export default function Reviews({ session, setOpen }) { row[questionLabels[questionId] || `Question ${questionId}`] = response; } }); + return row; }); - + + // Générer le fichier Excel const worksheet = XLSX.utils.json_to_sheet(data); const workbook = XLSX.utils.book_new(); XLSX.utils.book_append_sheet(workbook, worksheet, 'Quizz'); - + + // Télécharger le fichier Excel XLSX.writeFile(workbook, `questionnaires_session_${session.id}.xlsx`); }; + return ( <> diff --git a/pages/api/satisfaction/add.js b/pages/api/satisfaction/add.js index e0cde3d..7b4b09a 100644 --- a/pages/api/satisfaction/add.js +++ b/pages/api/satisfaction/add.js @@ -13,7 +13,7 @@ function serializeBigIntFields(data) { export default async function handler(req, res) { if (req.method === 'POST') { - const { userId, sessionId, responses, type } = req.body; + const { userId, sessionId, registrationId, responses, type } = req.body; try { console.log('Creating new satisfaction with data:', { userId, sessionId, responses, type }); @@ -26,6 +26,7 @@ export default async function handler(req, res) { data: { accountId: userId ? parseInt(userId) : null, sessionId: sessionId ? parseInt(sessionId) : null, + registrationId: registrationId ? parseInt(registrationId) : null, responses: responses ? responses : null, }, }); @@ -35,6 +36,7 @@ export default async function handler(req, res) { data: { userId: userId ? parseInt(userId) : null, sessionId: sessionId ? parseInt(sessionId) : null, + registrationId: registrationId ? parseInt(registrationId) : null, responses: responses ? responses : null, }, }); diff --git a/pages/api/satisfaction/fromSession.js b/pages/api/satisfaction/fromSession.js index 029d2b8..919de66 100644 --- a/pages/api/satisfaction/fromSession.js +++ b/pages/api/satisfaction/fromSession.js @@ -28,13 +28,23 @@ export default async function handler(req, res) { select: { nom: true, prenom: true, + registrations: true }, }, Session: true, // Inclure la session si nécessaire + // Registration: { // Inclure les informations de la registration + // select: { + // id: true, + // mail: true, + // structure: true, + // fonction: true, + // typeFonction: true, + // ville: true + // }, + // }, }, }); - // Récupération des satisfactions des comptes spéciaux const accountSatisfaction = await prisma.accountSatisfaction.findMany({ where: { @@ -45,14 +55,24 @@ export default async function handler(req, res) { select: { email: true, type: true, + accountRegistrations: true, }, }, Session: true, // Inclure la session si nécessaire + // AccountRegistration: { // Inclure les informations de la registration + // select: { + // id: true, + // nom: true, + // prenom: true, + // structure: true, + // fonction: true, + // typeFonction: true, + // ville: true + // }, + // }, }, }); - - // Combinaison des résultats const combinedSatisfaction = [ ...satisfaction.map(item => ({ diff --git a/prisma/schema.prisma b/prisma/schema.prisma index 17901fc..82790f9 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -91,7 +91,7 @@ model MetasSession { } model Registration { - id Int @id @default(autoincrement()) + id Int @id @default(autoincrement()) civilite String nom String prenom String @@ -115,8 +115,9 @@ model Registration { presence Boolean? programmeTETE String? participationUlterieure Boolean? - session Session @relation(fields: [sessionId], references: [id]) - user User @relation(fields: [userId], references: [id]) + session Session @relation(fields: [sessionId], references: [id]) + user User @relation(fields: [userId], references: [id]) + Satisfaction Satisfaction[] } model Review { @@ -143,17 +144,19 @@ model Account { /// This model contains row level security and requires additional setup for migrations. Visit https://pris.ly/d/row-level-security for more info. model Satisfaction { - id BigInt @id @default(autoincrement()) - userId Int? - sessionId Int? - created_at DateTime @default(now()) @db.Timestamptz(6) - responses Json? - Session Session? @relation(fields: [sessionId], references: [id], onDelete: NoAction, onUpdate: NoAction) - User User? @relation(fields: [userId], references: [id], onDelete: NoAction, onUpdate: NoAction) + id BigInt @id @default(autoincrement()) + userId Int? + sessionId Int? + created_at DateTime @default(now()) @db.Timestamptz(6) + responses Json? + registrationId Int? + Registration Registration? @relation(fields: [registrationId], references: [id], onDelete: NoAction, onUpdate: NoAction) + Session Session? @relation(fields: [sessionId], references: [id], onDelete: NoAction, onUpdate: NoAction) + User User? @relation(fields: [userId], references: [id], onDelete: NoAction, onUpdate: NoAction) } model AccountRegistration { - id Int @id @default(autoincrement()) + id Int @id @default(autoincrement()) civilite String? nom String? prenom String? @@ -177,8 +180,9 @@ model AccountRegistration { presence Boolean? programmeTETE String? participationUlterieure Boolean? - account Account @relation(fields: [accountId], references: [id], onDelete: Cascade, onUpdate: NoAction) - session Session @relation(fields: [sessionId], references: [id], onDelete: Cascade, onUpdate: NoAction) + account Account @relation(fields: [accountId], references: [id], onDelete: Cascade, onUpdate: NoAction) + session Session @relation(fields: [sessionId], references: [id], onDelete: Cascade, onUpdate: NoAction) + AccountSatisfaction AccountSatisfaction[] } model AccountReview { @@ -192,11 +196,13 @@ model AccountReview { } model AccountSatisfaction { - id BigInt @id @default(autoincrement()) - accountId Int? - sessionId Int? - created_at DateTime? @default(now()) @db.Timestamptz(6) - responses Json? - Account Account? @relation(fields: [accountId], references: [id], onDelete: NoAction, onUpdate: NoAction) - Session Session? @relation(fields: [sessionId], references: [id], onDelete: NoAction, onUpdate: NoAction) + id BigInt @id @default(autoincrement()) + accountId Int? + sessionId Int? + created_at DateTime? @default(now()) @db.Timestamptz(6) + responses Json? + registrationId Int? + Account Account? @relation(fields: [accountId], references: [id], onDelete: NoAction, onUpdate: NoAction) + AccountRegistration AccountRegistration? @relation(fields: [registrationId], references: [id], onDelete: NoAction, onUpdate: NoAction) + Session Session? @relation(fields: [sessionId], references: [id], onDelete: NoAction, onUpdate: NoAction) } From fdf9ff906f248bd874d847baa4cdfaf5802c66eb Mon Sep 17 00:00:00 2001 From: AntonyKLINGER Date: Tue, 1 Oct 2024 09:31:44 +0200 Subject: [PATCH 095/100] maj slug cote dazur --- pages/api/sessions/slug.js | 2 +- pages/rencontres/[category]/index.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pages/api/sessions/slug.js b/pages/api/sessions/slug.js index a5f1ce9..9bf75a8 100644 --- a/pages/api/sessions/slug.js +++ b/pages/api/sessions/slug.js @@ -24,7 +24,7 @@ const regionSlugs = { 'saint-pierre-et-miquelon': 'Saint-Pierre et Miquelon', 'ocean-indien': 'Océan Indien', 'nouvelle-caledonie': "Nouvelle Calédonie", - 'provence-alpes-cote-d-azur': 'Provence-Alpes-Côte d\'Azur' + 'provence-alpes-cote-dazur': 'Provence-Alpes-Côte d\'Azur' }; export default async function handle(req, res) { diff --git a/pages/rencontres/[category]/index.js b/pages/rencontres/[category]/index.js index 92e1b69..e02568e 100644 --- a/pages/rencontres/[category]/index.js +++ b/pages/rencontres/[category]/index.js @@ -274,7 +274,7 @@ export default function Module({ data }){ title={session.module.nom} link={`/rencontres/${session.module.slug}/session-${formatDate(session.dateDebut).replaceAll('/', '-')}-${session.region.normalize("NFD") .replace(/[\u0300-\u036f]/g, "") - .replace(/[.,]/g, "") + .replace(/[.,']/g, "") .replace(/\s+/g, '-') .toLowerCase()}`} dept={session.departement} From 9830bd7f7415ae43770fce71787b30fc0d5da177 Mon Sep 17 00:00:00 2001 From: AntonyKLINGER Date: Mon, 7 Oct 2024 21:46:50 +0200 Subject: [PATCH 096/100] maj module slug --- package-lock.json | 240 ++++++++++++++++++------------------ pages/api/modules/update.js | 10 +- 2 files changed, 125 insertions(+), 125 deletions(-) diff --git a/package-lock.json b/package-lock.json index c79d0a0..fa09ca7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -613,6 +613,21 @@ "resolved": "https://registry.npmjs.org/@next/env/-/env-14.1.0.tgz", "integrity": "sha512-Py8zIo+02ht82brwwhTg36iogzFqGLPXlRGKQw5s+qP/kMNc4MAyDeEwBKDijk6zTIbegEgu8Qy7C1LboslQAw==" }, + "node_modules/@next/swc-darwin-arm64": { + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-14.1.0.tgz", + "integrity": "sha512-nUDn7TOGcIeyQni6lZHfzNoo9S0euXnu0jhsbMOmMJUBfgsnESdjN97kM7cBqQxZa8L/bM9om/S5/1dzCrW6wQ==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, "node_modules/@next/swc-darwin-x64": { "version": "14.1.0", "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-14.1.0.tgz", @@ -628,6 +643,111 @@ "node": ">= 10" } }, + "node_modules/@next/swc-linux-arm64-gnu": { + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-14.1.0.tgz", + "integrity": "sha512-RHo7Tcj+jllXUbK7xk2NyIDod3YcCPDZxj1WLIYxd709BQ7WuRYl3OWUNG+WUfqeQBds6kvZYlc42NJJTNi4tQ==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-arm64-musl": { + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-14.1.0.tgz", + "integrity": "sha512-v6kP8sHYxjO8RwHmWMJSq7VZP2nYCkRVQ0qolh2l6xroe9QjbgV8siTbduED4u0hlk0+tjS6/Tuy4n5XCp+l6g==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-x64-gnu": { + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-14.1.0.tgz", + "integrity": "sha512-zJ2pnoFYB1F4vmEVlb/eSe+VH679zT1VdXlZKX+pE66grOgjmKJHKacf82g/sWE4MQ4Rk2FMBCRnX+l6/TVYzQ==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-x64-musl": { + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-14.1.0.tgz", + "integrity": "sha512-rbaIYFt2X9YZBSbH/CwGAjbBG2/MrACCVu2X0+kSykHzHnYH5FjHxwXLkcoJ10cX0aWCEynpu+rP76x0914atg==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-win32-arm64-msvc": { + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-14.1.0.tgz", + "integrity": "sha512-o1N5TsYc8f/HpGt39OUQpQ9AKIGApd3QLueu7hXk//2xq5Z9OxmV6sQfNp8C7qYmiOlHYODOGqNNa0e9jvchGQ==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-win32-ia32-msvc": { + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-14.1.0.tgz", + "integrity": "sha512-XXIuB1DBRCFwNO6EEzCTMHT5pauwaSj4SWs7CYnME57eaReAKBXCnkUE80p/pAZcewm7hs+vGvNqDPacEXHVkw==", + "cpu": [ + "ia32" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-win32-x64-msvc": { + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-14.1.0.tgz", + "integrity": "sha512-9WEbVRRAqJ3YFVqEZIxUqkiO8l1nool1LmNxygr5HWF8AcSYsEpneUDhmjUVJEzO2A04+oPtZdombzzPPkTtgg==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, "node_modules/@pdf-lib/standard-fonts": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/@pdf-lib/standard-fonts/-/standard-fonts-1.0.0.tgz", @@ -3855,126 +3975,6 @@ "engines": { "node": ">= 6" } - }, - "node_modules/@next/swc-darwin-arm64": { - "version": "14.1.0", - "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-14.1.0.tgz", - "integrity": "sha512-nUDn7TOGcIeyQni6lZHfzNoo9S0euXnu0jhsbMOmMJUBfgsnESdjN97kM7cBqQxZa8L/bM9om/S5/1dzCrW6wQ==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@next/swc-linux-arm64-gnu": { - "version": "14.1.0", - "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-14.1.0.tgz", - "integrity": "sha512-RHo7Tcj+jllXUbK7xk2NyIDod3YcCPDZxj1WLIYxd709BQ7WuRYl3OWUNG+WUfqeQBds6kvZYlc42NJJTNi4tQ==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@next/swc-linux-arm64-musl": { - "version": "14.1.0", - "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-14.1.0.tgz", - "integrity": "sha512-v6kP8sHYxjO8RwHmWMJSq7VZP2nYCkRVQ0qolh2l6xroe9QjbgV8siTbduED4u0hlk0+tjS6/Tuy4n5XCp+l6g==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@next/swc-linux-x64-gnu": { - "version": "14.1.0", - "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-14.1.0.tgz", - "integrity": "sha512-zJ2pnoFYB1F4vmEVlb/eSe+VH679zT1VdXlZKX+pE66grOgjmKJHKacf82g/sWE4MQ4Rk2FMBCRnX+l6/TVYzQ==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@next/swc-linux-x64-musl": { - "version": "14.1.0", - "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-14.1.0.tgz", - "integrity": "sha512-rbaIYFt2X9YZBSbH/CwGAjbBG2/MrACCVu2X0+kSykHzHnYH5FjHxwXLkcoJ10cX0aWCEynpu+rP76x0914atg==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@next/swc-win32-arm64-msvc": { - "version": "14.1.0", - "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-14.1.0.tgz", - "integrity": "sha512-o1N5TsYc8f/HpGt39OUQpQ9AKIGApd3QLueu7hXk//2xq5Z9OxmV6sQfNp8C7qYmiOlHYODOGqNNa0e9jvchGQ==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@next/swc-win32-ia32-msvc": { - "version": "14.1.0", - "resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-14.1.0.tgz", - "integrity": "sha512-XXIuB1DBRCFwNO6EEzCTMHT5pauwaSj4SWs7CYnME57eaReAKBXCnkUE80p/pAZcewm7hs+vGvNqDPacEXHVkw==", - "cpu": [ - "ia32" - ], - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@next/swc-win32-x64-msvc": { - "version": "14.1.0", - "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-14.1.0.tgz", - "integrity": "sha512-9WEbVRRAqJ3YFVqEZIxUqkiO8l1nool1LmNxygr5HWF8AcSYsEpneUDhmjUVJEzO2A04+oPtZdombzzPPkTtgg==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10" - } } } } diff --git a/pages/api/modules/update.js b/pages/api/modules/update.js index 8541ca3..5121933 100644 --- a/pages/api/modules/update.js +++ b/pages/api/modules/update.js @@ -72,11 +72,11 @@ export default async function handle(req, res) { const now = new Date(); let slug = moduleData.nom - .normalize("NFD") - .replace(/[\u0300-\u036f]/g, "") - .replace(/[.,]/g, "") - .replace(/\s+/g, '-') - .toLowerCase(); + .normalize("NFD") + .replace(/[\u0300-\u036f]/g, "") + .replace(/[.,?]/g, "") + .replace(/\s+/g, '-') + .toLowerCase() const updatedModule = await prisma.module.update({ where: { id: parseInt(moduleId) }, From 150093f3998f558bce4d0d702899dcf458bb21b8 Mon Sep 17 00:00:00 2001 From: AntonyKLINGER Date: Mon, 7 Oct 2024 22:01:01 +0200 Subject: [PATCH 097/100] maj all bugs resolution --- components/AddSession.jsx | 2 -- components/AllSessions.jsx | 3 +++ components/EditSession.jsx | 2 -- components/RencontreDetail.jsx | 16 ++++++++-------- pages/index.js | 2 -- pages/rencontres/[category]/[session].js | 2 +- pages/rencontres/index.js | 2 -- 7 files changed, 12 insertions(+), 17 deletions(-) diff --git a/components/AddSession.jsx b/components/AddSession.jsx index 9a831cc..c3e9d31 100644 --- a/components/AddSession.jsx +++ b/components/AddSession.jsx @@ -457,8 +457,6 @@ export default function AddSession({setOpen, id, nom}){ - - diff --git a/components/AllSessions.jsx b/components/AllSessions.jsx index 3d1905d..3ace565 100644 --- a/components/AllSessions.jsx +++ b/components/AllSessions.jsx @@ -146,6 +146,9 @@ export default function Modules({setPage, page, user}){ + + + expand_more
    diff --git a/components/EditSession.jsx b/components/EditSession.jsx index 8c6667b..2bbc8d9 100644 --- a/components/EditSession.jsx +++ b/components/EditSession.jsx @@ -483,8 +483,6 @@ export default function EditSession({setOpen, id, nom, moduleId, page}){ - - diff --git a/components/RencontreDetail.jsx b/components/RencontreDetail.jsx index 4da0825..3b1423e 100644 --- a/components/RencontreDetail.jsx +++ b/components/RencontreDetail.jsx @@ -38,7 +38,7 @@ export default function RencontreDetail({ id, setOpen, userId, user }) { const questions = [ { id: 1, - text: "*De 1 à 5, comment évaluez-vous la qualité générale de la Rencontre ?", + text: "De 1 à 5, comment évaluez-vous la qualité générale de la Rencontre ?", options: [ { value: 5, label: "5/5 - Très satisfaisant" }, { value: 4, label: "4/5 - Satisfaisant" }, @@ -49,7 +49,7 @@ export default function RencontreDetail({ id, setOpen, userId, user }) { }, { id: 2, - text: "*De 1 à 5, comment évaluez-vous la qualité du contenu technique partagé lors de la Rencontre ?", + text: "De 1 à 5, comment évaluez-vous la qualité du contenu technique partagé lors de la Rencontre ?", options: [ { value: 5, label: "5/5 - Très satisfaisant" }, { value: 4, label: "4/5 - Satisfaisant" }, @@ -60,7 +60,7 @@ export default function RencontreDetail({ id, setOpen, userId, user }) { }, { id: 3, - text: "*De 1 à 5, comment évaluez-vous la pertinence des intervenant.e.s (expertises, témoignages ...) présent.e.s à la Rencontre ?", + text: "De 1 à 5, comment évaluez-vous la pertinence des intervenants (expertises, témoignages ...) présents à la Rencontre ?", options: [ { value: 5, label: "5/5 - Très satisfaisant" }, { value: 4, label: "4/5 - Satisfaisant" }, @@ -71,7 +71,7 @@ export default function RencontreDetail({ id, setOpen, userId, user }) { }, { id: 4, - text: "*De 1 à 5, comment évaluez-vous la richesse des échanges avec les autres participant.e.s durant la Rencontre ?", + text: "De 1 à 5, comment évaluez-vous la richesse des échanges avec les autres participants durant la Rencontre ?", options: [ { value: 5, label: "5/5 - Très satisfaisant" }, { value: 4, label: "4/5 - Satisfaisant" }, @@ -82,7 +82,7 @@ export default function RencontreDetail({ id, setOpen, userId, user }) { }, { id: 5, - text: "*De 1 à 5, comment évaluez-vous la qualité de l’animation (formats participatifs, dynamisme de l’animateur, etc.) de la Rencontre ?", + text: "De 1 à 5, comment évaluez-vous la qualité de l’animation (formats participatifs, dynamisme de l’animateur, etc.) de la Rencontre ?", options: [ { value: 5, label: "5/5 - Très satisfaisant" }, { value: 4, label: "4/5 - Satisfaisant" }, @@ -93,7 +93,7 @@ export default function RencontreDetail({ id, setOpen, userId, user }) { }, { id: 6, - text: "*De 1 à 5, comment évaluez-vous la qualité de l’organisation de la Rencontre (inscription, communication, lieu, repas, etc.) ?", + text: "De 1 à 5, comment évaluez-vous la qualité de l’organisation de la Rencontre (inscription, communication, lieu, repas, etc.) ?", options: [ { value: 5, label: "5/5 - Très satisfaisant" }, { value: 4, label: "4/5 - Satisfaisant" }, @@ -109,7 +109,7 @@ export default function RencontreDetail({ id, setOpen, userId, user }) { }, { id: 8, - text: "*Comment avez-vous connu les Rencontres Territoire Engagé Transition Ecologique ?", + text: "Comment avez-vous connu les Rencontres Territoire Engagé Transition Ecologique ?", options: [ { value: "Via un emailing de la Direction Régionale de l'ADEME", label: "Via un emailing de la Direction Régionale de l'ADEME" }, { value: "Via des articles de presse", label: "Via des articles de presse" }, @@ -177,7 +177,7 @@ export default function RencontreDetail({ id, setOpen, userId, user }) { const handleSubmit = async (event) => { event.preventDefault(); - const requiredQuestions = questions.filter(q => q.id !== 7); + const requiredQuestions = questions.filter(q => q.id == 100000); const unansweredQuestions = requiredQuestions.filter(q => !responses[q.id] || (q.type === 'radioWithText' && responses[q.id] === 'autre' && !responses[`${q.id}_autre`])); if (unansweredQuestions.length > 0) { diff --git a/pages/index.js b/pages/index.js index d904bc5..e382a7a 100644 --- a/pages/index.js +++ b/pages/index.js @@ -128,8 +128,6 @@ export default function Home() {
  • setRegion('GUA')} onMouseOut={() => setRegion('')}>roomGuadeloupe
  • setRegion('MART')} onMouseOut={() => setRegion('')}>roomMartinique
  • setRegion('GUY')} onMouseOut={() => setRegion('')}>roomGuyane
  • -
  • setRegion('REU')} onMouseOut={() => setRegion('')}>roomLa Reunion
  • -
  • setRegion('MAY')} onMouseOut={() => setRegion('')}>roomMayotte
  • setRegion('POL')} onMouseOut={() => setRegion('')}>roomPolynésie Française
  • setRegion('SPM')} onMouseOut={() => setRegion('')}>roomSaint-Pierre et Miquelon
  • setRegion('OIN')} onMouseOut={() => setRegion('')}>roomOcéan Indien
  • diff --git a/pages/rencontres/[category]/[session].js b/pages/rencontres/[category]/[session].js index 763e34d..572f0d4 100644 --- a/pages/rencontres/[category]/[session].js +++ b/pages/rencontres/[category]/[session].js @@ -442,7 +442,7 @@ export default function Session({ data, user }){
    Durée du module : - {data.metasSession.nombreJours} jour{data.metasSession.nombreJour > 1 ? 's' : ''} + {data.metasSession.nombreJours} jour{data.metasSession.nombreJours > 1 ? 's' : ''}
    diff --git a/pages/rencontres/index.js b/pages/rencontres/index.js index f7f98b9..d52de04 100644 --- a/pages/rencontres/index.js +++ b/pages/rencontres/index.js @@ -411,8 +411,6 @@ export default function Rencontres({ base, region, pilier, thematique }){
  • {setFiltres(prev => { return { ...prev, nom: '', departement: '', region: "Guadeloupe" } });setSwitcher(true)}}>roomGuadeloupe
  • {setFiltres(prev => { return { ...prev, nom: '', departement: '', region: "Martinique" } });setSwitcher(true)}}>roomMartinique
  • {setFiltres(prev => { return { ...prev, nom: '', departement: '', region: "Guyane" } });setSwitcher(true)}}>roomGuyane
  • -
  • {setFiltres(prev => { return { ...prev, nom: '', departement: '', region: "La Reunion" } });setSwitcher(true)}}>roomLa Reunion
  • -
  • {setFiltres(prev => { return { ...prev, nom: '', departement: '', region: "Mayotte" } });setSwitcher(true)}}>roomMayotte
  • {setFiltres(prev => { return { ...prev, nom: '', departement: '', region: "Polynésie Française" } });setSwitcher(true)}}>roomPolynésie Française
  • {setFiltres(prev => { return { ...prev, nom: '', departement: '', region: "Saint-Pierre et Miquelon" } });setSwitcher(true)}}>roomSaint-Pierre et Miquelon
  • {setFiltres(prev => { return { ...prev, nom: '', departement: '', region: "Océan Indien" } });setSwitcher(true)}}>roomOcéan Indien
  • From eea0b8501f5a201f5f28abba01e7e280db18c881 Mon Sep 17 00:00:00 2001 From: AntonyKLINGER Date: Fri, 11 Oct 2024 16:18:28 +0200 Subject: [PATCH 098/100] maj export structure --- components/Participants.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/Participants.jsx b/components/Participants.jsx index a901f2e..022b870 100644 --- a/components/Participants.jsx +++ b/components/Participants.jsx @@ -83,7 +83,7 @@ export default function Participants({ session, setOpen }){ nom: participant.nom, prenom: participant.prenom, program: participant.session.metasSession.programmeSession, - organisation: participant.organisation || '', + organisation: participant.structure || '', }; const response = await fetch('/api/generate-badge', { From 1f82a1e9918ae705b0a51ed6fe89d04ea38b57f8 Mon Sep 17 00:00:00 2001 From: AntonyKLINGER Date: Tue, 15 Oct 2024 23:01:47 +0200 Subject: [PATCH 099/100] maj supaurl --- pages/api/upload.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pages/api/upload.js b/pages/api/upload.js index 8353250..6877eee 100644 --- a/pages/api/upload.js +++ b/pages/api/upload.js @@ -9,7 +9,7 @@ export const config = { }, }; -const supabaseUrl = process.env.NEXT_PUBLIC_SUPABASE_URL; +const supabaseUrl = "https://eazuwwpllqueujyivlce.supabase.co" //process.env.NEXT_PUBLIC_SUPABASE_URL; const supabaseKey = process.env.SUPABASE_KEY; const supabase = createClient(supabaseUrl, supabaseKey); From 265d78f4f38d77d37a7d56bc2871f5cbe8f5c44e Mon Sep 17 00:00:00 2001 From: AntonyKLINGER Date: Mon, 21 Oct 2024 22:19:42 +0200 Subject: [PATCH 100/100] maj date locale --- components/RencontreDetail.jsx | 8 +++----- components/Rencontres.jsx | 8 +++----- 2 files changed, 6 insertions(+), 10 deletions(-) diff --git a/components/RencontreDetail.jsx b/components/RencontreDetail.jsx index 3b1423e..0c31ee4 100644 --- a/components/RencontreDetail.jsx +++ b/components/RencontreDetail.jsx @@ -219,12 +219,10 @@ export default function RencontreDetail({ id, setOpen, userId, user }) { }; function formatDate(dateString) { - const date = new Date(dateString); - const day = date.getDate().toString().padStart(2, '0'); - const month = (date.getMonth() + 1).toString().padStart(2, '0'); - const year = date.getFullYear(); + const base = dateString.split('T'); + const [year, month, day] = base[0].split('-') return `${day}/${month}/${year}`; - } + } const getUserSession = async () => { const fetcher = await fetch(`/api/sessions/${id}`); diff --git a/components/Rencontres.jsx b/components/Rencontres.jsx index b421346..1091966 100644 --- a/components/Rencontres.jsx +++ b/components/Rencontres.jsx @@ -34,12 +34,10 @@ export default function Rencontres({ user }){ }, [status, open]) function formatDate(dateString) { - const date = new Date(dateString); - const day = date.getDate().toString().padStart(2, '0'); - const month = (date.getMonth() + 1).toString().padStart(2, '0'); - const year = date.getFullYear(); + const base = dateString.split('T'); + const [year, month, day] = base[0].split('-') return `${day}/${month}/${year}`; - } + } return (
    Participant{participant}{question.User.nom || question.Account.email} {question.User.prenom || question.Account.type}