"use client"; import { useRouter } from "next/navigation"; import { useMemo, useState } from "react"; import { rehireEmployee } from "@/actions/employees"; import { Button } from "@/components/ui/Button"; import { SelectField, TextField } from "@/components/ui/Field"; import { SlideOver } from "@/components/ui/SlideOver"; import { useToast } from "@/components/ui/Toast"; import { fmtDate, fmtName } from "@/lib/format"; import type { OpenPositionResolved } from "@/lib/positions"; import type { Database } from "@/lib/types"; type EmployeeRow = Database["public"]["Tables"]["employees"]["Row"]; // Eine Wiedereinstellung braucht eine Planstelle — genau wie eine // Neueinstellung. // // Die alte Stelle ist dafür kein Ersatz: sie kann inzwischen besetzt, // ausgelaufen oder ganz entfallen sein. `rehire_employee` verlangte die // Angabe deshalb schon immer und wies den Aufruf sonst ab; nur schickte das // Formular sie nie mit, sodass jede Wiedereinstellung an einer Meldung // scheiterte, die sich im Dialog gar nicht beheben liess. export function RehirePanel({ open, onClose, employee, openPositions, }: { open: boolean; onClose: () => void; employee: EmployeeRow; openPositions: OpenPositionResolved[]; }) { const { showToast } = useToast(); const router = useRouter(); const [rehireDate, setRehireDate] = useState(""); const [positionId, setPositionId] = useState(""); const [pending, setPending] = useState(false); const options = useMemo( () => openPositions .slice() .sort((a, b) => a.orgLabel.localeCompare(b.orgLabel, "de") || a.title.localeCompare(b.title, "de")) .map((p) => ({ value: p.id, label: `${p.orgLabel} · ${p.title} (${p.position_number})` })), [openPositions] ); const selected = openPositions.find((p) => p.id === positionId); // Die Datenbank weist eine Besetzung ausserhalb der Gültigkeit ab. Das hier // nimmt die Meldung vorweg, solange sie noch etwas nützt — im Dialog, mit // beiden Daten sichtbar. const ausserhalb = selected && rehireDate ? rehireDate < selected.valid_from ? `Diese Planstelle gilt erst ab ${fmtDate(selected.valid_from)}.` : selected.valid_to && rehireDate >= selected.valid_to ? `Diese Planstelle gilt nur bis ${fmtDate(selected.valid_to)}.` : null : null; async function handleSubmit() { if (!rehireDate || !positionId) { showToast("Wiedereintrittsdatum und Planstelle sind Pflicht.", "error"); return; } setPending(true); const result = await rehireEmployee({ employee_id: employee.id, rehire_date: rehireDate, position_id: positionId, }); setPending(false); if (result.success) { showToast(`${employee.first_name} ${employee.last_name} wurde wiedereingestellt.`); router.refresh(); onClose(); } else { showToast(result.error ?? "Fehler beim Speichern.", "error"); } } return ( } >

Letzte Position

{employee.job_title}

Ausgetreten am {fmtDate(employee.exit_date)}

{options.length === 0 ? (

Es ist derzeit keine Planstelle frei. Ohne eine solche ist keine Wiedereinstellung möglich — zuerst eine Planstelle anlegen oder eine bestehende freimachen.

) : ( <> {selected && (
{selected.title}
{selected.orgLabel}
{selected.is_chief ? "Leitungsplanstelle" : "Mitarbeiterplanstelle"} {selected.future ? ` · gültig ab ${fmtDate(selected.valid_from)}` : ""} {selected.valid_to ? ` · endet am ${fmtDate(selected.valid_to)}` : ""}
)} {ausserhalb && (

{ausserhalb} Wiedereintritt und Gültigkeit müssen zusammenpassen.

)} )}
); }