'use client' import React, { useState, useEffect, useCallback } from 'react' import { API, SoAEntry } from '../_types' import { EmptyState, LoadingSpinner, StatCard, StatusBadge } from './shared' // ============================================================================= // TAB: SOA (Statement of Applicability) // ============================================================================= export function SoATab() { const [entries, setEntries] = useState([]) const [stats, setStats] = useState({ applicable: 0, notApplicable: 0, implemented: 0, planned: 0 }) const [loading, setLoading] = useState(true) const [filterStatus, setFilterStatus] = useState('') const [filterApplicable, setFilterApplicable] = useState('') const load = useCallback(async () => { setLoading(true) try { const params = new URLSearchParams() if (filterStatus) params.set('implementation_status', filterStatus) if (filterApplicable) params.set('is_applicable', filterApplicable) const res = await fetch(`${API}/soa?${params}`) if (res.ok) { const data = await res.json() setEntries(data.entries || []) setStats({ applicable: data.applicable_count || 0, notApplicable: data.not_applicable_count || 0, implemented: data.implemented_count || 0, planned: data.planned_count || 0, }) } } catch { /* ignore */ } setLoading(false) }, [filterStatus, filterApplicable]) useEffect(() => { load() }, [load]) if (loading) return return (
{/* Stats */}
{/* Filters */}
{entries.length === 0 ? ( ) : (
{entries.map(e => ( ))}
Control Titel Kategorie Anwendbar Status Coverage Version
{e.annex_a_control} {e.annex_a_title} {e.annex_a_category} {e.is_applicable ? 'Ja' : 'Nein'} {e.coverage_level || '-'} v{e.version}
)}
) }