Task #315: 12h time picker with explicit AM/PM (executive meetings)
Replaces native <input type="time"> in the executive-meetings editor with a TimePicker12h that always requires an explicit AM/PM choice for any 1–12 hour, fixing the "1:15 silently saved as 01:15 (AM) when user meant 13:15 (PM)" bug. Display stays compact 12h with no AM/PM marker (per #292); wire format remains canonical HH:mm 24h. What ships - src/lib/time-12h.ts: periodFromCanonical, formatCanonicalAs12h, combineTextWithPeriod (returns "ambiguous" for any unmarked 1–12 hour without a toggle pick; accepts hours 0 and 13–23 directly because they are unambiguous 24h shapes; typed marker always wins over toggle). - src/components/time-picker-12h.tsx: forwardRef component with imperative {commit, focus, select} handle, dirtyRef to avoid prop overwrite mid-edit, dir="ltr" for stable RTL layout, and Enter-on-toggle = "set AND save". - Wired into TimeRangeCell inline editor (commit-based save handles invalid/ambiguous/TimeOrderError as toasts and refocuses). - Wired into MeetingFormDialog with picker refs + handleSaveClick validation: Save button now calls commit() on both pickers, blocks on invalid/ambiguous (toast + focus offending picker), and passes canonical values straight to the parent's save handler so a stale React state batch from onChange-suppression cannot silently persist the previous value. Tests - 12 unit tests in src/__tests__/time-12h.test.mjs (incl. new "hour 0 is unambiguous, accepted without a toggle"). - 17 e2e tests in tests/executive-meetings-keyboard-editing.spec.mjs (incl. "compact + PM toggle" 0115→13:15 and "Tab walks start input → start AM/PM toggle → end input → end AM/PM toggle"). - Existing manage-create e2e suite still green. Locale keys (en + ar) - executiveMeetings.timeEditor.{am,pm,periodGroupStart,periodGroupEnd} - executiveMeetings.schedule.timeAmbiguousError Deviations from plan - Architect review #1 caught two issues that were both fixed: (1) combineTextWithPeriod treated hour 0 as ambiguous; now accepts 00:xx unambiguously. (2) MeetingFormDialog initially used pickers via value/onChange only, which left a silent-fallback hole because onChange suppresses ambiguous drafts. Added imperative refs + handleSaveClick validation; onSave signature changed to (committedStart, committedEnd) so the parent's save() can use the freshly-committed values directly. - Reverted accidental vite.config.ts typo (@replit/... was missing the leading @).
This commit is contained in:
Binary file not shown.
|
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 25 KiB |
Reference in New Issue
Block a user