"use client";
import { Plus, RefreshCw, X } from "lucide-react";
import { type FormEvent, type ReactNode, useState } from "react";
import { Button } from "@/components/ui/button";
import {
Dialog,
DialogClose,
DialogContent,
DialogDescription,
DialogFooter,
DialogHeader,
DialogTitle,
} from "@/components/ui/dialog";
import { Input } from "@/components/ui/input";
import { cn } from "@/lib/utils";
import {
addPatient,
type AllergySeverity,
generateFileNumber,
type Patient,
} from "@/lib/patients";
type AddPatientDialogProps = {
open: boolean;
onOpenChange: (open: boolean) => void;
onCreated: (fileNumber: string) => void;
};
type AllergyDraft = { substance: string; reaction: string; severity: AllergySeverity };
type MedicationDraft = { name: string; dose: string; frequency: string };
const controlClass =
"h-9 w-full rounded-3xl border border-transparent bg-input/50 px-3 text-sm text-foreground outline-none transition-[color,box-shadow] focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/30";
function Field({ label, children }: { label: string; children: ReactNode }) {
return (
);
}
function SectionHeader({
label,
onAdd,
}: {
label: string;
onAdd: () => void;
}) {
return (
);
}
function initialsFromName(name: string): string {
const parts = name.trim().split(/\s+/).filter(Boolean);
if (parts.length === 0) {
return "?";
}
return parts
.slice(0, 2)
.map((part) => part[0])
.join("")
.toUpperCase();
}
const today = () =>
new Date().toLocaleDateString("en-US", {
month: "short",
day: "2-digit",
year: "numeric",
});
export function AddPatientDialog({
open,
onOpenChange,
onCreated,
}: AddPatientDialogProps) {
// Lazily generate the file number on mount. The dialog is remounted (via a
// `key`) each time it opens, so this gives a fresh number + cleared form
// without a reset effect.
const [fileNumber, setFileNumber] = useState(generateFileNumber);
const [name, setName] = useState("");
const [age, setAge] = useState("");
const [sex, setSex] = useState("F");
const [status, setStatus] = useState("active");
const [pcp, setPcp] = useState("");
const [bp, setBp] = useState("");
const [hr, setHr] = useState("");
const [temp, setTemp] = useState("");
const [spo2, setSpo2] = useState("");
const [allergies, setAllergies] = useState([]);
const [medications, setMedications] = useState([]);
const handleSubmit = (event: FormEvent) => {
event.preventDefault();
if (!name.trim()) {
return;
}
const patient: Patient = {
fileNumber,
name: name.trim(),
age: Number(age) || 0,
sex,
pcp: pcp.trim() || "—",
status,
initials: initialsFromName(name),
allergies: allergies.filter((a) => a.substance.trim()),
alerts: [],
medications: medications.filter((m) => m.name.trim()),
problems: [],
vitals: {
bp: bp.trim() || "—",
hr: hr.trim() || "—",
temp: temp.trim() || "—",
spo2: spo2.trim() || "—",
takenAt: today(),
},
vitalsTrend: { label: "Heart rate", unit: "bpm", points: [] },
labs: [],
labTrend: { label: "—", unit: "", points: [] },
encounters: [],
};
addPatient(patient);
onCreated(fileNumber);
onOpenChange(false);
};
return (
);
}