'use client' import { useState, useMemo } from 'react' import Link from 'next/link' import { useVendorCompliance, Vendor, VendorStatus, VendorRole, ServiceCategory, VENDOR_ROLE_META, SERVICE_CATEGORY_META, getRiskLevelFromScore, formatDate, } from '@/lib/sdk/vendor-compliance' type SortField = 'name' | 'role' | 'status' | 'riskScore' | 'nextReviewDate' type SortOrder = 'asc' | 'desc' export default function VendorsPage() { const { vendors, contracts, deleteVendor, isLoading } = useVendorCompliance() const [searchTerm, setSearchTerm] = useState('') const [statusFilter, setStatusFilter] = useState('ALL') const [roleFilter, setRoleFilter] = useState('ALL') const [categoryFilter, setCategoryFilter] = useState('ALL') const [sortField, setSortField] = useState('name') const [sortOrder, setSortOrder] = useState('asc') const filteredVendors = useMemo(() => { let result = [...vendors] // Search filter if (searchTerm) { const term = searchTerm.toLowerCase() result = result.filter( (v) => v.name.toLowerCase().includes(term) || v.serviceDescription.toLowerCase().includes(term) ) } // Status filter if (statusFilter !== 'ALL') { result = result.filter((v) => v.status === statusFilter) } // Role filter if (roleFilter !== 'ALL') { result = result.filter((v) => v.role === roleFilter) } // Category filter if (categoryFilter !== 'ALL') { result = result.filter((v) => v.serviceCategory === categoryFilter) } // Sort result.sort((a, b) => { let comparison = 0 switch (sortField) { case 'name': comparison = a.name.localeCompare(b.name) break case 'role': comparison = a.role.localeCompare(b.role) break case 'status': comparison = a.status.localeCompare(b.status) break case 'riskScore': comparison = a.residualRiskScore - b.residualRiskScore break case 'nextReviewDate': const dateA = a.nextReviewDate ? new Date(a.nextReviewDate).getTime() : Infinity const dateB = b.nextReviewDate ? new Date(b.nextReviewDate).getTime() : Infinity comparison = dateA - dateB break } return sortOrder === 'asc' ? comparison : -comparison }) return result }, [vendors, searchTerm, statusFilter, roleFilter, categoryFilter, sortField, sortOrder]) const handleSort = (field: SortField) => { if (sortField === field) { setSortOrder(sortOrder === 'asc' ? 'desc' : 'asc') } else { setSortField(field) setSortOrder('asc') } } const handleDelete = async (id: string) => { if (confirm('Möchten Sie diesen Vendor wirklich löschen?')) { await deleteVendor(id) } } const getContractCount = (vendorId: string) => { return contracts.filter((c) => c.vendorId === vendorId).length } if (isLoading) { return (
) } return (
{/* Header */}

Vendor Register

Verwaltung von Auftragsverarbeitern und Dienstleistern

Neuer Vendor
{/* Filters */}
{/* Search */}
setSearchTerm(e.target.value)} />
{/* Status Filter */}
{/* Role Filter */}
{/* Category Filter */}
{/* Vendor Cards */}
{filteredVendors.map((vendor) => ( ))}
{filteredVendors.length === 0 && (

Keine Vendors gefunden

Erstellen Sie einen neuen Vendor, um zu beginnen.

Neuer Vendor
)} {/* Summary */}
{filteredVendors.length} von {vendors.length} Vendors
) } function VendorCard({ vendor, contractCount, onDelete, }: { vendor: Vendor contractCount: number onDelete: (id: string) => void }) { const riskLevel = getRiskLevelFromScore(vendor.residualRiskScore / 4) const isReviewDue = vendor.nextReviewDate && new Date(vendor.nextReviewDate) <= new Date() const riskColors = { LOW: 'border-l-green-500', MEDIUM: 'border-l-yellow-500', HIGH: 'border-l-orange-500', CRITICAL: 'border-l-red-500', } const statusConfig = { ACTIVE: { label: 'Aktiv', color: 'bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-200' }, INACTIVE: { label: 'Inaktiv', color: 'bg-gray-100 text-gray-800 dark:bg-gray-700 dark:text-gray-200' }, PENDING_REVIEW: { label: 'Review ausstehend', color: 'bg-yellow-100 text-yellow-800 dark:bg-yellow-900 dark:text-yellow-200' }, TERMINATED: { label: 'Beendet', color: 'bg-red-100 text-red-800 dark:bg-red-900 dark:text-red-200' }, } return (

{vendor.name}

{SERVICE_CATEGORY_META[vendor.serviceCategory]?.de}

{statusConfig[vendor.status].label}

{vendor.serviceDescription}

Rolle

{VENDOR_ROLE_META[vendor.role]?.de}

Risiko-Score

{vendor.residualRiskScore}
{contractCount} Verträge {vendor.certifications.length > 0 && ( {vendor.certifications.length} Zertifizierungen )}
{isReviewDue && (

Review fällig seit {formatDate(vendor.nextReviewDate)}

)}
Details anzeigen
Verträge
) }