"use client"; import { useRouter } from "next/navigation"; import { useState } from "react"; import { changeEmployeeData } from "@/actions/employees"; import { AngehoerigeSection } from "@/components/employees/AngehoerigeSection"; import { RoleEmploymentFields, type RoleEmploymentValue } from "@/components/employees/RoleEmploymentFields"; import { SvNummerField } from "@/components/employees/SvNummerField"; import { TitleFields, type TitleValue } from "@/components/employees/TitleFields"; import { CountryPicker } from "@/components/ui/CountryPicker"; import { SlideOver } from "@/components/ui/SlideOver"; import { useToast } from "@/components/ui/Toast"; import { UN_COUNTRIES } from "@/lib/countries"; import { fmtFullName, todayIso } from "@/lib/format"; import { isValidSvnr, requiresAustrianSvnr } from "@/lib/svnr"; import type { ContractType, Database, EmploymentType, GenderType } from "@/lib/supabase/types"; type EmployeeRow = Database["public"]["Tables"]["employees"]["Row"]; type Dependent = Database["public"]["Tables"]["employee_dependents"]["Row"]; export function DatenAendernPanel({ open, onClose, employee, dependents, locationCountry, }: { open: boolean; onClose: () => void; employee: EmployeeRow; dependents: Dependent[]; locationCountry: string | null | undefined; }) { const { showToast } = useToast(); const router = useRouter(); const [pending, setPending] = useState(false); // The DB trigger would reject a bad number anyway; catching it here keeps // the whole effective-dated change from being thrown away on submit. const [effectiveDate, setEffectiveDate] = useState(todayIso); const [firstName, setFirstName] = useState(employee.first_name); const [lastName, setLastName] = useState(employee.last_name); const [titles, setTitles] = useState({ titlePrefix: employee.title_prefix ?? [], titleSuffix: employee.title_suffix ?? [] }); function updateTitles(patch: Partial) { setTitles((prev) => ({ ...prev, ...patch })); } const [gender, setGender] = useState(employee.gender); const [birthDate, setBirthDate] = useState(employee.birth_date); const [svNummer, setSvNummer] = useState(employee.sv_nummer ?? ""); const svNummerOk = !svNummer.trim() || !requiresAustrianSvnr(locationCountry) || isValidSvnr(svNummer, birthDate || null); const [nationality, setNationality] = useState(employee.nationality); const [address, setAddress] = useState(employee.address ?? ""); const [postalCode, setPostalCode] = useState(employee.postal_code ?? ""); const [city, setCity] = useState(employee.city ?? ""); const [addressCountry, setAddressCountry] = useState(employee.address_country ?? "Österreich"); const [email, setEmail] = useState(employee.email); const [phone, setPhone] = useState(employee.phone ?? ""); const [employmentType, setEmploymentType] = useState(employee.employment_type); const [weeklyHours, setWeeklyHours] = useState(String(employee.weekly_hours)); const [contractType, setContractType] = useState(employee.contract_type); const [contractEndDate, setContractEndDate] = useState(employee.contract_end_date ?? ""); const [role, setRole] = useState({ workerType: employee.worker_type ?? "Angestellte:r", collectiveAgreement: employee.collective_agreement ?? "Handel", workDays: employee.work_days ?? ["Mo", "Di", "Mi", "Do", "Fr"], isBetriebsrat: employee.is_betriebsrat ?? false, hasDienstwagen: employee.has_dienstwagen ?? false, isLateraleFuehrung: employee.is_laterale_fuehrung ?? false, isCLevel: employee.is_c_level ?? false, }); function updateRole(patch: Partial) { setRole((prev) => ({ ...prev, ...patch })); } function handleEmploymentTypeChange(value: EmploymentType) { setEmploymentType(value); if (value === "Vollzeit") setWeeklyHours("38.5"); } async function handleSubmit() { if (employmentType === "Teilzeit" && (Number(weeklyHours) <= 0 || Number(weeklyHours) >= 38.5)) { showToast("Wochenstunden bei Teilzeit müssen zwischen 0 und 38,5 liegen.", "error"); return; } if (contractType === "befristet" && !contractEndDate) { showToast("Bei befristetem Vertrag ist ein Enddatum erforderlich.", "error"); return; } if (role.workDays.length === 0) { showToast("Mindestens ein Arbeitstag muss ausgewählt sein.", "error"); return; } if (!effectiveDate) { showToast("Bitte ein Wirksam-ab-Datum angeben.", "error"); return; } setPending(true); const result = await changeEmployeeData({ employee_id: employee.id, effective_date: effectiveDate, person: { first_name: firstName, last_name: lastName, title_prefix: titles.titlePrefix, title_suffix: titles.titleSuffix, gender, birth_date: birthDate, sv_nummer: svNummer, nationality, address, postal_code: postalCode, city, address_country: addressCountry, email, phone, }, contract: { employment_type: employmentType, weekly_hours: Number(weeklyHours), contract_type: contractType, contract_end_date: contractType === "befristet" ? contractEndDate : "", }, role: { worker_type: role.workerType, collective_agreement: role.collectiveAgreement, work_days: role.workDays, is_betriebsrat: role.isBetriebsrat, has_dienstwagen: role.hasDienstwagen, is_laterale_fuehrung: role.isLateraleFuehrung, is_c_level: role.isCLevel, }, }); setPending(false); if (result.success) { showToast("Daten aktualisiert."); router.refresh(); onClose(); } else { showToast(result.error ?? "Fehler beim Speichern.", "error"); } } return ( } >
setEffectiveDate(e.target.value)} className="w-full rounded border border-border px-3 py-2 text-sm" />

Person

setFirstName(e.target.value)} className="w-full rounded border border-border px-3 py-2 text-sm" />
setLastName(e.target.value)} className="w-full rounded border border-border px-3 py-2 text-sm" />
setBirthDate(e.target.value)} className="w-full rounded border border-border px-3 py-2 text-sm" />
setAddress(e.target.value)} className="w-full rounded border border-border px-3 py-2 text-sm" />
setPostalCode(e.target.value)} className="w-full rounded border border-border px-3 py-2 text-sm" />
setCity(e.target.value)} className="w-full rounded border border-border px-3 py-2 text-sm" />
setEmail(e.target.value)} className="w-full rounded border border-border px-3 py-2 text-sm" />
setPhone(e.target.value)} className="w-full rounded border border-border px-3 py-2 text-sm" />

Vertrag

setWeeklyHours(e.target.value)} className="w-full rounded border border-border px-3 py-2 text-sm disabled:bg-surface disabled:text-ink-muted" />
{contractType === "befristet" && (
setContractEndDate(e.target.value)} className="w-full rounded border border-border px-3 py-2 text-sm" />
)}

Rolle & Anstellung

); }