From f7ec04241b6499202521c7cbc1ccd01d8dda1ad0 Mon Sep 17 00:00:00 2001 From: Kyle Pope Date: Sat, 7 Mar 2026 17:04:44 +0800 Subject: [PATCH] Phase 4: mobile polish and touch fallbacks 4a. Touch fallbacks for group-hover actions: - 9 occurrences across 5 files changed from opacity-0 group-hover:opacity-100 to opacity-100 md:opacity-0 md:group-hover:opacity-100 - CalendarSidebar (3), SharedCalendarSection (2), TaskDetailPanel (2), NotificationsPage (1), CopyableField (1) - Action buttons now always visible on touch, hover-revealed on desktop 4b. FullCalendar mobile touch: - Wheel navigation disabled on touch devices (ontouchstart check) - Prevents scroll hijacking on mobile, allows native scroll Co-Authored-By: Claude Opus 4.6 --- frontend/src/components/calendar/CalendarPage.tsx | 2 ++ frontend/src/components/calendar/CalendarSidebar.tsx | 6 +++--- frontend/src/components/calendar/SharedCalendarSection.tsx | 4 ++-- frontend/src/components/notifications/NotificationsPage.tsx | 2 +- frontend/src/components/projects/TaskDetailPanel.tsx | 4 ++-- frontend/src/components/shared/CopyableField.tsx | 2 +- 6 files changed, 11 insertions(+), 9 deletions(-) diff --git a/frontend/src/components/calendar/CalendarPage.tsx b/frontend/src/components/calendar/CalendarPage.tsx index 51262e8..b4ee310 100644 --- a/frontend/src/components/calendar/CalendarPage.tsx +++ b/frontend/src/components/calendar/CalendarPage.tsx @@ -189,6 +189,8 @@ export default function CalendarPage() { if (!el) return; let debounceTimer: ReturnType | null = null; const handleWheel = (e: WheelEvent) => { + // Skip wheel navigation on touch devices (let them scroll normally) + if ('ontouchstart' in window) return; const api = calendarRef.current?.getApi(); if (!api || api.view.type !== 'dayGridMonth') return; e.preventDefault(); diff --git a/frontend/src/components/calendar/CalendarSidebar.tsx b/frontend/src/components/calendar/CalendarSidebar.tsx index 27cd799..482c47d 100644 --- a/frontend/src/components/calendar/CalendarSidebar.tsx +++ b/frontend/src/components/calendar/CalendarSidebar.tsx @@ -131,7 +131,7 @@ const CalendarSidebar = forwardRef(functio {cal.name} @@ -184,7 +184,7 @@ const CalendarSidebar = forwardRef(functio setEditingTemplate(tmpl); setShowTemplateForm(true); }} - className="opacity-0 group-hover:opacity-100 transition-opacity duration-150 text-muted-foreground hover:text-foreground" + className="opacity-100 md:opacity-0 md:group-hover:opacity-100 transition-opacity duration-150 text-muted-foreground hover:text-foreground" > @@ -194,7 +194,7 @@ const CalendarSidebar = forwardRef(functio if (!window.confirm(`Delete template "${tmpl.name}"?`)) return; deleteTemplateMutation.mutate(tmpl.id); }} - className="opacity-0 group-hover:opacity-100 transition-opacity duration-150 text-muted-foreground hover:text-destructive" + className="opacity-100 md:opacity-0 md:group-hover:opacity-100 transition-opacity duration-150 text-muted-foreground hover:text-destructive" > diff --git a/frontend/src/components/calendar/SharedCalendarSection.tsx b/frontend/src/components/calendar/SharedCalendarSection.tsx index d42308c..b0ecee6 100644 --- a/frontend/src/components/calendar/SharedCalendarSection.tsx +++ b/frontend/src/components/calendar/SharedCalendarSection.tsx @@ -73,7 +73,7 @@ export default function SharedCalendarSection({ @@ -104,7 +104,7 @@ export default function SharedCalendarSection({ {m.calendar_name} diff --git a/frontend/src/components/notifications/NotificationsPage.tsx b/frontend/src/components/notifications/NotificationsPage.tsx index f9d6eda..7ad45f9 100644 --- a/frontend/src/components/notifications/NotificationsPage.tsx +++ b/frontend/src/components/notifications/NotificationsPage.tsx @@ -316,7 +316,7 @@ export default function NotificationsPage() { {formatDistanceToNow(new Date(notification.created_at), { addSuffix: true })} -
+
{!notification.is_read && (