import { useState } from "react"; import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; import { Label } from "@/components/ui/label"; import { Badge } from "@/components/ui/badge"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from "@/components/ui/select"; import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogFooter, } from "@/components/ui/dialog"; import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow, } from "@/components/ui/table"; import { Switch } from "@/components/ui/switch"; import { Plus, Pencil, Trash2, Link2 } from "lucide-react"; type BridgeCategory = | "imaging" | "xray" | "perio" | "lab" | "prescription" | "billing" | "other"; interface ProgramBridge { id: number; name: string; category: BridgeCategory; executablePath: string; arguments: string; enabled: boolean; notes: string; } const CATEGORY_LABELS: Record = { imaging: "3D / CBCT Imaging", xray: "Digital X-Ray", perio: "Perio Charting", lab: "Lab Software", prescription: "e-Prescriptions", billing: "Billing / Clearinghouse", other: "Other", }; const CATEGORY_COLORS: Record = { imaging: "bg-purple-100 text-purple-700 border-purple-200", xray: "bg-blue-100 text-blue-700 border-blue-200", perio: "bg-green-100 text-green-700 border-green-200", lab: "bg-orange-100 text-orange-700 border-orange-200", prescription: "bg-rose-100 text-rose-700 border-rose-200", billing: "bg-amber-100 text-amber-700 border-amber-200", other: "bg-gray-100 text-gray-600 border-gray-200", }; const COMMON_PROGRAMS = [ "DEXIS", "Sidexis", "Schick CDR", "Apteryx XVWeb", "Carestream CS Imaging", "Dolphin Imaging", "i-CAT Vision", "Romexis", "EagleSoft", "Dentrix", "Eaglesoft Perio", "Florida Probe", "PerioVision", "DrFirst Rcopia", "NewCrop eRx", "DentalConnect", "Custom", ]; let nextId = 1; const newBridge = (): ProgramBridge => ({ id: nextId++, name: "", category: "other", executablePath: "", arguments: "", enabled: true, notes: "", }); export function ProgramBridgeTable() { const [bridges, setBridges] = useState([]); const [dialogOpen, setDialogOpen] = useState(false); const [editing, setEditing] = useState(newBridge()); const openAdd = () => { setEditing(newBridge()); setDialogOpen(true); }; const openEdit = (bridge: ProgramBridge) => { setEditing({ ...bridge }); setDialogOpen(true); }; const handleSave = () => { setBridges((prev) => { const idx = prev.findIndex((b) => b.id === editing.id); if (idx >= 0) { const next = [...prev]; next[idx] = editing; return next; } return [...prev, editing]; }); setDialogOpen(false); }; const handleDelete = (id: number) => { setBridges((prev) => prev.filter((b) => b.id !== id)); }; const toggleEnabled = (id: number) => { setBridges((prev) => prev.map((b) => (b.id === id ? { ...b, enabled: !b.enabled } : b)) ); }; const enabledCount = bridges.filter((b) => b.enabled).length; return (
Program Bridge {bridges.length > 0 && ( {enabledCount} / {bridges.length} active )}
On Program Category Executable Path Arguments Actions {bridges.length === 0 ? (
No program bridges configured. Click "Add Bridge" to connect external software.
) : ( bridges.map((bridge) => ( toggleEnabled(bridge.id)} className="scale-75" />

{bridge.name}

{bridge.notes && (

{bridge.notes}

)}
{CATEGORY_LABELS[bridge.category]} {bridge.executablePath || "—"} {bridge.arguments || "—"}
)) )}
Program Bridge
{editing.name === "Custom" && ( setEditing((d) => ({ ...d, name: e.target.value }))} /> )}
setEditing((d) => ({ ...d, executablePath: e.target.value }))} className="h-9 text-sm font-mono" />
setEditing((d) => ({ ...d, arguments: e.target.value }))} className="h-9 text-sm font-mono" />
setEditing((d) => ({ ...d, notes: e.target.value }))} className="h-9 text-sm" />
setEditing((d) => ({ ...d, enabled: v }))} />
); }