'use client' import React, { useState, useEffect, useCallback } from 'react' import { useParams } from 'next/navigation' import { QuestionnaireView } from '../_components/QuestionnaireView' import { AuditResult } from '../_components/AuditResult' interface Question { id: string mc_id: string mc_name: string question: string question_type: string evidence_required: boolean pass_criteria: string[] fail_criteria: string[] severity: string regulation: string depends_on?: string } interface Audit { id: string tenant_id: string template_id: string name: string target_name: string status: string total_questions: number answered_questions: number compliance_score: number questions: Question[] created_at: string completed_at: string | null } interface Answer { id: string question_id: string mc_id: string value: unknown comment: string evidence_ids: string[] status: string answered_at: string } interface ScoreResult { audit_id: string total_questions: number answered: number passed: number failed: number skipped: number compliance_score: number by_regulation: Record by_severity: Record } const TENANT_ID = '00000000-0000-0000-0000-000000000001' export default function AuditDetailPage() { const params = useParams() const auditId = params.auditId as string const [audit, setAudit] = useState(null) const [answers, setAnswers] = useState([]) const [score, setScore] = useState(null) const [loading, setLoading] = useState(true) const [error, setError] = useState('') const loadAudit = useCallback(async () => { try { const res = await fetch(`/api/sdk/v1/use-case/audits/${auditId}`, { headers: { 'X-Tenant-ID': TENANT_ID }, }) if (!res.ok) throw new Error('Audit nicht gefunden') const data = await res.json() setAudit(data.audit) setAnswers(data.answers || []) } catch (e) { setError(e instanceof Error ? e.message : 'Fehler') } finally { setLoading(false) } }, [auditId]) useEffect(() => { loadAudit() }, [loadAudit]) const handleAnswer = async (questionId: string, value: unknown, comment: string) => { if (!audit) return try { const res = await fetch(`/api/sdk/v1/use-case/audits/${auditId}/answer`, { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-Tenant-ID': TENANT_ID, }, body: JSON.stringify({ question_id: questionId, value, comment, status: 'answered', }), }) if (!res.ok) throw new Error('Antwort konnte nicht gespeichert werden') const data = await res.json() // Update local state setAnswers(prev => { const idx = prev.findIndex(a => a.question_id === questionId) const newAnswer = data.answer if (idx >= 0) { const copy = [...prev] copy[idx] = newAnswer return copy } return [...prev, newAnswer] }) if (data.progress) { setAudit(prev => prev ? { ...prev, answered_questions: data.progress.answered, compliance_score: data.progress.compliance_score, status: data.progress.answered >= prev.total_questions ? 'completed' : 'in_progress', } : null) } } catch (e) { setError(e instanceof Error ? e.message : 'Fehler') } } const handleSkip = async (questionId: string) => { if (!audit) return try { await fetch(`/api/sdk/v1/use-case/audits/${auditId}/answer`, { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-Tenant-ID': TENANT_ID, }, body: JSON.stringify({ question_id: questionId, value: null, status: 'skipped', }), }) await loadAudit() } catch { /* ignore */ } } const loadScore = async () => { try { const res = await fetch(`/api/sdk/v1/use-case/audits/${auditId}/score`, { headers: { 'X-Tenant-ID': TENANT_ID }, }) if (res.ok) { const data = await res.json() setScore(data) } } catch { /* ignore */ } } if (loading) { return (
Lade Audit...
) } if (error || !audit) { return (

{error || 'Audit nicht gefunden'}

Zurueck zur Liste
) } const showResult = audit.status === 'completed' || score !== null return (
{/* Header */}
← Alle Audits

{audit.name}

{audit.target_name && (

{audit.target_name}

)}
{/* Progress indicator */}
{audit.answered_questions} / {audit.total_questions} beantwortet
0 ? (audit.answered_questions / audit.total_questions) * 100 : 0}%` }} />
{audit.answered_questions > 0 && ( )}
{error && (

{error}

)} {showResult && score ? ( ) : ( )}
) }