This commit is contained in:
Arthur Belleville 2025-10-05 23:06:37 +02:00
parent f8f931aab1
commit 222391f315
No known key found for this signature in database
3 changed files with 104 additions and 60 deletions

View file

@ -1,7 +1,7 @@
import { Event, EventInsert } from "@ui/types/events.types";
import { useState } from "react";
import { useState, useEffect } from "react";
import { useTablosList } from "@ui/hooks/tablos";
import { useCreateEvents } from "@ui/hooks/events";
import { useCreateEvents, useEvent, useUpdateEvent } from "@ui/hooks/events";
import { useUser } from "@ui/providers/UserStoreProvider";
import {
Select,
@ -14,16 +14,21 @@ import { useTimePicker } from "@ui/ui-library/time-picker";
import { DatePicker, DatePickerButton } from "@ui/ui-library/date-picker";
import { Group } from "react-aria-components";
import { getLocalTimeZone, parseDate, today } from "@internationalized/date";
import { useNavigate, useSearchParams } from "react-router-dom";
import { useNavigate, useParams, useSearchParams } from "react-router-dom";
export const EventModal = ({ mode }: { mode: "create" | "edit" }) => {
const { event_id } = useParams();
const { data: event } = useEvent(event_id as string);
export const CreateEventModal = () => {
const user = useUser();
const [searchParams] = useSearchParams();
const tablo_id = searchParams.get("tablo_id");
const date = new Date(searchParams.get("date") || "");
const dateFromParams = searchParams.get("date");
const date = dateFromParams ? new Date(dateFromParams) : new Date();
const { data: tablos, isLoading: tablosLoading } = useTablosList();
const createEvents = useCreateEvents();
const updateEvent = useUpdateEvent();
const timeOptions = useTimePicker({ intervalInMinute: 15 });
const navigate = useNavigate();
@ -62,7 +67,7 @@ export const CreateEventModal = () => {
return nearestOption?.id || "";
};
const [createdEvent, setCreatedEvent] = useState<EventInsert>({
const [formEvent, setFormEvent] = useState<EventInsert>({
start_date: date ? getLocalDateString(date) : "",
start_time: date ? getNearestTimeOption(date, "start") : "",
end_time: date ? getNearestTimeOption(date, "end") : "",
@ -71,13 +76,30 @@ export const CreateEventModal = () => {
created_by: user.id,
});
// Initialize form data when in edit mode
useEffect(() => {
if (mode === "edit" && event) {
setFormEvent({
start_date: event.start_date,
start_time: event.start_time || "",
end_time: event.end_time || "",
tablo_id: event.tablo_id,
title: event.title,
description: event.description || "",
created_by: event.created_by,
});
}
}, [mode, event]);
return (
<div className="fixed inset-0 bg-black/80 flex items-center justify-center z-50 p-4">
<div className="bg-white dark:bg-gray-900 rounded-xl shadow-2xl w-full max-w-lg mx-4 overflow-hidden">
{/* Header with colored accent */}
<div className="bg-gradient-to-r from-blue-500 to-blue-600 p-6 text-white">
<div className="flex items-center justify-between">
<h2 className="text-xl font-medium">Nouvel événement</h2>
<h2 className="text-xl font-medium">
{mode === "edit" ? "Modifier l'événement" : "Nouvel événement"}
</h2>
<button
onClick={onClose}
className="text-white hover:text-gray-200 transition-colors"
@ -99,12 +121,19 @@ export const CreateEventModal = () => {
</button>
</div>
<div className="mt-2 text-blue-100 text-sm">
{date.toLocaleDateString("fr-FR", {
weekday: "long",
year: "numeric",
month: "long",
day: "numeric",
})}
{mode === "edit" && event
? new Date(event.start_date).toLocaleDateString("fr-FR", {
weekday: "long",
year: "numeric",
month: "long",
day: "numeric",
})
: date.toLocaleDateString("fr-FR", {
weekday: "long",
year: "numeric",
month: "long",
day: "numeric",
})}
</div>
</div>
@ -114,10 +143,10 @@ export const CreateEventModal = () => {
<div className="space-y-2">
<input
type="text"
value={createdEvent?.title}
value={formEvent?.title}
onChange={(e) =>
setCreatedEvent({
...createdEvent,
setFormEvent({
...formEvent,
title: e.target.value,
} as Event)
}
@ -136,10 +165,10 @@ export const CreateEventModal = () => {
</label>
<Select
placeholder="Sélectionner un tablo"
selectedKey={createdEvent?.tablo_id}
selectedKey={formEvent?.tablo_id}
onSelectionChange={(key) =>
setCreatedEvent({
...createdEvent,
setFormEvent({
...formEvent,
tablo_id: key as string,
} as Event)
}
@ -168,8 +197,8 @@ export const CreateEventModal = () => {
<DatePicker
aria-label="Date de l'événement"
value={
createdEvent?.start_date
? parseDate(createdEvent?.start_date)
formEvent?.start_date
? parseDate(formEvent?.start_date)
: null
}
minValue={today(getLocalTimeZone())}
@ -177,8 +206,8 @@ export const CreateEventModal = () => {
if (value === null) {
return;
}
setCreatedEvent({
...createdEvent,
setFormEvent({
...formEvent,
start_date: value.toString(),
});
}}
@ -194,14 +223,14 @@ export const CreateEventModal = () => {
<Select
aria-label="Heure de début"
className="min-w-[110px]"
selectedKey={createdEvent?.start_time}
selectedKey={formEvent?.start_time}
onSelectionChange={(value) => {
const option = timeOptions.find(
(option) => option.id === value
);
if (option && value) {
setCreatedEvent({
...createdEvent,
setFormEvent({
...formEvent,
start_time: value.toString(),
});
}
@ -225,14 +254,14 @@ export const CreateEventModal = () => {
<Select
aria-label="Heure de fin"
className="min-w-[110px]"
selectedKey={createdEvent?.end_time}
selectedKey={formEvent?.end_time}
onSelectionChange={(value) => {
const option = timeOptions.find(
(option) => option.id === value
);
if (option && value) {
setCreatedEvent({
...createdEvent,
setFormEvent({
...formEvent,
end_time: value.toString(),
});
}
@ -256,10 +285,10 @@ export const CreateEventModal = () => {
Description
</label>
<textarea
value={createdEvent?.description ?? ""}
value={formEvent?.description ?? ""}
onChange={(e) =>
setCreatedEvent({
...createdEvent,
setFormEvent({
...formEvent,
description: e.target.value,
} as Event)
}
@ -277,7 +306,11 @@ export const CreateEventModal = () => {
type="button"
className="px-4 py-2 text-sm font-medium text-gray-700 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-700 rounded-lg transition-colors"
onClick={onClose}
aria-label="Annuler la création d'événement"
aria-label={
mode === "edit"
? "Annuler la modification"
: "Annuler la création d'événement"
}
>
Annuler
</button>
@ -285,16 +318,27 @@ export const CreateEventModal = () => {
type="button"
className="px-6 py-2 text-sm font-medium text-white bg-blue-600 hover:bg-blue-700 rounded-lg disabled:opacity-50 disabled:cursor-not-allowed transition-all shadow-sm hover:shadow-md"
onClick={() => {
const eventName = createdEvent?.title.trim() || "(Sans titre)";
createEvents(
{ ...createdEvent, title: eventName },
{ onSuccess: () => onClose() }
);
const eventName = formEvent?.title.trim() || "(Sans titre)";
if (mode === "edit" && event) {
updateEvent.mutate(
{ id: event.id, ...formEvent, title: eventName },
{ onSuccess: () => onClose() }
);
} else {
createEvents(
{ ...formEvent, title: eventName },
{ onSuccess: () => onClose() }
);
}
}}
disabled={!createdEvent?.tablo_id}
aria-label="Enregistrer l'événement"
disabled={!formEvent?.tablo_id}
aria-label={
mode === "edit"
? "Modifier l'événement"
: "Enregistrer l'événement"
}
>
Enregistrer
{mode === "edit" ? "Modifier" : "Enregistrer"}
</button>
</div>
</div>

View file

@ -14,7 +14,7 @@ import { SignUpPage } from "@ui/pages/signup";
import { ResetPasswordPage } from "@ui/pages/reset-password";
import { AuthenticationGateway } from "@ui/components/AuthenticationGateway";
import ChatProvider from "@ui/providers/ChatProvider";
import { CreateEventModal } from "@ui/components/CreateEventModal";
import { EventModal } from "@ui/components/EventModal";
import { ChantiersPage } from "@ui/pages/chantiers";
import { ChatPage } from "@ui/pages/chat";
import { FeedbackPage } from "@ui/pages/feedback";
@ -55,8 +55,11 @@ export const routes: RouteObject[] = [
element: <PlanningPage />,
children: [
{ index: true },
{ path: ":tablo_id" },
{ path: "create", element: <CreateEventModal /> },
{
path: ":tablo_id/events/:event_id/edit",
element: <EventModal mode="edit" />,
},
{ path: "create", element: <EventModal mode="create" /> },
],
},
{

View file

@ -400,13 +400,9 @@ export const PlanningPage = () => {
onClick={(e) => {
e.stopPropagation();
if (canEditEvent(event)) {
navigate({
pathname: "/planning/create",
search:
selectedTabloId === "all"
? `?date=${day.toISOString()}`
: `?date=${day.toISOString()}&tablo_id=${selectedTabloId}`,
});
navigate(
`/planning/${event.tablo_id}/events/${event.event_id}/edit`
);
}
}}
>
@ -546,7 +542,11 @@ export const PlanningPage = () => {
}${!canEditEvent(event) ? " (Lecture seule)" : ""}`}
onClick={(e) => {
e.stopPropagation();
// Read-only events are not clickable
if (canEditEvent(event)) {
navigate(
`/planning/${event.tablo_id}/events/${event.event_id}/edit`
);
}
}}
>
<div className="text-[10px] font-medium leading-tight">
@ -664,7 +664,11 @@ export const PlanningPage = () => {
}${!canEditEvent(event) ? " (Lecture seule)" : ""}`}
onClick={(e) => {
e.stopPropagation();
// Read-only events are not clickable
if (canEditEvent(event)) {
navigate(
`/planning/${event.tablo_id}/events/${event.event_id}/edit`
);
}
}}
>
<div className="text-[10px] font-medium truncate leading-tight">
@ -978,13 +982,6 @@ export const PlanningPage = () => {
</div>
</div>
{/* {isEventModalOpen && (
<CreateEventModal
date={selectedDate}
close={() => setIsEventModalOpen(false)}
/>
)} */}
<Outlet />
{isImportModalOpen && (