The contract sheet had one field, "Merkmale", holding whatever applied, comma-separated — and a dash when nothing did. Two problems in one row. A dash cannot distinguish "has no company car" from "nobody ever answered the question", and the entry read "Dienstwagen" without saying which kind, which is the thing worth knowing since electric vehicles are tracked separately. Betriebsrat, Dienstwagen, laterale Führung and C-Level are now four lines like every other line on the sheet, each with Ja or Nein. The company car shows its drivetrain instead: E-KFZ or Verbrenner. That label existed in three places — the dropdown, the hire summary and now here. It lives in lib/dienstwagen.ts, so the same car cannot end up named differently depending on which screen you are looking at. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
70 lines
2.9 KiB
TypeScript
70 lines
2.9 KiB
TypeScript
import { dienstwagenLabel } from "@/lib/dienstwagen";
|
||
import { fmtDate, fmtFullName } from "@/lib/format";
|
||
import type { OpenPositionResolved } from "@/lib/positions";
|
||
import type { HireDraftData } from "./types";
|
||
|
||
const PAYGRADE_LABELS: Record<string, string> = {
|
||
A: "A – Einstieg",
|
||
B: "B – Qualifiziert",
|
||
C: "C – Erfahren",
|
||
D: "D – Spezialist:in",
|
||
E: "E – Teamleitung",
|
||
F: "F – Bereichsleitung / GF",
|
||
};
|
||
|
||
type StepSummaryProps = {
|
||
draft: HireDraftData;
|
||
selectedPosition: OpenPositionResolved | null;
|
||
locations: { id: string; name: string; country: string }[];
|
||
};
|
||
|
||
export function StepSummary({ draft, selectedPosition, locations }: StepSummaryProps) {
|
||
const location = locations.find((l) => l.id === draft.locationId);
|
||
const flags = [
|
||
draft.isBetriebsrat && "Betriebsrat",
|
||
draft.hasDienstwagen && `Dienstwagen (${dienstwagenLabel(draft.dienstwagenArt)})`,
|
||
draft.isLateraleFuehrung && "Laterale Führung",
|
||
draft.isCLevel && "C-Level",
|
||
].filter(Boolean);
|
||
const notfall = [draft.emergencyContactName, draft.emergencyContactRelation && `(${draft.emergencyContactRelation})`, draft.emergencyContactPhone]
|
||
.filter(Boolean)
|
||
.join(" ");
|
||
|
||
const rows: [string, string][] = [
|
||
["Personalnummer", draft.personnelNumber || "–"],
|
||
["Name", fmtFullName(draft.firstName, draft.lastName, draft.titlePrefix, draft.titleSuffix)],
|
||
["Geschlecht", draft.gender === "m" ? "männlich" : "weiblich"],
|
||
["Geburtsdatum", fmtDate(draft.birthDate)],
|
||
["SV-Nummer", draft.svNummer || "–"],
|
||
["E-Mail (privat)", draft.email || "–"],
|
||
["Telefon", draft.phone || "–"],
|
||
["Notfallkontakt", notfall || "–"],
|
||
["Standort", location ? `${location.name} (${location.country})` : "–"],
|
||
["Position", selectedPosition ? `${selectedPosition.title} (${selectedPosition.position_number})` : "–"],
|
||
["Organisationseinheit", selectedPosition?.orgLabel ?? "–"],
|
||
["Führungskraft", selectedPosition?.managerName ?? "–"],
|
||
["Besetzung", draft.besetzung],
|
||
["Eintrittsdatum", fmtDate(draft.entryDate)],
|
||
["Vertragsart", draft.contractType === "befristet" ? `befristet bis ${fmtDate(draft.contractEndDate)}` : "unbefristet"],
|
||
["Beschäftigungsausmaß", `${draft.employmentType} (${draft.weeklyHours} h)`],
|
||
["Paygrade", PAYGRADE_LABELS[draft.paygrade]],
|
||
["Angestellte:r / Arbeiter:in", draft.workerType],
|
||
["Kollektivvertrag", draft.collectiveAgreement],
|
||
["Arbeitstage", draft.workDays.join(", ") || "–"],
|
||
["Merkmale", flags.length > 0 ? flags.join(", ") : "–"],
|
||
];
|
||
|
||
return (
|
||
<div className="flex flex-col gap-4">
|
||
<dl className="grid grid-cols-1 gap-x-6 gap-y-3 sm:grid-cols-2">
|
||
{rows.map(([label, value]) => (
|
||
<div key={label}>
|
||
<dt className="text-xs font-semibold uppercase tracking-wide text-ink-muted">{label}</dt>
|
||
<dd className="mt-0.5 text-sm text-ink">{value}</dd>
|
||
</div>
|
||
))}
|
||
</dl>
|
||
</div>
|
||
);
|
||
}
|