Merge branch 'features/updateProfile' into 'dev'
Features/updateprofile See merge request sae-but2/2025-26/gestion-benevoles-association/Frontend!30
This commit is contained in:
@@ -0,0 +1,33 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
|
||||
|
||||
<svg
|
||||
fill="#000000"
|
||||
width="800"
|
||||
height="800"
|
||||
viewBox="0 0 24 24"
|
||||
version="1.1"
|
||||
id="svg1"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<defs
|
||||
id="defs1" />
|
||||
<g
|
||||
id="Dark">
|
||||
<path
|
||||
d="m 12.741,20.917 a 9.389,9.389 0 0 1 -1.395,-0.105 9.141,9.141 0 0 1 -1.465,-17.7 1.177,1.177 0 0 1 1.21,0.281 1.273,1.273 0 0 1 0.325,1.293 8.112,8.112 0 0 0 -0.353,2.68 8.266,8.266 0 0 0 4.366,6.857 7.628,7.628 0 0 0 3.711,0.993 1.242,1.242 0 0 1 0.994,1.963 v 0 a 9.148,9.148 0 0 1 -7.393,3.738 z M 10.261,4.05 a 0.211,0.211 0 0 0 -0.065,0.011 8.137,8.137 0 1 0 9.131,12.526 v 0 A 0.224,0.224 0 0 0 19.34,16.352 0.232,0.232 0 0 0 19.134,16.216 8.619,8.619 0 0 1 14.946,15.1 9.274,9.274 0 0 1 10.063,7.4 9.123,9.123 0 0 1 10.463,4.392 0.286,0.286 0 0 0 10.394,4.107 0.184,0.184 0 0 0 10.261,4.05 Z"
|
||||
id="path1" />
|
||||
</g>
|
||||
<path
|
||||
style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0.6;stroke-opacity:1"
|
||||
d="M 12.27,19.887864 C 8.6252997,19.678981 5.5285722,16.983616 4.802205,13.387962 4.6751742,12.759136 4.6511961,12.497206 4.6531749,11.76 c 0.00153,-0.569372 0.01461,-0.787852 0.068001,-1.135667 C 4.9722048,8.989005 5.6646891,7.5303876 6.7700292,6.3087222 7.5904449,5.4019665 8.7542199,4.6113468 9.8911899,4.1883372 10.240576,4.0583481 10.339583,4.0517409 10.40655,4.1539446 10.47235,4.2543711 10.46876,4.3012971 10.3656,4.6890069 10.138096,5.5440534 10.057589,6.1522074 10.055041,7.035 c -0.002,0.7022856 0.03507,1.0781595 0.174729,1.7704386 0.441048,2.1862074 1.740566,4.2313134 3.533802,5.5612914 1.522152,1.128924 3.239127,1.76416 5.001426,1.850398 0.426916,0.02089 0.522077,0.04974 0.567784,0.172121 0.01351,0.03616 0.01272,0.09717 -0.0018,0.135571 -0.0463,0.122854 -0.480151,0.639299 -0.836032,0.99518 -1.646591,1.64659 -3.893995,2.501458 -6.225,2.367864 z"
|
||||
id="path2" />
|
||||
<path
|
||||
style="fill:#000000;stroke-width:0.6"
|
||||
d="M 12.24,20.891972 C 11.360122,20.823621 10.700414,20.69763 9.9480678,20.454259 8.4650988,19.974545 7.068363,19.071092 6.0273591,17.91822 3.5681787,15.194772 2.9603488,11.317696 4.4732148,8.0050236 5.4683391,5.8260321 7.3075485,4.1019471 9.54,3.2553909 c 0.474857,-0.1800684 0.671021,-0.2157843 0.918134,-0.1671678 0.388517,0.076436 0.689105,0.3111453 0.870584,0.6797817 0.07976,0.1620108 0.09971,0.2428032 0.110439,0.4473105 0.01165,0.2220426 -0.0021,0.3102909 -0.125027,0.7996359 -0.186386,0.7422312 -0.231182,1.0670649 -0.250567,1.816968 -0.01825,0.7060722 0.01143,1.0908765 0.130201,1.6880808 0.513779,2.583326 2.113703,4.659009 4.525866,5.871694 1.023273,0.514437 1.887784,0.742874 3.138603,0.829338 0.686858,0.04748 0.813587,0.08854 1.095191,0.354845 0.396466,0.374925 0.503868,0.948025 0.265728,1.417923 -0.188868,0.372671 -1.032844,1.304647 -1.622363,1.791523 -1.361429,1.124387 -3.007202,1.834185 -4.749821,2.048528 -0.372347,0.0458 -1.32298,0.08018 -1.606968,0.05812 z m 1.812099,-1.059112 c 2.09671,-0.362295 3.901569,-1.432794 5.155126,-3.05761 0.138666,-0.179734 0.168974,-0.239673 0.166437,-0.329157 -0.0049,-0.17327 -0.112259,-0.246087 -0.362835,-0.246118 -0.638294,-9e-5 -1.608859,-0.157002 -2.343213,-0.378853 -0.845921,-0.255557 -1.94952,-0.811781 -2.743228,-1.382616 C 12.717736,13.570686 11.728623,12.407926 11.05893,11.07 10.402835,9.7592388 10.076992,8.4125052 10.082658,7.035 10.086058,6.2084796 10.19082,5.4236802 10.394064,4.7021844 10.501518,4.3207323 10.50584,4.2345858 10.422823,4.1290458 10.333346,4.0152951 10.211226,4.0262211 9.8074461,4.1841018 8.7208542,4.6089669 7.7283636,5.269389 6.9148926,6.1088616 6.4866426,6.5508003 6.2969187,6.7845894 5.9734524,7.2689589 5.2794414,8.3081952 4.8329166,9.5184891 4.659645,10.83 4.602754,11.260615 4.6119,12.415262 4.675686,12.855 c 0.1862775,1.284197 0.6107841,2.410878 1.2942264,3.435 0.3498402,0.524227 0.5965434,0.824106 1.0489137,1.275 1.2796647,1.275489 2.8952232,2.063697 4.7361019,2.310675 0.483003,0.0648 1.818404,0.03991 2.297171,-0.04282 z"
|
||||
id="path3" />
|
||||
<path
|
||||
style="fill:#000000;stroke-width:2.75694"
|
||||
d="m 4.285738,11.874144 c 0.031414,-0.01988 0.3856,-0.02656 0.7854538,-0.01483 0.3998535,0.01172 0.3734269,0.02799 -0.058508,0.03615 -0.4319739,0.0082 -0.7591449,-0.0014 -0.7269853,-0.02132 z"
|
||||
id="path4" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 4.3 KiB |
@@ -0,0 +1,29 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
|
||||
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
|
||||
<svg version="1.0" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
width="800px" height="800px" viewBox="0 0 64 64" enable-background="new 0 0 64 64" xml:space="preserve">
|
||||
<g>
|
||||
<circle fill-rule="evenodd" clip-rule="evenodd" fill="#231F20" cx="32.003" cy="32.005" r="16.001"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" fill="#231F20" d="M12.001,31.997c0-2.211-1.789-4-4-4H4c-2.211,0-4,1.789-4,4
|
||||
s1.789,4,4,4h4C10.212,35.997,12.001,34.208,12.001,31.997z"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" fill="#231F20" d="M12.204,46.139l-2.832,2.833c-1.563,1.562-1.563,4.094,0,5.656
|
||||
c1.562,1.562,4.094,1.562,5.657,0l2.833-2.832c1.562-1.562,1.562-4.095,0-5.657C16.298,44.576,13.767,44.576,12.204,46.139z"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" fill="#231F20" d="M32.003,51.999c-2.211,0-4,1.789-4,4V60c0,2.211,1.789,4,4,4
|
||||
s4-1.789,4-4l-0.004-4.001C36.003,53.788,34.21,51.999,32.003,51.999z"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" fill="#231F20" d="M51.798,46.143c-1.559-1.566-4.091-1.566-5.653-0.004
|
||||
s-1.562,4.095,0,5.657l2.829,2.828c1.562,1.57,4.094,1.562,5.656,0s1.566-4.09,0-5.656L51.798,46.143z"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" fill="#231F20" d="M60.006,27.997l-4.009,0.008
|
||||
c-2.203-0.008-3.992,1.781-3.992,3.992c-0.008,2.211,1.789,4,3.992,4h4.001c2.219,0.008,4-1.789,4-4
|
||||
C64.002,29.79,62.217,27.997,60.006,27.997z"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" fill="#231F20" d="M51.798,17.859l2.828-2.829c1.574-1.566,1.562-4.094,0-5.657
|
||||
c-1.559-1.567-4.09-1.567-5.652-0.004l-2.829,2.836c-1.562,1.555-1.562,4.086,0,5.649C47.699,19.426,50.239,19.418,51.798,17.859z"
|
||||
/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" fill="#231F20" d="M32.003,11.995c2.207,0.016,4-1.789,4-3.992v-4
|
||||
c0-2.219-1.789-4-4-4c-2.211-0.008-4,1.781-4,3.993l0.008,4.008C28.003,10.206,29.792,11.995,32.003,11.995z"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" fill="#231F20" d="M12.212,17.855c1.555,1.562,4.079,1.562,5.646-0.004
|
||||
c1.574-1.551,1.566-4.09,0.008-5.649l-2.829-2.828c-1.57-1.571-4.094-1.559-5.657,0c-1.575,1.559-1.575,4.09-0.012,5.653
|
||||
L12.212,17.855z"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.3 KiB |
@@ -4,18 +4,29 @@ 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 { logout } = useContext(AuthContext);
|
||||
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 (
|
||||
<>
|
||||
<Button variant={"transparent"} onClick={() => setOpen(!open)}>
|
||||
@@ -28,6 +39,24 @@ export default function SettingsModal() {
|
||||
<div className={styles.section}>
|
||||
<h3>Compte</h3>
|
||||
<Button variant={"danger"} onClick={handleLogout}> Déconnexion </Button>
|
||||
|
||||
<div className={styles.section}>
|
||||
<h4>Changer de Prénom</h4>
|
||||
<TextInput value={name} onChange={e => setName(e.target.value)} type={"text"} />
|
||||
</div>
|
||||
|
||||
<div className={styles.section}>
|
||||
<h4>Changer de nom</h4>
|
||||
<TextInput value={lastname} onChange={e => setLastName(e.target.value)} type={"text"} />
|
||||
</div>
|
||||
|
||||
<div className={styles.section}>
|
||||
<h4>Changer de numéro de téléphone</h4>
|
||||
<TextInput value={phone} onChange={e => setPhone(e.target.value)} type={"text"} />
|
||||
</div>
|
||||
|
||||
<Button className={styles.submitBtn} onClick={handleSubmit}>Confirmer</Button>
|
||||
|
||||
</div>
|
||||
|
||||
<div className={styles.section}>
|
||||
|
||||
@@ -14,5 +14,10 @@
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 10px;
|
||||
margin-bottom: 30px;
|
||||
margin-top: 15px;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
.submitBtn {
|
||||
align-self: center;
|
||||
}
|
||||
@@ -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 <div className={styles.overlay}>
|
||||
const handleOverlayClick = () => {
|
||||
onClose();
|
||||
};
|
||||
|
||||
<div className={styles.modal}>
|
||||
const handleModalClick = (e) => {
|
||||
e.stopPropagation();
|
||||
};
|
||||
|
||||
{title && <h2>{title}</h2>}
|
||||
return createPortal(
|
||||
<div className={styles.overlay} onClick={handleOverlayClick}>
|
||||
<div className={styles.modal} onClick={handleModalClick}>
|
||||
{title && <h2>{title}</h2>}
|
||||
{children}
|
||||
<div className={styles.modalFooter}>
|
||||
<Button onClick={onClose}>Fermer</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>,
|
||||
document.body
|
||||
);
|
||||
};
|
||||
|
||||
{children}
|
||||
|
||||
<div className={styles.modalFooter}> <Button onClick={onClose}>Fermer</Button> </div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
}
|
||||
|
||||
export default Modal;
|
||||
export default Modal;
|
||||
|
||||
@@ -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,6 +18,7 @@
|
||||
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: clamp(300px, 50vw, 600px);
|
||||
|
||||
@@ -1,19 +1,30 @@
|
||||
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(() => {
|
||||
setTheme(localStorage.getItem("theme"));
|
||||
}, []);
|
||||
|
||||
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 <Button variant={"default"} onClick={switchTheme}> Changer de thème </Button>
|
||||
return <Button variant={"default"} onClick={switchTheme} className={styles.themeBtn}>
|
||||
<img src={`/public/icons/theme/${theme}.svg`} alt={`${theme} icon`} className={styles.themeIcon} />
|
||||
<p>Changer de thème </p>
|
||||
</Button>
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
.themeBtn {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 5px;
|
||||
}
|
||||
|
||||
.themeIcon {
|
||||
height: 20px;
|
||||
width: 20px;
|
||||
}
|
||||
@@ -30,8 +30,13 @@ export function AuthProvider({ children }) {
|
||||
setUser(null);
|
||||
};
|
||||
|
||||
const update = async () => {
|
||||
const u = await getUser();
|
||||
setUser(u);
|
||||
}
|
||||
|
||||
return (
|
||||
<AuthContext.Provider value={{ user, loading, login, logout }}>
|
||||
<AuthContext.Provider value={{ user, loading, login, logout, update }}>
|
||||
{children}
|
||||
</AuthContext.Provider>
|
||||
);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user