import React, { useState, useEffect } from 'react' import { Briefcase, PlaneTakeoff, PlaneLanding, AlertTriangle, Activity, RotateCw, X, Filter } from 'lucide-react' import { fetchEntries } from '../lib/pocketbase.js' const STATUS_META = { 'in-transit': { label: 'In Transit', className: 'status-in-transit' }, 'at-risk': { label: 'At Risk', className: 'status-at-risk' }, 'post-travel': { label: 'Post-Travel', className: 'status-post-travel' }, 'pre-travel': { label: 'Pre-Travel', className: 'status-pre-travel' }, } function getGreeting() { const h = new Date().getHours() if (h < 12) return 'Good morning' if (h < 17) return 'Good afternoon' return 'Good evening' } /** * Dashboard — main content viewport for CTM Concierge. * Shows real-time stat cards and a patient journey table powered by PocketBase. */ export default function Dashboard() { const [travellers, setTravellers] = useState([]) const [loading, setLoading] = useState(true) const [error, setError] = useState(null) const [selectedStatus, setSelectedStatus] = useState('all') const today = new Date().toLocaleDateString('en-US', { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric', }) async function loadData() { setLoading(true) setError(null) try { const data = await fetchEntries() setTravellers(data || []) } catch (err) { setError(err.message || 'Unable to connect to PocketBase backend.') } finally { setLoading(false) } } useEffect(() => { loadData() }, []) const preTravelCount = travellers.filter((t) => t.status === 'pre-travel').length const inTransitCount = travellers.filter((t) => t.status === 'in-transit').length const atRiskCount = travellers.filter((t) => t.status === 'at-risk').length const postTravelCount = travellers.filter((t) => t.status === 'post-travel').length const filteredTravellers = selectedStatus === 'all' ? travellers : travellers.filter((t) => t.status === selectedStatus) const stats = [ { id: 'pre-travel', icon: Briefcase, value: preTravelCount, label: 'In Pre-Travel', accent: 'violet' }, { id: 'in-transit', icon: PlaneTakeoff, value: inTransitCount, label: 'In Transit', accent: 'blue' }, { id: 'at-risk', icon: AlertTriangle, value: atRiskCount, label: 'At Risk', accent: 'amber' }, { id: 'post-travel', icon: PlaneLanding, value: postTravelCount, label: 'In Post-Travel', accent: 'teal' }, ] return (
{/* ── Header ─────────────────────────────────────────────────────────── */}

{getGreeting()}

Patient Trip Overview

{today}

{/* ── Error Banner ────────────────────────────────────────────────────── */} {error ? (

PocketBase Connection Error

{error}

) : ( <> {/* ── Stat Cards ─────────────────────────────────────────────────────── */}
{stats.map((stat) => { const Icon = stat.icon const isActive = selectedStatus === stat.id return (
setSelectedStatus(isActive ? 'all' : stat.id)} role="button" tabIndex={0} onKeyDown={(e) => { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault() setSelectedStatus(isActive ? 'all' : stat.id) } }} aria-pressed={isActive} aria-label={`Filter by ${stat.label}`} >
) })}
{/* ── Patient Journey Table ───────────────────────────────────────────── */}

Live Patient Board {selectedStatus !== 'all' && ( {STATUS_META[selectedStatus]?.label || selectedStatus} ({filteredTravellers.length} of {travellers.length}) )}

{selectedStatus !== 'all' && ( )}
{travellers.length === 0 && !loading ? ( ) : filteredTravellers.length === 0 ? ( ) : ( filteredTravellers.map((p) => { const meta = STATUS_META[p.status] || STATUS_META['pre-travel'] return ( ) }) )}
EMR ID Name Location Departure Arrival Status
No travellers found in PocketBase database.
No patients found matching status "{STATUS_META[selectedStatus]?.label || selectedStatus}".
{p.emrID} {p.name} {p.location || 'N/A'} {new Date(p.departure).toLocaleDateString('en-US', { month: 'short', day: 'numeric', year: 'numeric', })} {new Date(p.arrival).toLocaleDateString('en-US', { month: 'short', day: 'numeric', year: 'numeric', })} {meta.label}
)}
) }