From 2f7351f4fe8fc70e2669eb982dba18ab20db4509 Mon Sep 17 00:00:00 2001 From: lethemanh Date: Thu, 9 Apr 2026 09:17:42 +0700 Subject: [PATCH] #685 view more events in month view on mobile --- src/components/Calendar/Calendar.tsx | 47 ++++++++++++----- src/components/Calendar/ViewMoreEvents.tsx | 60 ++++++++++++++++++++++ 2 files changed, 95 insertions(+), 12 deletions(-) create mode 100644 src/components/Calendar/ViewMoreEvents.tsx diff --git a/src/components/Calendar/Calendar.tsx b/src/components/Calendar/Calendar.tsx index d58eaaa..c3f4351 100644 --- a/src/components/Calendar/Calendar.tsx +++ b/src/components/Calendar/Calendar.tsx @@ -11,7 +11,7 @@ import { extractEventBaseUuid } from '@/utils/extractEventBaseUuid' import { setSelectedCalendars as setSelectedCalendarsToStorage } from '@/utils/storage/setSelectedCalendars' import { useSelectedCalendars } from '@/utils/storage/useSelectedCalendars' import { browserDefaultTimeZone } from '@/utils/timezone' -import type { EventApi, LocaleInput } from '@fullcalendar/core' +import type { EventApi, LocaleInput, MoreLinkArg } from '@fullcalendar/core' import { CalendarApi, DateSelectArg } from '@fullcalendar/core' import frLocale from '@fullcalendar/core/locales/fr' import ruLocale from '@fullcalendar/core/locales/ru' @@ -46,6 +46,7 @@ import { CALENDAR_VIEWS } from './utils/constants' import Sidebar from './Sidebar/SideBar' import TempSearchDialog from './TempSearchDialog' import { setIsMobileSearchOpen } from '@/features/Calendars/CalendarSlice' +import ViewMoreEvents from './ViewMoreEvents' const localeMap: Record = { fr: frLocale, @@ -315,6 +316,18 @@ const CalendarApp: React.FC = ({ const [tempUsers, setTempUsers] = useState([]) const [tempEvent, setTempEvent] = useState({} as CalendarEvent) + const [isMoreEventsDrawerOpen, setIsMoreEventsDrawerOpen] = useState(false) + const [moreEvents, setMoreEvents] = useState([]) + + const handleMoreLinkClick = (arg: MoreLinkArg): string | void => { + if (!isMobile) return + + setMoreEvents(arg.hiddenSegs.map(seg => seg.event)) + setIsMoreEventsDrawerOpen(true) + + return 'none' + } + useEffect(() => { if (view !== 'calendar') return const targetView = @@ -447,6 +460,7 @@ const CalendarApp: React.FC = ({ timeGridWeek: { titleFormat: { month: 'long', year: 'numeric' } } }} dayMaxEvents={true} + moreLinkClick={handleMoreLinkClick} events={eventToFullCalendarFormat( filteredEvents, filteredTempEvents, @@ -614,17 +628,26 @@ const CalendarApp: React.FC = ({ {isMobile && ( - { - dispatch(setIsMobileSearchOpen(false)) - onCloseSidebar() - }} - handleToggleEventPreview={() => - eventHandlers.handleDateSelect(null as unknown as DateSelectArg) - } - /> + <> + { + dispatch(setIsMobileSearchOpen(false)) + onCloseSidebar() + }} + handleToggleEventPreview={() => + eventHandlers.handleDateSelect(null as unknown as DateSelectArg) + } + /> + setIsMoreEventsDrawerOpen(true)} + onClose={() => setIsMoreEventsDrawerOpen(false)} + moreEvents={moreEvents} + handleEventClick={eventHandlers.handleEventClick} + /> + )} ) diff --git a/src/components/Calendar/ViewMoreEvents.tsx b/src/components/Calendar/ViewMoreEvents.tsx new file mode 100644 index 0000000..cfce56d --- /dev/null +++ b/src/components/Calendar/ViewMoreEvents.tsx @@ -0,0 +1,60 @@ +import type { EventApi, EventClickArg } from '@fullcalendar/core' +import { + List, + ListItem, + SwipeableDrawer, + ListItemButton, + ListItemText, + ListItemIcon +} from '@linagora/twake-mui' +import RepeatIcon from '@mui/icons-material/Repeat' + +interface ViewMoreEventsProps { + isOpen: boolean + onOpen: () => void + onClose: () => void + moreEvents: EventApi[] + handleEventClick: (arg: EventClickArg) => void +} + +const ViewMoreEvents: React.FC = ({ + isOpen, + onOpen, + onClose, + moreEvents, + handleEventClick +}: ViewMoreEventsProps) => { + return ( + + + {moreEvents.map((event, index) => ( + + { + onClose() + handleEventClick({ + event, + jsEvent: { preventDefault: () => {} } + } as EventClickArg) + }} + > + + {event.extendedProps.recurrenceId && ( + + + + )} + + + ))} + + + ) +} + +export default ViewMoreEvents