style(13-03): apply Prettier formatting across repo

Mechanical reformat — no logic changes. 398 files changed, 19125
insertions(+), 16457 deletions(-). Prettier 3.8.4 with .prettierrc
(singleQuote:true, semi:true, tabWidth:2, trailingComma:all,
printWidth:100). Isolated per D-13-08 for reviewability.
This commit is contained in:
Lucas Berger
2026-06-11 20:35:18 -04:00
parent 4bc0445173
commit 982438dc10
398 changed files with 19050 additions and 16382 deletions
+59 -65
View File
@@ -22,26 +22,26 @@
* - aria-modal="true", role="dialog"
*/
import { useEffect, useRef } from 'react'
import { useQueryClient } from '@tanstack/react-query'
import { MapPin, Edit2, Trash2 } from 'lucide-react'
import { useCalendarStore } from '../store/calendarStore.js'
import type { CalendarOccurrence } from '../api/client.js'
import { useEffect, useRef } from 'react';
import { useQueryClient } from '@tanstack/react-query';
import { MapPin, Edit2, Trash2 } from 'lucide-react';
import { useCalendarStore } from '../store/calendarStore.js';
import type { CalendarOccurrence } from '../api/client.js';
// ── Types ──────────────────────────────────────────────────────────────────
/** Shape of props passed by Schedule-X customComponents.eventModal */
interface ScheduleXEventModalProps {
calendarEvent?: {
id?: string | number
title?: string
start?: unknown
end?: unknown
calendarId?: string
location?: string
description?: string
_familySync?: { uid: string; color: string; isShared: boolean }
}
id?: string | number;
title?: string;
start?: unknown;
end?: unknown;
calendarId?: string;
location?: string;
description?: string;
_familySync?: { uid: string; color: string; isShared: boolean };
};
}
// ── Helpers ────────────────────────────────────────────────────────────────
@@ -58,41 +58,41 @@ function formatDateTime(start: string, end: string, allDay: boolean): string {
if (allDay) {
// YYYY-MM-DD — format as a date without time
try {
const d = new Date(start + 'T00:00:00')
const d = new Date(start + 'T00:00:00');
return d.toLocaleDateString(undefined, {
weekday: 'short',
year: 'numeric',
month: 'long',
day: 'numeric',
})
});
} catch {
return start
return start;
}
}
// Timed — parse offset-aware ISO string.
// Strip trailing IANA bracket e.g. '[America/Toronto]' before passing to new Date():
// new Date() cannot parse the bracket notation and returns Invalid Date.
try {
const cleanStart = start.replace(/\[[^\]]*\]$/, '')
const cleanEnd = end.replace(/\[[^\]]*\]$/, '')
const startDate = new Date(cleanStart)
const endDate = new Date(cleanEnd)
const cleanStart = start.replace(/\[[^\]]*\]$/, '');
const cleanEnd = end.replace(/\[[^\]]*\]$/, '');
const startDate = new Date(cleanStart);
const endDate = new Date(cleanEnd);
const dateStr = startDate.toLocaleDateString(undefined, {
weekday: 'short',
month: 'long',
day: 'numeric',
})
});
const startTime = startDate.toLocaleTimeString(undefined, {
hour: 'numeric',
minute: '2-digit',
})
});
const endTime = endDate.toLocaleTimeString(undefined, {
hour: 'numeric',
minute: '2-digit',
})
return `${dateStr}, ${startTime} ${endTime}`
});
return `${dateStr}, ${startTime} ${endTime}`;
} catch {
return start
return start;
}
}
@@ -106,65 +106,65 @@ function formatDateTime(start: string, end: string, allDay: boolean): string {
* In standalone mode it resolves the event from TanStack Query cache.
*/
export function EventDetailPopover(props: ScheduleXEventModalProps = {}) {
const { openEventId, setOpenEventId } = useCalendarStore()
const setEventForm = useCalendarStore((s) => s.setEventForm)
const setDeleteDialog = useCalendarStore((s) => s.setDeleteDialog)
const queryClient = useQueryClient()
const dialogRef = useRef<HTMLDivElement>(null)
const { openEventId, setOpenEventId } = useCalendarStore();
const setEventForm = useCalendarStore((s) => s.setEventForm);
const setDeleteDialog = useCalendarStore((s) => s.setDeleteDialog);
const queryClient = useQueryClient();
const dialogRef = useRef<HTMLDivElement>(null);
// Resolve the event to display:
// 1. If Schedule-X passed a calendarEvent prop, use it to get the id
// 2. Otherwise use Zustand openEventId
const activeId: string | null = (() => {
if (props.calendarEvent?.id != null) {
return String(props.calendarEvent.id)
return String(props.calendarEvent.id);
}
return openEventId
})()
return openEventId;
})();
// Lookup the occurrence in TanStack Query cache.
// We search all 'events' query entries for a matching id.
const occurrence: CalendarOccurrence | null = (() => {
if (!activeId) return null
if (!activeId) return null;
// queryClient.getQueriesData returns [{queryKey, data}] entries
const allEntries = queryClient.getQueriesData<{ occurrences: CalendarOccurrence[] }>({
queryKey: ['events'],
})
});
for (const [, data] of allEntries) {
if (!data?.occurrences) continue
const found = data.occurrences.find((o) => o.id === activeId)
if (found) return found
if (!data?.occurrences) continue;
const found = data.occurrences.find((o) => o.id === activeId);
if (found) return found;
}
return null
})()
return null;
})();
// Close handler
const handleClose = () => setOpenEventId(null)
const handleClose = () => setOpenEventId(null);
// Escape key listener — add to document so it works even when focus is trapped
useEffect(() => {
if (!activeId) return
if (!activeId) return;
const onKeyDown = (e: KeyboardEvent) => {
if (e.key === 'Escape') {
handleClose()
handleClose();
}
}
document.addEventListener('keydown', onKeyDown)
return () => document.removeEventListener('keydown', onKeyDown)
}, [activeId]) // eslint-disable-line react-hooks/exhaustive-deps
};
document.addEventListener('keydown', onKeyDown);
return () => document.removeEventListener('keydown', onKeyDown);
}, [activeId]); // eslint-disable-line react-hooks/exhaustive-deps
// Focus trap — when popover opens, focus the dialog
useEffect(() => {
if (activeId && dialogRef.current) {
dialogRef.current.focus()
dialogRef.current.focus();
}
}, [activeId])
}, [activeId]);
// Nothing to show
if (!activeId || !occurrence) return null
if (!activeId || !occurrence) return null;
// Responsive: detect phone breakpoint
const isPhone = typeof window !== 'undefined' && window.matchMedia('(max-width: 767px)').matches
const isPhone = typeof window !== 'undefined' && window.matchMedia('(max-width: 767px)').matches;
const dialogStyle: React.CSSProperties = isPhone
? {
@@ -198,7 +198,7 @@ export function EventDetailPopover(props: ScheduleXEventModalProps = {}) {
overflowY: 'auto',
zIndex: 200,
fontFamily: 'var(--font-family-base)',
}
};
return (
<>
@@ -316,11 +316,7 @@ export function EventDetailPopover(props: ScheduleXEventModalProps = {}) {
fontFamily: 'var(--font-family-base)',
}}
>
<MapPin
size={14}
style={{ flexShrink: 0, marginTop: '2px' }}
aria-hidden="true"
/>
<MapPin size={14} style={{ flexShrink: 0, marginTop: '2px' }} aria-hidden="true" />
{/* Plain text — XSS guard */}
<span>{occurrence.location}</span>
</div>
@@ -374,9 +370,7 @@ export function EventDetailPopover(props: ScheduleXEventModalProps = {}) {
{/* Plain text — XSS guard (T-02e-01).
Show 'Family' for shared-calendar events; owner display name for personal
events; fall back to calendarName when ownerName is null. */}
{occurrence.isShared
? 'Family'
: (occurrence.ownerName ?? occurrence.calendarName)}
{occurrence.isShared ? 'Family' : (occurrence.ownerName ?? occurrence.calendarName)}
</div>
{/* Phase 3 footer: Edit / Delete actions (D-10) */}
@@ -394,8 +388,8 @@ export function EventDetailPopover(props: ScheduleXEventModalProps = {}) {
<button
aria-label="Edit event"
onClick={() => {
setEventForm(true, 'edit', occurrence.uid)
setOpenEventId(null)
setEventForm(true, 'edit', occurrence.uid);
setOpenEventId(null);
}}
style={{
background: 'none',
@@ -424,7 +418,7 @@ export function EventDetailPopover(props: ScheduleXEventModalProps = {}) {
<button
aria-label="Delete event"
onClick={() => {
setDeleteDialog(true, occurrence.uid)
setDeleteDialog(true, occurrence.uid);
}}
style={{
background: 'none',
@@ -451,5 +445,5 @@ export function EventDetailPopover(props: ScheduleXEventModalProps = {}) {
</div>
</div>
</>
)
);
}