feat(patients): drop phone/dateOfBirth, name fields optional

Reduced the patient record to the minimum a dental clinic actually needs:
just a code, optional first/last name and free-text notes. Phone and
date-of-birth fields are gone from the UI everywhere — Add form, edit
dialog inside the table, the Bağlantı Bilgileri block on job detail, and
the table column list. The patient list now surfaces 'Notlar' instead.

Backend
  - DB: firstName and lastName columns set to required=false via Appwrite
    MCP (tables_db_update_string_column). Existing rows untouched.
  - schema.ts Patient interface: firstName/lastName now optional, phone
    and dateOfBirth removed from the type entirely. The underlying columns
    are still in the DB so legacy rows aren't broken — we just stop
    referencing them in code.
  - validation/patient.ts: firstName/lastName drop min(1), phone and dob
    fields removed.
  - patient-actions.ts: pickFields no longer reads phone/dob, create and
    update payloads no longer write them.

UI fallbacks
  - PatientsTable: header has 'Notlar' instead of Telefon/Doğum. Ad Soyad
    cell shows the joined name or em-dash. Edit dialog mirrors the same
    simplified form.
  - jobs/[jobId] detail page: when patient row has neither name, the page
    title falls back to 'Hasta {patientCode}' (same as before for jobs
    without a linked patient). The Hasta Bilgileri card now shows Ad Soyad
    and Patient Code side by side, with notes spanning both columns.
This commit is contained in:
kovakmedya
2026-05-21 23:01:52 +03:00
parent 0dea028845
commit ca4ea87d37
6 changed files with 32 additions and 84 deletions
+10 -10
View File
@@ -100,10 +100,13 @@ export default async function JobDetailPage({
{counterpartLabel}: {counterpart?.companyName ?? "—"}
</p>
<h1 className="text-2xl font-bold tracking-tight">
{patient ? `${patient.firstName} ${patient.lastName}` : `Hasta ${job.patientCode}`}
{(() => {
const name = [patient?.firstName, patient?.lastName].filter(Boolean).join(" ");
return name || `Hasta ${job.patientCode}`;
})()}
</h1>
<p className="text-muted-foreground text-sm">
{patient && (
{patient && (patient.firstName || patient.lastName) && (
<>
<span className="font-mono">{job.patientCode}</span> ·{" "}
</>
@@ -211,18 +214,15 @@ export default async function JobDetailPage({
dışında bir veri görmez.
</CardDescription>
</CardHeader>
<CardContent className="grid gap-4 text-sm md:grid-cols-3">
<CardContent className="grid gap-4 text-sm md:grid-cols-2">
<Info label="Ad Soyad">
{patient.firstName} {patient.lastName}
{[patient.firstName, patient.lastName].filter(Boolean).join(" ") || "—"}
</Info>
<Info label="Telefon">{patient.phone || "—"}</Info>
<Info label="Doğum Tarihi">
{patient.dateOfBirth
? dateFormatter.format(new Date(patient.dateOfBirth))
: "—"}
<Info label="Hasta Kodu">
<span className="font-mono">{patient.patientCode}</span>
</Info>
{patient.notes && (
<div className="md:col-span-3">
<div className="md:col-span-2">
<p className="text-muted-foreground mb-1 text-xs font-medium uppercase tracking-wide">
Notlar
</p>