From d03022c21b87f3cc9330fb0440a34a1a21b41016 Mon Sep 17 00:00:00 2001 From: Arthur Belleville Date: Wed, 10 Sep 2025 22:44:31 +0200 Subject: [PATCH] Enhance AvailabilityCard and AvailabilitiesPage components by adding a copy functionality for time ranges across days. Introduce a modal for selecting target days and confirm copying of availability settings, improving user experience and flexibility. --- ui/src/components/AvailabilityCard.tsx | 19 ++- ui/src/pages/availabilities.tsx | 162 +++++++++++++++++++++++++ 2 files changed, 180 insertions(+), 1 deletion(-) diff --git a/ui/src/components/AvailabilityCard.tsx b/ui/src/components/AvailabilityCard.tsx index f829b62..52247a5 100644 --- a/ui/src/components/AvailabilityCard.tsx +++ b/ui/src/components/AvailabilityCard.tsx @@ -2,7 +2,7 @@ import { useState } from "react"; import { Switch } from "@ui/ui-library/switch"; import { Text } from "@ui/ui-library/text"; import { Button } from "@ui/ui-library/button"; -import { MinusIcon, PlusIcon } from "@ui/ui-library/icons"; +import { MinusIcon, PlusIcon, CopyIcon } from "@ui/ui-library/icons"; import { Select, SelectButton, @@ -22,6 +22,11 @@ interface AvailabilityCardProps { onEnabledChange: (enabled: boolean) => void; timeRanges: TimeRange[]; onTimeRangesChange: (ranges: TimeRange[]) => void; + onCopyToOtherDays?: ( + sourceDay: number, + enabled: boolean, + timeRanges: TimeRange[] + ) => void; } const MINUTES_IN_DAY = 24 * 60; @@ -146,6 +151,7 @@ export function AvailabilityCard({ onEnabledChange, timeRanges, onTimeRangesChange, + onCopyToOtherDays, }: AvailabilityCardProps) { const dayDisplay = DAYS_OF_WEEK_DISPLAY[day]; @@ -239,6 +245,17 @@ export function AvailabilityCard({
{dayDisplay} + {onCopyToOtherDays && enabled && timeRanges.length > 0 && ( + + )}
void; + title: string; + children: React.ReactNode; +} + +function CustomModal({ isOpen, onClose, title, children }: CustomModalProps) { + if (!isOpen) return null; + + return ( +
+ {/* Backdrop */} +
+ + {/* Modal */} +
+ {/* Header */} +
+

+ {title} +

+ +
+ + {/* Content */} +
{children}
+
+
+ ); +} const DAYS_OF_WEEK = [0, 1, 2, 3, 4, 5, 6]; +const DAYS_OF_WEEK_DISPLAY = [ + "Lundi", + "Mardi", + "Mercredi", + "Jeudi", + "Vendredi", + "Samedi", + "Dimanche", +]; + +interface TimeRange { + start: string; + end: string; +} export function AvailabilitiesPage() { const { @@ -19,6 +88,47 @@ export function AvailabilitiesPage() { setDraftAvailabilities, } = useAvailabilities(); + const [copyModalOpen, setCopyModalOpen] = useState(false); + const [sourceDayData, setSourceDayData] = useState<{ + day: number; + enabled: boolean; + timeRanges: TimeRange[]; + } | null>(null); + const [selectedDays, setSelectedDays] = useState([]); + + const handleCopyToOtherDays = ( + sourceDay: number, + enabled: boolean, + timeRanges: TimeRange[] + ) => { + setSourceDayData({ day: sourceDay, enabled, timeRanges }); + setSelectedDays([]); + setCopyModalOpen(true); + }; + + const applyCopyToSelectedDays = () => { + if (!sourceDayData) return; + + const updatedAvailabilities = { ...draftAvailabilities }; + selectedDays.forEach((day) => { + updatedAvailabilities[day] = { + enabled: sourceDayData.enabled, + timeRanges: [...sourceDayData.timeRanges], + }; + }); + + setDraftAvailabilities(updatedAvailabilities); + setCopyModalOpen(false); + setSourceDayData(null); + setSelectedDays([]); + + toast.add({ + title: "Succès", + description: `Horaires copiés vers ${selectedDays.length} jour(s)`, + type: "success", + }); + }; + return (
@@ -91,6 +201,7 @@ export function AvailabilitiesPage() { }, }); }} + onCopyToOtherDays={handleCopyToOtherDays} />
@@ -164,6 +275,57 @@ export function AvailabilitiesPage() { {isUpdating ? "Enregistrement..." : "Enregistrer les disponibilités"}
+ + {/* Copy Modal */} + setCopyModalOpen(false)} + title={`Copier les horaires de ${ + sourceDayData ? DAYS_OF_WEEK_DISPLAY[sourceDayData.day] : "" + }`} + > +
+ + Sélectionnez les jours vers lesquels vous souhaitez copier ces + horaires : + + +
+ {DAYS_OF_WEEK.filter((day) => day !== sourceDayData?.day).map( + (day) => ( + { + if (isSelected) { + setSelectedDays([...selectedDays, day]); + } else { + setSelectedDays(selectedDays.filter((d) => d !== day)); + } + }} + > + + {DAYS_OF_WEEK_DISPLAY[day]} + + + ) + )} +
+ +
+ + +
+
+
); }