diff --git a/public/icons/settings-wheel.svg b/public/icons/settings-wheel.svg new file mode 100644 index 0000000..9a4e19b --- /dev/null +++ b/public/icons/settings-wheel.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/public/icons/theme/dark.svg b/public/icons/theme/dark.svg new file mode 100644 index 0000000..7a1ccf1 --- /dev/null +++ b/public/icons/theme/dark.svg @@ -0,0 +1,33 @@ + + + + + + + + + + + + diff --git a/public/icons/theme/light.svg b/public/icons/theme/light.svg new file mode 100644 index 0000000..bc68130 --- /dev/null +++ b/public/icons/theme/light.svg @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/components/SettingsModal/SettingsModal.jsx b/src/components/SettingsModal/SettingsModal.jsx new file mode 100644 index 0000000..e39c64d --- /dev/null +++ b/src/components/SettingsModal/SettingsModal.jsx @@ -0,0 +1,70 @@ +import Modal from "../ui/modal/modal.jsx"; +import Button from "../ui/button/button.jsx"; +import styles from "./SettingsModal.module.css" +import { useContext, useState } from "react"; +import ThemeSwitcher from "../ui/themeSwitcher/ThemeSwitcher.jsx"; +import { AuthContext } from "../../contexts/auth/AuthContext.js"; +import TextInput from "../ui/input/input.jsx"; +import updateUser from "../../utils/users/updateUser.js"; + + +export default function SettingsModal() { + + const { user, logout, update } = useContext(AuthContext); + + const [open, setOpen] = useState(false); + + const [name, setName] = useState(user.name); + const [lastname, setLastName] = useState(user.lastname); + const [phone, setPhone] = useState(user.phone); + + const handleLogout = () => { + logout(); + } + + const handleSubmit = async () => { + await updateUser(name, lastname, phone); + update(); + } + + return ( + <> + + + setOpen(false)}> +
+ +
+

Compte

+ + +
+

Changer de Prénom

+ setName(e.target.value)} type={"text"} /> +
+ +
+

Changer de nom

+ setLastName(e.target.value)} type={"text"} /> +
+ +
+

Changer de numéro de téléphone

+ setPhone(e.target.value)} type={"text"} /> +
+ + + +
+ +
+

Apparence

+ +
+
+
+ + ) +} \ No newline at end of file diff --git a/src/components/SettingsModal/SettingsModal.module.css b/src/components/SettingsModal/SettingsModal.module.css new file mode 100644 index 0000000..80b9d81 --- /dev/null +++ b/src/components/SettingsModal/SettingsModal.module.css @@ -0,0 +1,23 @@ +.content { + width: 100%; + padding: 20px; + display: flex; + flex-direction: column; +} + +.modifyIcon { + height: 30px; + width: 30px; +} + +.section { + display: flex; + flex-direction: column; + gap: 10px; + margin-top: 15px; + margin-bottom: 15px; +} + +.submitBtn { + align-self: center; +} \ No newline at end of file diff --git a/src/components/loginform/loginForm.jsx b/src/components/loginform/loginForm.jsx index cd22971..7562cba 100644 --- a/src/components/loginform/loginForm.jsx +++ b/src/components/loginform/loginForm.jsx @@ -30,7 +30,7 @@ function LoginForm({ className }) { />
- setPassword(e.target.value)} value={password} /> + setPassword(e.target.value)} value={password} placeholder={"Mot de passe"} />
diff --git a/src/components/ui/input/input.jsx b/src/components/ui/input/input.jsx index 0218b3e..7713b27 100644 --- a/src/components/ui/input/input.jsx +++ b/src/components/ui/input/input.jsx @@ -18,7 +18,7 @@ const TextInput = ({ placeholder, onChange, value, borderStyle, password, classN diff --git a/src/components/ui/modal/modal.jsx b/src/components/ui/modal/modal.jsx index 66ae46b..822398c 100644 --- a/src/components/ui/modal/modal.jsx +++ b/src/components/ui/modal/modal.jsx @@ -1,23 +1,31 @@ -import styles from "./modal.module.css" +import { createPortal } from "react-dom"; +import styles from "./modal.module.css"; import Button from "../button/button.jsx"; const Modal = ({ open, onClose, children, title }) => { - if(!open) return null; + if (!open) return null; - return
+ const handleOverlayClick = () => { + onClose(); + }; -
+ const handleModalClick = (e) => { + e.stopPropagation(); + }; - {title &&

{title}

} + return createPortal( +
+
+ {title &&

{title}

} + {children} +
+ +
+
+
, + document.body + ); +}; - {children} - -
- -
- -
-} - -export default Modal; \ No newline at end of file +export default Modal; diff --git a/src/components/ui/modal/modal.module.css b/src/components/ui/modal/modal.module.css index 76b108a..fa3566f 100644 --- a/src/components/ui/modal/modal.module.css +++ b/src/components/ui/modal/modal.module.css @@ -7,8 +7,10 @@ background-color: rgba(0, 0, 0, 0.25); display: flex; justify-content: center; - align-items: center; z-index: 1000; + align-items: flex-start; + overflow-y: auto; + padding: 40px 0; } .modal { @@ -16,9 +18,10 @@ border-radius: 8px; min-width: 300px; max-width: 70%; + max-height: none; position: relative; box-shadow: 0 4px 15px rgba(0,0,0,0.2); - width: fit-content; + width: clamp(300px, 50vw, 600px); border: 1px solid rgba(200, 200, 200, 0.3); background: rgba(255, 255, 255, 0.5); backdrop-filter: blur(10px); diff --git a/src/components/ui/themeSwitcher/ThemeSwitcher.jsx b/src/components/ui/themeSwitcher/ThemeSwitcher.jsx index 1b9a84f..a3aa96f 100644 --- a/src/components/ui/themeSwitcher/ThemeSwitcher.jsx +++ b/src/components/ui/themeSwitcher/ThemeSwitcher.jsx @@ -1,19 +1,32 @@ import Button from "../button/button.jsx"; -import React from "react"; +import { useState, useEffect } from "react"; +import styles from "./ThemeSwitcher.module.css"; + export default function ThemeSwitcher() { + const [theme, setTheme] = useState(""); + + useEffect(() => { + const t = localStorage.getItem("theme"); + if(t) setTheme(t); + else setTheme("light"); + }, []); + const switchTheme = () => { - const currentTheme = localStorage.getItem("theme"); - let newTheme = currentTheme === "light" ? "dark" : "light"; + let newTheme = theme === "light" ? "dark" : "light"; - if(currentTheme === null) newTheme = "dark"; + if(theme === null || theme === "") newTheme = "dark"; localStorage.setItem("theme", newTheme); + setTheme(newTheme); window.dispatchEvent(new Event("theme-changed")); }; - return + return } \ No newline at end of file diff --git a/src/components/ui/themeSwitcher/ThemeSwitcher.module.css b/src/components/ui/themeSwitcher/ThemeSwitcher.module.css new file mode 100644 index 0000000..93b6fc6 --- /dev/null +++ b/src/components/ui/themeSwitcher/ThemeSwitcher.module.css @@ -0,0 +1,12 @@ +.themeBtn { + display: flex; + flex-direction: row; + align-items: center; + justify-content: center; + gap: 5px; +} + +.themeIcon { + height: 20px; + width: 20px; +} \ No newline at end of file diff --git a/src/contexts/auth/authProvider.jsx b/src/contexts/auth/authProvider.jsx index 009ec58..850c3a2 100644 --- a/src/contexts/auth/authProvider.jsx +++ b/src/contexts/auth/authProvider.jsx @@ -30,8 +30,13 @@ export function AuthProvider({ children }) { setUser(null); }; + const update = async () => { + const u = await getUser(); + setUser(u); + } + return ( - + {children} ); diff --git a/src/index.css b/src/index.css index 6246007..ce69093 100644 --- a/src/index.css +++ b/src/index.css @@ -65,6 +65,19 @@ body { overflow: hidden; } +.glassBorder{ + border-radius: 20px; + padding: 15px; + margin-top: 16px; + border: none; + background: rgb(255, 255, 255, 0.25); + box-shadow: + inset 1.25px 1.25px 1px rgba(255, 255, 255, 1), + inset -1.25px -1.25px 1px rgba(255, 255, 255, 1), + inset -0.25px 0.25px 1px rgba(0, 0, 0, 0.2), + inset 0.25px -0.25px 1px rgba(0, 0, 0, 0.2); +} + h1 { font-size: 3.2em; line-height: 1.1; diff --git a/src/pages/Events/EventsPage.jsx b/src/pages/Events/EventsPage.jsx index ef95b9b..8765650 100644 --- a/src/pages/Events/EventsPage.jsx +++ b/src/pages/Events/EventsPage.jsx @@ -2,7 +2,6 @@ import { useEffect, useState } from "react"; import Event from "../../components/Event/Event.jsx"; import styles from "./EventsPage.module.css"; import ToolBar from "../../components/ToolBar/ToolBar.jsx"; -import filter from "../../utils/filter.js"; import getAllEvents from "../../utils/event/getAllEvents.js"; diff --git a/src/pages/Home/HomePage.jsx b/src/pages/Home/HomePage.jsx index fc12601..ae603b2 100644 --- a/src/pages/Home/HomePage.jsx +++ b/src/pages/Home/HomePage.jsx @@ -1,11 +1,181 @@ +import { useState } from "react"; +import { useMemo } from "react"; +import styles from "./HomePage.module.css"; +function HomePage() { + const events = { + "2025-11-07": ["Réunion de projet", "Anniversaire de Marie"], + "2025-11-10": ["Cours de React", "Rendez-vous médecin"], + "2025-11-14": ["Sortie cinéma"], + }; -function HomePage(){ + const monthNames = [ + "Janvier", "Février", "Mars", "Avril", "Mai", "Juin", + "Juillet", "Août", "Septembre", "Octobre", "Novembre", "Décembre" + ]; + + const today = new Date(); + const [currentMonth, setCurrentMonth] = useState(today.getMonth()); + const [currentYear, setCurrentYear] = useState(today.getFullYear()); + const [selectedDay, setSelectedDay] = useState(() => { + const year = today.getFullYear(); + const month = String(today.getMonth() + 1).padStart(2, "0"); + const day = String(today.getDate()).padStart(2, "0"); + const key = `${year}-${month}-${day}`; + return { date: key, events: events[key] || [] }; + }); + + const daysInMonth = new Date(currentYear, currentMonth + 1, 0).getDate(); + const firstDay = new Date(currentYear, currentMonth, 1).getDay(); + const startDay = (firstDay + 6) % 7; + + const days = []; + for (let i = 0; i < startDay; i++) days.push(null); + for (let i = 1; i <= daysInMonth; i++) days.push(i); + + const handlePrevMonth = () => { + let newMonth = currentMonth - 1; + let newYear = currentYear; + + if (newMonth < 0) { + newMonth = 11; + newYear--; + } + + setCurrentMonth(newMonth); + setCurrentYear(newYear); + + const key = `${newYear}-${String(newMonth + 1).padStart(2, "0")}-01`; + setSelectedDay({ date: key, events: events[key] || [] }); + }; + + const handleNextMonth = () => { + let newMonth = currentMonth + 1; + let newYear = currentYear; + + if (newMonth > 11) { + newMonth = 0; + newYear++; + } + + setCurrentMonth(newMonth); + setCurrentYear(newYear); + + const key = `${newYear}-${String(newMonth + 1).padStart(2, "0")}-01`; + setSelectedDay({ date: key, events: events[key] || [] }); + }; + + const handleDayClick = (day) => { + if (!day) return; + const key = `${currentYear}-${String(currentMonth + 1).padStart(2, "0")}-${String(day).padStart(2, "0")}`; + setSelectedDay({ date: key, events: events[key] || [] }); + }; + + const sortedEvents = useMemo(() => { + return Object.entries(events) + .map(([dateKey, eventList]) => ({ date: dateKey, events: eventList })) + .sort((a, b) => new Date(a.date) - new Date(b.date)); + }, [events]); + + const formatDate = (dateString) => { + const [year, month, day] = dateString.split('-'); + return `${day} ${monthNames[parseInt(month) - 1]} ${year}`; + }; return ( -
+
+
+
+
+ +

{monthNames[currentMonth]} {currentYear}

+ +
+ + + + + + + + + + + + + + + + {Array.from({ length: Math.ceil(days.length / 7) }).map((_, weekIndex) => ( + + {days.slice(weekIndex * 7, weekIndex * 7 + 7).map((day, index) => { + const key = `${currentYear}-${String(currentMonth + 1).padStart(2, "0")}-${String(day).padStart(2, "0")}`; + const hasEvent = events[key]; + + return ( + + ); + })} + + ))} + +
LunMarMerJeuVenSamDim
handleDayClick(day)} + > + {day || ""} +
+ + {selectedDay && ( +
+

Événements du {formatDate(selectedDay.date)}

+ + {selectedDay.events.length > 0 ? ( +
    + {selectedDay.events.map((ev, i) => ( +
  • {ev}
  • + ))} +
+ ) : ( +

Aucun événement ce jour-là.

+ )} +
+ )} +
+
+
+
+

Liste des Événements à Venir

+ {sortedEvents.length > 0 ? ( +
    + {sortedEvents.map((eventGroup) => ( +
  • +
    + {formatDate(eventGroup.date)} +
    +
      + {eventGroup.events.map((event, i) => ( +
    • - {event}
    • + ))} +
    +
  • + ))} +
+ ) : ( +

Aucun événement planifié pour l'instant.

+ )} +
+
- ) + ); } export default HomePage; \ No newline at end of file diff --git a/src/pages/Home/HomePage.module.css b/src/pages/Home/HomePage.module.css index e83a063..7d6a67a 100644 --- a/src/pages/Home/HomePage.module.css +++ b/src/pages/Home/HomePage.module.css @@ -1,3 +1,173 @@ -.title { - color: red; +.calendarContainer { + padding: 20px; + font-family: Arial, sans-serif; + display: flex; + flex-direction: column; + align-items: center; +} + +.calendarHeader { + display: flex; + width: 100%; + flex-direction: row; + justify-content: space-between; + align-items: center; + gap: 10px; +} + +.calendarHeader p { + width: auto; + text-align: center; + font-weight: bold; + font-size: 40px; +} + +.calendarHeader button { + top: 50%; + left: 50%; + width: 40px; + height: 40px; + border-radius: 50%; + border: none; + background: transparent; + box-shadow: + inset 1.25px 1.25px 1px rgba(255, 255, 255, 1), + inset -1.25px -1.25px 1px rgba(255, 255, 255, 1), + inset -0.25px 0.25px 1px rgba(0, 0, 0, 0.2), + inset 0.25px -0.25px 1px rgba(0, 0, 0, 0.2); + font-size: 15px; + color: #019AFF; + cursor: pointer; +} + +.calendar { + border-collapse: collapse; + width: 80%; + max-width: 500px; +} + +.calendar th, .calendar td { + border: none; + padding: 10px; + width: 14.2%; + line-height: 130%; + text-align: center; + cursor: pointer; +} + +.today { + color: #007bff; +} + +.hasEvent { + position: relative; +} + +.hasEvent::before { + content: ""; + position: absolute; + left: 50%; + bottom: 10px; + width: 20px; + height: 2px; + background-color: #007bff; + transform: translateX(-50%); + border-radius: 10px; +} + +.hasEvent.selected::before { + width: 25px; + height: 2px; + bottom: 10px; +} + +.selected { + position: relative; + font-size: 18px; + font-weight: 600; +} + +.selected::after { + content: ""; + position: absolute; + top: 50%; + left: 50%; + width: 40px; + height: 40px; + transform: translate(-50%, -50%); + border-radius: 38%; + pointer-events: none; + background: transparent; + box-shadow: + inset 1.25px 1.25px 1px rgba(255, 255, 255, 1), + inset -1.25px -1.25px 1px rgba(255, 255, 255, 1), + inset -0.25px 0.25px 1px rgba(0, 0, 0, 0.2), + inset 0.25px -0.25px 1px rgba(0, 0, 0, 0.2); +} + +.eventBox { + border-radius: 20px; + padding: 15px; + margin-top: 16px; + border: none; + background: rgb(255, 255, 255, 0.25); + box-shadow: + inset 1.25px 1.25px 1px rgba(255, 255, 255, 1), + inset -1.25px -1.25px 1px rgba(255, 255, 255, 1), + inset -0.25px 0.25px 1px rgba(0, 0, 0, 0.2), + inset 0.25px -0.25px 1px rgba(0, 0, 0, 0.2); +} + +.eventBox ul { + list-style-type: disc; +} + +.eventGroup{ + border-radius: 20px; + padding: 15px; + margin-top: 16px; + border: none; + background: rgb(255, 255, 255, 0.25); + box-shadow: + inset 1.25px 1.25px 1px rgba(255, 255, 255, 1), + inset -1.25px -1.25px 1px rgba(255, 255, 255, 1), + inset -0.25px 0.25px 1px rgba(0, 0, 0, 0.2), + inset 0.25px -0.25px 1px rgba(0, 0, 0, 0.2); +} + +.glassCard { + width: 45%; + margin: 16px; + padding: 10px 20px 10px 20px; + height: fit-content; + background: rgba(255, 255, 255, 0.65); + backdrop-filter: blur(3px); + -webkit-backdrop-filter: blur(3px); + border-radius: 20px; + border: 1px solid rgba(255, 255, 255, 0.3); + box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1), + inset 0 1px 0 rgba(255, 255, 255, 0.5), + inset 0 -1px 0 rgba(255, 255, 255, 0.1), + inset 0 0 8px 4px rgba(255, 255, 255, 0.4); + overflow: hidden; +} +.allContent{ + display: flex; + flex-direction: row; +} + +@media (max-width: 768px) { + .glassCard { + width: 100%; + margin: 0px; + margin-top: 16px; + margin-bottom: 16px; + display: flex; + } + + + .allContent{ + display: flex; + flex-direction: column; + } } \ No newline at end of file diff --git a/src/pages/Login/LoginPage.jsx b/src/pages/Login/LoginPage.jsx index 93154f4..79af77a 100644 --- a/src/pages/Login/LoginPage.jsx +++ b/src/pages/Login/LoginPage.jsx @@ -1,8 +1,21 @@ import styles from "./LoginPage.module.css"; import LoginForm from "../../components/loginform/loginForm.jsx"; import Background from "../../components/background/background.jsx"; +import { useEffect, useContext } from "react"; +import { AuthContext } from "../../contexts/auth/AuthContext.js"; +import { useNavigate } from "react-router"; function LoginPage() { + + const { user, loading } = useContext(AuthContext) + const navigate = useNavigate(); + + useEffect(() => { + if (!loading && user) { + navigate("/"); + } + }, [loading, user]); + return (
diff --git a/src/pages/Profile/ProfilePage.jsx b/src/pages/Profile/ProfilePage.jsx index 0271d42..aaa1338 100644 --- a/src/pages/Profile/ProfilePage.jsx +++ b/src/pages/Profile/ProfilePage.jsx @@ -3,18 +3,11 @@ import styles from "./ProfilePage.module.css"; import { AuthContext } from "../../contexts/auth/AuthContext.js"; import formatDate from "../../utils/date/formatDate.js"; import Task from "../../components/Task/Task"; -import Button from "../../components/ui/button/button.jsx"; -import { useNavigate } from "react-router"; -import ThemeSwitcher from "../../components/ui/themeSwitcher/ThemeSwitcher.jsx"; +import SettingsModal from "../../components/SettingsModal/SettingsModal.jsx"; function ProfilePage() { - const { user, logout } = useContext(AuthContext); - const navigate = useNavigate(); - - const handleLogout = () => { - logout(); - } + const { user } = useContext(AuthContext); return (
@@ -30,10 +23,6 @@ function ProfilePage() {

{user.name} {user.lastname}

-
- - -
@@ -44,9 +33,7 @@ function ProfilePage() {

Mail : {user.email}

Téléphone : {user.phone}

- +

Vos Événements :

diff --git a/src/pages/Profile/ProfilePage.module.css b/src/pages/Profile/ProfilePage.module.css index e4e467b..1e7913f 100644 --- a/src/pages/Profile/ProfilePage.module.css +++ b/src/pages/Profile/ProfilePage.module.css @@ -38,10 +38,11 @@ } .topDescription { - display: flex; - flex-direction: column; - gap: 10px; - margin-bottom: 15px; + display: flex; + flex-direction: column; + align-items: center; + gap: 10px; + margin-bottom: 15px; } .infoBlock { @@ -122,11 +123,6 @@ } -.modifyIcon { - height:50px; - width:50px; -} - .headerProfile { display: flex; flex-direction: row; diff --git a/src/pages/Register/RegisterPage.jsx b/src/pages/Register/RegisterPage.jsx index cac9e4d..2046c9a 100644 --- a/src/pages/Register/RegisterPage.jsx +++ b/src/pages/Register/RegisterPage.jsx @@ -2,9 +2,11 @@ import styles from "./RegisterPage.module.css"; import Background from "../../components/background/background.jsx"; import Input from "../../components/ui/input/input.jsx"; import Button from "../../components/ui/button/button.jsx"; -import { useState } from "react"; +import {useContext, useEffect, useState} from "react"; import register from "../../utils/register.js"; import { useNavigate } from "react-router"; +import { AuthContext } from "../../contexts/auth/AuthContext.js"; +import Modal from "../../components/ui/modal/modal.jsx"; function RegisterPage() { @@ -12,20 +14,54 @@ function RegisterPage() { const navigate = useNavigate(); const [email, setEmail] = useState(""); + const [phone, setPhone] = useState(""); const [password, setPassword] = useState(""); + const [confirmPassword, setConfirmPassword] = useState(""); const [name, setName] = useState(""); const [lastName, setLastName] = useState(""); + const [open, setOpen] = useState(false); + const [title, setTitle] = useState(""); + const [message, setMessage] = useState(""); - const [showPassword, setShowPassword] = useState(false); + const { user, loading } = useContext(AuthContext) + useEffect(() => { + if (!loading && user) { + navigate("/"); + } + }, [loading, user]); + + const handleModal = (t, m) => { + setTitle(t) + setMessage(m) + setOpen(true); + } async function handleSubmit(e) { e.preventDefault(); - const res = await register(email, password, name, lastName); - if (!res || res.status !== 200) throw new Error("Register error"); - navigate("/login"); + + if(!(password === confirmPassword)) handleModal("Mot de passe invalide", "Les mots de passes ne conrrespondent pas"); + else if(password.length < 8) handleModal("Mot de passe invalide", "Le mot de passe doit faire plus de 8 charactères"); + else { + + const res = await register(email, password, name, lastName, phone); + + if (res.status === 422) { + if (res.errors.email) handleModal("Adresse Email invalide", "Le formet de votre adresse Email n'est pas valide"); + if (res.errors.phone) handleModal("Numéro de téléphone invalide", "Le formet de votre numéro de téléphone n'est pas valide"); + } else navigate("/login"); + + } } + const handlePhone = (e) => { + const value = e.target.value; + if (value === "" || /^[0-9 +]+$/.test(value)) { + setPhone(value); + } + }; + + return
@@ -61,8 +97,22 @@ function RegisterPage() { style={{ width: '100%' }} />
+
- setPassword(e.target.value)} value={password} /> + +
+ +
+ setPassword(e.target.value)} value={password} placeholder={"Mot de passe"}/> +
+ +
+ setConfirmPassword(e.target.value)} value={confirmPassword} placeholder={"Confirmer le mot de passe"} />
@@ -72,6 +122,10 @@ function RegisterPage() {
+ setOpen(false)} title={title}> +

{message}

+
+ } diff --git a/src/pages/Volunteers/VolunteerCard.jsx b/src/pages/Volunteers/VolunteerCard.jsx index 9c6f1cf..fe1cf00 100644 --- a/src/pages/Volunteers/VolunteerCard.jsx +++ b/src/pages/Volunteers/VolunteerCard.jsx @@ -58,8 +58,8 @@ export default function VolunteerCard({ user }) { {isExpanded && (
diff --git a/src/router.js b/src/router.js index bd0c986..f3fdef6 100644 --- a/src/router.js +++ b/src/router.js @@ -26,7 +26,7 @@ const router = createBrowserRouter([ Component: HomePage, }, { - path: "/stat", + path: "/admin", Component:StatPage, }, { diff --git a/src/utils/register.js b/src/utils/register.js index 313df77..43a8c1d 100644 --- a/src/utils/register.js +++ b/src/utils/register.js @@ -1,6 +1,6 @@ import getXSRFToken from "./getXSRF.js"; -export default async function register(email, password, name, lastname) { +export default async function register(email, password, name, lastname, phone) { const csrfToken = await getXSRFToken(); try { @@ -12,19 +12,25 @@ export default async function register(email, password, name, lastname) { 'X-XSRF-TOKEN': csrfToken, 'Accept': 'application/json' }, - body: JSON.stringify({ email, password, name, lastname }), + body: JSON.stringify({ email, password, name, lastname, phone }), }); - console.log('Code HTTP :', response.status); - - if (!response.ok) { - throw new Error(`Erreur HTTP ${response.status}`); - } - const data = await response.json(); + if (!response.ok) { + if (response.status === 422) { + return { + status: 422, + errors: data.errors + }; + } + + throw new Error(`Erreur HTTP ${response.status}`); + } + return { status: response.status, data }; + } catch (error) { - return error; + return { status: "error", error }; } } diff --git a/src/utils/searchEvents.js b/src/utils/searchEvents.js index db4a67f..a9974d0 100644 --- a/src/utils/searchEvents.js +++ b/src/utils/searchEvents.js @@ -2,7 +2,7 @@ export default async function searchEvents(query) { try { const encodedQuery = encodeURIComponent(query); const response = await fetch( - `http://localhost:80/api/events/search?query=${encodedQuery}`, + `http://${import.meta.env.VITE_API_URL}/api/events/search?query=${encodedQuery}`, { method: 'GET', credentials: 'include', diff --git a/src/utils/users/updateUser.js b/src/utils/users/updateUser.js new file mode 100644 index 0000000..dd2042e --- /dev/null +++ b/src/utils/users/updateUser.js @@ -0,0 +1,32 @@ +import getXSRFToken from "../getXSRF.js"; + +export default async function updateUser(name, lastname, phone) { + + const csrfToken = await getXSRFToken(); + + try { + const res = await fetch(`http://${import.meta.env.VITE_API_URL}/api/users/update`, { + method: 'POST', + credentials: 'include', + headers: { + 'Accept': 'application/json', + 'X-XSRF-TOKEN': csrfToken, + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ + name: name, + phone: phone, + lastname: lastname, + }) + }); + + if (!res.ok) { + throw new Error(`Erreur serveur : ${res.status}`); + } + + return await res.json(); + } catch (err) { + console.error('Erreur :', err); + return null; + } +} \ No newline at end of file