This commit is contained in:
p2405951
2026-02-11 15:28:09 +01:00
34 changed files with 626 additions and 399 deletions
+1 -1
View File
@@ -1,5 +1,5 @@
import styles from "./Filter.module.css";
import Button from "../ui/button/button.jsx"
import Button from "../ui/button/button.tsx"
function Filter({isFilterVisible, filters, setFilters}){
const setAlphabeticalOrder = (order) => {
+3 -3
View File
@@ -1,8 +1,8 @@
import styles from "./Footer.module.css"
import {Link} from "react-router";
import {useState} from "react";
import Modal from "../ui/modal/modal.jsx";
import Button from "../ui/button/button.jsx";
import Modal from "../ui/modal/modal.tsx";
import Button from "../ui/button/button.tsx";
import scrollToTop from "../../utils/scrollToTop.js";
export default function Footer(){
@@ -26,7 +26,7 @@ export default function Footer(){
</div>
<nav className={styles.footerNav}>
<Link to="/RGPD" className={styles.link} onClick={scrollToTop}>
<Link to="/rgpd" className={styles.link} onClick={scrollToTop}>
Fiche RGPD
</Link>
<span className={styles.separator}></span>
+1 -1
View File
@@ -3,7 +3,7 @@ import Filter from "../Filter/Filter.jsx";
import {useContext, useEffect, useState} from "react";
import SearchBar from "../SearchBar/SearchBar.jsx";
import CreateEventBtn from "../createEventBtn/CreateEventBtn.jsx";
import Button from "../ui/button/button.jsx";
import Button from "../ui/button/button.tsx";
import {AuthContext} from "../../contexts/auth/AuthContext.js";
function ToolBar({setFilters, filters, showCreate = true}) {
@@ -1,8 +1,8 @@
import styles from "./createEventBtn.module.css"
import { useState, useContext } from "react";
import Modal from "../ui/modal/modal.jsx";
import Button from "../ui/button/button.jsx";
import TextInput from "../ui/input/input.jsx";
import Modal from "../ui/modal/modal.tsx";
import Button from "../ui/button/button.tsx";
import TextInput from "../ui/input/input.tsx";
import { EventContext } from "../../contexts/events/EventContext.js";
+34 -43
View File
@@ -1,53 +1,44 @@
/*import styles from "./button.module.css";
const Button = ({ children, variant = "primary", onClick, className }) => {
let btnStyle;
if (variant === "primary") btnStyle = styles.primary;
else if (variant === "danger") btnStyle = styles.danger;
else if(variant === "transparent") btnStyle = styles.transparent;
else btnStyle = styles.default;
return <div className={`${styles.btn} ${btnStyle} ${className}`} onClick={onClick}>
{children}
</div>;
};
export default Button;
*/
import { ReactNode, MouseEventHandler } from "react";
import styles from "./button.module.css";
import { ReactNode, MouseEvent } from "react";
type ButtonVariant = "primary" | "danger" | "transparent" | "default";
interface ButtonProps {
children: ReactNode;
variant?: "primary" | "danger" | "transparent" | "default";
onClick?: (event: MouseEvent<HTMLDivElement>) => void;
className?: string;
children: ReactNode;
variant?: ButtonVariant;
onClick?: MouseEventHandler<HTMLDivElement>;
className?: string;
}
const Button = ({
children,
variant = "primary",
onClick,
className = "",
}: ButtonProps) => {
const variantStyles = {
primary: styles.primary,
danger: styles.danger,
transparent: styles.transparent,
default: styles.default,
};
const btnStyle = variantStyles[variant in variantStyles ? variant : "default"];
children,
variant = "primary",
onClick,
className = "",
}: ButtonProps) => {
let btnStyle: string;
return (
<div
className={`${styles.btn} ${btnStyle} ${className}`}
onClick={onClick}
>
{children}
</div>
);
if (variant === "primary") { // @ts-ignore
btnStyle = styles.primary;
}
else if (variant === "danger") { // @ts-ignore
btnStyle = styles.danger;
}
else if (variant === "transparent") { // @ts-ignore
btnStyle = styles.transparent;
}
else { // @ts-ignore
btnStyle = styles.default;
}
return (
<div
className={`${styles.btn} ${btnStyle} ${className}`}
onClick={onClick}
>
{children}
</div>
);
};
export default Button;
+46 -91
View File
@@ -1,107 +1,62 @@
/*import styles from "./input.module.css";
import { useState } from "react";
const TextInput = ({ placeholder, onChange, value, borderStyle, password, className, ...props }) => {
const [showPassword, setShowPassword] = useState(false);
let inputBorderStyle = styles.square;
if (borderStyle === "square") inputBorderStyle = styles.square;
if(borderStyle === "rounded") inputBorderStyle = styles.rounded;
const toggleShowPassword = () => {
setShowPassword(!showPassword);
};
if(password) return (
<div className={styles.passwordContainer}>
<TextInput
type={showPassword ? "text" : "password"}
value={value}
placeholder={placeholder}
onChange={onChange}
className={styles.passwordInput}
/>
<button
type="button"
onClick={toggleShowPassword}
className={styles.passwordBtn}
>
{showPassword ? '👁️' : '🔒'}
</button>
</div>
);
return <input className={`${styles.input} ${inputBorderStyle} ${className}`} onChange={onChange} placeholder={placeholder} value={value} {...props} />
};
export default TextInput;*/
import styles from "./input.module.css";
import { useState, InputHTMLAttributes, ChangeEvent } from "react";
import { useState, ChangeEvent, InputHTMLAttributes } from "react";
interface TextInputProps extends InputHTMLAttributes<HTMLInputElement> {
placeholder?: string;
onChange: (event: ChangeEvent<HTMLInputElement>) => void;
value: string;
borderStyle?: "square" | "rounded";
password?: boolean;
className?: string;
placeholder?: string;
value?: string;
onChange?: (e: ChangeEvent<HTMLInputElement>) => void;
borderStyle?: "square" | "rounded";
password?: boolean;
className?: string;
}
const TextInput = ({
placeholder,
onChange,
value,
borderStyle = "square",
password = false,
className = "",
...props
}: TextInputProps) => {
const [showPassword, setShowPassword] = useState(false);
const borderStyles = {
square: styles.square,
rounded: styles.rounded,
};
placeholder,
onChange,
value,
borderStyle = "square",
password,
className = "",
...props
}: TextInputProps) => {
const [showPassword, setShowPassword] = useState<boolean>(false);
const inputBorderStyle = borderStyles[borderStyle] || styles.square;
let inputBorderStyle = styles.square;
if (borderStyle === "rounded") inputBorderStyle = styles.rounded;
const toggleShowPassword = () => {
setShowPassword(!showPassword);
};
const toggleShowPassword = () => {
setShowPassword((prev) => !prev);
};
if (password)
return (
<div className={styles.passwordContainer}>
<TextInput
type={showPassword ? "text" : "password"}
value={value}
placeholder={placeholder}
onChange={onChange}
className={styles.passwordInput}
/>
<button
type="button"
onClick={toggleShowPassword}
className={styles.passwordBtn}
>
{showPassword ? "👁️" : "🔒"}
</button>
</div>
);
if (password) {
return (
<div className={styles.passwordContainer}>
<input
type={showPassword ? "text" : "password"}
value={value}
placeholder={placeholder}
onChange={onChange}
className={`${styles.input} ${styles.passwordInput} ${inputBorderStyle} ${className}`}
{...props}
className={`${styles.input} ${inputBorderStyle} ${className}`}
onChange={onChange}
placeholder={placeholder}
value={value}
{...props}
/>
<button
type="button"
onClick={toggleShowPassword}
className={styles.passwordBtn}
>
{showPassword ? "👁️" : "🔒"}
</button>
</div>
);
}
return (
<input
className={`${styles.input} ${inputBorderStyle} ${className}`}
onChange={onChange}
placeholder={placeholder}
value={value}
{...props}
/>
);
};
export default TextInput;
@@ -0,0 +1,32 @@
import Button from "../button/button.tsx";
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 = () => {
let newTheme = theme === "light" ? "dark" : "light";
if(theme === null || theme === "") newTheme = "dark";
localStorage.setItem("theme", newTheme);
setTheme(newTheme);
window.dispatchEvent(new Event("theme-changed"));
};
return <Button variant={"default"} onClick={switchTheme} className={styles.themeBtn}>
<img src={`/icons/theme/${theme}.svg`} alt={`${theme} icon`} className={styles.themeIcon} />
<p>Changer de thème </p>
</Button>
}
+1 -1
View File
@@ -12,7 +12,7 @@ export function AuthProvider({ children }) {
useEffect(() => {
(async () => {
const u = await getUser();
setUser(u.data);
if(u.status === 200) setUser(u.data);
setLoading(false);
})();
}, []);
+4
View File
@@ -0,0 +1,4 @@
export default interface Response<T> {
status: number;
data: T;
}
+3 -10
View File
@@ -1,10 +1,10 @@
import { useState, useContext } from "react";
import { useContext } from "react";
import styles from "./AdminPage.module.css";
import ParticipationChart from "./components/chart/ParticipationChart.jsx";
import IncompleteEvents from "./components/IncompleteEvent/IncompleteEvent.jsx";
import PendingMembers from "./components/pendingMembers/PendingMembers.jsx";
import { AuthContext } from "../../contexts/auth/AuthContext.js";
import { useNavigate } from "react-router";
import RegisterMember from "./components/registerMember/registerMember.tsx";
function AdminPage() {
@@ -12,18 +12,11 @@ function AdminPage() {
const { user } = useContext(AuthContext);
const navigate = useNavigate();
const [selected, setSelected] = useState("3");
const [participationRate] = useState(89);
if(!user.isAdmin) navigate("/");
return (
<div className={styles.container}>
<ParticipationChart
selected={selected}
setSelected={setSelected}
participationRate={participationRate}
/>
<RegisterMember />
<div className={styles.rightSection}>
<IncompleteEvents />
<PendingMembers />
@@ -1,111 +1,100 @@
import React, { useState, useEffect } from "react";
import Button from "../../../../components/ui/button/button.jsx";
import React, {useState, useEffect} from "react";
import Button from "../../../../components/ui/button/button.tsx";
import styles from "./PendingMembers.module.css";
import Modal from "../../../../components/ui/modal/modal.tsx";
import getUserToValidate from "../../../../utils/users/getUserToValidate.js";
import getUserById from "../../../../utils/users/getUserById.js";
import validateUser from "../../../../utils/users/validateUser.js";
import deleteOtherUser from "../../../../utils/users/deleteOtherUser.js";
function PendingMembers() {
const [pendingMembers, setPendingMembers] = useState([]);
const [loading, setLoading] = useState(true);
const [actionLoading, setActionLoading] = useState(null);
const [error, setError] = useState(null);
useEffect(() => {
const fetchPendingMembers = async () => {
setLoading(true);
const result = await getUserToValidate();
const userIds = result.data
if (userIds && userIds.length > 0) {
const users = await Promise.all(userIds.map((id) => getUserById(id)));
setPendingMembers(users.filter(Boolean));
} else {
setPendingMembers([]);
}
setLoading(false);
};
fetchPendingMembers();
}, []);
const removeMember = (id) => {
setPendingMembers(prevMembers =>
prevMembers.filter(member => member.id !== id)
);
};
const [open, setOpen] = useState(false);
const [message, setMessage] = useState("");
const [title, setTitle] = useState("");
const handleValidate = async (id) => {
setActionLoading(id);
setError(null);
try {
const result = await validateUser(id);
if (result === true) {
removeMember(id);
} else {
setError("Échec de la validation.");
const [pendingMembers, setPendingMembers] = useState([]);
const fetchUsers = async () => {
const result = await getUserToValidate();
const userIds = result.data;
if (userIds && userIds.length > 0) {
const users = await Promise.all(userIds.map(id => getUserById(id)));
const usersData = users.map(u => u.data);
setPendingMembers(usersData);
} else setPendingMembers([]);
}
} catch (err) {
setError("Erreur lors de la validation.");
} finally {
setActionLoading(null);
}
};
const handleReject = async (id) => {
setActionLoading(id);
setError(null);
try {
const result = await deleteUser(id);
if (result.status >= 200 && result.status < 300) {
removeMember(id);
} else {
setError(result.errors || "Échec de la suppression.");
useEffect(() => {
fetchUsers();
}, []);
const handleValidate = async (id, name) => {
const result = await validateUser(id);
if(result.status === 200) {
setTitle("Utilisateur accepté avec succès")
setMessage(`L'utilisateur ${name} a été accepté avec succès`)
setOpen(true);
} else {
setTitle("Erreur")
setMessage(`Une erreur est survenue durant l'acceptation de l'utilisateur ${name}`)
setOpen(true);
}
fetchUsers();
}
} catch (err) {
setError("Erreur lors de la suppression.");
} finally {
setActionLoading(null);
}
};
const handleRefuse = async (id, name) => {
const result = await deleteOtherUser(id);
if (loading) {
return <div>Chargement des membres en attente...</div>;
}
if(result.status === 200) {
setTitle("Utilisateur refusé avec succès")
setMessage(`L'utilisateur ${name} a été refusé avec succès`)
setOpen(true);
} else {
setTitle("Erreur")
setMessage(`Une erreur est survenue durant le refus de l'utilisateur ${name}`)
setOpen(true);
}
return (
<div className={`${styles.rightBlock} glassCard`}>
<h2>Membres en attente de validation</h2>
{error && <p style={{ color: "red" }}>{error}</p>}
fetchUsers();
}
<div className={styles.membersContainer}>
{pendingMembers.length === 0 && <p>Aucun membre en attente</p>}
return (
<div className={`${styles.rightBlock} glassCard`}>
<h2>Membres en attente de validation</h2>
<div className={styles.membersContainer}>
{pendingMembers.length === 0 && <p>Aucun membre en attente</p>}
{pendingMembers.map((member, index) => (
<div key={index} className={`glassCard ${styles.memberCard}`}>
<p>{member.name} {member.lastname}</p>
<div className={styles.buttonGroup}>
<Button variant="primary" onClick={() => handleValidate(member.id, `${member.name} ${member.lastname}`)}>Valider</Button>
<Button variant="danger" onClick={() => handleRefuse(member.id, `${member.name} ${member.lastname}`)}>Refuser</Button>
</div>
</div>
))}
{pendingMembers.map((member) => (
<div key={member.id} className={`glassCard ${styles.memberCard}`}>
<p>{member.name} {member.lastname}</p>
<div className={styles.buttonGroup}>
<Button
onClick={() => handleValidate(member.id)}
variant="primary"
disabled={actionLoading === member.id}
>
{actionLoading === member.id ? "En cours..." : "Valider"}
</Button>
<Button
onClick={() => handleReject(member.id)}
variant="danger"
disabled={actionLoading === member.id}
>
{actionLoading === member.id ? "En cours..." : "Refuser"}
</Button>
</div>
</div>
))}
</div>
</div>
);
<Modal open={open} onClose={() => setOpen(false)} title={title}>
{message}
</Modal>
</div>
);
}
export default PendingMembers;
@@ -0,0 +1,52 @@
.leftBlock {
width: 100%;
max-width: 720px;
display: flex;
flex-direction: column;
align-items: center;
min-height: calc(100vh - 260px);
box-sizing: border-box;
padding: 20px;
margin: 0 auto;
}
.registerMemberHeader {
display: flex;
align-items: center;
justify-content: center;
width: 100%;
margin-bottom: 20px;
}
.registerForm {
width: 100%;
display: flex;
flex-direction: column;
gap: 16px;
align-items: stretch;
}
.registerForm input {
width: 100%;
box-sizing: border-box;
}
.registerForm button {
width: 100%;
}
.modalContent {
text-align: center;
}
@media (min-width: 768px) {
.leftBlock {
width: 70%;
}
}
@media (min-width: 1024px) {
.leftBlock {
width: 40%;
}
}
@@ -0,0 +1,74 @@
import React, { useState } from "react"
import styles from "./registerMember.module.css"
import TextInput from "../../../../components/ui/input/input"
import Button from "../../../../components/ui/button/button";
import Response from "../../../../interfaces/response.interface";
import ResponseData from "./responseData.inteface";
import adminCreateUser from "../../../../utils/users/adminCreateUser";
import Modal from "../../../../components/ui/modal/modal";
const RegisterMember: React.FC = () => {
const [name, setName] = useState<string>("");
const [lastname, setLastName] = useState<string>("");
const [email, setEmail] = useState<string>("");
const [phone, setPhone] = useState<string>("");
const [password, setPassword] = useState<string>("");
const [open, setOpen] = useState<boolean>(false);
const [title, setTitle] = useState<string>("");
const [message, setMessage] = useState<string>("");
const handleCreate = async (): Promise<void> => {
if(name !== "" && lastname !== "" && email !== "" && phone !== "" ) {
const response: Response<ResponseData> = await adminCreateUser(email, name, lastname, phone);
if(response.status === 200) {
setPassword(response.data.password);
setTitle(`Utilisateur enregistré avec succès`);
setMessage(`L'utilisateur ${name} ${lastname} a été enregistré avec le mot de passe: ${response.data.password}`);
setOpen(true);
} else {
setTitle(`Erreur`);
setMessage(`Une erreur est survenue lors de l'enregistrement de ${name} ${lastname}`);
setOpen(true);
}
} else {
setTitle("Erreur");
setMessage("Un des champs n'a pas été rempli");
setOpen(true);
}
}
const showPassword = (): void => {
setTitle(`Mot de passe de ${name} ${lastname}`);
setMessage(password);
setOpen(true);
}
return <div className={`${styles.leftBlock} glassCard`}>
<div className={styles.registerMemberHeader}>
<h2>Enregister un bénévole</h2>
</div>
<div className={styles.registerForm}>
<TextInput placeholder={"Prenom"} type={"text"} value={name} onChange={e => setName(e.target.value)} />
<TextInput placeholder={"Nom"} type={"text"} value={lastname} onChange={e => setLastName(e.target.value)} />
<TextInput placeholder={"Adresse Email"} type={"email"} value={email} onChange={e => setEmail(e.target.value)} />
<TextInput placeholder={"Numéro de téléphone"} type={"tel"} value={phone} onChange={e => setPhone(e.target.value)} />
{password !== "" && <Button onClick={showPassword}> Afficher le mot de passe </Button>}
<Button variant={"default"} onClick={handleCreate}>Enregistrer</Button>
</div>
<Modal open={open} onClose={() => setOpen(false)} title={title}>
<p className={styles.modalContent}>{message}</p>
</Modal>
</div>
}
export default RegisterMember
@@ -0,0 +1,4 @@
export default interface ResponseData {
message: string;
password: string;
}
+1 -1
View File
@@ -1,7 +1,7 @@
import styles from "./Event.module.css";
import { useState, useEffect } from "react";
import { useNavigate } from "react-router";
import Button from "/src/components/ui/button/button.jsx"
import Button from "/src/components/ui/button/button"
function Event({event}){
@@ -1,8 +1,8 @@
import { useState, useContext } from "react";
import styles from "./loginForm.module.css";
import Button from "../../../../components/ui/button/button.jsx";
import Input from "../../../../components/ui/input/input.jsx";
import Modal from "../../../../components/ui/modal/modal.jsx";
import Button from "../../../../components/ui/button/button.tsx";
import Input from "../../../../components/ui/input/input.tsx";
import Modal from "../../../../components/ui/modal/modal.tsx";
import { useNavigate } from "react-router";
import { AuthContext } from "../../../../contexts/auth/AuthContext.js";
@@ -0,0 +1,86 @@
import Modal from "../../../../components/ui/modal/modal.tsx";
import Button from "../../../../components/ui/button/button.tsx";
import styles from "./SettingsModal.module.css"
import { useContext, useState } from "react";
import ThemeSwitcher from "../../../../components/ui/themeSwitcher/ThemeSwitcher.jsx";
import { AuthContext } from "../../../../contexts/auth/AuthContext.js";
import TextInput from "../../../../components/ui/input/input.tsx";
import updateUser from "../../../../utils/users/updateUser.js";
import deleteUser from "../../../../utils/users/deleteUser.js";
export default function SettingsModal() {
const { user, logout, update } = useContext(AuthContext);
const [open, setOpen] = useState(false);
const [isDelete, setIsDelete] = 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();
}
const handleDelete = async () => {
await deleteUser();
update();
}
return (
<>
<Button variant={"transparent"} onClick={() => setOpen(!open)}>
<img src={"/icons/settings-wheel.svg"} alt={"Modify btn"} className={styles.modifyIcon}/>
</Button>
<Modal title={"Paramètres"} open={open} onClose={() => setOpen(false)}>
<div className={styles.content}>
<div className={styles.section}>
<h3>Compte</h3>
<Button variant={"danger"} onClick={handleLogout}> Déconnexion </Button>
<Button variant={"danger"} onClick={() => setIsDelete(true)}> Supprimer le compte </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}>
<h3>Apparence</h3>
<ThemeSwitcher />
</div>
</div>
</Modal>
<Modal title={"Validation"} open={isDelete} onClose={() => setIsDelete(false)}>
<div className={styles.section}>
<p className={styles.alignText}> Êtes vous vraiment sûr de vouloir supprimer votre compte ?</p>
<Button variant={"danger"} className={styles.submitBtn} onClick={handleDelete}>Confirmer</Button>
</div>
</Modal>
</>
)
}
+3 -3
View File
@@ -1,12 +1,12 @@
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 Input from "../../components/ui/input/input.tsx";
import Button from "../../components/ui/button/button.tsx";
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";
import Modal from "../../components/ui/modal/modal.tsx";
function RegisterPage() {
@@ -1,5 +1,5 @@
import Button from "../../../../components/ui/button/button.jsx";
import Modal from "../../../../components/ui/modal/modal.jsx";
import Button from "../../../../components/ui/button/button.tsx";
import Modal from "../../../../components/ui/modal/modal.tsx";
import {useContext, useState} from "react";
import styles from "./manageMember.module.css"
import DeactivateMemberBtn from "./deactivateMember/deactivateMemberBtn.jsx";
@@ -1,5 +1,5 @@
import Button from "../../../../../components/ui/button/button.jsx";
import Modal from "../../../../../components/ui/modal/modal.jsx";
import Button from "../../../../../components/ui/button/button.tsx";
import Modal from "../../../../../components/ui/modal/modal.tsx";
import { useState } from "react";
import deactivateUser from "../../../../../utils/users/deactivateUser.js"
import { useNavigate } from "react-router";
@@ -1,9 +1,9 @@
import styles from "../manageMember.module.css";
import Button from "../../../../../components/ui/button/button.jsx";
import Button from "../../../../../components/ui/button/button.tsx";
import modifyRole from "../../../../../utils/users/modifyRole.js";
import { useState, useEffect } from "react";
import getRoles from "../../../../../utils/getRoles.js";
import Modal from "../../../../../components/ui/modal/modal.jsx";
import Modal from "../../../../../components/ui/modal/modal.tsx";
export default function ModifyRole({ user }) {
+1 -1
View File
@@ -2,7 +2,7 @@ import React, {useState} from "react";
import styles from "./VolunteersPage.module.css";
import formatDate from "../../utils/date/formatDate.js";
import { useNavigate } from "react-router";
import Button from "../../components/ui/button/button.jsx";
import Button from "../../components/ui/button/button.tsx";
export default function VolunteerCard({ user }) {
@@ -1,11 +1,11 @@
import styles from "./eventTask.module.css";
import { formatDateLetter } from "../../../../utils/date/formatDateLetter.js";
import Button from "../../../../components/ui/button/button.jsx";
import Button from "../../../../components/ui/button/button.tsx";
import assign from "../../../../utils/tasks/assign.js";
import unAssign from "../../../../utils/tasks/unAssign.js";
import { useContext, useEffect, useState } from "react";
import isAssigned from "../../../../utils/tasks/isAssigned.js";
import Modal from "../../../../components/ui/modal/modal.jsx";
import Modal from "../../../../components/ui/modal/modal.tsx";
import { AuthContext } from "../../../../contexts/auth/AuthContext.js";
import DeleteTaskBtn from "../deleteTaskBtn/deleteTaskBtn.jsx";
@@ -1,8 +1,8 @@
import styles from "../../eventDetail.module.css";
import Button from "../../../../components/ui/button/button.jsx";
import Button from "../../../../components/ui/button/button.tsx";
import {useContext, useState} from "react";
import TextInput from "../../../../components/ui/input/input.jsx";
import Modal from "../../../../components/ui/modal/modal.jsx";
import TextInput from "../../../../components/ui/input/input.tsx";
import Modal from "../../../../components/ui/modal/modal.tsx";
import createTaskApi from "../../../../utils/tasks/createTask.js";
import {EventDetailContext} from "../../../../contexts/eventDetail/eventDetail.js";
@@ -1,6 +1,6 @@
import styles from "../../eventDetail.module.css";
import Button from "../../../../components/ui/button/button.jsx";
import Modal from "../../../../components/ui/modal/modal.jsx";
import Button from "../../../../components/ui/button/button.tsx";
import Modal from "../../../../components/ui/modal/modal.tsx";
import { useContext, useState } from "react";
import { EventDetailContext } from "../../../../contexts/eventDetail/eventDetail.js";
import { EventContext } from "../../../../contexts/events/EventContext.js";
@@ -1,9 +1,9 @@
import { useContext } from "react";
import { AuthContext } from "../../../../contexts/auth/AuthContext.js";
import { EventDetailContext } from "../../../../contexts/eventDetail/eventDetail.js";
import Button from "../../../../components/ui/button/button.jsx";
import Button from "../../../../components/ui/button/button.tsx";
import { useState } from "react";
import Modal from "../../../../components/ui/modal/modal.jsx";
import Modal from "../../../../components/ui/modal/modal.tsx";
import styles from "../../eventDetail.module.css";
export default function DeleteTaskBtn({ taskId, eventId, taskName }) {
@@ -1,6 +1,6 @@
import styles from "./validationErrorPage.module.css"
import Background from "../../components/background/background.jsx";
import Button from "../../components/ui/button/button.jsx";
import Button from "../../components/ui/button/button.tsx";
import { useContext } from "react";
import { AuthContext } from "../../contexts/auth/AuthContext.js";
import { Navigate, useNavigate, Link } from "react-router";
@@ -15,6 +15,10 @@ export default function ValidationErrorPage() {
navigate("/login");
}
const handleRefresh = () => {
window.location.reload();
}
if(user && user.validate === 1) return <Navigate to="/" />;
return <Background>
@@ -27,7 +31,10 @@ export default function ValidationErrorPage() {
https://comite.beaupont.fr/contactez-nous
</Link>
</p>
<Button variant={"danger"} onClick={handleLogout}> Déconnexion </Button>
<div className={styles.btnContainer}>
<Button variant={"default"} onClick={handleRefresh}> Recharger </Button>
<Button variant={"danger"} onClick={handleLogout}> Déconnexion </Button>
</div>
</div>
</div>
</Background>
@@ -22,4 +22,10 @@
p {
font-size: large;
}
}
.btnContainer {
display: flex;
flex-direction: row;
gap: 15px;
}
+1 -1
View File
@@ -72,7 +72,7 @@ const router = createBrowserRouter([
Component: legalNotices,
},
{
path: "/RGPD",
path: "/rgpd",
Component: RGPD,
},
]
+1 -1
View File
@@ -1,6 +1,6 @@
import { fn } from 'storybook/test';
import Button from '../components/ui/button/button.jsx';
import Button from '../components/ui/button/button.tsx';
export default {
+1 -1
View File
@@ -1,5 +1,5 @@
import { useState } from "react";
import TextInput from "../components/ui/input/input.jsx";
import TextInput from "../components/ui/input/input.tsx";
export default {
+2 -2
View File
@@ -1,5 +1,5 @@
import Modal from "../components/ui/modal/modal.jsx";
import Button from "../components/ui/button/button.jsx";
import Modal from "../components/ui/modal/modal.tsx";
import Button from "../components/ui/button/button.tsx";
import { useState } from "react";
export default {
+14
View File
@@ -0,0 +1,14 @@
import fetchWrapper from "../fetchWrapper.js";
import getXSRFToken from "../getXSRF.js";
import Response from "../../interfaces/response.interface";
export default async function adminCreateUser(email: string, name: string, lastname: string, phone: string): Promise<Response> {
const csrfToken = await getXSRFToken();
return fetchWrapper(
"/api/users/create",
{ email, name, lastname, phone },
"POST",
{ "X-XSRF-TOKEN": csrfToken }
);
}