frontend: safe fixes from the #109 punch-list #113

Merged
logan merged 1 commits from fix/frontend-punchlist-batch into main 2026-09-07 00:13:36 -04:00
Owner

The trivially-safe items from server-26 #109. Untypechecked (no node/npm in authoring env); next build in deploy.yml gates it.

  • CallSpineEntry.tsx — drop the dead hasAudio prop + the return null that sat between hooks in InlinePlayer (React #310 risk; parent already gates the mount).
  • NodeCard.tsx + nodes/page.tsx — pending-node card double-fire. NodeCard gains linkToDetail (default true); pending branch passes false so the wrapper onClick (open config modal) isn't swallowed by the inner <Link>. preventDefault doesn't work here — Next's Link handler runs first.
  • trips/page.tsx — TripCard badge buckets on end_date >= today to match the list split.
  • trips/page.tsx, NodeConfigModal.tsx, nodes/[id]/page.tsx — tall modals get p-4 overlay + max-h-[90vh] overflow-y-auto panel.
  • lib/types.ts — IncidentRecord.units/vehicles optional (Firestore omits them on older docs); incidents/[id] gains ?? [].

Higher-risk to confirm on a real typecheck: the vehicles narrowing in incidents/[id]/page.tsx, the body JSX extraction in NodeCard.tsx.

🤖 Generated with Claude Code

The trivially-safe items from server-26 #109. **Untypechecked** (no node/npm in authoring env); `next build` in `deploy.yml` gates it. - **`CallSpineEntry.tsx`** — drop the dead `hasAudio` prop + the `return null` that sat between hooks in `InlinePlayer` (React #310 risk; parent already gates the mount). - **`NodeCard.tsx` + `nodes/page.tsx`** — pending-node card double-fire. `NodeCard` gains `linkToDetail` (default true); pending branch passes false so the wrapper `onClick` (open config modal) isn't swallowed by the inner `<Link>`. `preventDefault` doesn't work here — Next's Link handler runs first. - **`trips/page.tsx`** — `TripCard` badge buckets on `end_date >= today` to match the list split. - **`trips/page.tsx`, `NodeConfigModal.tsx`, `nodes/[id]/page.tsx`** — tall modals get `p-4` overlay + `max-h-[90vh] overflow-y-auto` panel. - **`lib/types.ts`** — `IncidentRecord.units`/`vehicles` optional (Firestore omits them on older docs); `incidents/[id]` gains `?? []`. Higher-risk to confirm on a real typecheck: the `vehicles` narrowing in `incidents/[id]/page.tsx`, the `body` JSX extraction in `NodeCard.tsx`. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
logan added 1 commit 2026-09-07 00:07:57 -04:00
- CallSpineEntry.tsx: drop the dead `hasAudio` prop + the early `return null`
  that sat between hooks in InlinePlayer (React #310 risk). Parent already
  gates the mount on audio presence.
- NodeCard.tsx + nodes/page.tsx: pending-node card no longer double-fires.
  NodeCard gains `linkToDetail` (default true); the pending branch passes
  false so the wrapping onClick (open config modal) isn't swallowed by the
  inner <Link> navigation. List view unchanged.
- trips/page.tsx: TripCard badge now buckets on end_date >= today, matching
  the list's own upcoming/past split — an in-progress trip no longer shows a
  "Past" badge under "Upcoming".
- trips/page.tsx, NodeConfigModal.tsx, nodes/[id]/page.tsx: tall modals get
  `p-4` on the overlay + `max-h-[90vh] overflow-y-auto` on the panel so they
  don't clip on short viewports (incidents' CreateModal pattern).
- lib/types.ts: IncidentRecord.units / vehicles are optional now, matching
  Firestore (older docs omit them); incidents/[id] gains a `?? []` guard.

Untypechecked (no node/npm locally). next build in deploy.yml gates it.
Full list of remaining items in server-26 #109.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
logan merged commit a739fa64f0 into main 2026-09-07 00:13:36 -04:00
Sign in to join this conversation.