+
onToggleVisibility(String(calendar.id))}
label=""
- aria-label={`${t('calendar.list.showCalendar')} ${calendar.name}`}
+ aria-label={`${t("calendar.list.showCalendar")} ${calendar.name}`}
/>
{
- e.stopPropagation();
+ (calendarUrl: string) => {
setOpenMenuUrl(openMenuUrl === calendarUrl ? null : calendarUrl);
},
[openMenuUrl]
diff --git a/src/frontend/apps/calendars/src/features/calendar/components/calendar-list/types.ts b/src/frontend/apps/calendars/src/features/calendar/components/calendar-list/types.ts
index 98934ef..7c71d37 100644
--- a/src/frontend/apps/calendars/src/features/calendar/components/calendar-list/types.ts
+++ b/src/frontend/apps/calendars/src/features/calendar/components/calendar-list/types.ts
@@ -21,10 +21,11 @@ export interface CalendarModalProps {
* Props for the CalendarItemMenu component.
*/
export interface CalendarItemMenuProps {
+ isOpen: boolean;
+ onOpenChange: (isOpen: boolean) => void;
onEdit: () => void;
onDelete: () => void;
onSubscription?: () => void;
- onClose: () => void;
}
/**
@@ -46,7 +47,7 @@ export interface CalendarListItemProps {
isVisible: boolean;
isMenuOpen: boolean;
onToggleVisibility: (url: string) => void;
- onMenuToggle: (url: string, e: React.MouseEvent) => void;
+ onMenuToggle: (url: string) => void;
onEdit: (calendar: CalDavCalendar) => void;
onDelete: (calendar: CalDavCalendar) => void;
onSubscription?: (calendar: CalDavCalendar) => void;
diff --git a/src/frontend/apps/calendars/src/features/calendar/components/index.ts b/src/frontend/apps/calendars/src/features/calendar/components/index.ts
index 2618d5d..6b9c94f 100644
--- a/src/frontend/apps/calendars/src/features/calendar/components/index.ts
+++ b/src/frontend/apps/calendars/src/features/calendar/components/index.ts
@@ -1,3 +1,2 @@
-export { LeftPanel } from "./LeftPanel";
-export { MiniCalendar } from "./MiniCalendar";
-export { AttendeesInput } from "./AttendeesInput";
+export { LeftPanel, MiniCalendar } from "./left-panel";
+export { AttendeesInput } from "./scheduler";
diff --git a/src/frontend/apps/calendars/src/features/calendar/components/LeftPanel.scss b/src/frontend/apps/calendars/src/features/calendar/components/left-panel/LeftPanel.scss
similarity index 65%
rename from src/frontend/apps/calendars/src/features/calendar/components/LeftPanel.scss
rename to src/frontend/apps/calendars/src/features/calendar/components/left-panel/LeftPanel.scss
index eebec5f..b187803 100644
--- a/src/frontend/apps/calendars/src/features/calendar/components/LeftPanel.scss
+++ b/src/frontend/apps/calendars/src/features/calendar/components/left-panel/LeftPanel.scss
@@ -3,16 +3,22 @@
flex-direction: column;
height: 100%;
background-color: var(--c--theme--colors--greyscale-000);
- border-right: 1px solid
- var(--c--contextuals--border--semantic--neutral--tertiary);
+
overflow-y: auto;
&__create {
- padding: 1rem 0.75rem;
+ padding: 0.75rem 0.75rem;
.c__button {
width: 100%;
justify-content: center;
}
}
+
+ .mini-calendar {
+ width: 100%;
+ max-width: 280px;
+ align-self: center;
+ flex-shrink: 0;
+ }
}
diff --git a/src/frontend/apps/calendars/src/features/calendar/components/left-panel/LeftPanel.tsx b/src/frontend/apps/calendars/src/features/calendar/components/left-panel/LeftPanel.tsx
new file mode 100644
index 0000000..cf07f31
--- /dev/null
+++ b/src/frontend/apps/calendars/src/features/calendar/components/left-panel/LeftPanel.tsx
@@ -0,0 +1,160 @@
+/**
+ * LeftPanel component - Calendar sidebar with mini calendar and calendar list.
+ */
+
+import { useCallback, useMemo } from "react";
+import { useTranslation } from "react-i18next";
+import { Button, useModal } from "@gouvfr-lasuite/cunningham-react";
+import { IcsEvent } from "ts-ics";
+
+import { CalendarList } from "../calendar-list";
+import { MiniCalendar } from "./MiniCalendar";
+import { EventModal } from "../scheduler/EventModal";
+import { useCalendarContext } from "../../contexts";
+import { useCalendars } from "../../hooks/useCalendars";
+
+const BROWSER_TIMEZONE = Intl.DateTimeFormat().resolvedOptions().timeZone;
+
+/**
+ * Get rounded start and end times for a new event.
+ * Rounds down to the current hour, end is 1 hour later.
+ * Example: 14:30 -> start: 14:00, end: 15:00
+ */
+const getDefaultEventTimes = () => {
+ const now = new Date();
+ const start = new Date(now);
+ start.setMinutes(0, 0, 0);
+
+ const end = new Date(start);
+ end.setHours(end.getHours() + 1);
+
+ return { start, end };
+};
+
+export const LeftPanel = () => {
+ const { t } = useTranslation();
+ const modal = useModal();
+
+ const {
+ selectedDate,
+ setSelectedDate,
+ davCalendars,
+ caldavService,
+ adapter,
+ calendarRef,
+ } = useCalendarContext();
+
+ const { data: calendars = [] } = useCalendars();
+
+ // Get default calendar URL
+ const defaultCalendarUrl = davCalendars[0]?.url || "";
+
+ // Create default event with rounded times
+ const defaultEvent = useMemo(() => {
+ const { start, end } = getDefaultEventTimes();
+
+ // Create "fake UTC" dates for the adapter
+ const fakeUtcStart = new Date(
+ Date.UTC(
+ start.getFullYear(),
+ start.getMonth(),
+ start.getDate(),
+ start.getHours(),
+ start.getMinutes(),
+ 0
+ )
+ );
+ const fakeUtcEnd = new Date(
+ Date.UTC(
+ end.getFullYear(),
+ end.getMonth(),
+ end.getDate(),
+ end.getHours(),
+ end.getMinutes(),
+ 0
+ )
+ );
+
+ return {
+ start: {
+ date: fakeUtcStart,
+ type: "DATE-TIME" as const,
+ local: {
+ date: fakeUtcStart,
+ timezone: BROWSER_TIMEZONE,
+ tzoffset: adapter.getTimezoneOffset(start, BROWSER_TIMEZONE),
+ },
+ },
+ end: {
+ date: fakeUtcEnd,
+ type: "DATE-TIME" as const,
+ local: {
+ date: fakeUtcEnd,
+ timezone: BROWSER_TIMEZONE,
+ tzoffset: adapter.getTimezoneOffset(end, BROWSER_TIMEZONE),
+ },
+ },
+ };
+ }, [adapter]);
+
+ // Handle save event
+ const handleSave = useCallback(
+ async (event: IcsEvent, calendarUrl: string) => {
+ const result = await caldavService.createEvent({
+ calendarUrl,
+ event,
+ });
+
+ if (!result.success) {
+ throw new Error(result.error || "Failed to create event");
+ }
+
+ // Refresh the calendar view
+ if (calendarRef.current) {
+ calendarRef.current.refetchEvents();
+ }
+ },
+ [caldavService, calendarRef]
+ );
+
+ const handleClose = useCallback(() => {
+ modal.close();
+ }, [modal]);
+
+ return (
+ <>
+
+
+
+
+
+
+
+
+
+
+
+
+ {modal.isOpen && (
+
+ )}
+ >
+ );
+};
diff --git a/src/frontend/apps/calendars/src/features/calendar/components/MiniCalendar.scss b/src/frontend/apps/calendars/src/features/calendar/components/left-panel/MiniCalendar.scss
similarity index 52%
rename from src/frontend/apps/calendars/src/features/calendar/components/MiniCalendar.scss
rename to src/frontend/apps/calendars/src/features/calendar/components/left-panel/MiniCalendar.scss
index ed73c4f..149e808 100644
--- a/src/frontend/apps/calendars/src/features/calendar/components/MiniCalendar.scss
+++ b/src/frontend/apps/calendars/src/features/calendar/components/left-panel/MiniCalendar.scss
@@ -12,9 +12,9 @@
&__month-title {
font-size: 1rem;
- font-weight: 500;
+ font-weight: 700;
text-transform: capitalize;
- color: var(--c--theme--colors--greyscale-800);
+ color: var(--c--contextuals--content--semantic--neutral--primary);
}
&__nav {
@@ -23,29 +23,6 @@
gap: 0.25rem;
}
- &__nav-btn {
- display: flex;
- align-items: center;
- justify-content: center;
- width: 1.75rem;
- height: 1.75rem;
- border: none;
- background: transparent;
- border-radius: 50%;
- cursor: pointer;
- color: var(--c--theme--colors--greyscale-500);
- transition: background-color 0.15s, color 0.15s;
-
- &:hover {
- background-color: var(--c--theme--colors--greyscale-100);
- color: var(--c--theme--colors--greyscale-700);
- }
-
- .material-icons {
- font-size: 1.25rem;
- }
- }
-
&__grid {
display: flex;
flex-direction: column;
@@ -63,15 +40,15 @@
align-items: center;
justify-content: center;
height: 1.5rem;
- font-size: 0.75rem;
- font-weight: 600;
- color: var(--c--theme--colors--greyscale-800);
+ font-size: var(--c--globals--font--sizes--s);
+ font-weight: 700;
+ color: var(--c--contextuals--content--semantic--neutral--primary);
text-transform: lowercase;
&--week-num {
- color: var(--c--theme--colors--greyscale-500);
+ color: var(--c--contextuals--content--semantic--neutral--tertiary);
font-weight: 500;
- font-size: 0.7rem;
+ font-size: 0.6rem;
}
}
@@ -91,8 +68,8 @@
display: flex;
align-items: center;
justify-content: center;
- font-size: 0.75rem;
- color: var(--c--theme--colors--greyscale-400);
+ font-size: 0.6rem;
+ color: var(--c--contextuals--content--semantic--neutral--tertiary);
font-weight: 400;
}
@@ -107,32 +84,53 @@
border-radius: 4px;
cursor: pointer;
font-size: 0.8rem;
- color: var(--c--theme--colors--greyscale-800);
+ color: var(--c--contextuals--content--semantic--neutral--primary);
font-weight: 500;
transition: background-color 0.15s;
- &:hover {
- background-color: var(--c--theme--colors--greyscale-100);
- }
-
&--outside {
- color: var(--c--theme--colors--greyscale-400);
+ color: var(--c--contextuals--content--semantic--neutral--tertiary);
font-weight: 400;
+
+ &.mini-calendar__day--today {
+ color: var(--c--contextuals--content--semantic--neutral--primary);
+ font-weight: 700;
+ }
+
+ &.mini-calendar__day--selected {
+ color: white;
+ font-weight: 600;
+ }
}
- &--today {
- color: var(--c--theme--colors--primary-600);
+ &--today:not(.mini-calendar__day--outside) {
+ color: var(--c--contextuals--content--semantic--brand--primary);
font-weight: 600;
}
+ // &:not(&--outside):--today {
+ // color: var(--c--contextuals--content--semantic--neutral--primary);
+ // font-weight: 600;
+ // }
+
+ &:hover {
+ background-color: var(
+ --c--contextuals--background--semantic--neutral--tertiary
+ );
+ }
+
&--selected {
- background-color: #8b4513;
+ background-color: var(
+ --c--contextuals--background--semantic--brand--primary
+ );
color: white;
font-weight: 600;
border-radius: 4px;
&:hover {
- background-color: #7a3d11;
+ background-color: var(
+ --c--contextuals--background--semantic--brand--primary-hover
+ );
}
}
}
diff --git a/src/frontend/apps/calendars/src/features/calendar/components/MiniCalendar.tsx b/src/frontend/apps/calendars/src/features/calendar/components/left-panel/MiniCalendar.tsx
similarity index 82%
rename from src/frontend/apps/calendars/src/features/calendar/components/MiniCalendar.tsx
rename to src/frontend/apps/calendars/src/features/calendar/components/left-panel/MiniCalendar.tsx
index e30937c..812e8e3 100644
--- a/src/frontend/apps/calendars/src/features/calendar/components/MiniCalendar.tsx
+++ b/src/frontend/apps/calendars/src/features/calendar/components/left-panel/MiniCalendar.tsx
@@ -18,8 +18,9 @@ import {
subMonths,
} from "date-fns";
import { useTranslation } from "react-i18next";
-import { useCalendarContext } from "../contexts";
-import { useCalendarLocale } from "../hooks/useCalendarLocale";
+import { useCalendarContext } from "../../contexts";
+import { useCalendarLocale } from "../../hooks/useCalendarLocale";
+import { Button } from "@gouvfr-lasuite/cunningham-react";
interface MiniCalendarProps {
selectedDate: Date;
@@ -71,13 +72,13 @@ export const MiniCalendar = ({
// Generate weekday labels based on locale and first day of week
const weekDays = useMemo(() => {
const days = [
- t('calendar.recurrence.weekdays.mo'),
- t('calendar.recurrence.weekdays.tu'),
- t('calendar.recurrence.weekdays.we'),
- t('calendar.recurrence.weekdays.th'),
- t('calendar.recurrence.weekdays.fr'),
- t('calendar.recurrence.weekdays.sa'),
- t('calendar.recurrence.weekdays.su'),
+ t("calendar.recurrence.weekdays.mo"),
+ t("calendar.recurrence.weekdays.tu"),
+ t("calendar.recurrence.weekdays.we"),
+ t("calendar.recurrence.weekdays.th"),
+ t("calendar.recurrence.weekdays.fr"),
+ t("calendar.recurrence.weekdays.sa"),
+ t("calendar.recurrence.weekdays.su"),
];
// Rotate array based on firstDayOfWeek (0 = Sunday, 1 = Monday)
if (firstDayOfWeek === 0) {
@@ -106,20 +107,23 @@ export const MiniCalendar = ({
{format(viewDate, "MMMM yyyy", { locale: dateFnsLocale })}
-
-
+
+
+ />
@@ -155,7 +159,9 @@ export const MiniCalendar = ({
className={`mini-calendar__day ${
!isCurrentMonth ? "mini-calendar__day--outside" : ""
} ${isSelected ? "mini-calendar__day--selected" : ""} ${
- isToday && !isSelected ? "mini-calendar__day--today" : ""
+ isToday && !isSelected
+ ? "mini-calendar__day--today"
+ : ""
}`}
onClick={() => handleDayClick(day)}
>
diff --git a/src/frontend/apps/calendars/src/features/calendar/components/left-panel/index.ts b/src/frontend/apps/calendars/src/features/calendar/components/left-panel/index.ts
new file mode 100644
index 0000000..d277d2b
--- /dev/null
+++ b/src/frontend/apps/calendars/src/features/calendar/components/left-panel/index.ts
@@ -0,0 +1,2 @@
+export { LeftPanel } from "./LeftPanel";
+export { MiniCalendar } from "./MiniCalendar";
diff --git a/src/frontend/apps/calendars/src/features/calendar/components/AttendeesInput.scss b/src/frontend/apps/calendars/src/features/calendar/components/scheduler/AttendeesInput.scss
similarity index 100%
rename from src/frontend/apps/calendars/src/features/calendar/components/AttendeesInput.scss
rename to src/frontend/apps/calendars/src/features/calendar/components/scheduler/AttendeesInput.scss
diff --git a/src/frontend/apps/calendars/src/features/calendar/components/AttendeesInput.tsx b/src/frontend/apps/calendars/src/features/calendar/components/scheduler/AttendeesInput.tsx
similarity index 100%
rename from src/frontend/apps/calendars/src/features/calendar/components/AttendeesInput.tsx
rename to src/frontend/apps/calendars/src/features/calendar/components/scheduler/AttendeesInput.tsx
diff --git a/src/frontend/apps/calendars/src/features/calendar/components/EventModal.scss b/src/frontend/apps/calendars/src/features/calendar/components/scheduler/EventModal.scss
similarity index 100%
rename from src/frontend/apps/calendars/src/features/calendar/components/EventModal.scss
rename to src/frontend/apps/calendars/src/features/calendar/components/scheduler/EventModal.scss
diff --git a/src/frontend/apps/calendars/src/features/calendar/components/scheduler/EventModal.tsx b/src/frontend/apps/calendars/src/features/calendar/components/scheduler/EventModal.tsx
index af11f3d..8e07113 100644
--- a/src/frontend/apps/calendars/src/features/calendar/components/scheduler/EventModal.tsx
+++ b/src/frontend/apps/calendars/src/features/calendar/components/scheduler/EventModal.tsx
@@ -21,8 +21,8 @@ import {
} from "@gouvfr-lasuite/cunningham-react";
import { useAuth } from "@/features/auth/Auth";
-import { AttendeesInput } from "../AttendeesInput";
-import { RecurrenceEditor } from "../RecurrenceEditor";
+import { AttendeesInput } from "./AttendeesInput";
+import { RecurrenceEditor } from "./RecurrenceEditor";
import { DeleteEventModal } from "./DeleteEventModal";
import type { EventModalProps, RecurringDeleteOption } from "./types";
import {
diff --git a/src/frontend/apps/calendars/src/features/calendar/components/RecurrenceEditor.scss b/src/frontend/apps/calendars/src/features/calendar/components/scheduler/RecurrenceEditor.scss
similarity index 100%
rename from src/frontend/apps/calendars/src/features/calendar/components/RecurrenceEditor.scss
rename to src/frontend/apps/calendars/src/features/calendar/components/scheduler/RecurrenceEditor.scss
diff --git a/src/frontend/apps/calendars/src/features/calendar/components/RecurrenceEditor.tsx b/src/frontend/apps/calendars/src/features/calendar/components/scheduler/RecurrenceEditor.tsx
similarity index 100%
rename from src/frontend/apps/calendars/src/features/calendar/components/RecurrenceEditor.tsx
rename to src/frontend/apps/calendars/src/features/calendar/components/scheduler/RecurrenceEditor.tsx
diff --git a/src/frontend/apps/calendars/src/features/calendar/components/scheduler/Scheduler.tsx b/src/frontend/apps/calendars/src/features/calendar/components/scheduler/Scheduler.tsx
index 3200a4f..5b69f0e 100644
--- a/src/frontend/apps/calendars/src/features/calendar/components/scheduler/Scheduler.tsx
+++ b/src/frontend/apps/calendars/src/features/calendar/components/scheduler/Scheduler.tsx
@@ -98,7 +98,11 @@ export const Scheduler = ({ defaultCalendarUrl }: SchedulerProps) => {
// Callback to update toolbar state when calendar dates/view changes
const handleDatesSet = useCallback(
- (info: { start: Date; end: Date; view?: { type: string; title: string } }) => {
+ (info: {
+ start: Date;
+ end: Date;
+ view?: { type: string; title: string };
+ }) => {
// Update current date for MiniCalendar sync
const midTime = (info.start.getTime() + info.end.getTime()) / 2;
setCurrentDate(new Date(midTime));
@@ -112,7 +116,7 @@ export const Scheduler = ({ defaultCalendarUrl }: SchedulerProps) => {
}
}
},
- [setCurrentDate, calendarRef]
+ [setCurrentDate, calendarRef],
);
// Initialize calendar
@@ -171,7 +175,7 @@ export const Scheduler = ({ defaultCalendarUrl }: SchedulerProps) => {
ref={containerRef}
id="event-calendar"
className="scheduler__calendar"
- style={{ height: "calc(100vh - 160px)" }}
+ style={{ height: "calc(100vh - 52px - 90px)" }}
/>
{
const { t } = useTranslation();
const [isViewDropdownOpen, setIsViewDropdownOpen] = useState(false);
- const [focusedIndex, setFocusedIndex] = useState(-1);
- const dropdownRef = useRef(null);
- const triggerRef = useRef(null);
- const isOpenRef = useRef(isViewDropdownOpen);
- // Keep ref in sync with state to avoid stale closures
- isOpenRef.current = isViewDropdownOpen;
+ const handleViewChange = useCallback(
+ (value: string) => {
+ calendarRef.current?.setOption("view", value);
+ onViewChange?.(value);
+ setIsViewDropdownOpen(false);
+ },
+ [calendarRef, onViewChange],
+ );
- const viewOptions: ViewOption[] = useMemo(
+ const viewOptions: DropdownMenuOption[] = useMemo(
() => [
- { value: "timeGridDay", label: t("calendar.views.day") },
- { value: "timeGridWeek", label: t("calendar.views.week") },
- { value: "dayGridMonth", label: t("calendar.views.month") },
- { value: "listWeek", label: t("calendar.views.listWeek") },
+ {
+ value: "timeGridDay",
+ label: t("calendar.views.day"),
+ callback: () => handleViewChange("timeGridDay"),
+ },
+ {
+ value: "timeGridWeek",
+ label: t("calendar.views.week"),
+ callback: () => handleViewChange("timeGridWeek"),
+ },
+ {
+ value: "dayGridMonth",
+ label: t("calendar.views.month"),
+ callback: () => handleViewChange("dayGridMonth"),
+ },
+ {
+ value: "listWeek",
+ label: t("calendar.views.listWeek"),
+ callback: () => handleViewChange("listWeek"),
+ },
],
- [t],
+ [t, handleViewChange],
);
const currentViewLabel = useMemo(() => {
@@ -46,55 +60,6 @@ export const SchedulerToolbar = ({
return option?.label || t("calendar.views.week");
}, [currentView, viewOptions, t]);
- // Handle click outside to close dropdown (uses ref to avoid stale closure)
- useEffect(() => {
- const handleClickOutside = (event: MouseEvent) => {
- if (
- isOpenRef.current &&
- dropdownRef.current &&
- !dropdownRef.current.contains(event.target as Node)
- ) {
- setIsViewDropdownOpen(false);
- setFocusedIndex(-1);
- }
- };
- document.addEventListener("mousedown", handleClickOutside);
- return () => document.removeEventListener("mousedown", handleClickOutside);
- }, []);
-
- // Handle keyboard events for accessibility
- useEffect(() => {
- const handleKeyDown = (event: KeyboardEvent) => {
- if (!isOpenRef.current) return;
-
- switch (event.key) {
- case "Escape":
- setIsViewDropdownOpen(false);
- setFocusedIndex(-1);
- triggerRef.current?.focus();
- break;
- case "ArrowDown":
- event.preventDefault();
- setFocusedIndex((prev) =>
- prev < viewOptions.length - 1 ? prev + 1 : 0,
- );
- break;
- case "ArrowUp":
- event.preventDefault();
- setFocusedIndex((prev) =>
- prev > 0 ? prev - 1 : viewOptions.length - 1,
- );
- break;
- case "Tab":
- setIsViewDropdownOpen(false);
- setFocusedIndex(-1);
- break;
- }
- };
- document.addEventListener("keydown", handleKeyDown);
- return () => document.removeEventListener("keydown", handleKeyDown);
- }, [viewOptions.length]);
-
const handleToday = useCallback(() => {
calendarRef.current?.setOption("date", new Date());
}, [calendarRef]);
@@ -107,55 +72,6 @@ export const SchedulerToolbar = ({
calendarRef.current?.next();
}, [calendarRef]);
- const handleViewChange = useCallback(
- (value: string) => {
- calendarRef.current?.setOption("view", value);
- onViewChange?.(value);
- setIsViewDropdownOpen(false);
- },
- [calendarRef, onViewChange],
- );
-
- const toggleViewDropdown = useCallback(() => {
- setIsViewDropdownOpen((prev) => {
- if (!prev) {
- // Opening: set focus to current view
- const currentIndex = viewOptions.findIndex(
- (opt) => opt.value === currentView,
- );
- setFocusedIndex(currentIndex >= 0 ? currentIndex : 0);
- } else {
- setFocusedIndex(-1);
- }
- return !prev;
- });
- }, [viewOptions, currentView]);
-
- const handleKeyDownOnTrigger = useCallback(
- (event: React.KeyboardEvent) => {
- if (event.key === "ArrowDown" && !isViewDropdownOpen) {
- event.preventDefault();
- setIsViewDropdownOpen(true);
- const currentIndex = viewOptions.findIndex(
- (opt) => opt.value === currentView,
- );
- setFocusedIndex(currentIndex >= 0 ? currentIndex : 0);
- }
- },
- [isViewDropdownOpen, viewOptions, currentView],
- );
-
- const handleKeyDownOnOption = useCallback(
- (event: React.KeyboardEvent, value: string) => {
- if (event.key === "Enter" || event.key === " ") {
- event.preventDefault();
- handleViewChange(value);
- triggerRef.current?.focus();
- }
- },
- [handleViewChange],
- );
-
return (
@@ -186,51 +102,31 @@ export const SchedulerToolbar = ({
{viewTitle}
-
-
-
- {isViewDropdownOpen && (
-
- {viewOptions.map((option, index) => (
-
- )}
+ expand_more
+
+ }
+ aria-haspopup="listbox"
+ >
+
{currentViewLabel}
+
+
);
diff --git a/src/frontend/apps/calendars/src/features/calendar/components/scheduler/index.ts b/src/frontend/apps/calendars/src/features/calendar/components/scheduler/index.ts
index dfbcb9a..1e363ff 100644
--- a/src/frontend/apps/calendars/src/features/calendar/components/scheduler/index.ts
+++ b/src/frontend/apps/calendars/src/features/calendar/components/scheduler/index.ts
@@ -5,6 +5,8 @@
export { Scheduler } from "./Scheduler";
export { EventModal } from "./EventModal";
export { DeleteEventModal } from "./DeleteEventModal";
+export { AttendeesInput } from "./AttendeesInput";
+export { RecurrenceEditor } from "./RecurrenceEditor";
export { useSchedulerHandlers } from "./hooks/useSchedulerHandlers";
export { useSchedulerInit, useSchedulingCapabilitiesCheck } from "./hooks/useSchedulerInit";
export * from "./types";
diff --git a/src/frontend/apps/calendars/src/features/i18n/translations.json b/src/frontend/apps/calendars/src/features/i18n/translations.json
index a2381bf..2b91297 100644
--- a/src/frontend/apps/calendars/src/features/i18n/translations.json
+++ b/src/frontend/apps/calendars/src/features/i18n/translations.json
@@ -162,7 +162,7 @@
"errorServer": "Server error. Please try again later."
},
"leftPanel": {
- "create": "Create"
+ "newEvent": "New event"
},
"miniCalendar": {
"previousMonth": "Previous month",
@@ -731,7 +731,7 @@
"errorServer": "Erreur serveur. Veuillez réessayer plus tard."
},
"leftPanel": {
- "create": "Créer"
+ "newEvent": "Nouvel événement"
},
"miniCalendar": {
"previousMonth": "Mois précédent",
@@ -1047,7 +1047,7 @@
"errorServer": "Serverfout. Probeer het later opnieuw."
},
"leftPanel": {
- "create": "Aanmaken"
+ "newEvent": "Nieuw evenement"
},
"miniCalendar": {
"previousMonth": "Vorige maand",
diff --git a/src/frontend/apps/calendars/src/pages/calendar.tsx b/src/frontend/apps/calendars/src/pages/calendar.tsx
index 5122b9b..42b5d84 100644
--- a/src/frontend/apps/calendars/src/pages/calendar.tsx
+++ b/src/frontend/apps/calendars/src/pages/calendar.tsx
@@ -2,43 +2,23 @@
* Calendar page - Main calendar view with sidebar.
*/
-import { useCallback } from "react";
-
import { MainLayout } from "@gouvfr-lasuite/ui-kit";
import Head from "next/head";
import { useTranslation } from "next-i18next";
import { login, useAuth } from "@/features/auth/Auth";
import { LeftPanel } from "@/features/calendar/components";
-import { useCalendars } from "@/features/calendar/hooks/useCalendars";
import { GlobalLayout } from "@/features/layouts/components/global/GlobalLayout";
import { HeaderRight } from "@/features/layouts/components/header/Header";
import { SpinnerPage } from "@/features/ui/components/spinner/SpinnerPage";
import { Toaster } from "@/features/ui/components/toaster/Toaster";
import { Scheduler } from "@/features/calendar/components/scheduler/Scheduler";
-import { CalendarContextProvider, useCalendarContext } from "@/features/calendar/contexts";
+import { CalendarContextProvider } from "@/features/calendar/contexts";
export default function CalendarPage() {
const { t } = useTranslation();
const { user } = useAuth();
- // Use selectedDate from context (the specific day user has clicked/selected)
- // Note: currentDate (for view sync) is used directly by MiniCalendar
- const { selectedDate, setSelectedDate } = useCalendarContext();
-
- // Fetch calendars for the sidebar
- const { data: calendars = [] } = useCalendars();
-
-
- // Handlers
- const handleDateSelect = useCallback((date: Date) => {
- setSelectedDate(date);
- }, [setSelectedDate]);
-
- const handleCreateEvent = useCallback(() => {
- console.log("handleCreateEvent");
- }, []);
-
// Redirect to login if not authenticated
if (!user) {
if (typeof window !== "undefined") {
@@ -56,24 +36,12 @@ export default function CalendarPage() {
-
-
-
-
-
-
-
-
-
+
-
>
);
@@ -82,23 +50,22 @@ export default function CalendarPage() {
CalendarPage.getLayout = function getLayout(page: React.ReactElement) {
return (
-
- }
- rightHeaderContent={}
- >
- {page}
-
-
-
+
+
+ }
+ icon={
+
+ }
+ rightHeaderContent={}
+ >
+ {page}
+
+
+
);
};
diff --git a/src/frontend/apps/calendars/src/styles/globals.scss b/src/frontend/apps/calendars/src/styles/globals.scss
index a95b20b..e8c5fc3 100644
--- a/src/frontend/apps/calendars/src/styles/globals.scss
+++ b/src/frontend/apps/calendars/src/styles/globals.scss
@@ -8,12 +8,12 @@
@use "./../features/ui/components/generic-disclaimer/GenericDisclaimer.scss";
@use "./../features/ui/components/spinner/SpinnerPage.scss";
@use "./../features/layouts/components/left-panel/LeftPanelMobile.scss";
-@use "./../features/calendar/components/MiniCalendar.scss";
-@use "./../features/calendar/components/CalendarList.scss";
-@use "./../features/calendar/components/LeftPanel.scss";
-@use "./../features/calendar/components/EventModal.scss";
-@use "./../features/calendar/components/RecurrenceEditor.scss";
-@use "./../features/calendar/components/AttendeesInput.scss";
+@use "./../features/calendar/components/left-panel/MiniCalendar.scss";
+@use "./../features/calendar/components/calendar-list/CalendarList.scss";
+@use "./../features/calendar/components/left-panel/LeftPanel.scss";
+@use "./../features/calendar/components/scheduler/EventModal.scss";
+@use "./../features/calendar/components/scheduler/RecurrenceEditor.scss";
+@use "./../features/calendar/components/scheduler/AttendeesInput.scss";
@use "./../features/calendar/components/scheduler/Scheduler.scss";
@use "./../features/calendar/components/scheduler/scheduler-theme.scss";
@use "./../features/calendar/components/scheduler/SchedulerToolbar.scss";