diff --git a/src/components/SearchBar/SearchBar.tsx b/src/components/SearchBar/SearchBar.tsx index d1ef4c6..3e928ee 100644 --- a/src/components/SearchBar/SearchBar.tsx +++ b/src/components/SearchBar/SearchBar.tsx @@ -1,8 +1,8 @@ import styles from "./SearchBar.module.css"; import { Link } from "react-router"; import { useEffect, useState } from "react"; -import searchEvents from "../../utils/events/searchEvents.js"; -import searchUsers from "../../utils/users/searchUsers.js"; +import searchEvents from "../../utils/events/searchEvents"; +import searchUsers from "../../utils/users/searchUsers"; import { useLocation } from "react-router"; function SearchBar(): any { diff --git a/src/components/Task/Task.tsx b/src/components/Task/Task.tsx index daf805d..0c8c161 100644 --- a/src/components/Task/Task.tsx +++ b/src/components/Task/Task.tsx @@ -1,5 +1,5 @@ import { useEffect, useState } from "react"; -import getEventById from "../../utils/events/getEventById.js"; +import getEventById from "../../utils/events/getEventById"; import styles from "./Task.module.css"; import formatDate from "../../utils/date/formatDate"; diff --git a/src/components/ToolBar/tools/CreateEventBtn/CreateEventBtn.jsx b/src/components/ToolBar/tools/CreateEventBtn/CreateEventBtn.jsx index 5aae9d6..1db6a10 100644 --- a/src/components/ToolBar/tools/CreateEventBtn/CreateEventBtn.jsx +++ b/src/components/ToolBar/tools/CreateEventBtn/CreateEventBtn.jsx @@ -26,7 +26,7 @@ export default function CreateEventBtn() { setIsOpen(false); } - if(!user.isAdmin) return null; + if(!user?.isAdmin) return null; return <> diff --git a/src/components/ui/Input/Input.tsx b/src/components/ui/Input/Input.tsx index 0ced004..8f523b2 100644 --- a/src/components/ui/Input/Input.tsx +++ b/src/components/ui/Input/Input.tsx @@ -11,14 +11,14 @@ interface TextInputProps extends InputHTMLAttributes { } const TextInput = ({ - placeholder, - onChange, - value, - borderStyle = "square", - password, - className = "", - ...props - }: TextInputProps) => { + placeholder = "", + onChange, + value = "", + borderStyle = "square", + password = false, + className = "", + ...props +}: TextInputProps) => { const [showPassword, setShowPassword] = useState(false); let inputBorderStyle = styles.square; @@ -28,15 +28,16 @@ const TextInput = ({ setShowPassword((prev) => !prev); }; - if (password) + if (password) { return (
-
); + } return ( Loading

; + if (loading) return + + ; if (!user) return ; if(user && user.validate === 0) return ; diff --git a/src/pages/Admin/AdminPage.jsx b/src/pages/Admin/AdminPage.jsx index 7d36503..5765849 100644 --- a/src/pages/Admin/AdminPage.jsx +++ b/src/pages/Admin/AdminPage.jsx @@ -1,8 +1,8 @@ import { useContext } from "react"; import styles from "./AdminPage.module.css"; -import IncompleteEvents from "./components/IncompleteEvent/IncompleteEvent.jsx"; -import PendingMembers from "./components/PendingMembers/PendingMembers.jsx"; -import { AuthContext } from "../../contexts/Auth/AuthContext.js"; +import IncompleteEvents from "./components/IncompleteEvent/IncompleteEvent"; +import PendingMembers from "./components/PendingMembers/PendingMembers"; +import { AuthContext } from "../../contexts/Auth/AuthContext"; import { useNavigate } from "react-router"; import RegisterMember from "./components/RegisterMember/RegisterMember"; diff --git a/src/pages/Admin/components/IncompleteEvent/IncompleteEvent.jsx b/src/pages/Admin/components/IncompleteEvent/IncompleteEvent.jsx index 73b637c..c5a31a8 100644 --- a/src/pages/Admin/components/IncompleteEvent/IncompleteEvent.jsx +++ b/src/pages/Admin/components/IncompleteEvent/IncompleteEvent.jsx @@ -10,25 +10,28 @@ function IncompleteEvent() {

Derniers événements

- {events.map((event) => ( -
-

{event.name}

-

- {new Date(event.start).toLocaleDateString("fr-FR")} - {new Date(event.end).toLocaleDateString("fr-FR")} -

-

{event.description}

-

Tâches associées :

-
    - {event.tasks?.length ? ( - event.tasks.map((task, taskIndex) => ( -
  • {task.name}
  • - )) - ) : ( -
  • Aucune tâche associée.
  • - )} -
-
- ))} + {Array.isArray(events) && events.length > 0 ? ( + events.map((event) => ( +
+

{event.name}

+

+ {new Date(event.start).toLocaleDateString("fr-FR")} - {new Date(event.end).toLocaleDateString("fr-FR")} +

+

{event.description}

+

Tâches associées :

+
    + {event.tasks?.length ? ( + event.tasks.map((task, taskIndex) => ( +
  • {task.name}
  • + )) + ) : ( +
  • Aucune tâche associée.
  • + )} +
+
+ ))) : ( +

Aucun événement n'existe pour le moment

+ )}
); diff --git a/src/pages/Admin/components/PendingMembers/PendingMembers.jsx b/src/pages/Admin/components/PendingMembers/PendingMembers.jsx index d93714a..473e536 100644 --- a/src/pages/Admin/components/PendingMembers/PendingMembers.jsx +++ b/src/pages/Admin/components/PendingMembers/PendingMembers.jsx @@ -7,8 +7,6 @@ import deleteOtherUser from "../../../../utils/users/deleteOtherUser.js"; import { PendingMembersContext } from "../../../../contexts/PendingMembers/PendingMembersContext"; function PendingMembers() { - - const [open, setOpen] = useState(false); const [message, setMessage] = useState(""); const [title, setTitle] = useState(""); diff --git a/src/pages/EventDetail/EventDetailPage.jsx b/src/pages/EventDetail/EventDetailPage.jsx deleted file mode 100644 index ee31c39..0000000 --- a/src/pages/EventDetail/EventDetailPage.jsx +++ /dev/null @@ -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 ( -
-
-
- Illustration événement -
-

{eventInfo?.name}

-
-
-

{eventInfo && formatDateLetter(eventInfo.start)}

-

{eventInfo?.description}

-
- {user?.isAdmin &&
- - -
} -
-
-
- -

Tâches

-
- {tasks?.map((task, index) => ( - - ))} -
-
-
- ); -} - -export default EventDetailPage; \ No newline at end of file diff --git a/src/pages/EventDetail/EventDetailPage.tsx b/src/pages/EventDetail/EventDetailPage.tsx new file mode 100644 index 0000000..9c76e8e --- /dev/null +++ b/src/pages/EventDetail/EventDetailPage.tsx @@ -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 ( +
+
+
+ Illustration événement + +
+

{eventInfo?.name}

+ +
+
+

{eventInfo && formatDateLetter(eventInfo.start)}

+

{eventInfo?.description}

+
+ + {user?.isAdmin && ( +
+ + +
+ )} +
+
+
+ +

Tâches

+ +
+ {tasks?.map((task: any, index: number) => ( + + ))} +
+
+
+ ); +} + +export default EventDetailPage; \ No newline at end of file diff --git a/src/pages/EventDetail/components/AssignUserBtn/AssignUserBtn.module.css b/src/pages/EventDetail/components/AssignUserBtn/AssignUserBtn.module.css new file mode 100644 index 0000000..c5798dc --- /dev/null +++ b/src/pages/EventDetail/components/AssignUserBtn/AssignUserBtn.module.css @@ -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; +} \ No newline at end of file diff --git a/src/pages/EventDetail/components/AssignUserBtn/AssignUserBtn.tsx b/src/pages/EventDetail/components/AssignUserBtn/AssignUserBtn.tsx new file mode 100644 index 0000000..9a9ad3d --- /dev/null +++ b/src/pages/EventDetail/components/AssignUserBtn/AssignUserBtn.tsx @@ -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(false); + const [users, setUsers] = useState>([]); + const [loading, setLoading] = useState(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 => { + 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 <> + + + setOpen(false)} title={"Assigner un utilisateur à cette tâche"}> +
+ {loading ? : users.map((user: User, index) => ( +
+

+ {user.name} {user.lastname} +

+ + {isUserAssigned(user) ? ( + + ) : ( + + )} +
+ ))} +
+
+ +} \ No newline at end of file diff --git a/src/pages/EventDetail/components/CreateTaskBtn/CreateTaskBtn.tsx b/src/pages/EventDetail/components/CreateTaskBtn/CreateTaskBtn.tsx new file mode 100644 index 0000000..9b228c3 --- /dev/null +++ b/src/pages/EventDetail/components/CreateTaskBtn/CreateTaskBtn.tsx @@ -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(""); + const [taskDescription, setTaskDescription] = useState(""); + const [taskLocation, setTaskLocation] = useState(""); + const [maxParticipants, setMaxParticipants] = useState(""); + const [startTime, setStartTime] = useState(""); + const [endTime, setEndTime] = useState(""); + + 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 ( + <> + + + setOpenTaskModal(false)} + title={"Créer tâche"} + > +
+
+

Nom de la tâche

+ setTaskName(e.target.value)} + placeholder="Nom de la tâche" + /> +
+ +
+

Description

+ setTaskDescription(e.target.value)} + placeholder="Description de la tâche" + /> +
+ +
+

Lieu

+ setTaskLocation(e.target.value)} + placeholder="Lieu" + /> +
+ +
+

Nombre maximum de participants

+ setMaxParticipants(e.target.value)} + placeholder="Participants max" + /> +
+ +
+

Heure de début

+ setStartTime(e.target.value)} + /> +
+ +
+

Heure de fin

+ setEndTime(e.target.value)} + /> +
+ + +
+
+ + ); +} \ No newline at end of file diff --git a/src/pages/EventDetail/components/DeleteEventBtn/DeleteEventBtn.jsx b/src/pages/EventDetail/components/DeleteEventBtn/DeleteEventBtn.jsx deleted file mode 100644 index 5309450..0000000 --- a/src/pages/EventDetail/components/DeleteEventBtn/DeleteEventBtn.jsx +++ /dev/null @@ -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 <> - - - - setOpen(false)} title={"Suppression"}> -
-

Etes-vous sur de vouloir supprimer l'événement {eventInfo?.name} ?

- - -
-
- - -} \ No newline at end of file diff --git a/src/pages/EventDetail/components/DeleteEventBtn/DeleteEventBtn.tsx b/src/pages/EventDetail/components/DeleteEventBtn/DeleteEventBtn.tsx new file mode 100644 index 0000000..9a79467 --- /dev/null +++ b/src/pages/EventDetail/components/DeleteEventBtn/DeleteEventBtn.tsx @@ -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 ( + <> + + + setOpen(false)} title={"Suppression"}> +
+

+ Etes-vous sur de vouloir supprimer l'événement {eventInfo?.name} ? +

+ + +
+
+ + ); +} \ No newline at end of file diff --git a/src/pages/EventDetail/components/DeleteTaskBtn/DeleteTaskBtn.jsx b/src/pages/EventDetail/components/DeleteTaskBtn/DeleteTaskBtn.jsx deleted file mode 100644 index af6e3d0..0000000 --- a/src/pages/EventDetail/components/DeleteTaskBtn/DeleteTaskBtn.jsx +++ /dev/null @@ -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 <> - - - -
-

Etes-vous sur de vouloir supprimer la tâche {taskName} ?

- -
-
- -} \ No newline at end of file diff --git a/src/pages/EventDetail/components/DeleteTaskBtn/DeleteTaskBtn.tsx b/src/pages/EventDetail/components/DeleteTaskBtn/DeleteTaskBtn.tsx new file mode 100644 index 0000000..6c16221 --- /dev/null +++ b/src/pages/EventDetail/components/DeleteTaskBtn/DeleteTaskBtn.tsx @@ -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(false); + + if (!user?.isAdmin) return null; + + return ( + <> + + + setOpenModal(false)} title={"Suppression"}> +
+

+ Etes-vous sur de vouloir supprimer la tâche {taskName} ? +

+ + +
+
+ + ); +} \ No newline at end of file diff --git a/src/pages/EventDetail/components/EventTask/EventTask.jsx b/src/pages/EventDetail/components/EventTask/EventTask.jsx deleted file mode 100644 index 41e6429..0000000 --- a/src/pages/EventDetail/components/EventTask/EventTask.jsx +++ /dev/null @@ -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
-
-
- {task.name} -

{formatDateLetter(task.start)} - {formatDateLetter(task.end)}

-

{task.description}

-
-
- {assigned ? - - : - - } - -
-
- - -

{message}

-
-
-} \ No newline at end of file diff --git a/src/pages/EventDetail/components/EventTask/EventTask.tsx b/src/pages/EventDetail/components/EventTask/EventTask.tsx new file mode 100644 index 0000000..4a1188b --- /dev/null +++ b/src/pages/EventDetail/components/EventTask/EventTask.tsx @@ -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(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 ( +
+
+
+ + {task.name} + +

+ {formatDateLetter(task.start)} - {formatDateLetter(task.end)} +

+

{task.description}

+
+ +
+ {assigned ? ( + + ) : ( + + )} + + + + +
+
+ + setOpen(false)} title={title}> +

{message}

+
+
+ ); +} \ No newline at end of file diff --git a/src/pages/Events/EventsPage.jsx b/src/pages/Events/EventsPage.jsx index 60f46be..256e825 100644 --- a/src/pages/Events/EventsPage.jsx +++ b/src/pages/Events/EventsPage.jsx @@ -19,9 +19,12 @@ function EventsPage(){
- {filter(events, filters, "event").map((event, index) => ( - - ))} + {Array.isArray(events) && events.length > 0 ? ( + filter(events, filters, "event").map((event, index) => ( + + ))) : ( +

Aucun événement n'existe pour le moment

+ )}
) diff --git a/src/pages/Events/components/Event/Event.jsx b/src/pages/Events/components/Event/Event.jsx index 3067e79..fe15c4e 100644 --- a/src/pages/Events/components/Event/Event.jsx +++ b/src/pages/Events/components/Event/Event.jsx @@ -1,5 +1,4 @@ import styles from "./Event.module.css"; -import { useState, useEffect } from "react"; import { useNavigate } from "react-router"; import Button from "/src/components/ui/Button/Button" @@ -7,27 +6,10 @@ function Event({event}){ const navigate = useNavigate(); - const [eventMenu, seteventMenu] = useState(false); - const [windowSize, setWindowSize] = useState({ - width: null, - height: null, - }); - - useEffect(() => { - function handleResize() { - setWindowSize({ - width: window.innerWidth, - height: window.innerHeight, - }); - } - window.addEventListener("resize", handleResize); - handleResize(); - return () => window.removeEventListener("resize", handleResize); - }, []); - + const handleNavigate = () => navigate(`/events/` + event.id); return ( -
seteventMenu(!eventMenu)}> +
@@ -40,40 +22,9 @@ function Event({event}){

{event.name}

{event.description}

- {event.tasks != null ? ( -
-
    - {event.tasks - .slice(0,5) - .map((task, index) => ( -
  • - {task.name}
  • - ))} - {event.tasks.length > 5 ? ( -
  • ...
  • - ) : null} -
-
- ) : null}
- {windowSize.width > 768 ? ( -
- -
- ) : null} -
-
- {(windowSize.width <= 768 || eventMenu) ? ( - - - - ) : null} +
) diff --git a/src/pages/Events/components/Event/Event.module.css b/src/pages/Events/components/Event/Event.module.css index 021f7bd..409ce24 100644 --- a/src/pages/Events/components/Event/Event.module.css +++ b/src/pages/Events/components/Event/Event.module.css @@ -6,6 +6,10 @@ padding: 1rem 0.5rem; } +.eventContainer:hover { + cursor: pointer; +} + .eventContainerTop { display: flex; justify-content: space-between; @@ -99,6 +103,11 @@ display: none; } +.openBtn { + align-self: center; + white-space: nowrap; +} + @media screen and (max-width: 768px) { .eventImage { width: 100%; diff --git a/src/pages/Home/components/Calendar/Calendar.jsx b/src/pages/Home/components/Calendar/Calendar.jsx index 53ba22a..574b172 100644 --- a/src/pages/Home/components/Calendar/Calendar.jsx +++ b/src/pages/Home/components/Calendar/Calendar.jsx @@ -3,13 +3,12 @@ import styles from "./Calendar.module.css"; import {formatDateLetterJS} from "../../../../utils/date/formatDateLetter.js"; import Button from "../../../../components/ui/Button/Button"; import {AuthContext} from "../../../../contexts/Auth/AuthContext.ts"; +import ExportBtn from "./ExportBtn.tsx"; function Calendar() { const { user } = useContext(AuthContext); - const calendarUrl = `${import.meta.env.VITE_API_URL}/api/export/ics/${user.id}`; - const monthNames = [ "Janvier", "Février", "Mars", "Avril", "Mai", "Juin", "Juillet", "Août", "Septembre", "Octobre", "Novembre", "Décembre" @@ -152,16 +151,7 @@ Calendar() {
)}
-

votre lien d'agenda: {calendarUrl}

- +
diff --git a/src/pages/Home/components/Calendar/Calendar.module.css b/src/pages/Home/components/Calendar/Calendar.module.css index b70ac34..c577ba6 100644 --- a/src/pages/Home/components/Calendar/Calendar.module.css +++ b/src/pages/Home/components/Calendar/Calendar.module.css @@ -156,6 +156,7 @@ margin-top: 16px; display: flex; align-items: center; + justify-content: center; } .exportbtn { diff --git a/src/pages/Home/components/Calendar/ExportBtn.tsx b/src/pages/Home/components/Calendar/ExportBtn.tsx new file mode 100644 index 0000000..c5192aa --- /dev/null +++ b/src/pages/Home/components/Calendar/ExportBtn.tsx @@ -0,0 +1,21 @@ +import Button from "../../../../components/ui/Button/Button"; +import styles from "../../HomePage.module.css" +import { useContext } from "react"; +import { AuthContext, AuthContextType } from "../../../../contexts/Auth/AuthContext"; +import { APP_CONFIG } from "../../../../config/appConfig"; + +export default function ExportBtn() { + + const { user } = useContext(AuthContext) as AuthContextType; + const calendarUrl = `${import.meta.env.VITE_API_URL}/api/export/ics/${user?.id}`; + + return +} \ No newline at end of file diff --git a/src/pages/Home/components/EventList/EventItem.tsx b/src/pages/Home/components/EventList/EventItem.tsx index 185f09d..2b48c79 100644 --- a/src/pages/Home/components/EventList/EventItem.tsx +++ b/src/pages/Home/components/EventList/EventItem.tsx @@ -1,6 +1,6 @@ import styles from "./EventList.module.css"; import { formatDateLetter } from "../../../../utils/date/formatDateLetter"; -import { useState } from "react"; +import { useNavigate } from "react-router"; type Task = { name: string; @@ -10,6 +10,7 @@ type Task = { }; type EventGroup = { + id: number; date: string; name: string; start: string | Date; @@ -21,60 +22,19 @@ type EventItemProps = { }; export default function EventItem({ eventGroup }: EventItemProps) { - const [isVisible, setIsVisible] = useState(false); + + const navigate = useNavigate(); return (
setIsVisible(!isVisible)} + onClick={() => navigate(`/events/${eventGroup.id}`)} >

{eventGroup.name}

{formatDateLetter(eventGroup.start)}

- - {isVisible && ( -
    - {eventGroup.tasks.map((task, i) => ( -
  • -

    - - {task.name} - {task.description} -

    -

    - {formatDateLetter(task.start)} - {formatDateLetter(task.end)} -

    -
  • - ))} -
- )}
); -} - -/*import styles from "./eventList.module.css"; -import { formatDateLetter } from "../../../../utils/date/formatDateLetter.ts"; -import { useState } from "react"; - -export default function EventItem({ eventGroup }) { - - const [isVisible, setIsVisible] = useState(false); - - return
setIsVisible(!isVisible)}> -
-

{eventGroup.name}

-

{formatDateLetter(eventGroup.start)}

-
- {isVisible && -
    - {eventGroup.tasks.map((task, i) => ( -
  • -

    - {task.name} - {task.description}

    -

    {formatDateLetter(task.start)} - {formatDateLetter(task.end)}

    -
  • - ))} -
- } -
-} -*/ \ No newline at end of file +} \ No newline at end of file diff --git a/src/pages/Home/components/EventList/EventList.tsx b/src/pages/Home/components/EventList/EventList.tsx index 711d057..5d36f63 100644 --- a/src/pages/Home/components/EventList/EventList.tsx +++ b/src/pages/Home/components/EventList/EventList.tsx @@ -1,38 +1,3 @@ -/*import { useMemo } from "react"; -import styles from "./eventList.module.css"; -import EventItem from "./eventItem.jsx"; -import { EventContext } from "../../../../contexts/events/EventContext.js"; -import { useContext } from "react"; - -function EventList() { - // Utilise une valeur par défaut pour `events` si elle est `undefined` - const { events = [] } = useContext(EventContext); - - const sortedEvents = useMemo(() => { - // Vérifie explicitement que `events` est un tableau avant de trier - if (!Array.isArray(events)) return []; - return [...events].sort( - (a, b) => new Date(a.start) - new Date(b.start) - ); - }, [events]); - - return ( -
-

Liste des événements à venir

- {sortedEvents.length > 0 ? ( -
- {sortedEvents.map((eventGroup, index) => ( - - ))} -
- ) : ( -

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

- )} -
- ); -} - -export default EventList;*/ import { useMemo, useContext } from "react"; import styles from "./EventList.module.css"; import EventItem from "./EventItem"; diff --git a/src/pages/Login/LoginPage.tsx b/src/pages/Login/LoginPage.tsx new file mode 100644 index 0000000..9868eaa --- /dev/null +++ b/src/pages/Login/LoginPage.tsx @@ -0,0 +1,28 @@ +import styles from "./LoginPage.module.css"; +import LoginForm from "./components/LoginForm/LoginForm"; +import Background from "../../components/Background/Background.jsx"; +import { useEffect, useContext } from "react"; +import { AuthContext, AuthContextType } from "../../../src/contexts/Auth/AuthContext"; +import { useNavigate } from "react-router"; + +function LoginPage() { + const { user, loading } = useContext(AuthContext) as AuthContextType; + const navigate = useNavigate(); + + useEffect(() => { + if (!loading && user) { + navigate("/"); + } + }, [loading, user, navigate]); + + return ( + +
+

Connexion

+ +
+
+ ); +} + +export default LoginPage; \ No newline at end of file diff --git a/src/pages/Login/components/LoginForm/LoginForm.tsx b/src/pages/Login/components/LoginForm/LoginForm.tsx index 49d576b..a899b16 100644 --- a/src/pages/Login/components/LoginForm/LoginForm.tsx +++ b/src/pages/Login/components/LoginForm/LoginForm.tsx @@ -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 { diff --git a/src/pages/Profile/ProfilePage.module.css b/src/pages/Profile/ProfilePage.module.css index 2bcecee..288c0d1 100644 --- a/src/pages/Profile/ProfilePage.module.css +++ b/src/pages/Profile/ProfilePage.module.css @@ -1,4 +1,3 @@ -/* Conteneur principal */ .container { width: 100%; padding: 12px; @@ -113,7 +112,6 @@ margin: 0; } -/* Conteneur des informations principales */ .topDescription { display: flex; flex-direction: column; @@ -122,14 +120,12 @@ margin-bottom: 20px; } -/* Bloc d'informations */ .infoBlock { width: 100%; padding: 12px; box-sizing: border-box; } -/* Conteneur pour les paramètres */ .settingImage { width: 100%; display: flex; @@ -137,7 +133,29 @@ margin-top: 16px; } -/* Adaptation pour tablette et PC */ +.profilePictureContainer { + position: relative; +} + +.pictureOverlay { + position: absolute; + bottom: 0; + left: 0; + right: 0; + background: rgba(0, 0, 0, 0.5); + color: white; + text-align: center; + padding: 2px; + border-radius: 0 0 90% 90%; + opacity: 0; + transition: opacity 0.2s; +} +.clickable { + cursor: pointer; +} +.profilePictureContainer:hover .pictureOverlay { + opacity: 1; +} @media (min-width: 768px) { .contentWrapper { flex-direction: row; @@ -177,7 +195,6 @@ } } -/* Adaptation pour grand écran */ @media (min-width: 1024px) { .container { max-width: 1200px; diff --git a/src/pages/Profile/ProfilePage.tsx b/src/pages/Profile/ProfilePage.tsx index 9ec3b79..8eaa107 100644 --- a/src/pages/Profile/ProfilePage.tsx +++ b/src/pages/Profile/ProfilePage.tsx @@ -7,28 +7,26 @@ import SettingsModal from "./components/SettingsModal/SettingsModal"; import {useParams} from "react-router"; import {useNavigate} from "react-router"; import {useRef} from "react"; -import getUserById from "../../utils/users/getUserById.js"; +import getUserById from "../../utils/users/getUserById"; import ManageMember from "./components/ManageMember/ManageMember.jsx"; - import uploadProfilePhoto from "../../utils/users/uploadProfilePhoto"; import deleteProfilePhoto from "../../utils/users/deleteProfilePhoto.js"; - interface TaskType { - id: number; - name: string; - description: string; - location: string; - start: string; - end: string; - max_participants: number; - events_id: number; - created_at: string; - updated_at: string; - pivot: { - user_id: number; - task_id: number; - }; + id: number; + name: string; + description: string; + location: string; + start: string; + end: string; + max_participants: number; + events_id: number; + created_at: string; + updated_at: string; + pivot: { + user_id: number; + task_id: number; + }; } @@ -51,162 +49,132 @@ interface AuthContextType { } function ProfilePage() { - const navigate = useNavigate(); - const {id} = useParams(); - const {user, update} = useContext(AuthContext) as AuthContextType; - const [profileUser, setProfileUser] = useState(null); - const [profilePicture, setProfilePicture] = useState(null); - const [error, setError] = useState(null); - const [success, setSuccess] = useState(null); - const fileInputRef = useRef(null); + const navigate = useNavigate(); + const { id } = useParams(); + const { user, update } = useContext(AuthContext) as AuthContextType; + const [profileUser, setProfileUser] = useState(null); + const [profilePicture, setProfilePicture] = useState(null); + const fileInputRef = useRef(null); - const isOwnProfile = !id || user?.id.toString() === id; + const isOwnProfile = !id || user?.id.toString() === id; - useEffect(() => { - (async () => { - if (!isOwnProfile && id) { - const res = await getUserById(id); - if (res.status === 404) { - navigate("/404"); - return; - } - if (res.status !== 200) { - console.error("Erreur lors du chargement du profil", res); - return; - } - setProfileUser(res.data); - } else { - update(); - setProfileUser(user); - if (user?.profile_photo_path) { - setProfilePicture(`${import.meta.env.VITE_API_URL}/storage/${user.profile_photo_path}`); - } - } - })(); - }, [user, id]); - - const handleEditPictureClick = () => { - if (fileInputRef.current) { - fileInputRef.current.click(); + useEffect(() => { + (async () => { + console.log(JSON.stringify(import.meta.env.VITE_API_URL)); + if (!isOwnProfile && id) { + const res = await getUserById(Number(id)); + if (res.status === 404) { + navigate("/404"); + return; } - }; - - // Remplacé : handleFileChange extrait vers utils/users/uploadProfilePhoto - const handleFileChange = async (e: React.ChangeEvent) => { - const file = e.target.files?.[0]; - if (!file) return; - - try { - const res = await uploadProfilePhoto(file); - if (res.ok) { - setProfilePicture(`${import.meta.env.VITE_API_URL}/storage/${res.data.profile_photo_path}`); - setSuccess("Photo mise à jour !"); - setError(null); - await update(); - } else { - setError(res.data?.message || res.error || "Erreur lors de l'upload."); - setSuccess(null); - } - } catch (err) { - setError("Erreur réseau."); - setSuccess(null); + if (res.status !== 200) { + console.log("Erreur lors du chargement du profil", res); + return; } - }; - - // Remplacé : handleDeletePicture extrait vers utils/users/deleteProfilePhoto - const handleDeletePicture = async () => { - try { - const res = await deleteProfilePhoto(); - if (res.status >= 200 && res.status < 300) { - setProfilePicture(null); - setSuccess("Photo supprimée !"); - setError(null); - await update(); - } else { - setError(res.data?.message || "Erreur lors de la suppression."); - setSuccess(null); - } - } catch (err) { - setError("Erreur réseau."); - setSuccess(null); + setProfileUser(res.data); + } else { + setProfileUser(user); + if (user?.profile_photo_path) { + setProfilePicture(`${import.meta.env.VITE_API_URL}/storage/${user.profile_photo_path}`); } - }; + } + })(); + }, [user, id]); - return ( -
-
-
-
- Photo de profil -
+ const handleEditPictureClick = () => { + if (fileInputRef.current) { + fileInputRef.current.click(); + } + }; - {isOwnProfile && ( -
- - {user?.profile_photo_path && ( - - )} -
- )} + const handleFileChange = async (e: React.ChangeEvent) => { + const file = e.target.files?.[0]; + if (!file) return; - - {error &&

{error}

} - {success &&

{success}

} + try { + const res = await uploadProfilePhoto(file); + if (res.ok) { + setProfilePicture(`${import.meta.env.VITE_API_URL}/storage/${res.data.profile_photo_path}`); + console.log("Photo mise à jour") + await update(); + } else { + console.log(res.data?.message || res.error || "Erreur lors de l'upload."); + } + } catch (err) { + console.log("Erreur réseau."); + } + }; + const handleDeletePicture = async () => { + + await deleteProfilePhoto(); + setProfilePicture(null); + }; -
-
-

- {profileUser?.name} {profileUser?.lastname} -

- {user?.isAdmin && profileUser && !isOwnProfile && ( - - )} -
- -
-
-

Role : {profileUser?.role}

-

Membre depuis : {profileUser && formatDate(profileUser.created_at)} -

-
- -
-

Mail : {profileUser?.email}

-

Téléphone : {profileUser?.phone ?? "Non renseigné"}

-
- - {isOwnProfile && ( -
- -
- )} -
- -

Tâches :

- {profileUser?.tasks.length ? ( - profileUser.tasks.map((task) =>) - ) : ( -

Aucune tâche.

- )} -
+ return ( +
+
+
+
+ Photo de profil + {isOwnProfile && ( +
+ Modifier
+ )} +
+ + + + +
+
+

+ {profileUser?.name} {profileUser?.lastname} +

+ {user?.isAdmin && profileUser && !isOwnProfile && ( + + )}
+ +
+
+

Role : {profileUser?.role}

+

Membre depuis : {profileUser && formatDate(profileUser.created_at)}

+
+ +
+

Mail : {profileUser?.email}

+

Téléphone : {profileUser?.phone ?? "Non renseigné"}

+
+ + {isOwnProfile && ( +
+ +
+ )} +
+ +

Tâches :

+ {profileUser?.tasks.length ? ( + profileUser.tasks.map((task) => ) + ) : ( +

Aucune tâche.

+ )} +
- ); +
+
+ ); } export default ProfilePage; \ No newline at end of file diff --git a/src/pages/Profile/components/SettingsModal/SettingsModal.tsx b/src/pages/Profile/components/SettingsModal/SettingsModal.tsx index 6bb2320..118f430 100644 --- a/src/pages/Profile/components/SettingsModal/SettingsModal.tsx +++ b/src/pages/Profile/components/SettingsModal/SettingsModal.tsx @@ -35,7 +35,7 @@ interface AuthContextType { } export default function SettingsModal() { - const {user, logout, update} = useContext(AuthContext) as AuthContextType; + const {user, logout, update} = useContext(AuthContext) as unknown as AuthContextType; const [open, setOpen] = useState(false); const [isDelete, setIsDelete] = useState(false); diff --git a/src/pages/Register/RegisterPage.jsx b/src/pages/Register/RegisterPage.tsx similarity index 86% rename from src/pages/Register/RegisterPage.jsx rename to src/pages/Register/RegisterPage.tsx index 949348b..74849a1 100644 --- a/src/pages/Register/RegisterPage.jsx +++ b/src/pages/Register/RegisterPage.tsx @@ -1,12 +1,13 @@ import styles from "./RegisterPage.module.css"; -import Background from "../../components/Background/Background.jsx"; +import Background from "../../components/Background/Background"; import Input from "../../components/ui/Input/Input"; import Button from "../../components/ui/Button/Button"; 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 { AuthContext } from "../../contexts/Auth/AuthContext"; import Modal from "../../components/ui/Modal/Modal"; +import {AuthContextType } from "../../../src/contexts/Auth/AuthContext"; function RegisterPage() { @@ -22,8 +23,7 @@ function RegisterPage() { const [open, setOpen] = useState(false); const [title, setTitle] = useState(""); const [message, setMessage] = useState(""); - - const { user, loading } = useContext(AuthContext) + const { user, loading } = useContext(AuthContext) as AuthContextType useEffect(() => { if (!loading && user) { @@ -31,15 +31,21 @@ function RegisterPage() { } }, [loading, user]); - const handleModal = (t, m) => { + const handleModal = (t: string, m: string) => { setTitle(t) setMessage(m) setOpen(true); } - async function handleSubmit(e) { - e.preventDefault(); - + const handleKeyDown = (e: React.KeyboardEvent) => { + if (e.key === 'Enter') { + handleSubmit(); + } + }; + + async function handleSubmit():Promise + { + 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 { @@ -54,7 +60,7 @@ function RegisterPage() { } } - const handlePhone = (e) => { + const handlePhone = (e:React.ChangeEvent) => { const value = e.target.value; if (value === "" || /^[0-9 +]+$/.test(value)) { setPhone(value); @@ -62,13 +68,13 @@ function RegisterPage() { }; - return + return

Créer un compte

-
+
JSX.Element) => ( + + + + ), + ], +}; + +export const Default = {}; diff --git a/src/stories/Header.stories.tsx b/src/stories/Header.stories.tsx new file mode 100644 index 0000000..0d4610e --- /dev/null +++ b/src/stories/Header.stories.tsx @@ -0,0 +1,30 @@ +import { JSX } from "react"; +import { MemoryRouter } from "react-router"; +import Header from "../components/Header/Header"; +import { EventProvider } from "../contexts/Events/EventProvider"; +import { PendingMembersProvider } from "../contexts/PendingMembers/PendingMembersProvider"; +import { AuthProvider } from "../contexts/Auth/AuthProvider"; + +export default { + title: "Layout/Header", + component: Header, + parameters: { + layout: "fullscreen", + }, + tags: ["autodocs"], + decorators: [ + (Story: () => JSX.Element) => ( + + + + + + + + + + ), + ], +}; + +export const Default = {}; diff --git a/src/stories/Loading.stories.jsx b/src/stories/Loading.stories.jsx deleted file mode 100644 index d856a7e..0000000 --- a/src/stories/Loading.stories.jsx +++ /dev/null @@ -1,13 +0,0 @@ -import Loading from "../components/ui/Loading/Loading"; - - -export default { - title: 'UI/Loading', - component: Loading, - parameters: { - layout: 'centered', - }, - tags: ['autodocs'], -}; - -export const Primary = {}; \ No newline at end of file diff --git a/src/stories/Loading.stories.tsx b/src/stories/Loading.stories.tsx new file mode 100644 index 0000000..c2bc6aa --- /dev/null +++ b/src/stories/Loading.stories.tsx @@ -0,0 +1,14 @@ +import Loading from "../components/ui/Loading/Loading" + + +export default { + title: "UI/Loading", + component: Loading, + parameters: { + layout: "centered", + }, + tags: ['autodocs'], + argTypes: {}, +} + +export const Default = {} \ No newline at end of file diff --git a/src/utils/auth/login.js b/src/utils/auth/login.js deleted file mode 100644 index 1d99d02..0000000 --- a/src/utils/auth/login.js +++ /dev/null @@ -1,13 +0,0 @@ -import fetchWrapper from "../fetchWrapper.js"; -import getXSRFToken from "../getXSRF.js"; - -export default async function login(email, password) { - const csrfToken = await getXSRFToken(); - - return fetchWrapper( - "/api/users/login", - { email, password }, - "POST", - { "X-XSRF-TOKEN": csrfToken } - ); -} diff --git a/src/utils/auth/login.ts b/src/utils/auth/login.ts new file mode 100644 index 0000000..3c7c6e2 --- /dev/null +++ b/src/utils/auth/login.ts @@ -0,0 +1,14 @@ +import fetchWrapper from "../fetchWrapper"; +import getXSRFToken from "../getXSRF"; + + + +export default async function login(email: string, password: string) { + const csrfToken: string = await getXSRFToken(); + return fetchWrapper( + "/api/users/login", + { email, password }, + "POST", + { "X-XSRF-TOKEN": csrfToken } + ); +} \ No newline at end of file diff --git a/src/utils/auth/logout.js b/src/utils/auth/logout.ts similarity index 100% rename from src/utils/auth/logout.js rename to src/utils/auth/logout.ts diff --git a/src/utils/date/formatDateLetter.ts b/src/utils/date/formatDateLetter.ts index f4c3f91..1da9160 100644 --- a/src/utils/date/formatDateLetter.ts +++ b/src/utils/date/formatDateLetter.ts @@ -1,35 +1,3 @@ - - -/*export function formatDateLetter(d) { - if (!d) return "Date inconnue"; - - const dateObj = new Date(d); - if (isNaN(dateObj.getTime())) return "Date invalide"; - - const monthNames = [ - "Janvier", "Février", "Mars", "Avril", "Mai", "Juin", - "Juillet", "Août", "Septembre", "Octobre", "Novembre", "Décembre" - ]; - - const day = dateObj.getDate().toString().padStart(2, "0"); - const month = monthNames[dateObj.getMonth()]; - const year = dateObj.getFullYear(); - const hours = dateObj.getHours().toString().padStart(2, "0"); - const minutes = dateObj.getMinutes().toString().padStart(2, "0"); - - return `${day} ${month} ${year} à ${hours}:${minutes}`; -} - - -export function formatDateLetterJS(d) { - const monthNames = [ - "Janvier", "Février", "Mars", "Avril", "Mai", "Juin", - "Juillet", "Août", "Septembre", "Octobre", "Novembre", "Décembre" - ]; - const [year, month, day] = d.split('-'); - return `${day} ${monthNames[parseInt(month) - 1]} ${year}`; -}*/ - export function formatDateLetter(d: string | Date | null | undefined): string { if (!d) return "Date inconnue"; diff --git a/src/utils/events/createEvent.js b/src/utils/events/createEvent.ts similarity index 52% rename from src/utils/events/createEvent.js rename to src/utils/events/createEvent.ts index 764d419..eac4b13 100644 --- a/src/utils/events/createEvent.js +++ b/src/utils/events/createEvent.ts @@ -1,7 +1,7 @@ -import fetchWrapper from "../fetchWrapper.js"; -import getXSRFToken from "../getXSRF.js"; +import fetchWrapper from "../fetchWrapper"; +import getXSRFToken from "../getXSRF"; -export default async function createEvent(name, description, start, end) { +export default async function createEvent(name:string, description:string, start:string, end:string) { const csrfToken = await getXSRFToken(); return fetchWrapper( diff --git a/src/utils/events/deleteEvent.js b/src/utils/events/deleteEvent.ts similarity index 57% rename from src/utils/events/deleteEvent.js rename to src/utils/events/deleteEvent.ts index 10c8a49..7a748a1 100644 --- a/src/utils/events/deleteEvent.js +++ b/src/utils/events/deleteEvent.ts @@ -1,7 +1,7 @@ -import fetchWrapper from "../fetchWrapper.js"; -import getXSRFToken from "../getXSRF.js"; +import fetchWrapper from "../fetchWrapper"; +import getXSRFToken from "../getXSRF"; -export default async function deleteEvent(eventId) { +export default async function deleteEvent(eventId:number) { const csrfToken = await getXSRFToken(); return fetchWrapper( diff --git a/src/utils/events/eventCounter.js b/src/utils/events/eventCounter.js deleted file mode 100644 index 20ee578..0000000 --- a/src/utils/events/eventCounter.js +++ /dev/null @@ -1,28 +0,0 @@ -import { useEffect, useState } from "react"; -import getAllEvents from "../../utils/events/getAllEvents"; - -function EventsCounter() { - const [eventsCount, setEventsCount] = useState(0); - const [loading, setLoading] = useState(true); - useEffect(() => { - const fetchEvents = async () => { - try { - const events = await getAllEvents(); - if (Array.isArray(events)) { - setEventsCount(events.length); - } else { - setEventsCount(0); - } - } catch (err) { - console.error(err); - setEventsCount(0); - } finally { - setLoading(false); - } - }; - fetchEvents(); - }, []); - if (loading) return

Chargement...

; - return

Nombre d’événements : {eventsCount}

; -} -export default EventsCounter; diff --git a/src/utils/events/getAllEvents.js b/src/utils/events/getAllEvents.ts similarity index 68% rename from src/utils/events/getAllEvents.js rename to src/utils/events/getAllEvents.ts index b35f979..79bfc67 100644 --- a/src/utils/events/getAllEvents.js +++ b/src/utils/events/getAllEvents.ts @@ -1,4 +1,4 @@ -import fetchWrapper from "../fetchWrapper.js"; +import fetchWrapper from "../fetchWrapper"; export default async function getAllEvents() { return fetchWrapper("/api/events/", null, "GET"); diff --git a/src/utils/events/getEventById.js b/src/utils/events/getEventById.js deleted file mode 100644 index 97d6272..0000000 --- a/src/utils/events/getEventById.js +++ /dev/null @@ -1,5 +0,0 @@ -import fetchWrapper from "../fetchWrapper.js"; - -export default async function GetEventById(id) { - return fetchWrapper(`/api/events/${id}`, null, "GET"); -} diff --git a/src/utils/events/getEventById.ts b/src/utils/events/getEventById.ts new file mode 100644 index 0000000..70cb6db --- /dev/null +++ b/src/utils/events/getEventById.ts @@ -0,0 +1,5 @@ +import fetchWrapper from "../fetchWrapper"; + +export default async function GetEventById(id:number) { + return fetchWrapper(`/api/events/${id}`, null, "GET"); +} diff --git a/src/utils/events/searchEvents.js b/src/utils/events/searchEvents.ts similarity index 80% rename from src/utils/events/searchEvents.js rename to src/utils/events/searchEvents.ts index aa8a327..351ae77 100644 --- a/src/utils/events/searchEvents.js +++ b/src/utils/events/searchEvents.ts @@ -1,4 +1,4 @@ -export default async function searchEvents(query) { +export default async function searchEvents(query: string): Promise { try { const encodedQuery = encodeURIComponent(query); const response = await fetch( @@ -13,7 +13,7 @@ export default async function searchEvents(query) { } ); const data = await response.json(); - return data.hits.map(hit => hit.document); + return data.hits.map((hit: any) => hit.document); } catch (err) { console.error("Erreur :", err); diff --git a/src/utils/fetchWrapper.ts b/src/utils/fetchWrapper.ts index a130373..4f04e5e 100644 --- a/src/utils/fetchWrapper.ts +++ b/src/utils/fetchWrapper.ts @@ -1,44 +1,3 @@ -/*export default async function fetchWrapper(path,data = null,method = "GET",headers = {}) { - try { - const res = await fetch( - `${import.meta.env.VITE_API_URL}${path}`, - { - method, - credentials: "include", - headers: { - "Accept": "application/json", - "Content-Type": "application/json", - ...headers, - }, - body: data ? JSON.stringify(data) : null, - } - ); - - let responseData = null; - - try { - responseData = await res.json(); - } catch (_) { - responseData = null; - } - - return { - status: res.status, - data: responseData, - }; - - } catch (err) { - console.error("❌ Erreur réseau :", err); - - return { - status: 0, - data: { - message: "Network error", - }, - }; - } -}*/ - interface FetchResponse { status: number; data: T | null; @@ -79,7 +38,7 @@ export default async function fetchWrapper( }; } catch (err) { - console.error("❌ Erreur réseau :", err); + console.error("Erreur réseau :", err); return { status: 0, diff --git a/src/utils/getRoles.js b/src/utils/getRoles.ts similarity index 68% rename from src/utils/getRoles.js rename to src/utils/getRoles.ts index 99cadb6..fd8d0d4 100644 --- a/src/utils/getRoles.js +++ b/src/utils/getRoles.ts @@ -1,4 +1,4 @@ -import fetchWrapper from "./fetchWrapper.js"; +import fetchWrapper from "./fetchWrapper"; export default async function getRoles() { return fetchWrapper("/api/roles", null, "GET"); diff --git a/src/utils/getUser.js b/src/utils/getUser.ts similarity index 67% rename from src/utils/getUser.js rename to src/utils/getUser.ts index 6d71295..811c2b5 100644 --- a/src/utils/getUser.js +++ b/src/utils/getUser.ts @@ -1,5 +1,5 @@ -import fetchWrapper from "./fetchWrapper.js"; +import fetchWrapper from "./fetchWrapper"; export default async function getUser() { return fetchWrapper("/api/users/me", null, "GET"); -} +} \ No newline at end of file diff --git a/src/utils/notifications/deleteNotificationUser.js b/src/utils/notifications/deleteNotificationUser.ts similarity index 92% rename from src/utils/notifications/deleteNotificationUser.js rename to src/utils/notifications/deleteNotificationUser.ts index b7d7a93..4322722 100644 --- a/src/utils/notifications/deleteNotificationUser.js +++ b/src/utils/notifications/deleteNotificationUser.ts @@ -1,6 +1,6 @@ -import getXSRFToken from "../getXSRF.js"; +import getXSRFToken from "../getXSRF"; -export default async function deleteNotificationUser(notificationId) { +export default async function deleteNotificationUser(notificationId:number) { const csrfToken = await getXSRFToken(); try { diff --git a/src/utils/notifications/getUserNotifications.js b/src/utils/notifications/getUserNotifications.ts similarity index 100% rename from src/utils/notifications/getUserNotifications.js rename to src/utils/notifications/getUserNotifications.ts diff --git a/src/utils/notifications/readNotifications.js b/src/utils/notifications/readNotifications.ts similarity index 94% rename from src/utils/notifications/readNotifications.js rename to src/utils/notifications/readNotifications.ts index 0f406ce..5b7f998 100644 --- a/src/utils/notifications/readNotifications.js +++ b/src/utils/notifications/readNotifications.ts @@ -1,4 +1,4 @@ -import getXSRFToken from "../getXSRF.js"; +import getXSRFToken from "../getXSRF"; export default async function readNotifications() { diff --git a/src/utils/register.js b/src/utils/register.ts similarity index 52% rename from src/utils/register.js rename to src/utils/register.ts index 489f07c..69a983c 100644 --- a/src/utils/register.js +++ b/src/utils/register.ts @@ -1,7 +1,7 @@ -import fetchWrapper from "./fetchWrapper.js"; -import getXSRFToken from "./getXSRF.js"; +import fetchWrapper from "./fetchWrapper"; +import getXSRFToken from "./getXSRF"; -export default async function register(email, password, name, lastname, phone) { +export default async function register(email:string, password:string, name:string, lastname:string, phone:string) { const csrfToken = await getXSRFToken(); return fetchWrapper( diff --git a/src/utils/scrollToTop.js b/src/utils/scrollToTop.ts similarity index 100% rename from src/utils/scrollToTop.js rename to src/utils/scrollToTop.ts diff --git a/src/utils/tasks/assign.ts b/src/utils/tasks/assign.ts new file mode 100644 index 0000000..a9d7e8b --- /dev/null +++ b/src/utils/tasks/assign.ts @@ -0,0 +1,13 @@ +import fetchWrapper from "../fetchWrapper"; +import getXSRFToken from "../getXSRF"; + +export default async function assign(taskId: number): Promise { + const csrfToken = await getXSRFToken(); + + return fetchWrapper( + "/api/events/task/assign", + {task_id: taskId}, + "POST", + {"X-XSRF-TOKEN": csrfToken} + ); +} diff --git a/src/utils/tasks/assign.js b/src/utils/tasks/assignOtherUser.ts similarity index 64% rename from src/utils/tasks/assign.js rename to src/utils/tasks/assignOtherUser.ts index cb85dd3..189c06b 100644 --- a/src/utils/tasks/assign.js +++ b/src/utils/tasks/assignOtherUser.ts @@ -1,11 +1,11 @@ import fetchWrapper from "../fetchWrapper.js"; import getXSRFToken from "../getXSRF.js"; -export default async function assign(taskId) { +export default async function assignOtherUser(taskId: number, userId: number): Promise { const csrfToken = await getXSRFToken(); return fetchWrapper( - "/api/events/task/assign", + `/api/events/task/assign/${userId}`, {task_id: taskId}, "POST", {"X-XSRF-TOKEN": csrfToken} diff --git a/src/utils/tasks/createTask.js b/src/utils/tasks/createTask.js deleted file mode 100644 index a023d70..0000000 --- a/src/utils/tasks/createTask.js +++ /dev/null @@ -1,29 +0,0 @@ -import fetchWrapper from "../fetchWrapper.js"; -import getXSRFToken from "../getXSRF.js"; - -export default async function createTask({ - eventId, - name, - description, - start, - end, - location, - maxParticipants, - }) { - const csrfToken = await getXSRFToken(); - - return fetchWrapper( - "/api/events/task", - { - event_id: eventId, - name, - description, - start, - end, - location, - max_participants: maxParticipants, - }, - "POST", - {"X-XSRF-TOKEN": csrfToken} - ); -} diff --git a/src/utils/tasks/createTask.ts b/src/utils/tasks/createTask.ts new file mode 100644 index 0000000..495b67e --- /dev/null +++ b/src/utils/tasks/createTask.ts @@ -0,0 +1,39 @@ +import fetchWrapper from "../fetchWrapper"; +import getXSRFToken from "../getXSRF"; + +interface CreateTaskParams { + eventId: number; + name: string; + description: string; + start: string; + end: string; + location: string; + maxParticipants: number; +} + +export default async function createTask({ + eventId, + name, + description, + start, + end, + location, + maxParticipants, +}: CreateTaskParams): Promise { + const csrfToken = await getXSRFToken(); + + return fetchWrapper( + "/api/events/task", + { + event_id: eventId, + name, + description, + start, + end, + location, + max_participants: maxParticipants, + }, + "POST", + {"X-XSRF-TOKEN": csrfToken} + ); +} diff --git a/src/utils/tasks/deleteTask.js b/src/utils/tasks/deleteTask.js deleted file mode 100644 index 2641307..0000000 --- a/src/utils/tasks/deleteTask.js +++ /dev/null @@ -1,13 +0,0 @@ -import fetchWrapper from "../fetchWrapper.js"; -import getXSRFToken from "../getXSRF.js"; - -export default async function deleteTask(taskId) { - const csrfToken = await getXSRFToken(); - - return fetchWrapper( - `/api/events/tasks/${taskId}`, - { task_id: taskId }, - "DELETE", - { "X-XSRF-TOKEN": csrfToken } - ); -} diff --git a/src/utils/tasks/deleteTask.ts b/src/utils/tasks/deleteTask.ts new file mode 100644 index 0000000..bc0e163 --- /dev/null +++ b/src/utils/tasks/deleteTask.ts @@ -0,0 +1,13 @@ +import fetchWrapper from "../fetchWrapper"; +import getXSRFToken from "../getXSRF"; + +export default async function deleteTask(taskId: number): Promise { + const csrfToken = await getXSRFToken(); + + return fetchWrapper( + `/api/events/tasks/${taskId}`, + {task_id: taskId}, + "DELETE", + {"X-XSRF-TOKEN": csrfToken} + ); +} diff --git a/src/utils/tasks/isAssigned.js b/src/utils/tasks/isAssigned.js deleted file mode 100644 index 99ce6ff..0000000 --- a/src/utils/tasks/isAssigned.js +++ /dev/null @@ -1,9 +0,0 @@ -import fetchWrapper from "../fetchWrapper.js"; - -export default async function isAssigned(taskId) { - return fetchWrapper( - `/api/events/tasks/${taskId}/assigned`, - null, - "GET" - ); -} diff --git a/src/utils/tasks/isAssigned.ts b/src/utils/tasks/isAssigned.ts new file mode 100644 index 0000000..aafd14e --- /dev/null +++ b/src/utils/tasks/isAssigned.ts @@ -0,0 +1,9 @@ +import fetchWrapper from "../fetchWrapper"; + +export default async function isAssigned(taskId: number): Promise { + return fetchWrapper( + `/api/events/tasks/${taskId}/assigned`, + null, + "GET" + ); +} diff --git a/src/utils/tasks/unAssign.ts b/src/utils/tasks/unAssign.ts new file mode 100644 index 0000000..4871a2e --- /dev/null +++ b/src/utils/tasks/unAssign.ts @@ -0,0 +1,13 @@ +import fetchWrapper from "../fetchWrapper"; +import getXSRFToken from "../getXSRF"; + +export default async function unAssign(taskId: number): Promise { + const csrfToken = await getXSRFToken(); + + return fetchWrapper( + "/api/events/task/unassign", + {task_id: taskId}, + "POST", + {"X-XSRF-TOKEN": csrfToken} + ); +} diff --git a/src/utils/tasks/unAssign.js b/src/utils/tasks/unAssignOtherUser.ts similarity index 63% rename from src/utils/tasks/unAssign.js rename to src/utils/tasks/unAssignOtherUser.ts index 7110328..0781dca 100644 --- a/src/utils/tasks/unAssign.js +++ b/src/utils/tasks/unAssignOtherUser.ts @@ -1,13 +1,13 @@ import fetchWrapper from "../fetchWrapper.js"; import getXSRFToken from "../getXSRF.js"; -export default async function unAssign(taskId) { +export default async function unAssignOtherUser(taskId: number, userId: number): Promise { const csrfToken = await getXSRFToken(); return fetchWrapper( - "/api/events/task/unassign", + `/api/events/task/unassign/${userId}`, {task_id: taskId}, "POST", {"X-XSRF-TOKEN": csrfToken} ); -} +} \ No newline at end of file diff --git a/src/utils/users/adminCreateUser.ts b/src/utils/users/adminCreateUser.ts index 01860d3..86f02bd 100644 --- a/src/utils/users/adminCreateUser.ts +++ b/src/utils/users/adminCreateUser.ts @@ -1,8 +1,8 @@ -import fetchWrapper from "../fetchWrapper.js"; -import getXSRFToken from "../getXSRF.js"; +import fetchWrapper from "../fetchWrapper"; +import getXSRFToken from "../getXSRF"; import Response from "../../interfaces/response.interface"; -export default async function adminCreateUser(email: string, name: string, lastname: string, phone: string): Promise { +export default async function adminCreateUser(email: string, name: string, lastname: string, phone: string) { const csrfToken = await getXSRFToken(); return fetchWrapper( diff --git a/src/utils/users/deactivateUser.js b/src/utils/users/deactivateUser.ts similarity index 58% rename from src/utils/users/deactivateUser.js rename to src/utils/users/deactivateUser.ts index fdf4c44..bbb4161 100644 --- a/src/utils/users/deactivateUser.js +++ b/src/utils/users/deactivateUser.ts @@ -1,7 +1,7 @@ -import fetchWrapper from "../fetchWrapper.js"; -import getXSRFToken from "../getXSRF.js"; +import fetchWrapper from "../fetchWrapper"; +import getXSRFToken from "../getXSRF"; -export default async function deactivateUser(userId) { +export default async function deactivateUser(userId:number) { const csrfToken = await getXSRFToken(); return fetchWrapper( diff --git a/src/utils/users/deleteOtherUser.js b/src/utils/users/deleteOtherUser.ts similarity index 56% rename from src/utils/users/deleteOtherUser.js rename to src/utils/users/deleteOtherUser.ts index ece6425..daf5d4d 100644 --- a/src/utils/users/deleteOtherUser.js +++ b/src/utils/users/deleteOtherUser.ts @@ -1,7 +1,7 @@ -import fetchWrapper from "../fetchWrapper.js"; -import getXSRFToken from "../getXSRF.js"; +import fetchWrapper from "../fetchWrapper"; +import getXSRFToken from "../getXSRF"; -export default async function deleteOtherUser(userId) { +export default async function deleteOtherUser(userId:number) { const csrfToken = await getXSRFToken(); return fetchWrapper( diff --git a/src/utils/users/deleteProfilePhoto.ts b/src/utils/users/deleteProfilePhoto.ts index a5e830f..ca55ef4 100644 --- a/src/utils/users/deleteProfilePhoto.ts +++ b/src/utils/users/deleteProfilePhoto.ts @@ -1,4 +1,4 @@ -import getXSRFToken from "../getXSRF.js"; +import getXSRFToken from "../getXSRF"; export default async function deleteProfilePhoto(): Promise<{ status: number; ok: boolean; data?: any; error?: string }> { try { diff --git a/src/utils/users/getAllUsers.js b/src/utils/users/getAllUsers.ts similarity index 64% rename from src/utils/users/getAllUsers.js rename to src/utils/users/getAllUsers.ts index 584c39f..1b75dc9 100644 --- a/src/utils/users/getAllUsers.js +++ b/src/utils/users/getAllUsers.ts @@ -1,4 +1,4 @@ -import fetchWrapper from "../fetchWrapper.js"; +import fetchWrapper from "../fetchWrapper"; export default async function getAllUser() { return fetchWrapper("/api/users"); diff --git a/src/utils/users/getUserById.js b/src/utils/users/getUserById.js deleted file mode 100644 index e9a2c75..0000000 --- a/src/utils/users/getUserById.js +++ /dev/null @@ -1,5 +0,0 @@ -import fetchWrapper from "../fetchWrapper.js"; - -export default async function getUserById(id) { - return fetchWrapper(`/api/users/${id}`); -} diff --git a/src/utils/users/getUserById.ts b/src/utils/users/getUserById.ts new file mode 100644 index 0000000..d08943a --- /dev/null +++ b/src/utils/users/getUserById.ts @@ -0,0 +1,5 @@ +import fetchWrapper from "../fetchWrapper"; + +export default async function getUserById(id:number) { + return fetchWrapper(`/api/users/${id}`); +} diff --git a/src/utils/users/getUserToValidate.js b/src/utils/users/getUserToValidate.ts similarity index 68% rename from src/utils/users/getUserToValidate.js rename to src/utils/users/getUserToValidate.ts index 5176f1f..b0fde0e 100644 --- a/src/utils/users/getUserToValidate.js +++ b/src/utils/users/getUserToValidate.ts @@ -1,4 +1,4 @@ -import fetchWrapper from "../fetchWrapper.js"; +import fetchWrapper from "../fetchWrapper"; export default async function getUserToValidate() { return fetchWrapper("/api/users/invalid"); diff --git a/src/utils/users/modifyRole.js b/src/utils/users/modifyRole.ts similarity index 55% rename from src/utils/users/modifyRole.js rename to src/utils/users/modifyRole.ts index 6526cea..592f739 100644 --- a/src/utils/users/modifyRole.js +++ b/src/utils/users/modifyRole.ts @@ -1,7 +1,7 @@ -import fetchWrapper from "../fetchWrapper.js"; -import getXSRFToken from "../getXSRF.js"; +import fetchWrapper from "../fetchWrapper"; +import getXSRFToken from "../getXSRF"; -export default async function modifyRole(role, userId) { +export default async function modifyRole(role:number, userId:number) { const csrfToken = await getXSRFToken(); return fetchWrapper( diff --git a/src/utils/users/searchUsers.js b/src/utils/users/searchUsers.ts similarity index 80% rename from src/utils/users/searchUsers.js rename to src/utils/users/searchUsers.ts index ae0bd3a..6c06005 100644 --- a/src/utils/users/searchUsers.js +++ b/src/utils/users/searchUsers.ts @@ -1,4 +1,4 @@ -export default async function searchUsers(query) { +export default async function searchUsers(query: string): Promise { try { const encodedQuery = encodeURIComponent(query); const response = await fetch( @@ -13,7 +13,7 @@ export default async function searchUsers(query) { } ); const data = await response.json(); - return data.hits.map(hit => hit.document); + return data.hits.map((hit: any) => hit.document); } catch (err) { console.error("Erreur :", err); diff --git a/src/utils/users/updateUser.ts b/src/utils/users/updateUser.ts index 6714250..48f5b51 100644 --- a/src/utils/users/updateUser.ts +++ b/src/utils/users/updateUser.ts @@ -1,33 +1,12 @@ -/*import fetchWrapper from "../fetchWrapper.js"; -import getXSRFToken from "../getXSRF.js"; - -export default async function updateUser(name, lastname, phone) { - const csrfToken = await getXSRFToken(); - - return fetchWrapper( - "/api/users/update", - { name, lastname, phone }, - "POST", - { "X-XSRF-TOKEN": csrfToken } - ); -}*/ - import fetchWrapper from "../fetchWrapper"; import getXSRFToken from "../getXSRF"; -interface UserUpdateData { - name: string; - lastname: string; - phone: string | null; +export default async function updateUser(name: string, lastname: string, phone: string | null) { + const csrfToken = await getXSRFToken(); + return fetchWrapper( + "/api/users/update", + { name, lastname, phone }, + "POST", + { "X-XSRF-TOKEN": csrfToken } + ); } - -interface RequestHeaders { - "X-XSRF-TOKEN": string; -} -export default async function updateUser(name: string,lastname: string,phone: string | null): Promise { - const csrfToken: string = await getXSRFToken(); - const userData: UserUpdateData = {name,lastname,phone,}; - const headers: RequestHeaders = {"X-XSRF-TOKEN": csrfToken,}; - return fetchWrapper("/api/users/update",userData,"POST",headers); -} - diff --git a/src/utils/users/uploadProfilePhoto.ts b/src/utils/users/uploadProfilePhoto.ts index ca252a2..f3341ee 100644 --- a/src/utils/users/uploadProfilePhoto.ts +++ b/src/utils/users/uploadProfilePhoto.ts @@ -1,4 +1,4 @@ -import getXSRFToken from "../getXSRF.js"; +import getXSRFToken from "../getXSRF"; export default async function uploadProfilePhoto(file: File): Promise<{ status: number; ok: boolean; data?: any; error?: string }> { const formData = new FormData(); diff --git a/src/utils/users/validateUser.js b/src/utils/users/validateUser.ts similarity index 56% rename from src/utils/users/validateUser.js rename to src/utils/users/validateUser.ts index f73b3ef..de10071 100644 --- a/src/utils/users/validateUser.js +++ b/src/utils/users/validateUser.ts @@ -1,7 +1,7 @@ -import fetchWrapper from "../fetchWrapper.js"; -import getXSRFToken from "../getXSRF.js"; +import fetchWrapper from "../fetchWrapper"; +import getXSRFToken from "../getXSRF"; -export default async function validateUser(userId) { +export default async function validateUser(userId:number) { const csrfToken = await getXSRFToken(); return fetchWrapper(