/** * TrusteeContractsView * * Vertrags-Verwaltung für eine Trustee-Instanz. * Zeigt Kundenverträge mit Organisation-Zuordnung. */ import React, { useState, useMemo } from 'react'; import { useTrusteeContracts, useTrusteeContractOperations, TrusteeContract } from '../../../hooks/useTrustee'; import { useTrusteeOptions } from '../../../hooks/useTrusteeOptions'; import { useTablePermission } from '../../../hooks/useInstancePermissions'; import { Popup } from '../../../components/UiComponents/Popup/Popup'; import { TrusteeEditForm, FieldConfig } from './components'; import styles from './TrusteeViews.module.css'; export const TrusteeContractsView: React.FC = () => { const { items: contracts, loading, error, refetch } = useTrusteeContracts(); const { handleDelete, handleCreate, handleUpdate, deletingItems, creatingItem } = useTrusteeContractOperations(); const { canCreate, canUpdate, canDelete } = useTablePermission('TrusteeContract'); // Options für Label-Auflösung const { getLabelFast, loading: optionsLoading } = useTrusteeOptions(['organisations']); // Modal State const [isModalOpen, setIsModalOpen] = useState(false); const [editingContract, setEditingContract] = useState(null); const [formError, setFormError] = useState(null); // Feld-Konfiguration für das Formular const fields: FieldConfig[] = useMemo(() => [ { key: 'organisationId', label: 'Organisation', type: 'enum', required: true, optionsReference: 'organisations', editable: !editingContract, // Nicht änderbar nach Erstellung helpText: editingContract ? 'Organisation kann nicht geändert werden' : undefined, }, { key: 'label', label: 'Bezeichnung', type: 'string', required: true, placeholder: 'z.B. Kunde AG 2026', }, { key: 'enabled', label: 'Status', type: 'boolean', helpText: 'Vertrag ist aktiv', }, ], [editingContract]); if (loading || optionsLoading) { return
Lade Verträge...
; } if (error) { return
Fehler: {error}
; } const onDelete = async (contractId: string) => { if (window.confirm('Vertrag wirklich löschen?')) { const success = await handleDelete(contractId); if (success) { refetch(); } } }; const onEdit = (contract: TrusteeContract) => { setEditingContract(contract); setFormError(null); setIsModalOpen(true); }; const onCreate = () => { setEditingContract(null); setFormError(null); setIsModalOpen(true); }; const onCloseModal = () => { setIsModalOpen(false); setEditingContract(null); setFormError(null); }; const onSave = async (data: Partial) => { setFormError(null); try { if (editingContract) { // Bei Update: organisationId nicht mitsenden (ist immutable) const { organisationId, ...updateData } = data; const result = await handleUpdate(editingContract.id, updateData); if (!result.success) { setFormError(result.error || 'Fehler beim Aktualisieren'); return; } } else { const result = await handleCreate(data); if (!result.success) { setFormError(result.error || 'Fehler beim Erstellen'); return; } } onCloseModal(); refetch(); } catch (err: any) { setFormError(err.message || 'Ein Fehler ist aufgetreten'); } }; return (
{/* Toolbar */}
{canCreate && ( )}
{/* Tabelle */} {contracts.length === 0 ? (

Keine Verträge vorhanden.

) : ( {contracts.map((contract) => ( ))}
Bezeichnung Organisation Status Aktionen
{contract.label} {getLabelFast('organisations', contract.organisationId)} {contract.enabled ? 'Aktiv' : 'Inaktiv'} {canUpdate && ( )} {canDelete && ( )}
)} {/* Create/Edit Modal */} {formError && (
{formError}
)} initialData={editingContract || { enabled: true }} fields={fields} onSave={onSave} onCancel={onCloseModal} isSaving={creatingItem} isEdit={!!editingContract} saveLabel={editingContract ? 'Aktualisieren' : 'Erstellen'} />
); }; export default TrusteeContractsView;