Merge branch 'features/admin-assign' into 'dev'
Features/admin assign See merge request sae-but2/2025-26/gestion-benevoles-association/Frontend!90
This commit is contained in:
@@ -1,55 +0,0 @@
|
||||
import {useEffect, useContext} from "react";
|
||||
import styles from "./EventDetailPage.module.css";
|
||||
import {useParams} from "react-router";
|
||||
import {formatDateLetter} from "../../utils/date/formatDateLetter.js";
|
||||
import EventTask from "./components/EventTask/EventTask.jsx";
|
||||
import {AuthContext} from "../../contexts/Auth/AuthContext.js";
|
||||
import {EventDetailContext} from "../../contexts/EventDetail/EventDetailContext.js";
|
||||
import CreateTaskBtn from "./components/CreateTaskBtn/CreateTaskBtn.jsx";
|
||||
import DeleteEventBtn from "./components/DeleteEventBtn/DeleteEventBtn.jsx";
|
||||
|
||||
|
||||
function EventDetailPage() {
|
||||
|
||||
const params = useParams();
|
||||
const id = params.id;
|
||||
const {user} = useContext(AuthContext)
|
||||
const {tasks, updateEventInfo, eventInfo} = useContext(EventDetailContext)
|
||||
|
||||
useEffect(() => {
|
||||
updateEventInfo(id);
|
||||
}, [])
|
||||
|
||||
|
||||
return (
|
||||
<div className={styles.allContent}>
|
||||
<div className={`glassCard`}>
|
||||
<div className={styles.textImage}>
|
||||
<img src="/icons/theme/dark.svg" alt="Illustration événement" className={styles.eventImage}/>
|
||||
<div className={styles.eventInfo}>
|
||||
<h2>{eventInfo?.name}</h2>
|
||||
<div className={styles.eventContent}>
|
||||
<div>
|
||||
<p>{eventInfo && formatDateLetter(eventInfo.start)}</p>
|
||||
<p>{eventInfo?.description}</p>
|
||||
</div>
|
||||
{user?.isAdmin && <div className={styles.manageEvent}>
|
||||
<DeleteEventBtn id={id}/>
|
||||
<CreateTaskBtn id={id}/>
|
||||
</div>}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h2>Tâches</h2>
|
||||
<div className={styles.tasks}>
|
||||
{tasks?.map((task, index) => (
|
||||
<EventTask task={task} key={index} eventId={id} />
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default EventDetailPage;
|
||||
@@ -0,0 +1,65 @@
|
||||
import { useEffect, useContext } from "react";
|
||||
import styles from "./EventDetailPage.module.css";
|
||||
import { useParams } from "react-router";
|
||||
import { formatDateLetter } from "../../utils/date/formatDateLetter";
|
||||
import EventTask from "./components/EventTask/EventTask";
|
||||
import { AuthContext } from "../../contexts/Auth/AuthContext";
|
||||
import { EventDetailContext } from "../../contexts/EventDetail/EventDetailContext";
|
||||
import CreateTaskBtn from "./components/CreateTaskBtn/CreateTaskBtn";
|
||||
import DeleteEventBtn from "./components/DeleteEventBtn/DeleteEventBtn";
|
||||
|
||||
function EventDetailPage() {
|
||||
const params = useParams();
|
||||
const id = params.id as string;
|
||||
|
||||
const { user } = useContext(AuthContext) as any;
|
||||
const { tasks, updateEventInfo, eventInfo } = useContext(EventDetailContext) as any;
|
||||
|
||||
useEffect(() => {
|
||||
if (id) {
|
||||
updateEventInfo(id);
|
||||
}
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div className={styles.allContent}>
|
||||
<div className={`glassCard`}>
|
||||
<div className={styles.textImage}>
|
||||
<img
|
||||
src="/icons/theme/dark.svg"
|
||||
alt="Illustration événement"
|
||||
className={styles.eventImage}
|
||||
/>
|
||||
|
||||
<div className={styles.eventInfo}>
|
||||
<h2>{eventInfo?.name}</h2>
|
||||
|
||||
<div className={styles.eventContent}>
|
||||
<div>
|
||||
<p>{eventInfo && formatDateLetter(eventInfo.start)}</p>
|
||||
<p>{eventInfo?.description}</p>
|
||||
</div>
|
||||
|
||||
{user?.isAdmin && (
|
||||
<div className={styles.manageEvent}>
|
||||
<DeleteEventBtn id={id} />
|
||||
<CreateTaskBtn id={id} />
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h2>Tâches</h2>
|
||||
|
||||
<div className={styles.tasks}>
|
||||
{tasks?.map((task: any, index: number) => (
|
||||
<EventTask task={task} key={index} eventId={id} index={index} />
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default EventDetailPage;
|
||||
@@ -0,0 +1,23 @@
|
||||
.usersList {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 10px;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.userCard {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 10px 14px;
|
||||
border-radius: 10px;
|
||||
background: rgba(255,255,255,0.05);
|
||||
border: 1px solid rgba(255,255,255,0.08);
|
||||
}
|
||||
|
||||
.userName {
|
||||
max-width: 200px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
import {ReactNode, useContext, useEffect, useState} from "react";
|
||||
import Button from "../../../../components/ui/Button/Button";
|
||||
import Modal from "../../../../components/ui/Modal/Modal";
|
||||
import User from "../../../Volunteers/interfaces/user.interface";
|
||||
import getAllUser from "../../../../utils/users/getAllUsers";
|
||||
import Loading from "../../../../components/ui/Loading/Loading";
|
||||
import getUserById from "../../../../utils/users/getUserById";
|
||||
import styles from "./AssignUserBtn.module.css";
|
||||
import {AuthContext} from "../../../../contexts/Auth/AuthContext";
|
||||
import assignOtherUser from "../../../../utils/tasks/assignOtherUser";
|
||||
import unAssignOtherUser from "../../../../utils/tasks/unAssignOtherUser";
|
||||
|
||||
interface AssignUserBtnProps {
|
||||
taskId: string | number;
|
||||
}
|
||||
|
||||
export default function AssignUserBtn({ taskId }: AssignUserBtnProps): ReactNode {
|
||||
|
||||
const [open, setOpen] = useState<boolean>(false);
|
||||
const [users, setUsers] = useState<Array<User>>([]);
|
||||
const [loading, setLoading] = useState<boolean>(true);
|
||||
|
||||
const { user } = useContext(AuthContext) as any;
|
||||
|
||||
if (!user?.isAdmin) return null;
|
||||
|
||||
useEffect(() => {
|
||||
(async () => {
|
||||
setLoading(true);
|
||||
|
||||
const result = await getAllUser();
|
||||
|
||||
if (result.status !== 200 || !Array.isArray(result.data)) {
|
||||
console.error("Erreur lors du chargement des utilisateurs", result);
|
||||
return;
|
||||
}
|
||||
|
||||
const usersData = await Promise.all(
|
||||
result.data.map(async (id: number): Promise<User | null> => {
|
||||
const res = await getUserById(id);
|
||||
|
||||
if (res.status === 200) {
|
||||
return res.data as User;
|
||||
}
|
||||
|
||||
return null;
|
||||
})
|
||||
);
|
||||
|
||||
setUsers(usersData.filter((user): user is User => user !== null));
|
||||
setLoading(false);
|
||||
})();
|
||||
}, []);
|
||||
|
||||
const isUserAssigned = (u: User): boolean =>
|
||||
u.tasks.some(t => t.id === taskId);
|
||||
|
||||
const handleAssign = async (selectedUser: User) => {
|
||||
await assignOtherUser(taskId as number, selectedUser.id);
|
||||
setOpen(false);
|
||||
};
|
||||
|
||||
const handleUnassign = async (selectedUser: User) => {
|
||||
await unAssignOtherUser(taskId as number, selectedUser.id);
|
||||
setOpen(false);
|
||||
};
|
||||
|
||||
return <>
|
||||
<Button variant={"default"} onClick={() => setOpen(true)}>Assigner</Button>
|
||||
|
||||
<Modal open={open} onClose={() => setOpen(false)} title={"Assigner un utilisateur à cette tâche"}>
|
||||
<div className={styles.usersList}>
|
||||
{loading ? <Loading /> : users.map((user: User, index) => (
|
||||
<div key={index} className={styles.userCard}>
|
||||
<p className={styles.userName}>
|
||||
{user.name} {user.lastname}
|
||||
</p>
|
||||
|
||||
{isUserAssigned(user) ? (
|
||||
<Button variant={"danger"} onClick={() => handleUnassign(user)}>
|
||||
Désassigner
|
||||
</Button>
|
||||
) : (
|
||||
<Button onClick={() => handleAssign(user)}>
|
||||
Assigner
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</Modal>
|
||||
</>
|
||||
}
|
||||
@@ -1,116 +0,0 @@
|
||||
import styles from "../../EventDetailPage.module.css";
|
||||
import Button from "../../../../components/ui/Button/Button";
|
||||
import {useContext, useState} from "react";
|
||||
import TextInput from "../../../../components/ui/Input/Input";
|
||||
import Modal from "../../../../components/ui/Modal/Modal";
|
||||
import createTaskApi from "../../../../utils/tasks/createTask.js";
|
||||
import {EventDetailContext} from "../../../../contexts/EventDetail/EventDetailContext.js";
|
||||
|
||||
export default function CreateTaskBtn({ id }) {
|
||||
|
||||
const [openTaskModal, setOpenTaskModal] = useState(false);
|
||||
|
||||
const [taskName, setTaskName] = useState("");
|
||||
const [taskDescription, setTaskDescription] = useState("");
|
||||
const [taskLocation, setTaskLocation] = useState("");
|
||||
const [maxParticipants, setMaxParticipants] = useState("");
|
||||
const [startTime, setStartTime] = useState("");
|
||||
const [endTime, setEndTime] = useState("");
|
||||
|
||||
const { updateEventInfo } = useContext(EventDetailContext)
|
||||
|
||||
const createTask = async () => {
|
||||
const data = await createTaskApi({
|
||||
eventId: id,
|
||||
name: taskName,
|
||||
description: taskDescription,
|
||||
start: startTime,
|
||||
end: endTime,
|
||||
location: taskLocation,
|
||||
maxParticipants,
|
||||
});
|
||||
|
||||
if (data?.status === 200) {
|
||||
setOpenTaskModal(false);
|
||||
setTaskName("");
|
||||
setTaskDescription("");
|
||||
setTaskLocation("");
|
||||
setMaxParticipants("");
|
||||
setStartTime("");
|
||||
setEndTime("");
|
||||
|
||||
updateEventInfo(id)
|
||||
} else {
|
||||
console.log("⚠️ Échec de la création de la task");
|
||||
}
|
||||
};
|
||||
|
||||
return <>
|
||||
|
||||
<Button variant={"default"} className={styles.manageBtn} onClick={() => setOpenTaskModal(true)}>Créer tâche</Button>
|
||||
|
||||
<Modal open={openTaskModal} onClose={() => setOpenTaskModal(false)} title={"Créer tâche"}>
|
||||
<div className={styles.modalContent}>
|
||||
|
||||
<div>
|
||||
<p>Nom de la tâche</p>
|
||||
<TextInput
|
||||
value={taskName}
|
||||
onChange={(e) => setTaskName(e.target.value)}
|
||||
placeholder="Nom de la tâche"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<p>Description</p>
|
||||
<TextInput
|
||||
value={taskDescription}
|
||||
onChange={(e) => setTaskDescription(e.target.value)}
|
||||
placeholder="Description de la tâche"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<p>Lieu</p>
|
||||
<TextInput
|
||||
value={taskLocation}
|
||||
onChange={(e) => setTaskLocation(e.target.value)}
|
||||
placeholder="Lieu"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<p>Nombre maximum de participants</p>
|
||||
<TextInput
|
||||
type="number"
|
||||
value={maxParticipants}
|
||||
onChange={(e) => setMaxParticipants(e.target.value)}
|
||||
placeholder="Participants max"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<p>Heure de début</p>
|
||||
<TextInput
|
||||
type="datetime-local"
|
||||
value={startTime}
|
||||
onChange={(e) => setStartTime(e.target.value)}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<p>Heure de fin</p>
|
||||
<TextInput
|
||||
type="datetime-local"
|
||||
value={endTime}
|
||||
onChange={(e) => setEndTime(e.target.value)}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<Button variant="default" onClick={createTask}> Créer la tâche </Button>
|
||||
|
||||
</div>
|
||||
</Modal>
|
||||
|
||||
</>
|
||||
}
|
||||
@@ -0,0 +1,129 @@
|
||||
import styles from "../../EventDetailPage.module.css";
|
||||
import Button from "../../../../components/ui/Button/Button";
|
||||
import { useContext, useState } from "react";
|
||||
import TextInput from "../../../../components/ui/Input/Input";
|
||||
import Modal from "../../../../components/ui/Modal/Modal";
|
||||
import createTaskApi from "../../../../utils/tasks/createTask";
|
||||
import { EventDetailContext } from "../../../../contexts/EventDetail/EventDetailContext";
|
||||
|
||||
type CreateTaskBtnProps = {
|
||||
id: string | number;
|
||||
};
|
||||
|
||||
export default function CreateTaskBtn({ id }: CreateTaskBtnProps) {
|
||||
const [openTaskModal, setOpenTaskModal] = useState(false);
|
||||
|
||||
const [taskName, setTaskName] = useState<string>("");
|
||||
const [taskDescription, setTaskDescription] = useState<string>("");
|
||||
const [taskLocation, setTaskLocation] = useState<string>("");
|
||||
const [maxParticipants, setMaxParticipants] = useState<string>("");
|
||||
const [startTime, setStartTime] = useState<string>("");
|
||||
const [endTime, setEndTime] = useState<string>("");
|
||||
|
||||
const { updateEventInfo } = useContext(EventDetailContext) as any;
|
||||
|
||||
const createTask = async () => {
|
||||
const data = await createTaskApi({
|
||||
eventId: id,
|
||||
name: taskName,
|
||||
description: taskDescription,
|
||||
start: startTime,
|
||||
end: endTime,
|
||||
location: taskLocation,
|
||||
maxParticipants,
|
||||
});
|
||||
|
||||
if (data?.status === 200) {
|
||||
setOpenTaskModal(false);
|
||||
setTaskName("");
|
||||
setTaskDescription("");
|
||||
setTaskLocation("");
|
||||
setMaxParticipants("");
|
||||
setStartTime("");
|
||||
setEndTime("");
|
||||
|
||||
updateEventInfo(id);
|
||||
} else {
|
||||
console.log("⚠️ Échec de la création de la task");
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<Button
|
||||
variant={"default"}
|
||||
className={styles.manageBtn}
|
||||
onClick={() => setOpenTaskModal(true)}
|
||||
>
|
||||
Créer tâche
|
||||
</Button>
|
||||
|
||||
<Modal
|
||||
open={openTaskModal}
|
||||
onClose={() => setOpenTaskModal(false)}
|
||||
title={"Créer tâche"}
|
||||
>
|
||||
<div className={styles.modalContent}>
|
||||
<div>
|
||||
<p>Nom de la tâche</p>
|
||||
<TextInput
|
||||
value={taskName}
|
||||
onChange={(e: any) => setTaskName(e.target.value)}
|
||||
placeholder="Nom de la tâche"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<p>Description</p>
|
||||
<TextInput
|
||||
value={taskDescription}
|
||||
onChange={(e: any) => setTaskDescription(e.target.value)}
|
||||
placeholder="Description de la tâche"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<p>Lieu</p>
|
||||
<TextInput
|
||||
value={taskLocation}
|
||||
onChange={(e: any) => setTaskLocation(e.target.value)}
|
||||
placeholder="Lieu"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<p>Nombre maximum de participants</p>
|
||||
<TextInput
|
||||
type="number"
|
||||
value={maxParticipants}
|
||||
onChange={(e: any) => setMaxParticipants(e.target.value)}
|
||||
placeholder="Participants max"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<p>Heure de début</p>
|
||||
<TextInput
|
||||
type="datetime-local"
|
||||
value={startTime}
|
||||
onChange={(e: any) => setStartTime(e.target.value)}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<p>Heure de fin</p>
|
||||
<TextInput
|
||||
type="datetime-local"
|
||||
value={endTime}
|
||||
onChange={(e: any) => setEndTime(e.target.value)}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<Button variant="default" onClick={createTask}>
|
||||
Créer la tâche
|
||||
</Button>
|
||||
</div>
|
||||
</Modal>
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -1,42 +0,0 @@
|
||||
import styles from "../../EventDetailPage.module.css";
|
||||
import Button from "../../../../components/ui/Button/Button";
|
||||
import Modal from "../../../../components/ui/Modal/Modal";
|
||||
import { useContext, useState } from "react";
|
||||
import { EventDetailContext } from "../../../../contexts/EventDetail/EventDetailContext.js";
|
||||
import { EventContext } from "../../../../contexts/Events/EventContext.js";
|
||||
import { useNavigate } from "react-router";
|
||||
|
||||
export default function DeleteEventBtn({ id }) {
|
||||
|
||||
const { eventInfo } = useContext(EventDetailContext)
|
||||
const { removeEvent } = useContext(EventContext)
|
||||
const [open, setOpen] = useState(false);
|
||||
const navigate = useNavigate();
|
||||
|
||||
const handleDelete = () => {
|
||||
setOpen(true);
|
||||
}
|
||||
|
||||
const delEvent = async () => {
|
||||
const result = await removeEvent(id);
|
||||
|
||||
if (result.status === 200 || result.status === 204) {
|
||||
setOpen(false);
|
||||
navigate("/events");
|
||||
}
|
||||
}
|
||||
|
||||
return <>
|
||||
|
||||
<Button variant={"danger"} className={styles.manageBtn} onClick={handleDelete}>Supprimer</Button>
|
||||
|
||||
<Modal open={open} onClose={() => setOpen(false)} title={"Suppression"}>
|
||||
<div className={styles.modalContent}>
|
||||
<p>Etes-vous sur de vouloir supprimer l'événement {eventInfo?.name} ?</p>
|
||||
|
||||
<Button variant={"default"} onClick={delEvent}>Confirmer</Button>
|
||||
</div>
|
||||
</Modal>
|
||||
|
||||
</>
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
import styles from "../../EventDetailPage.module.css";
|
||||
import Button from "../../../../components/ui/Button/Button";
|
||||
import Modal from "../../../../components/ui/Modal/Modal";
|
||||
import { useContext, useState } from "react";
|
||||
import { EventDetailContext } from "../../../../contexts/EventDetail/EventDetailContext";
|
||||
import { EventContext } from "../../../../contexts/Events/EventContext";
|
||||
import { useNavigate } from "react-router";
|
||||
|
||||
type DeleteEventBtnProps = {
|
||||
id: string | number;
|
||||
};
|
||||
|
||||
export default function DeleteEventBtn({ id }: DeleteEventBtnProps) {
|
||||
const { eventInfo } = useContext(EventDetailContext) as any;
|
||||
const { removeEvent } = useContext(EventContext) as any;
|
||||
|
||||
const [open, setOpen] = useState(false);
|
||||
const navigate = useNavigate();
|
||||
|
||||
const handleDelete = () => {
|
||||
setOpen(true);
|
||||
};
|
||||
|
||||
const delEvent = async () => {
|
||||
const result = await removeEvent(id);
|
||||
|
||||
if (result.status === 200 || result.status === 204) {
|
||||
setOpen(false);
|
||||
navigate("/events");
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<Button
|
||||
variant={"danger"}
|
||||
className={styles.manageBtn}
|
||||
onClick={handleDelete}
|
||||
>
|
||||
Supprimer
|
||||
</Button>
|
||||
|
||||
<Modal open={open} onClose={() => setOpen(false)} title={"Suppression"}>
|
||||
<div className={styles.modalContent}>
|
||||
<p>
|
||||
Etes-vous sur de vouloir supprimer l'événement {eventInfo?.name} ?
|
||||
</p>
|
||||
|
||||
<Button variant={"default"} onClick={delEvent}>
|
||||
Confirmer
|
||||
</Button>
|
||||
</div>
|
||||
</Modal>
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
import { useContext } from "react";
|
||||
import { AuthContext } from "../../../../contexts/Auth/AuthContext.js";
|
||||
import { EventDetailContext } from "../../../../contexts/EventDetail/EventDetailContext.js";
|
||||
import Button from "../../../../components/ui/Button/Button";
|
||||
import { useState } from "react";
|
||||
import Modal from "../../../../components/ui/Modal/Modal";
|
||||
import styles from "../../EventDetailPage.module.css";
|
||||
|
||||
export default function DeleteTaskBtn({ taskId, eventId, taskName }) {
|
||||
|
||||
const { user } = useContext(AuthContext)
|
||||
const { deleteTask } = useContext(EventDetailContext)
|
||||
|
||||
const [openModal, setOpenModal] = useState(false);
|
||||
|
||||
if(!user?.isAdmin) return null;
|
||||
|
||||
return <>
|
||||
<Button variant={"danger"} onClick={() => setOpenModal(true)}> Supprimer </Button>
|
||||
|
||||
<Modal open={openModal} onClose={setOpenModal} title={"Suppression"}>
|
||||
<div className={styles.modalContent}>
|
||||
<p className={styles.modalContent}>Etes-vous sur de vouloir supprimer la tâche {taskName} ? </p>
|
||||
<Button variant={"danger"} onClick={() => { deleteTask(taskId, eventId); setOpenModal(false) }}> Confirmer </Button>
|
||||
</div>
|
||||
</Modal>
|
||||
</>
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
import { useContext, useState } from "react";
|
||||
import { AuthContext } from "../../../../contexts/Auth/AuthContext";
|
||||
import { EventDetailContext } from "../../../../contexts/EventDetail/EventDetailContext";
|
||||
import Button from "../../../../components/ui/Button/Button";
|
||||
import Modal from "../../../../components/ui/Modal/Modal";
|
||||
import styles from "../../EventDetailPage.module.css";
|
||||
|
||||
type DeleteTaskBtnProps = {
|
||||
taskId: string | number;
|
||||
eventId: string | number;
|
||||
taskName: string;
|
||||
};
|
||||
|
||||
export default function DeleteTaskBtn({ taskId, eventId, taskName }: DeleteTaskBtnProps) {
|
||||
|
||||
const { user } = useContext(AuthContext) as any;
|
||||
const { deleteTask } = useContext(EventDetailContext) as any;
|
||||
|
||||
const [openModal, setOpenModal] = useState<boolean>(false);
|
||||
|
||||
if (!user?.isAdmin) return null;
|
||||
|
||||
return (
|
||||
<>
|
||||
<Button variant={"danger"} onClick={() => setOpenModal(true)}>
|
||||
Supprimer
|
||||
</Button>
|
||||
|
||||
<Modal open={openModal} onClose={() => setOpenModal(false)} title={"Suppression"}>
|
||||
<div className={styles.modalContent}>
|
||||
<p className={styles.modalContent}>
|
||||
Etes-vous sur de vouloir supprimer la tâche {taskName} ?
|
||||
</p>
|
||||
|
||||
<Button
|
||||
variant={"danger"}
|
||||
onClick={() => {
|
||||
deleteTask(taskId, eventId);
|
||||
setOpenModal(false);
|
||||
}}
|
||||
>
|
||||
Confirmer
|
||||
</Button>
|
||||
</div>
|
||||
</Modal>
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -1,98 +0,0 @@
|
||||
import styles from "./EventTask.module.css";
|
||||
import { formatDateLetter } from "../../../../utils/date/formatDateLetter.js";
|
||||
import Button from "../../../../components/ui/Button/Button";
|
||||
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";
|
||||
import { AuthContext } from "../../../../contexts/Auth/AuthContext.js";
|
||||
import DeleteTaskBtn from "../DeleteTaskBtn/DeleteTaskBtn.jsx";
|
||||
|
||||
export default function EventTask({ task, index, eventId }) {
|
||||
|
||||
const { update } = useContext(AuthContext)
|
||||
|
||||
const [assigned, setAssigned] = useState(false);
|
||||
const [open, setOpen] = useState(false);
|
||||
const [title, setTitle] = useState("");
|
||||
const [message, setMessage] = useState("");
|
||||
|
||||
async function checkAssign() {
|
||||
const data = await isAssigned(task.id);
|
||||
setAssigned(data?.data.assigned);
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
checkAssign();
|
||||
}, [])
|
||||
|
||||
|
||||
const handleRegisterBtn = async () => {
|
||||
const res = await assign(task.id);
|
||||
|
||||
switch (res.status) {
|
||||
case 200:
|
||||
update()
|
||||
setTitle("Inscription réussie")
|
||||
setMessage(`Vous êtes maintenant inscrit à la tâche ${task.name}`);
|
||||
setOpen(true);
|
||||
setAssigned(true);
|
||||
break;
|
||||
|
||||
case 409:
|
||||
setTitle("Erreur lors de l'inscription")
|
||||
setMessage("Vous êtes déjà inscrit à cette tâche")
|
||||
setOpen(true);
|
||||
break;
|
||||
|
||||
case 403:
|
||||
setTitle("Erreur lors de l'inscription")
|
||||
setMessage("Le nombre maximum d'inscription pour cette tâche à été atteint")
|
||||
setOpen(true);
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
const handleUnassign = async () => {
|
||||
const res = await unAssign(task.id);
|
||||
|
||||
switch (res.status) {
|
||||
case 200:
|
||||
update()
|
||||
setTitle("Désinscription réussie")
|
||||
setMessage(`Vous n'êtes plus inscrit à la tâche ${task.name}`);
|
||||
setOpen(true);
|
||||
setAssigned(false);
|
||||
break;
|
||||
|
||||
case 409:
|
||||
setTitle("Erreur lors de la désinscription")
|
||||
setMessage(`Vous n'êtes pas inscrit à cette tâche`);
|
||||
setOpen(true);
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
return <div style={{"--i": index}} key={index} className={styles.content}>
|
||||
<div className={styles.task}>
|
||||
<div>
|
||||
<span><strong>{task.name}</strong></span>
|
||||
<p className={styles.taskDate}> {formatDateLetter(task.start)} - {formatDateLetter(task.end)} </p>
|
||||
<p>{task.description}</p>
|
||||
</div>
|
||||
<div className={styles.manageTaskBtn}>
|
||||
{assigned ?
|
||||
<Button variant={"danger"} onClick={() => handleUnassign()}> Se désinscrire </Button>
|
||||
:
|
||||
<Button onClick={() => handleRegisterBtn()}> S’inscrire </Button>
|
||||
}
|
||||
<DeleteTaskBtn eventId={eventId} taskId={task.id} taskName={task.name} />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Modal open={open} onClose={setOpen} title={title}>
|
||||
<p className={styles.modalContent}>{message}</p>
|
||||
</Modal>
|
||||
</div>
|
||||
}
|
||||
@@ -0,0 +1,122 @@
|
||||
import styles from "./EventTask.module.css";
|
||||
import { formatDateLetter } from "../../../../utils/date/formatDateLetter";
|
||||
import Button from "../../../../components/ui/Button/Button";
|
||||
import assign from "../../../../utils/tasks/assign";
|
||||
import unAssign from "../../../../utils/tasks/unAssign";
|
||||
import { useContext, useEffect, useState } from "react";
|
||||
import isAssigned from "../../../../utils/tasks/isAssigned";
|
||||
import Modal from "../../../../components/ui/Modal/Modal";
|
||||
import { AuthContext } from "../../../../contexts/Auth/AuthContext";
|
||||
import DeleteTaskBtn from "../DeleteTaskBtn/DeleteTaskBtn";
|
||||
import AssignUserBtn from "../AssignUserBtn/AssignUserBtn";
|
||||
|
||||
type EventTaskProps = {
|
||||
task: any;
|
||||
index: number;
|
||||
eventId: string | number;
|
||||
};
|
||||
|
||||
export default function EventTask({ task, index, eventId }: EventTaskProps) {
|
||||
|
||||
const { update } = useContext(AuthContext) as any;
|
||||
|
||||
const [assigned, setAssigned] = useState<boolean>(false);
|
||||
const [open, setOpen] = useState<boolean>(false);
|
||||
const [title, setTitle] = useState<string>("");
|
||||
const [message, setMessage] = useState<string>("");
|
||||
|
||||
async function checkAssign() {
|
||||
const data = await isAssigned(task.id);
|
||||
setAssigned(data?.data.assigned);
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
checkAssign();
|
||||
}, []);
|
||||
|
||||
const handleRegisterBtn = async () => {
|
||||
const res = await assign(task.id);
|
||||
|
||||
switch (res.status) {
|
||||
case 200:
|
||||
update();
|
||||
setTitle("Inscription réussie");
|
||||
setMessage(`Vous êtes maintenant inscrit à la tâche ${task.name}`);
|
||||
setOpen(true);
|
||||
setAssigned(true);
|
||||
break;
|
||||
|
||||
case 409:
|
||||
setTitle("Erreur lors de l'inscription");
|
||||
setMessage("Vous êtes déjà inscrit à cette tâche");
|
||||
setOpen(true);
|
||||
break;
|
||||
|
||||
case 403:
|
||||
setTitle("Erreur lors de l'inscription");
|
||||
setMessage("Le nombre maximum d'inscription pour cette tâche à été atteint");
|
||||
setOpen(true);
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
const handleUnassign = async () => {
|
||||
const res = await unAssign(task.id);
|
||||
|
||||
switch (res.status) {
|
||||
case 200:
|
||||
update();
|
||||
setTitle("Désinscription réussie");
|
||||
setMessage(`Vous n'êtes plus inscrit à la tâche ${task.name}`);
|
||||
setOpen(true);
|
||||
setAssigned(false);
|
||||
break;
|
||||
|
||||
case 409:
|
||||
setTitle("Erreur lors de la désinscription");
|
||||
setMessage(`Vous n'êtes pas inscrit à cette tâche`);
|
||||
setOpen(true);
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div style={{ "--i": index } as any} key={index} className={styles.content}>
|
||||
<div className={styles.task}>
|
||||
<div>
|
||||
<span>
|
||||
<strong>{task.name}</strong>
|
||||
</span>
|
||||
<p className={styles.taskDate}>
|
||||
{formatDateLetter(task.start)} - {formatDateLetter(task.end)}
|
||||
</p>
|
||||
<p>{task.description}</p>
|
||||
</div>
|
||||
|
||||
<div className={styles.manageTaskBtn}>
|
||||
{assigned ? (
|
||||
<Button variant={"danger"} onClick={() => handleUnassign()}>
|
||||
Se désinscrire
|
||||
</Button>
|
||||
) : (
|
||||
<Button onClick={() => handleRegisterBtn()}>
|
||||
S’inscrire
|
||||
</Button>
|
||||
)}
|
||||
|
||||
<DeleteTaskBtn
|
||||
eventId={eventId}
|
||||
taskId={task.id}
|
||||
taskName={task.name}
|
||||
/>
|
||||
|
||||
<AssignUserBtn taskId={task.id} />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Modal open={open} onClose={() => setOpen(false)} title={title}>
|
||||
<p className={styles.modalContent}>{message}</p>
|
||||
</Modal>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -3,7 +3,7 @@ import styles from "./LoginForm.module.css";
|
||||
import Button from "../../../../components/ui/Button/Button";
|
||||
import Input from "../../../../components/ui/Input/Input";
|
||||
import Modal from "../../../../components/ui/Modal/Modal";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { useNavigate } from "react-router";
|
||||
import { AuthContext, AuthContextType } from "../../../../contexts/Auth/AuthContext";
|
||||
|
||||
interface LoginFormProps {
|
||||
|
||||
+1
-1
@@ -9,7 +9,7 @@ import EventsPage from "./pages/Events/EventsPage.jsx";
|
||||
import AdminPage from "./pages/Admin/AdminPage.jsx";
|
||||
import WaitValidationPage from "./pages/WaitValidation/WaitValidationPage.jsx";
|
||||
import PageNotFoundPage from "./pages/PageNotFound/PageNotFoundPage.jsx";
|
||||
import eventDetail from "./pages/EventDetail/EventDetailPage.jsx";
|
||||
import eventDetail from "./pages/EventDetail/EventDetailPage.tsx";
|
||||
import legalNotices from "./pages/LegalNotices/LegalNoticesPage.jsx";
|
||||
import RGPDPage from "./pages/RGPD/RGPDPage.jsx";
|
||||
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
import fetchWrapper from "../fetchWrapper.js";
|
||||
import getXSRFToken from "../getXSRF.js";
|
||||
|
||||
export default async function assignOtherUser(taskId: number, userId: number): Promise<any> {
|
||||
const csrfToken = await getXSRFToken();
|
||||
|
||||
return fetchWrapper(
|
||||
`/api/events/task/assign/${userId}`,
|
||||
{task_id: taskId},
|
||||
"POST",
|
||||
{"X-XSRF-TOKEN": csrfToken}
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
import fetchWrapper from "../fetchWrapper.js";
|
||||
import getXSRFToken from "../getXSRF.js";
|
||||
|
||||
export default async function unAssignOtherUser(taskId: number, userId: number): Promise<any> {
|
||||
const csrfToken = await getXSRFToken();
|
||||
|
||||
return fetchWrapper(
|
||||
`/api/events/task/unassign/${userId}`,
|
||||
{task_id: taskId},
|
||||
"POST",
|
||||
{"X-XSRF-TOKEN": csrfToken}
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user