"use client"; import { Cable, RefreshCw, Search } from "lucide-react"; import { useEffect, useMemo, useState } from "react"; import { useTranslation } from "react-i18next"; import { Avatar, AvatarFallback } from "@/components/ui/avatar"; import { Badge } from "@/components/ui/badge"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; import { ApiError } from "@/lib/api-client"; import { getIntegration, type IntegrationConfig, syncFhirLabs, } from "@/lib/integrations"; import type { Patient } from "@/lib/patients"; import { notify } from "@/lib/toast"; import { cn } from "@/lib/utils"; // The Lab page's HL7/FHIR connection panel: shows the connection status and, when // enabled, lets staff pull a patient's results from the configured lab system. export function LabIntegrationCard({ patients, onSynced, }: { patients: Patient[]; onSynced: () => void; }) { const { t } = useTranslation(); const [config, setConfig] = useState(null); const [query, setQuery] = useState(""); const [selected, setSelected] = useState(null); const [syncing, setSyncing] = useState(false); useEffect(() => { let active = true; getIntegration("fhir").then((c) => active && setConfig(c)); return () => { active = false; }; }, []); const search = query.trim().toLowerCase(); const matches = useMemo(() => { if (!search) return []; return patients .filter( (p) => p.name.toLowerCase().includes(search) || p.fileNumber.includes(search), ) .slice(0, 5); }, [patients, search]); // Hide entirely until we know the config (avoids a flash); render a muted // "configure me" card when present but disabled. if (!config) return null; const sync = async () => { if (!selected) return; setSyncing(true); try { const { imported } = await syncFhirLabs(selected.fileNumber); notify.success( t("integrations.fhir.syncedTitle"), t("integrations.fhir.syncedBody", { count: imported, name: selected.name, }), ); setSelected(null); setQuery(""); onSynced(); } catch (err) { notify.error( t("integrations.fhir.failedTitle"), err instanceof ApiError ? err.message : t("integrations.fhir.failedBody"), ); } finally { setSyncing(false); } }; return (

{t("integrations.fhir.cardTitle")}

{t(`settings.integrations.status.${config.status}`)}
{!config.enabled ? (

{t("integrations.fhir.disabledHint")}

) : selected ? (
{selected.initials}
{selected.name} #{selected.fileNumber}
) : (
setQuery(e.target.value)} placeholder={t("integrations.fhir.searchPlaceholder")} value={query} />
{matches.length > 0 && (
{matches.map((p) => ( ))}
)}
)}
); }