Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
'use client'

/**
* Insurance-prompt card — Automation Gate P3a (#1466).
*
* A PERSISTENT, NON-BLOCKING prompt rendered above the grouped automation jobs
* while any traveler's insurance decision is still pending. It deep-links to the
* Insurance tab (?tab=insurance) — it does NOT re-implement the proposal dialog.
*
* The urgency badge is DISPLAY-ONLY (Al: purchase_window_hours never gates).
* The underlying read-model fails open to "no badge" / no card on any error, so
* this can never block the Automation tab from rendering.
*/

import * as React from 'react'
import { useRouter } from 'next/navigation'
import { Shield, ChevronRight } from 'lucide-react'
import { Button } from '@/components/ui/button'
import { useInsurancePrompt } from '@/hooks/use-automations'
import type { InsuranceUrgencyTier } from '@tailfire/shared-types/api'

interface InsurancePromptCardProps {
tripId: string
}

const URGENCY_BADGE: Record<
Exclude<InsuranceUrgencyTier, 'none'>,
{ label: string; className: string }
> = {
urgent: { label: 'Purchase window closing', className: 'bg-red-100 text-red-700' },
soon: { label: 'Purchase window soon', className: 'bg-amber-100 text-amber-700' },
}

export function InsurancePromptCard({ tripId }: InsurancePromptCardProps) {
const router = useRouter()

Check failure on line 35 in apps/admin/src/app/trips/[id]/_components/insurance-prompt-card.tsx

View workflow job for this annotation

GitHub Actions / Admin tests (informational)

src/app/trips/[id]/_components/trip-automations.spec.tsx > TripAutomations (#1049 WS-3 wiring) > flag ON (controls enabled) > confirms a per-item RELATIVE (push) reschedule from the same dialog (#1064)

Error: invariant expected app router to be mounted ❯ useRouter ../../node_modules/.pnpm/next@15.5.12_@babel+core@7.28.5_@opentelemetry+api@1.9.0_@playwright+test@1.57.0_react-_5247abed2ad5ba6994a904aa72775bd6/node_modules/next/dist/client/components/navigation.js:124:37 ❯ InsurancePromptCard src/app/trips/[id]/_components/insurance-prompt-card.tsx:35:18 ❯ renderWithHooks ../../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.development.js:15486:18 ❯ mountIndeterminateComponent ../../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.development.js:20103:13 ❯ beginWork ../../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.development.js:21626:16 ❯ beginWork$1 ../../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.development.js:27465:14 ❯ performUnitOfWork ../../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.development.js:26599:12 ❯ workLoopSync ../../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.development.js:26505:5 ❯ renderRootSync ../../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.development.js:26473:7 ❯ recoverFromConcurrentError ../../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.development.js:25889:20 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ Serialized Error: { __NEXT_ERROR_CODE: 'E238' }

Check failure on line 35 in apps/admin/src/app/trips/[id]/_components/insurance-prompt-card.tsx

View workflow job for this annotation

GitHub Actions / Admin tests (informational)

src/app/trips/[id]/_components/trip-automations.spec.tsx > TripAutomations (#1049 WS-3 wiring) > flag ON (controls enabled) > confirms a per-item reschedule with a single-job selector (#1064)

Error: invariant expected app router to be mounted ❯ useRouter ../../node_modules/.pnpm/next@15.5.12_@babel+core@7.28.5_@opentelemetry+api@1.9.0_@playwright+test@1.57.0_react-_5247abed2ad5ba6994a904aa72775bd6/node_modules/next/dist/client/components/navigation.js:124:37 ❯ InsurancePromptCard src/app/trips/[id]/_components/insurance-prompt-card.tsx:35:18 ❯ renderWithHooks ../../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.development.js:15486:18 ❯ mountIndeterminateComponent ../../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.development.js:20103:13 ❯ beginWork ../../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.development.js:21626:16 ❯ beginWork$1 ../../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.development.js:27465:14 ❯ performUnitOfWork ../../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.development.js:26599:12 ❯ workLoopSync ../../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.development.js:26505:5 ❯ renderRootSync ../../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.development.js:26473:7 ❯ recoverFromConcurrentError ../../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.development.js:25889:20 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ Serialized Error: { __NEXT_ERROR_CODE: 'E238' }

Check failure on line 35 in apps/admin/src/app/trips/[id]/_components/insurance-prompt-card.tsx

View workflow job for this annotation

GitHub Actions / Admin tests (informational)

src/app/trips/[id]/_components/trip-automations.spec.tsx > TripAutomations (#1049 WS-3 wiring) > flag ON (controls enabled) > renders a per-item Reschedule action that opens the 3-mode dialog scoped to one job (#1064)

Error: invariant expected app router to be mounted ❯ useRouter ../../node_modules/.pnpm/next@15.5.12_@babel+core@7.28.5_@opentelemetry+api@1.9.0_@playwright+test@1.57.0_react-_5247abed2ad5ba6994a904aa72775bd6/node_modules/next/dist/client/components/navigation.js:124:37 ❯ InsurancePromptCard src/app/trips/[id]/_components/insurance-prompt-card.tsx:35:18 ❯ renderWithHooks ../../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.development.js:15486:18 ❯ mountIndeterminateComponent ../../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.development.js:20103:13 ❯ beginWork ../../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.development.js:21626:16 ❯ beginWork$1 ../../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.development.js:27465:14 ❯ performUnitOfWork ../../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.development.js:26599:12 ❯ workLoopSync ../../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.development.js:26505:5 ❯ renderRootSync ../../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.development.js:26473:7 ❯ recoverFromConcurrentError ../../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.development.js:25889:20 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ Serialized Error: { __NEXT_ERROR_CODE: 'E238' }

Check failure on line 35 in apps/admin/src/app/trips/[id]/_components/insurance-prompt-card.tsx

View workflow job for this annotation

GitHub Actions / Admin tests (informational)

src/app/trips/[id]/_components/trip-automations.spec.tsx > TripAutomations (#1049 WS-3 wiring) > flag ON (controls enabled) > renders per-item Preview + unified Edit actions and opens the Edit modal

Error: invariant expected app router to be mounted ❯ useRouter ../../node_modules/.pnpm/next@15.5.12_@babel+core@7.28.5_@opentelemetry+api@1.9.0_@playwright+test@1.57.0_react-_5247abed2ad5ba6994a904aa72775bd6/node_modules/next/dist/client/components/navigation.js:124:37 ❯ InsurancePromptCard src/app/trips/[id]/_components/insurance-prompt-card.tsx:35:18 ❯ renderWithHooks ../../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.development.js:15486:18 ❯ mountIndeterminateComponent ../../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.development.js:20103:13 ❯ beginWork ../../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.development.js:21626:16 ❯ beginWork$1 ../../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.development.js:27465:14 ❯ performUnitOfWork ../../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.development.js:26599:12 ❯ workLoopSync ../../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.development.js:26505:5 ❯ renderRootSync ../../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.development.js:26473:7 ❯ recoverFromConcurrentError ../../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.development.js:25889:20 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ Serialized Error: { __NEXT_ERROR_CODE: 'E238' }

Check failure on line 35 in apps/admin/src/app/trips/[id]/_components/insurance-prompt-card.tsx

View workflow job for this annotation

GitHub Actions / Admin tests (informational)

src/app/trips/[id]/_components/trip-automations.spec.tsx > TripAutomations (#1049 WS-3 wiring) > flag ON (controls enabled) > keeps cancelled + paused jobs visible but dimmed and non-cancellable

Error: invariant expected app router to be mounted ❯ useRouter ../../node_modules/.pnpm/next@15.5.12_@babel+core@7.28.5_@opentelemetry+api@1.9.0_@playwright+test@1.57.0_react-_5247abed2ad5ba6994a904aa72775bd6/node_modules/next/dist/client/components/navigation.js:124:37 ❯ InsurancePromptCard src/app/trips/[id]/_components/insurance-prompt-card.tsx:35:18 ❯ renderWithHooks ../../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.development.js:15486:18 ❯ mountIndeterminateComponent ../../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.development.js:20103:13 ❯ beginWork ../../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.development.js:21626:16 ❯ beginWork$1 ../../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.development.js:27465:14 ❯ performUnitOfWork ../../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.development.js:26599:12 ❯ workLoopSync ../../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.development.js:26505:5 ❯ renderRootSync ../../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.development.js:26473:7 ❯ recoverFromConcurrentError ../../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.development.js:25889:20 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ Serialized Error: { __NEXT_ERROR_CODE: 'E238' }

Check failure on line 35 in apps/admin/src/app/trips/[id]/_components/insurance-prompt-card.tsx

View workflow job for this annotation

GitHub Actions / Admin tests (informational)

src/app/trips/[id]/_components/trip-automations.spec.tsx > TripAutomations (#1049 WS-3 wiring) > flag ON (controls enabled) > HIDES system status-transition jobs entirely — the advisor never sees the engine

Error: invariant expected app router to be mounted ❯ useRouter ../../node_modules/.pnpm/next@15.5.12_@babel+core@7.28.5_@opentelemetry+api@1.9.0_@playwright+test@1.57.0_react-_5247abed2ad5ba6994a904aa72775bd6/node_modules/next/dist/client/components/navigation.js:124:37 ❯ InsurancePromptCard src/app/trips/[id]/_components/insurance-prompt-card.tsx:35:18 ❯ renderWithHooks ../../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.development.js:15486:18 ❯ mountIndeterminateComponent ../../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.development.js:20103:13 ❯ beginWork ../../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.development.js:21626:16 ❯ beginWork$1 ../../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.development.js:27465:14 ❯ performUnitOfWork ../../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.development.js:26599:12 ❯ workLoopSync ../../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.development.js:26505:5 ❯ renderRootSync ../../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.development.js:26473:7 ❯ recoverFromConcurrentError ../../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.development.js:25889:20 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ Serialized Error: { __NEXT_ERROR_CODE: 'E238' }

Check failure on line 35 in apps/admin/src/app/trips/[id]/_components/insurance-prompt-card.tsx

View workflow job for this annotation

GitHub Actions / Admin tests (informational)

src/app/trips/[id]/_components/trip-automations.spec.tsx > TripAutomations (#1049 WS-3 wiring) > flag ON (controls enabled) > shows the audience badge on cards

Error: invariant expected app router to be mounted ❯ useRouter ../../node_modules/.pnpm/next@15.5.12_@babel+core@7.28.5_@opentelemetry+api@1.9.0_@playwright+test@1.57.0_react-_5247abed2ad5ba6994a904aa72775bd6/node_modules/next/dist/client/components/navigation.js:124:37 ❯ InsurancePromptCard src/app/trips/[id]/_components/insurance-prompt-card.tsx:35:18 ❯ renderWithHooks ../../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.development.js:15486:18 ❯ mountIndeterminateComponent ../../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.development.js:20103:13 ❯ beginWork ../../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.development.js:21626:16 ❯ beginWork$1 ../../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.development.js:27465:14 ❯ performUnitOfWork ../../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.development.js:26599:12 ❯ workLoopSync ../../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.development.js:26505:5 ❯ renderRootSync ../../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.development.js:26473:7 ❯ recoverFromConcurrentError ../../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.development.js:25889:20 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ Serialized Error: { __NEXT_ERROR_CODE: 'E238' }

Check failure on line 35 in apps/admin/src/app/trips/[id]/_components/insurance-prompt-card.tsx

View workflow job for this annotation

GitHub Actions / Admin tests (informational)

src/app/trips/[id]/_components/trip-automations.spec.tsx > TripAutomations (#1049 WS-3 wiring) > flag ON (controls enabled) > DEFAULTS to grouping by traveller with a Whole trip fallback

Error: invariant expected app router to be mounted ❯ useRouter ../../node_modules/.pnpm/next@15.5.12_@babel+core@7.28.5_@opentelemetry+api@1.9.0_@playwright+test@1.57.0_react-_5247abed2ad5ba6994a904aa72775bd6/node_modules/next/dist/client/components/navigation.js:124:37 ❯ InsurancePromptCard src/app/trips/[id]/_components/insurance-prompt-card.tsx:35:18 ❯ renderWithHooks ../../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.development.js:15486:18 ❯ mountIndeterminateComponent ../../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.development.js:20103:13 ❯ beginWork ../../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.development.js:21626:16 ❯ beginWork$1 ../../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.development.js:27465:14 ❯ performUnitOfWork ../../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.development.js:26599:12 ❯ workLoopSync ../../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.development.js:26505:5 ❯ renderRootSync ../../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.development.js:26473:7 ❯ recoverFromConcurrentError ../../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.development.js:25889:20 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ Serialized Error: { __NEXT_ERROR_CODE: 'E238' }

Check failure on line 35 in apps/admin/src/app/trips/[id]/_components/insurance-prompt-card.tsx

View workflow job for this annotation

GitHub Actions / Admin tests (informational)

src/app/trips/[id]/_components/trip-automations.spec.tsx > TripAutomations (#1049 WS-3 wiring) > flag ON (controls enabled) > renders the filter bar + schedule-new button

Error: invariant expected app router to be mounted ❯ useRouter ../../node_modules/.pnpm/next@15.5.12_@babel+core@7.28.5_@opentelemetry+api@1.9.0_@playwright+test@1.57.0_react-_5247abed2ad5ba6994a904aa72775bd6/node_modules/next/dist/client/components/navigation.js:124:37 ❯ InsurancePromptCard src/app/trips/[id]/_components/insurance-prompt-card.tsx:35:18 ❯ renderWithHooks ../../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.development.js:15486:18 ❯ mountIndeterminateComponent ../../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.development.js:20103:13 ❯ beginWork ../../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.development.js:21626:16 ❯ beginWork$1 ../../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.development.js:27465:14 ❯ performUnitOfWork ../../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.development.js:26599:12 ❯ workLoopSync ../../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.development.js:26505:5 ❯ renderRootSync ../../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.development.js:26473:7 ❯ recoverFromConcurrentError ../../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.development.js:25889:20 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ Serialized Error: { __NEXT_ERROR_CODE: 'E238' }

Check failure on line 35 in apps/admin/src/app/trips/[id]/_components/insurance-prompt-card.tsx

View workflow job for this annotation

GitHub Actions / Admin tests (informational)

src/app/trips/[id]/_components/trip-automations.spec.tsx > TripAutomations (#1049 WS-3 wiring) > flag OFF (v1 preserved) > renders the v1 list without the new controls

Error: invariant expected app router to be mounted ❯ useRouter ../../node_modules/.pnpm/next@15.5.12_@babel+core@7.28.5_@opentelemetry+api@1.9.0_@playwright+test@1.57.0_react-_5247abed2ad5ba6994a904aa72775bd6/node_modules/next/dist/client/components/navigation.js:124:37 ❯ InsurancePromptCard src/app/trips/[id]/_components/insurance-prompt-card.tsx:35:18 ❯ renderWithHooks ../../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.development.js:15486:18 ❯ mountIndeterminateComponent ../../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.development.js:20103:13 ❯ beginWork ../../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.development.js:21626:16 ❯ beginWork$1 ../../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.development.js:27465:14 ❯ performUnitOfWork ../../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.development.js:26599:12 ❯ workLoopSync ../../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.development.js:26505:5 ❯ renderRootSync ../../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.development.js:26473:7 ❯ recoverFromConcurrentError ../../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.development.js:25889:20 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ Serialized Error: { __NEXT_ERROR_CODE: 'E238' }
const { data } = useInsurancePrompt(tripId)

// Fail-open: no data yet, or nothing pending → render nothing (card hidden
// once every traveler's insurance is resolved).
if (!data || !data.anyPending) return null

const badge = data.urgency === 'none' ? null : URGENCY_BADGE[data.urgency]
const count = data.pendingCount
const travelerWord = count === 1 ? 'traveller' : 'travellers'

return (
<div className="flex items-start justify-between gap-3 rounded-lg border border-sky-200 bg-sky-50 px-4 py-3">
<div className="flex items-start gap-3">
<Shield className="mt-0.5 h-5 w-5 shrink-0 text-sky-600" />
<div className="space-y-0.5">
<div className="flex items-center gap-2">
<p className="text-sm font-semibold text-sky-900">Insurance not yet confirmed</p>
{badge && (
<span
className={`inline-flex items-center rounded-full px-2 py-0.5 text-xs font-medium ${badge.className}`}
>
{badge.label}
</span>
)}
</div>
<p className="text-xs text-sky-700">
{count} {travelerWord} still {count === 1 ? 'needs' : 'need'} an insurance decision.
Confirm coverage, record their own policy, or log a declination on the Insurance tab.
</p>
</div>
</div>
<Button
size="sm"
variant="outline"
className="shrink-0 gap-1 border-sky-300 bg-white text-sky-800 hover:bg-sky-100"
onClick={() => router.push(`/trips/${tripId}?tab=insurance`)}
>
Review insurance
<ChevronRight className="h-4 w-4" />
</Button>
</div>
)
}
20 changes: 15 additions & 5 deletions apps/admin/src/app/trips/[id]/_components/trip-automations.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import {
import { AutomationScheduleDialog } from './automation-schedule-dialog'
import { AutomationRecalibrateButton } from './automation-recalibrate-button'
import { AutomationTasksSection } from './automation-tasks-section'
import { InsurancePromptCard } from './insurance-prompt-card'
import {
useTripAutomations,
usePauseAutomation,
Expand Down Expand Up @@ -364,13 +365,19 @@ export function TripAutomations({ trip }: TripAutomationsProps) {
}

// Flag OFF + no jobs → exact v1 empty state (no header), keeping v1 inert.
// The insurance prompt (#1466 P3a) is NOT gated by the automation-control flag —
// it renders above the empty state whenever a traveler's insurance is pending,
// and returns null otherwise (so the flag-off/no-pending case stays byte-identical).
if (!controlsEnabled && sortedJobs.length === 0) {
return (
<EmptyState
icon={<Zap className="h-6 w-6" />}
title="No automation jobs yet"
description="Jobs will appear here when you initiate insurance proposals or other automated workflows."
/>
<div className="space-y-4">
<InsurancePromptCard tripId={trip.id} />
<EmptyState
icon={<Zap className="h-6 w-6" />}
title="No automation jobs yet"
description="Jobs will appear here when you initiate insurance proposals or other automated workflows."
/>
</div>
Comment on lines +368 to +380

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Wiring InsurancePromptCard breaks the existing trip-automations.spec.tsx suite (confirmed by CI logs).

InsurancePromptCard calls useRouter() unconditionally, and rendering it here now throws invariant expected app router to be mounted in ~10 previously-passing tests, since the existing test setup doesn't provide a Next.js App Router context. This is a real regression that needs to be fixed as part of this PR (e.g. mock next/navigation's useRouter in the spec's render helper), not just an "informational" pipeline note.

🔧 Suggested test-setup fix (in trip-automations.spec.tsx)
+jest.mock('next/navigation', () => ({
+  useRouter: () => ({ push: jest.fn(), replace: jest.fn(), back: jest.fn() }),
+}))

Also applies to: 514-516

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/admin/src/app/trips/`[id]/_components/trip-automations.tsx around lines
368 - 380, The new InsurancePromptCard render in trip-automations.tsx is causing
tests to fail because it unconditionally uses useRouter without an App Router
context. Update trip-automations.spec.tsx (and its shared render helper) to mock
next/navigation’s useRouter or otherwise provide a router context so the
InsurancePromptCard path can render safely; use InsurancePromptCard,
trip-automations.spec.tsx, and the render helper as the main points to patch.

Source: Pipeline failures

)
}

Expand Down Expand Up @@ -504,6 +511,9 @@ export function TripAutomations({ trip }: TripAutomationsProps) {
{renderHeader()}
{renderFilterBar()}

{/* #1466 P3a — persistent, non-blocking insurance prompt above the jobs. */}
<InsurancePromptCard tripId={trip.id} />

{pendingReview.length > 0 &&
renderGroup(
'__pending_review__',
Expand Down
18 changes: 18 additions & 0 deletions apps/admin/src/hooks/use-automations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import type {
CreateAdHocAutomationParams,
EditAutomationContent,
ExecuteNowResult,
InsurancePromptDto,
JobIdentity,
JobSelector,
RescheduleMode,
Expand All @@ -48,6 +49,7 @@ export type {
ReconcileApplyItem,
ReconcileApplyRequest,
ReconcileApplyResponse,
InsurancePromptDto,
JobIdentity,
JobSelector,
RescheduleMode,
Expand Down Expand Up @@ -147,6 +149,8 @@ export const tripAutomationKeys = {
list: (tripId: string) => [...tripAutomationKeys.all, tripId] as const,
insurancePreview: (tripId: string) =>
[...tripAutomationKeys.all, 'insurance-preview', tripId] as const,
insurancePrompt: (tripId: string) =>
[...tripAutomationKeys.all, 'insurance-prompt', tripId] as const,
contentPreview: (tripId: string, queueName: string, jobId: string) =>
[...tripAutomationKeys.all, 'content-preview', tripId, queueName, jobId] as const,
reconcilePreview: (tripId: string) =>
Expand Down Expand Up @@ -208,6 +212,20 @@ export function useInsurancePreview(tripId: string, enabled = true) {
})
}

/**
* Fetch the non-blocking insurance-prompt read-model (#1466 P3a). Drives the
* persistent prompt card in the Automation tab: `anyPending` toggles the card,
* `urgency` is a DISPLAY badge only. Read-only; the endpoint fails open to an
* empty read-model, so this never blocks the tab render.
*/
export function useInsurancePrompt(tripId: string, enabled = true) {
return useQuery({
queryKey: tripAutomationKeys.insurancePrompt(tripId),
queryFn: () => api.get<InsurancePromptDto>(`/trips/${tripId}/automations/insurance-prompt`),
enabled: !!tripId && enabled,
})
}

/**
* Resolve the channel-aware rendered content of a queued/paused job for the
* preview pane + the edit modal's seed (WS-2 content-preview). Read-only:
Expand Down
Loading
Loading