import type { TourListItem } from '@trek/shared'; import { AlertTriangle } from 'lucide-react'; import { useId, useMemo } from 'react'; import type { Assignment } from '../../types'; import CustomTimePicker from '../shared/CustomTimePicker'; import { EditorField, GRID_2 } from '../shared/dialogParts'; import { fs } from '../shared/DialogShell'; import { TourEndHint } from '../Tours/TourDayTimeParts'; import { timeCollisions, type PlaceFormData } from './PlaceFormModal.helpers'; type Translate = (key: string, params?: Record) => string; const WARNING_BANNER = 'flex items-start gap-1.5 rounded-[10px] bg-warning-soft px-2.5 py-1.5 text-warning'; interface TimeSectionProps { form: PlaceFormData; handleChange: (field: string, value: string) => void; assignmentId: number | null; dayAssignments: Assignment[]; hasTimeError: boolean; /** On a road trip the End is when the drive leaves, which the field says. In Days it * stays the plain label it has always been: nothing is scheduled off it there. */ endIsLeave: boolean; /** TIME-02: the tour this place is, whose end the time fields work out from its start. */ tour?: TourListItem | null; t: Translate; } /** The place form's start and end time, with the warnings about them and a tour's worked-out end. */ export function TimeSection({ form, handleChange, assignmentId, dayAssignments, hasTimeError, endIsLeave, tour, t, }: TimeSectionProps) { const collisions = useMemo( () => timeCollisions(assignmentId, dayAssignments, form.place_time, form.end_time), [assignmentId, dayAssignments, form.place_time, form.end_time] ); const errorId = useId(); return (
handleChange('place_time', v)} aria-label={t('places.startTime')} /> handleChange('end_time', v)} aria-label={t('places.endTime')} aria-invalid={hasTimeError} aria-describedby={hasTimeError ? errorId : undefined} />
a.id === assignmentId)} tour={tour} /> {hasTimeError && (
)} {collisions.length > 0 && (
)}
); }