import { useState, useCallback, useRef } from "react"; import { SignIn, UserButton, OrganizationSwitcher, useAuth } from "@clerk/react"; import { ThemeProvider } from "./ThemeProvider"; import Sidebar from "./components/Sidebar"; import StatCard from "./components/StatCard"; import WorklistTable from "./components/WorklistTable"; import CSVImport from "./components/CSVImport"; import CSVExport from "./components/CSVExport"; import ThemeToggle from "./components/ThemeToggle"; import Toast from "./components/Toast"; import { showToast } from "./lib/toast"; import { uploadToBackend, apiRecordToLocal } from "./lib/api"; import { parseCSV, processBatch } from "./lib/coverage"; function AppInner() { const { getToken } = useAuth(); const [records, setRecords] = useState([]); const [batchId, setBatchId] = useState(null); const [activeFilter, setActiveFilter] = useState("all"); const [importLabel, setImportLabel] = useState("No data imported"); const csvImportRef = useRef(null); const ooc = records.filter((r) => r.flag === "OUT_OF_COVERAGE").length; const visitDue = records.filter((r) => r.flag === "VISIT_DUE").length; const refill = records.filter((r) => r.flag === "REFILL_WINDOW").length; const okCount = records.filter((r) => r.flag === "OK").length; const urgent = ooc + visitDue; const handleResults = useCallback(async (file) => { const label = new Date().toLocaleDateString("en-US", { month: "short", day: "numeric", year: "numeric", }); const token = await getToken().catch(() => null); const data = await uploadToBackend(file, token); if (data) { const results = data.records.map(apiRecordToLocal); setRecords(results); setBatchId(data.batch_id || null); setImportLabel(`${file.name} · ${label} · via Signal API`); let msg = `Loaded ${data.total} patient${data.total !== 1 ? "s" : ""} from ${file.name}`; if (data.skipped) msg += ` · ${data.skipped} skipped`; showToast(msg); return; } // Backend unreachable — process locally setBatchId(null); const reader = new FileReader(); reader.onload = (e) => { const rows = parseCSV(e.target.result); const { results, skipped } = processBatch(rows); setRecords(results); setImportLabel(`${file.name} · ${label} · local processing`); let msg = `Loaded ${results.length} patient${results.length !== 1 ? "s" : ""} from ${file.name}`; if (skipped.length) msg += ` · ${skipped.length} skipped`; showToast(msg); }; reader.readAsText(file); }, [getToken]); return (
{/* Sidebar */} csvImportRef.current?.trigger()} /> {/* Hidden CSV import trigger */} {/* Main */}
{/* Topbar */}

Outreach Worklist

{importLabel}
{/* Content */}
{/* Stats row */}
{/* Worklist */}
); } export default function App() { const { isSignedIn, isLoaded } = useAuth(); if (!isLoaded) { return
; } if (!isSignedIn) { return (
); } return ( ); }