'use client' import { useEffect, useRef, useState } from 'react' import { Button } from '@/components/ui/button' import { Input } from '@/components/ui/input' import { Badge } from '@/components/ui/badge' import { trackIncident } from '@/lib/actions' import type { PublicIncidentView } from '@/lib/incident-logic' export function TrackClient({ initialToken, autoSubmit, }: { initialToken: string autoSubmit: boolean }) { const [token, setToken] = useState(initialToken) const [loading, setLoading] = useState(false) const [error, setError] = useState(null) const [view, setView] = useState(null) const didAuto = useRef(false) async function lookup(t: string) { setError(null) setView(null) setLoading(true) const res = await trackIncident({ token: t.trim() }) setLoading(false) if ('error' in res && res.error) { setError(res.error) return } setView(res.data ?? null) } useEffect(() => { if (autoSubmit && initialToken && !didAuto.current) { didAuto.current = true lookup(initialToken) } // eslint-disable-next-line react-hooks/exhaustive-deps }, []) return (
{ e.preventDefault() if (token.trim()) lookup(token) }} className="flex gap-2" > setToken(e.target.value)} placeholder="Tracking code" aria-label="Tracking code" className="font-mono" />
{error &&

{error}

} {view && (

{view.title}

{view.statusLabel} {view.severity}

{view.body}

Filed
{new Date(view.createdAt).toLocaleString()}
{view.acknowledgedAt && ( <>
Acknowledged
{new Date(view.acknowledgedAt).toLocaleString()}
)} {view.decidedAt && ( <>
Decided
{new Date(view.decidedAt).toLocaleString()}
)} {view.closedAt && ( <>
Closed
{new Date(view.closedAt).toLocaleString()}
)}
{view.disposition && (

Outcome

{view.disposition}

)}

Updates

{view.updates.length === 0 ? (

No updates yet.

) : (
    {view.updates.map((u, i) => (
  • {u.body}

    {u.author} · {new Date(u.createdAt).toLocaleString()}

  • ))}
)}
)}
) }