Update planning

This commit is contained in:
Arthur Belleville 2025-06-29 17:30:41 +02:00
parent 44d837496f
commit 976b51ca1b
No known key found for this signature in database

View file

@ -5,102 +5,68 @@ interface Event {
title: string;
date: string;
time: string;
endTime?: string;
type: "meeting" | "task" | "reminder";
color: string;
description?: string;
}
type ViewType = "month" | "week" | "day";
export const PlanningPage = () => {
const [currentDate, setCurrentDate] = useState(new Date());
const [selectedDate, setSelectedDate] = useState(new Date());
const [currentView, setCurrentView] = useState<ViewType>("month");
const [events, setEvents] = useState<Event[]>([
{
id: 1,
title: "Réunion équipe",
date: "2024-01-15",
time: "10:00",
endTime: "11:00",
type: "meeting",
color: "bg-blue-500",
description: "Discussion sur les objectifs du trimestre",
},
{
id: 2,
title: "Présentation client",
date: "2024-01-16",
time: "14:30",
endTime: "16:00",
type: "meeting",
color: "bg-red-500",
description: "Présentation du nouveau produit",
},
{
id: 3,
title: "Révision code",
date: "2024-01-17",
time: "09:00",
endTime: "10:30",
type: "task",
color: "bg-green-500",
description: "Code review des fonctionnalités développées",
},
{
id: 4,
title: "Appel client",
date: "2024-01-18",
time: "15:00",
endTime: "15:30",
type: "meeting",
color: "bg-purple-500",
},
]);
const [isEventModalOpen, setIsEventModalOpen] = useState(false);
const [newEventTitle, setNewEventTitle] = useState("");
const [newEventTime, setNewEventTime] = useState("");
const [newEventEndTime, setNewEventEndTime] = useState("");
const [newEventType, setNewEventType] = useState<
"meeting" | "task" | "reminder"
>("meeting");
// Get calendar days for current month
const getDaysInMonth = (date: Date) => {
const year = date.getFullYear();
const month = date.getMonth();
const firstDay = new Date(year, month, 1);
const lastDay = new Date(year, month + 1, 0);
const daysInMonth = lastDay.getDate();
const startingDayOfWeek = firstDay.getDay();
const days = [];
// Add empty cells for days before the first day of the month
for (let i = 0; i < startingDayOfWeek; i++) {
days.push(null);
}
// Add all days of the month
for (let day = 1; day <= daysInMonth; day++) {
days.push(new Date(year, month, day));
}
return days;
};
const formatDate = (date: Date) => {
return date.toISOString().split("T")[0];
};
const getEventsForDate = (date: Date) => {
const dateString = formatDate(date);
return events.filter((event) => event.date === dateString);
};
const addEvent = () => {
if (newEventTitle.trim()) {
const newEvent: Event = {
id: Math.max(...events.map((e) => e.id), 0) + 1,
title: newEventTitle.trim(),
date: formatDate(selectedDate),
time: newEventTime || "09:00",
type: newEventType,
color:
newEventType === "meeting"
? "bg-blue-500"
: newEventType === "task"
? "bg-green-500"
: "bg-yellow-500",
};
setEvents([...events, newEvent]);
setIsEventModalOpen(false);
setNewEventTitle("");
setNewEventTime("");
setNewEventType("meeting");
}
};
const [newEventDescription, setNewEventDescription] = useState("");
const monthNames = [
"Janvier",
@ -117,171 +83,493 @@ export const PlanningPage = () => {
"Décembre",
];
const dayNames = ["Dim", "Lun", "Mar", "Mer", "Jeu", "Ven", "Sam"];
const dayNames = [
"Dimanche",
"Lundi",
"Mardi",
"Mercredi",
"Jeudi",
"Vendredi",
"Samedi",
];
const dayNamesShort = ["Lun", "Mar", "Mer", "Jeu", "Ven", "Sam", "Dim"];
const navigateMonth = (direction: number) => {
setCurrentDate(
new Date(currentDate.getFullYear(), currentDate.getMonth() + direction, 1)
);
const formatDate = (date: Date) => {
// Use local timezone instead of UTC to avoid timezone issues
const year = date.getFullYear();
const month = (date.getMonth() + 1).toString().padStart(2, "0");
const day = date.getDate().toString().padStart(2, "0");
return `${year}-${month}-${day}`;
};
return (
<div className="min-h-screen bg-gray-50 dark:bg-gray-900">
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-4">
<div className="flex justify-between items-center mb-6">
<h1 className="text-3xl font-bold text-gray-900 dark:text-white">
Planning
</h1>
<button
onClick={() => setIsEventModalOpen(true)}
className="px-4 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition-colors"
const getEventsForDate = (date: Date) => {
const dateString = formatDate(date);
return events.filter((event) => event.date === dateString);
};
const navigateDate = (direction: number) => {
const newDate = new Date(currentDate);
if (currentView === "month") {
newDate.setMonth(newDate.getMonth() + direction);
} else if (currentView === "week") {
newDate.setDate(newDate.getDate() + direction * 7);
} else {
newDate.setDate(newDate.getDate() + direction);
}
setCurrentDate(newDate);
};
const goToToday = () => {
const today = new Date();
setCurrentDate(today);
setSelectedDate(today);
};
const addEvent = () => {
if (newEventTitle.trim()) {
const newEvent: Event = {
id: Math.max(...events.map((e) => e.id), 0) + 1,
title: newEventTitle.trim(),
date: formatDate(selectedDate),
time: newEventTime || "09:00",
endTime: newEventEndTime || "",
type: newEventType,
color:
newEventType === "meeting"
? "bg-blue-500"
: newEventType === "task"
? "bg-green-500"
: "bg-yellow-500",
description: newEventDescription.trim(),
};
setEvents([...events, newEvent]);
setIsEventModalOpen(false);
setNewEventTitle("");
setNewEventTime("");
setNewEventEndTime("");
setNewEventType("meeting");
setNewEventDescription("");
}
};
const getViewTitle = () => {
if (currentView === "month") {
return `${
monthNames[currentDate.getMonth()]
} ${currentDate.getFullYear()}`;
} else if (currentView === "week") {
const startOfWeek = new Date(currentDate);
// Get Monday as first day (0=Sunday, 1=Monday, etc.)
const dayOfWeek = currentDate.getDay();
const daysFromMonday = dayOfWeek === 0 ? 6 : dayOfWeek - 1;
startOfWeek.setDate(currentDate.getDate() - daysFromMonday);
const endOfWeek = new Date(startOfWeek);
endOfWeek.setDate(startOfWeek.getDate() + 6);
if (startOfWeek.getMonth() === endOfWeek.getMonth()) {
return `${startOfWeek.getDate()} - ${endOfWeek.getDate()} ${
monthNames[startOfWeek.getMonth()]
} ${startOfWeek.getFullYear()}`;
} else {
return `${startOfWeek.getDate()} ${
monthNames[startOfWeek.getMonth()]
} - ${endOfWeek.getDate()} ${
monthNames[endOfWeek.getMonth()]
} ${startOfWeek.getFullYear()}`;
}
} else {
return currentDate.toLocaleDateString("fr-FR", {
weekday: "long",
year: "numeric",
month: "long",
day: "numeric",
});
}
};
const getDaysInMonth = (date: Date) => {
const year = date.getFullYear();
const month = date.getMonth();
const firstDay = new Date(year, month, 1);
const lastDay = new Date(year, month + 1, 0);
const daysInMonth = lastDay.getDate();
// Adjust for Monday as first day of week
const startingDayOfWeek = firstDay.getDay();
const mondayStartingDay =
startingDayOfWeek === 0 ? 6 : startingDayOfWeek - 1;
const days = [];
for (let i = 0; i < mondayStartingDay; i++) {
days.push(null);
}
for (let day = 1; day <= daysInMonth; day++) {
days.push(new Date(year, month, day));
}
return days;
};
const getWeekDays = () => {
const startOfWeek = new Date(currentDate);
// Get Monday as first day (0=Sunday, 1=Monday, etc.)
const dayOfWeek = currentDate.getDay();
const daysFromMonday = dayOfWeek === 0 ? 6 : dayOfWeek - 1; // Sunday = 6 days from Monday
startOfWeek.setDate(currentDate.getDate() - daysFromMonday);
const weekDays = [];
for (let i = 0; i < 7; i++) {
const day = new Date(startOfWeek);
day.setDate(startOfWeek.getDate() + i);
weekDays.push(day);
}
return weekDays;
};
const timeSlots = Array.from(
{ length: 24 },
(_, i) => `${i.toString().padStart(2, "0")}:00`
);
const renderMonthView = () => (
<div className="flex-1 bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700">
{/* Days header */}
<div className="grid grid-cols-7 border-b border-gray-200 dark:border-gray-700">
{dayNamesShort.map((day) => (
<div
key={day}
className="p-4 text-center text-sm font-medium text-gray-500 dark:text-gray-400 border-r border-gray-200 dark:border-gray-700 last:border-r-0"
>
+ Nouvel événement
</button>
</div>
{day}
</div>
))}
</div>
<div className="space-y-6">
{/* Calendar */}
<div className="bg-white dark:bg-gray-800 rounded-lg shadow p-6">
{/* Calendar Header */}
<div className="flex justify-between items-center mb-4">
<h2 className="text-xl font-semibold text-gray-900 dark:text-white">
{monthNames[currentDate.getMonth()]} {currentDate.getFullYear()}
</h2>
<div className="flex space-x-2">
<button
onClick={() => navigateMonth(-1)}
className="p-2 hover:bg-gray-100 dark:hover:bg-gray-700 rounded"
{/* Calendar grid */}
<div className="grid grid-cols-7">
{getDaysInMonth(currentDate).map((day, index) => (
<div
key={index}
className={`min-h-[120px] border-b border-gray-200 dark:border-gray-700 ${
(index + 1) % 7 !== 0
? "border-r border-gray-200 dark:border-gray-700"
: ""
} ${
day
? "cursor-pointer hover:bg-gray-50 dark:hover:bg-gray-700"
: "bg-gray-50 dark:bg-gray-900"
} ${
day && formatDate(day) === formatDate(new Date())
? "bg-blue-50 dark:bg-blue-900/20"
: ""
}`}
onClick={() => {
if (day) {
setSelectedDate(day);
setIsEventModalOpen(true);
}
}}
>
{day && (
<div className="p-2">
<div
className={`text-sm font-medium mb-1 ${
formatDate(day) === formatDate(new Date())
? "text-blue-600 dark:text-blue-400"
: "text-gray-900 dark:text-white"
}`}
>
<svg
className="w-5 h-5"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth="2"
d="M15 19l-7-7 7-7"
/>
</svg>
</button>
<button
onClick={() => navigateMonth(1)}
className="p-2 hover:bg-gray-100 dark:hover:bg-gray-700 rounded"
>
<svg
className="w-5 h-5"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth="2"
d="M9 5l7 7-7 7"
/>
</svg>
</button>
{day.getDate()}
</div>
<div className="space-y-1">
{getEventsForDate(day)
.slice(0, 3)
.map((event) => (
<div
key={event.id}
className={`text-xs px-2 py-1 rounded text-white ${event.color} truncate cursor-pointer hover:opacity-80`}
title={`${event.time} ${event.title}`}
>
{event.title}
</div>
))}
{getEventsForDate(day).length > 3 && (
<div className="text-xs text-gray-500 dark:text-gray-400 px-2">
+{getEventsForDate(day).length - 3} autres
</div>
)}
</div>
</div>
</div>
)}
</div>
))}
</div>
</div>
);
{/* Calendar Grid */}
<div className="grid grid-cols-7 gap-1 mb-2">
{dayNames.map((day) => (
const renderWeekView = () => (
<div className="flex-1 bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 flex flex-col">
{/* Week header */}
<div className="flex border-b border-gray-200 dark:border-gray-700">
<div className="w-20 p-4 border-r border-gray-200 dark:border-gray-700 flex-shrink-0"></div>
{getWeekDays().map((day, index) => (
<div
key={day.toISOString()}
className={`flex-1 p-4 text-center border-r border-gray-200 dark:border-gray-700 ${
index === 6 ? "border-r-0" : ""
}`}
>
<div className="text-xs text-gray-500 dark:text-gray-400 uppercase">
{dayNamesShort[day.getDay() === 0 ? 6 : day.getDay() - 1]}
</div>
<div
className={`text-lg font-medium mt-1 ${
formatDate(day) === formatDate(new Date())
? "text-blue-600 dark:text-blue-400"
: "text-gray-900 dark:text-white"
}`}
>
{day.getDate()}
</div>
</div>
))}
</div>
{/* Time slots */}
<div className="flex-1 overflow-y-auto">
{timeSlots.map((time) => (
<div
key={time}
className="flex border-b border-gray-200 dark:border-gray-700"
>
<div className="w-20 p-2 text-xs text-gray-500 dark:text-gray-400 text-right border-r border-gray-200 dark:border-gray-700 flex-shrink-0">
{time}
</div>
{getWeekDays().map((day, index) => (
<div
key={`${day.toISOString()}-${time}`}
className={`flex-1 min-h-[60px] border-r border-gray-200 dark:border-gray-700 hover:bg-gray-50 dark:hover:bg-gray-700 cursor-pointer relative ${
index === 6 ? "border-r-0" : ""
}`}
onClick={() => {
setSelectedDate(day);
setNewEventTime(time);
setIsEventModalOpen(true);
}}
>
{getEventsForDate(day)
.filter((event) => event.time.startsWith(time.split(":")[0]))
.map((event) => (
<div
key={event.id}
className={`absolute left-1 right-1 top-1 p-1 rounded text-white ${event.color} text-xs`}
>
<div className="font-medium truncate">{event.title}</div>
<div className="opacity-75">
{event.time} - {event.endTime}
</div>
</div>
))}
</div>
))}
</div>
))}
</div>
</div>
);
const renderDayView = () => (
<div className="flex-1 bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700">
{/* Day header */}
<div className="p-4 border-b border-gray-200 dark:border-gray-700 text-center">
<div className="text-sm text-gray-500 dark:text-gray-400 uppercase">
{dayNames[currentDate.getDay()]}
</div>
<div className="text-2xl font-medium text-gray-900 dark:text-white mt-1">
{currentDate.getDate()}
</div>
</div>
{/* Time slots */}
<div className="max-h-[600px] overflow-y-auto">
{timeSlots.map((time) => (
<div
key={time}
className="flex border-b border-gray-100 dark:border-gray-700 hover:bg-gray-50 dark:hover:bg-gray-700 cursor-pointer relative min-h-[60px]"
onClick={() => {
setNewEventTime(time);
setIsEventModalOpen(true);
}}
>
<div className="w-20 p-2 text-xs text-gray-500 dark:text-gray-400 text-right border-r border-gray-200 dark:border-gray-700">
{time}
</div>
<div className="flex-1 p-2 relative">
{getEventsForDate(currentDate)
.filter((event) => event.time.startsWith(time.split(":")[0]))
.map((event) => (
<div
key={event.id}
className={`p-2 rounded text-white ${event.color} mb-1`}
>
<div className="font-medium">{event.title}</div>
<div className="text-sm opacity-75">
{event.time} - {event.endTime}
</div>
{event.description && (
<div className="text-sm mt-1 opacity-75">
{event.description}
</div>
)}
</div>
))}
</div>
</div>
))}
</div>
</div>
);
return (
<div className="min-h-screen bg-gray-100 dark:bg-gray-900">
<div className="flex">
{/* Sidebar */}
<div className="w-64 bg-white dark:bg-gray-800 border-r border-gray-200 dark:border-gray-700 min-h-screen">
<div className="p-4">
<button
onClick={() => setIsEventModalOpen(true)}
className="w-full px-4 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition-colors font-medium shadow-sm"
>
+ Créer un événement
</button>
</div>
{/* Mini Calendar */}
<div className="p-4 border-t border-gray-200 dark:border-gray-700">
<div className="text-sm font-medium text-gray-900 dark:text-white mb-3">
{monthNames[currentDate.getMonth()]} {currentDate.getFullYear()}
</div>
<div className="grid grid-cols-7 gap-1 text-xs">
{dayNamesShort.map((day) => (
<div
key={day}
className="p-3 text-center text-sm font-medium text-gray-500 dark:text-gray-400"
className="text-center text-gray-500 dark:text-gray-400 p-1"
>
{day}
{day.slice(0, 1)}
</div>
))}
</div>
<div className="grid grid-cols-7 gap-1">
{getDaysInMonth(currentDate).map((day, index) => (
<div
key={index}
className={`min-h-[120px] p-2 border border-gray-200 dark:border-gray-700 ${
day
? "cursor-pointer hover:bg-gray-50 dark:hover:bg-gray-700"
: ""
className={`text-center p-1 cursor-pointer rounded ${
day ? "hover:bg-gray-100 dark:hover:bg-gray-700" : ""
} ${
day && formatDate(day) === formatDate(selectedDate)
? "bg-blue-100 dark:bg-blue-900"
day && formatDate(day) === formatDate(new Date())
? "bg-blue-600 text-white"
: day
? "text-gray-900 dark:text-white"
: ""
}`}
onClick={() => day && setSelectedDate(day)}
onClick={() => {
if (day) {
setSelectedDate(day);
setIsEventModalOpen(true);
}
}}
>
{day && (
<>
<div className="text-base font-medium text-gray-900 dark:text-white mb-2">
{day.getDate()}
</div>
<div className="space-y-1">
{getEventsForDate(day)
.slice(0, 3)
.map((event) => (
<div
key={event.id}
className={`text-xs px-2 py-1 rounded text-white ${event.color} truncate`}
>
{event.time} {event.title}
</div>
))}
{getEventsForDate(day).length > 3 && (
<div className="text-xs text-gray-500 dark:text-gray-400">
+{getEventsForDate(day).length - 3} autres
</div>
)}
</div>
</>
)}
{day ? day.getDate() : ""}
</div>
))}
</div>
</div>
</div>
{/* Selected Date Events */}
<div className="bg-white dark:bg-gray-800 rounded-lg shadow p-6">
<h3 className="text-lg font-semibold text-gray-900 dark:text-white mb-4">
Événements du{" "}
{selectedDate.toLocaleDateString("fr-FR", {
weekday: "long",
year: "numeric",
month: "long",
day: "numeric",
})}
</h3>
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
{getEventsForDate(selectedDate).length > 0 ? (
getEventsForDate(selectedDate).map((event) => (
<div
key={event.id}
className="flex items-center space-x-3 p-3 rounded-lg bg-gray-50 dark:bg-gray-700"
{/* Main Content */}
<div className="flex-1 flex flex-col">
{/* Header */}
<div className="bg-white dark:bg-gray-800 border-b border-gray-200 dark:border-gray-700 p-4">
<div className="flex items-center justify-between">
<div className="flex items-center space-x-4">
<h1 className="text-2xl font-semibold text-gray-900 dark:text-white">
Planning
</h1>
<button
onClick={goToToday}
className="px-3 py-1.5 text-sm border border-gray-300 dark:border-gray-600 rounded hover:bg-gray-50 dark:hover:bg-gray-700 text-gray-700 dark:text-gray-300"
>
Aujourd&apos;hui
</button>
<div className="flex items-center space-x-2">
<button
onClick={() => navigateDate(-1)}
className="p-2 hover:bg-gray-100 dark:hover:bg-gray-700 rounded text-gray-700 dark:text-gray-300"
>
<div
className={`w-4 h-4 rounded-full ${event.color}`}
></div>
<div className="flex-1">
<div className="text-sm font-medium text-gray-900 dark:text-white">
{event.title}
</div>
<div className="text-xs text-gray-500 dark:text-gray-400">
{event.time} {event.type}
</div>
</div>
</div>
))
) : (
<p className="text-gray-500 dark:text-gray-400 text-sm col-span-full">
Aucun événement prévu pour cette date
</p>
)}
<svg
className="w-5 h-5"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth="2"
d="M15 19l-7-7 7-7"
/>
</svg>
</button>
<button
onClick={() => navigateDate(1)}
className="p-2 hover:bg-gray-100 dark:hover:bg-gray-700 rounded text-gray-700 dark:text-gray-300"
>
<svg
className="w-5 h-5"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth="2"
d="M9 5l7 7-7 7"
/>
</svg>
</button>
</div>
<h2 className="text-xl font-medium text-gray-900 dark:text-white">
{getViewTitle()}
</h2>
</div>
<div className="flex items-center space-x-2">
<div className="flex bg-gray-100 dark:bg-gray-700 rounded-lg p-1">
{(["month", "week", "day"] as ViewType[]).map((view) => (
<button
key={view}
onClick={() => setCurrentView(view)}
className={`px-3 py-1.5 text-sm rounded-md transition-colors capitalize ${
currentView === view
? "bg-white dark:bg-gray-800 text-gray-900 dark:text-white shadow-sm"
: "text-gray-600 dark:text-gray-400 hover:text-gray-900 dark:hover:text-white"
}`}
>
{view === "month"
? "Mois"
: view === "week"
? "Semaine"
: "Jour"}
</button>
))}
</div>
</div>
</div>
</div>
{/* Calendar Views */}
<div className="flex-1 p-4">
{currentView === "month" && renderMonthView()}
{currentView === "week" && renderWeekView()}
{currentView === "day" && renderDayView()}
</div>
</div>
</div>
@ -289,35 +577,48 @@ export const PlanningPage = () => {
{isEventModalOpen && (
<div className="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50">
<div className="bg-white dark:bg-gray-800 rounded-lg shadow-xl p-6 w-full max-w-md mx-4">
<h2 className="text-xl font-bold text-gray-900 dark:text-white mb-4">
<h2 className="text-xl font-semibold text-gray-900 dark:text-white mb-4">
Nouvel événement
</h2>
<div className="space-y-4">
<div>
<label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
Titre
Titre *
</label>
<input
type="text"
value={newEventTitle}
onChange={(e) => setNewEventTitle(e.target.value)}
className="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md shadow-sm focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500 dark:bg-gray-700 dark:text-white"
placeholder="Titre de l'événement"
placeholder="Ajouter un titre"
autoFocus
/>
</div>
<div>
<label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
Heure
</label>
<input
type="time"
value={newEventTime}
onChange={(e) => setNewEventTime(e.target.value)}
className="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md shadow-sm focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500 dark:bg-gray-700 dark:text-white"
/>
<div className="grid grid-cols-2 gap-4">
<div>
<label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
Début
</label>
<input
type="time"
value={newEventTime}
onChange={(e) => setNewEventTime(e.target.value)}
className="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md shadow-sm focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500 dark:bg-gray-700 dark:text-white"
/>
</div>
<div>
<label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
Fin
</label>
<input
type="time"
value={newEventEndTime}
onChange={(e) => setNewEventEndTime(e.target.value)}
className="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md shadow-sm focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500 dark:bg-gray-700 dark:text-white"
/>
</div>
</div>
<div>
@ -339,26 +640,52 @@ export const PlanningPage = () => {
</select>
</div>
<div className="text-sm text-gray-600 dark:text-gray-400">
Date: {selectedDate.toLocaleDateString("fr-FR")}
<div>
<label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
Description
</label>
<textarea
value={newEventDescription}
onChange={(e) => setNewEventDescription(e.target.value)}
rows={3}
className="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md shadow-sm focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500 dark:bg-gray-700 dark:text-white"
placeholder="Ajouter une description (optionnel)"
/>
</div>
<div className="text-sm text-gray-600 dark:text-gray-400 bg-gray-50 dark:bg-gray-700 p-3 rounded-md">
📅{" "}
{selectedDate.toLocaleDateString("fr-FR", {
weekday: "long",
year: "numeric",
month: "long",
day: "numeric",
})}
</div>
</div>
<div className="flex justify-end space-x-3 mt-6">
<button
type="button"
className="px-4 py-2 text-sm font-medium text-gray-700 dark:text-gray-300 bg-gray-100 dark:bg-gray-700 hover:bg-gray-200 dark:hover:bg-gray-600 rounded-md"
onClick={() => setIsEventModalOpen(false)}
className="px-4 py-2 text-sm font-medium text-gray-700 dark:text-gray-300 hover:bg-gray-50 dark:hover:bg-gray-700 rounded-md transition-colors"
onClick={() => {
setIsEventModalOpen(false);
setNewEventTitle("");
setNewEventTime("");
setNewEventEndTime("");
setNewEventType("meeting");
setNewEventDescription("");
}}
>
Annuler
</button>
<button
type="button"
className="px-4 py-2 text-sm font-medium text-white bg-blue-600 hover:bg-blue-700 rounded-md disabled:opacity-50 disabled:cursor-not-allowed"
className="px-4 py-2 text-sm font-medium text-white bg-blue-600 hover:bg-blue-700 rounded-md disabled:opacity-50 disabled:cursor-not-allowed transition-colors"
onClick={addEvent}
disabled={!newEventTitle.trim()}
>
Créer
Enregistrer
</button>
</div>
</div>