Show every field the edit dialog can change
The master-data tab summarised where the edit dialog itemises. Titles were
collapsed into one line, street, postcode and town were fused into a single
"Adresse", and first and last name appeared only in the page header — so
checking a value meant opening the change dialog to see it, which puts you
inside a form when you only wanted to look.
The tab now mirrors the dialog's "Person" section field for field and in the
same order, personnel number included.
Two deliberate departures from a literal mirror:
- Standort sits at the end rather than between Adresse and Land. It is the
workplace, not part of the person's address, and next to the postal
fields it reads as though it were.
- The emergency contact keeps the separate block it got earlier today,
with its phone number as a tel: link. In an emergency someone reaches
for it in a hurry; it should not be one cell among fourteen.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -6,42 +6,41 @@ type EmployeeRow = Database["public"]["Tables"]["employees"]["Row"];
|
||||
type Location = Database["public"]["Tables"]["locations"]["Row"];
|
||||
type Dependent = Database["public"]["Tables"]["employee_dependents"]["Row"];
|
||||
|
||||
function formatAddress(employee: EmployeeRow): string {
|
||||
const cityLine = [employee.postal_code, employee.city].filter(Boolean).join(" ");
|
||||
return [employee.address, cityLine].filter(Boolean).join(", ") || "–";
|
||||
}
|
||||
|
||||
export function StammdatenTab({ employee, location, dependents }: { employee: EmployeeRow; location?: Location; dependents: Dependent[] }) {
|
||||
// Defensive against a DB that hasn't received the title_prefix/title_suffix
|
||||
// migration yet — select("*") simply omits unknown columns, so these can
|
||||
// be undefined rather than the empty array the column default implies.
|
||||
const titles = [...(employee.title_prefix ?? []), ...(employee.title_suffix ?? [])];
|
||||
const prefixe = employee.title_prefix ?? [];
|
||||
const suffixe = employee.title_suffix ?? [];
|
||||
|
||||
// Feld für Feld dieselbe Liste wie im Abschnitt „Person" von „Daten
|
||||
// ändern", in derselben Reihenfolge.
|
||||
//
|
||||
// Vorher fasste die Anzeige zusammen: Titel in einer Zeile, Adresse mit
|
||||
// Postleitzahl und Ort verschmolzen, Vor- und Nachname gar nicht — die
|
||||
// standen nur in der Kopfzeile. Wer eine Angabe prüfen wollte, musste den
|
||||
// Änderungsdialog öffnen, um sie überhaupt zu sehen, und stand dann schon
|
||||
// in einem Formular. Was sich ändern lässt, soll sich auch ansehen lassen.
|
||||
const rows: [string, string][] = [
|
||||
["Titel", titles.length > 0 ? titles.join(", ") : "–"],
|
||||
["Personalnummer", String(employee.personnel_number)],
|
||||
["Vorname", employee.first_name],
|
||||
["Nachname", employee.last_name],
|
||||
["Titel (vorangestellt)", prefixe.length > 0 ? prefixe.join(", ") : "–"],
|
||||
["Titel (nachgestellt)", suffixe.length > 0 ? suffixe.join(", ") : "–"],
|
||||
["Geschlecht", employee.gender === "m" ? "männlich" : "weiblich"],
|
||||
["Geburtsdatum", `${fmtDate(employee.birth_date)} (${fmtAge(employee.birth_date)} Jahre)`],
|
||||
["SV-Nummer", employee.sv_nummer ?? "–"],
|
||||
["Staatsbürgerschaft", employee.nationality],
|
||||
["Adresse", employee.address ?? "–"],
|
||||
["Postleitzahl", employee.postal_code ?? "–"],
|
||||
["Ort", employee.city ?? "–"],
|
||||
["Land", employee.address_country ?? "–"],
|
||||
["E-Mail", employee.email],
|
||||
["Telefon", employee.phone ?? "–"],
|
||||
// Der Standort ist keine Angabe zur Person, sondern die Betriebsstätte —
|
||||
// er steht deshalb am Ende und nicht zwischen Adresse und Land, wo man
|
||||
// ihn für den Wohnort halten könnte.
|
||||
["Standort", location ? `${location.name} (${location.country})` : "–"],
|
||||
["Adresse", formatAddress(employee)],
|
||||
["Land", employee.address_country ?? "–"],
|
||||
["Geschlecht", employee.gender === "m" ? "männlich" : "weiblich"],
|
||||
// Der Notfallkontakt steht als eigene Zeile und nicht in einer Zeile mit
|
||||
// dem Telefon der Person: im Ernstfall greift jemand danach, und dann
|
||||
// darf keine Verwechslung möglich sein.
|
||||
[
|
||||
"Notfallkontakt",
|
||||
employee.emergency_contact_name
|
||||
? [
|
||||
employee.emergency_contact_name,
|
||||
employee.emergency_contact_relation ? `(${employee.emergency_contact_relation})` : "",
|
||||
employee.emergency_contact_phone,
|
||||
]
|
||||
.filter(Boolean)
|
||||
.join(" ")
|
||||
: "–",
|
||||
],
|
||||
];
|
||||
return (
|
||||
<div className="flex flex-col gap-6">
|
||||
@@ -53,6 +52,45 @@ export function StammdatenTab({ employee, location, dependents }: { employee: Em
|
||||
</div>
|
||||
))}
|
||||
</dl>
|
||||
|
||||
{/* Eigener Abschnitt statt einer Zelle im Raster.
|
||||
Der Notfallkontakt sind drei Angaben — Name, Verhältnis, Nummer —,
|
||||
und in eine Zelle gepresst standen sie als eine Zeile Fliesstext da.
|
||||
Im Ernstfall greift jemand in Eile danach; dann muss die Nummer
|
||||
sofort zu finden sein und nicht zwischen Adresse und Geschlecht. */}
|
||||
<div className="border-t border-border pt-6">
|
||||
<h3 className="mb-3 text-xs font-bold uppercase tracking-wide text-brand-700">Notfallkontakt</h3>
|
||||
{employee.emergency_contact_name ? (
|
||||
<dl className="grid grid-cols-1 gap-x-8 gap-y-4 sm:grid-cols-2 lg:grid-cols-3">
|
||||
<div>
|
||||
<dt className="text-xs font-semibold uppercase tracking-wide text-ink-muted">Name</dt>
|
||||
<dd className="mt-1 text-sm text-ink">{employee.emergency_contact_name}</dd>
|
||||
</div>
|
||||
<div>
|
||||
<dt className="text-xs font-semibold uppercase tracking-wide text-ink-muted">Telefon</dt>
|
||||
<dd className="mt-1 text-sm font-semibold text-ink">
|
||||
{employee.emergency_contact_phone ? (
|
||||
<a
|
||||
href={`tel:${employee.emergency_contact_phone.replace(/\s/g, "")}`}
|
||||
className="rounded hover:text-brand-700 hover:underline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-brand-500"
|
||||
>
|
||||
{employee.emergency_contact_phone}
|
||||
</a>
|
||||
) : (
|
||||
"–"
|
||||
)}
|
||||
</dd>
|
||||
</div>
|
||||
<div>
|
||||
<dt className="text-xs font-semibold uppercase tracking-wide text-ink-muted">Verhältnis</dt>
|
||||
<dd className="mt-1 text-sm text-ink">{employee.emergency_contact_relation || "–"}</dd>
|
||||
</div>
|
||||
</dl>
|
||||
) : (
|
||||
<p className="text-sm text-ink-muted">Kein Notfallkontakt hinterlegt.</p>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<AngehoerigeSection employeeId={employee.id} dependents={dependents} />
|
||||
</div>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user