Files
breakpilot-compliance/admin-compliance/app/sdk/vendor-assessment/_components/AssessmentProgress.tsx
T
Benjamin Admin 0b9150f16f
Build + Deploy / build-admin-compliance (push) Successful in 2m16s
Build + Deploy / build-backend-compliance (push) Successful in 3m27s
Build + Deploy / build-ai-sdk (push) Successful in 58s
Build + Deploy / build-developer-portal (push) Successful in 1m13s
Build + Deploy / build-tts (push) Successful in 1m43s
Build + Deploy / build-document-crawler (push) Successful in 45s
Build + Deploy / build-dsms-gateway (push) Successful in 30s
Build + Deploy / build-dsms-node (push) Successful in 19s
CI / branch-name (push) Has been skipped
CI / guardrail-integrity (push) Has been skipped
CI / loc-budget (push) Failing after 17s
CI / secret-scan (push) Has been skipped
CI / go-lint (push) Has been skipped
CI / python-lint (push) Has been skipped
CI / nodejs-lint (push) Has been skipped
CI / nodejs-build (push) Successful in 2m35s
CI / dep-audit (push) Has been skipped
CI / sbom-scan (push) Has been skipped
CI / test-go (push) Successful in 43s
CI / test-python-backend (push) Successful in 37s
CI / test-python-document-crawler (push) Successful in 26s
CI / test-python-dsms-gateway (push) Successful in 21s
CI / validate-canonical-controls (push) Successful in 14s
Build + Deploy / trigger-orca (push) Successful in 3m33s
feat(vendor-assessment): Pruefprotokoll + Frontend + Sidebar
Phase 4-5: Professional Pruefprotokoll report builder with styled HTML
output (Kopfdaten, Kategorie-Scores, L1/L2 Check-Hierarchie, Findings,
Freigabe-Block). Frontend at /sdk/vendor-assessment with 3-step flow:
DocumentUploader → AssessmentProgress → PruefprotokollView.

Sidebar: "Use-Case Audits" → "Vertragspruefung" renamed.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-12 23:24:12 +02:00

94 lines
3.2 KiB
TypeScript

'use client'
import React, { useEffect, useRef, useState } from 'react'
interface Props {
assessmentId: string
backendUrl: string
// eslint-disable-next-line @typescript-eslint/no-explicit-any
onComplete: (result: any) => void
onError: (msg: string) => void
}
export function AssessmentProgress({ assessmentId, backendUrl, onComplete, onError }: Props) {
const [progress, setProgress] = useState('Initialisierung...')
const [dots, setDots] = useState(0)
const pollRef = useRef<ReturnType<typeof setInterval> | null>(null)
useEffect(() => {
const dotTimer = setInterval(() => setDots(d => (d + 1) % 4), 500)
pollRef.current = setInterval(async () => {
try {
const res = await fetch(
`${backendUrl}/api/vendor-compliance/assessments/${assessmentId}`,
)
if (!res.ok) return
const data = await res.json()
if (data.status === 'completed' && data.result) {
if (pollRef.current) clearInterval(pollRef.current)
clearInterval(dotTimer)
onComplete(data.result)
return
}
if (data.status === 'failed') {
if (pollRef.current) clearInterval(pollRef.current)
clearInterval(dotTimer)
onError(data.error || 'Pruefung fehlgeschlagen')
return
}
if (data.progress) {
setProgress(data.progress)
}
} catch {
// retry silently
}
}, 2000)
return () => {
if (pollRef.current) clearInterval(pollRef.current)
clearInterval(dotTimer)
}
}, [assessmentId, backendUrl, onComplete, onError])
return (
<div className="bg-white rounded-xl border border-gray-200 p-12 text-center">
<div className="w-16 h-16 mx-auto mb-6 relative">
<div className="absolute inset-0 border-4 border-blue-200 rounded-full" />
<div className="absolute inset-0 border-4 border-blue-600 rounded-full border-t-transparent animate-spin" />
</div>
<h2 className="text-xl font-semibold text-gray-800 mb-2">
Vertragspruefung laeuft
</h2>
<p className="text-gray-600 text-sm mb-6">
{progress}{'.'.repeat(dots)}
</p>
<div className="max-w-md mx-auto">
<div className="flex items-center gap-3 text-left text-xs text-gray-500 mb-2">
<span className="w-5 h-5 rounded-full bg-blue-100 flex items-center justify-center text-blue-600 font-bold">1</span>
Text extrahieren
</div>
<div className="flex items-center gap-3 text-left text-xs text-gray-500 mb-2">
<span className="w-5 h-5 rounded-full bg-blue-100 flex items-center justify-center text-blue-600 font-bold">2</span>
Checklisten pruefen (L1/L2)
</div>
<div className="flex items-center gap-3 text-left text-xs text-gray-500 mb-2">
<span className="w-5 h-5 rounded-full bg-blue-100 flex items-center justify-center text-blue-600 font-bold">3</span>
Cross-Check zwischen Dokumenten
</div>
<div className="flex items-center gap-3 text-left text-xs text-gray-500">
<span className="w-5 h-5 rounded-full bg-blue-100 flex items-center justify-center text-blue-600 font-bold">4</span>
Pruefprotokoll generieren
</div>
</div>
</div>
)
}