- CLAUDE.md: Comprehensive documentation for Compliance SDK platform - docs-src: AI-Compliance-SDK docs (architecture, developer, auditor, SBOM) - mkdocs.yml: Compliance-specific nav with purple theme - docker-compose: Added docs service (port 8011, profile: docs) - admin-compliance: New /development/docs page with iframe + quick links - navigation.ts: Added development category with docs module - .claude/rules: testing, docs, open-source, compliance-checklist Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
189 lines
7.1 KiB
TypeScript
189 lines
7.1 KiB
TypeScript
'use client'
|
|
|
|
import { useState } from 'react'
|
|
import { ExternalLink, Maximize2, Minimize2, RefreshCw, Search, BookOpen, ArrowRight } from 'lucide-react'
|
|
|
|
// Quick links to compliance documentation sections
|
|
const quickLinks = [
|
|
{ name: 'AI Compliance SDK', path: 'services/ai-compliance-sdk/', icon: '🔒' },
|
|
{ name: 'Architektur', path: 'services/ai-compliance-sdk/ARCHITECTURE/', icon: '🏗️' },
|
|
{ name: 'Developer Guide', path: 'services/ai-compliance-sdk/DEVELOPER/', icon: '👩💻' },
|
|
{ name: 'Auditor Doku', path: 'services/ai-compliance-sdk/AUDITOR_DOCUMENTATION/', icon: '📋' },
|
|
{ name: 'SBOM', path: 'services/ai-compliance-sdk/SBOM/', icon: '📦' },
|
|
{ name: 'CI/CD Pipeline', path: 'development/ci-cd-pipeline/', icon: '🚀' },
|
|
]
|
|
|
|
export default function DocsPage() {
|
|
const [isFullscreen, setIsFullscreen] = useState(false)
|
|
const [isLoading, setIsLoading] = useState(true)
|
|
const [currentPath, setCurrentPath] = useState('')
|
|
|
|
const getDocsUrl = () => {
|
|
if (typeof window !== 'undefined') {
|
|
const protocol = window.location.protocol
|
|
const hostname = window.location.hostname
|
|
const port = window.location.port
|
|
return `${protocol}//${hostname}${port ? ':' + port : ''}/docs`
|
|
}
|
|
return '/docs'
|
|
}
|
|
|
|
const docsUrl = getDocsUrl()
|
|
|
|
const handleIframeLoad = () => {
|
|
setIsLoading(false)
|
|
}
|
|
|
|
const navigateTo = (path: string) => {
|
|
setCurrentPath(path)
|
|
setIsLoading(true)
|
|
}
|
|
|
|
const toggleFullscreen = () => {
|
|
setIsFullscreen(!isFullscreen)
|
|
}
|
|
|
|
const openInNewTab = () => {
|
|
window.open(`${docsUrl}/${currentPath}`, '_blank')
|
|
}
|
|
|
|
const refreshDocs = () => {
|
|
setIsLoading(true)
|
|
setCurrentPath(currentPath + '?refresh=' + Date.now())
|
|
setTimeout(() => setCurrentPath(currentPath), 100)
|
|
}
|
|
|
|
if (isFullscreen) {
|
|
return (
|
|
<div className="fixed inset-0 z-50 bg-white">
|
|
<div className="absolute top-0 left-0 right-0 h-12 bg-slate-900 flex items-center justify-between px-4 z-10">
|
|
<div className="flex items-center gap-2 text-white">
|
|
<BookOpen className="w-5 h-5" />
|
|
<span className="font-semibold">BreakPilot Compliance Dokumentation</span>
|
|
</div>
|
|
<div className="flex items-center gap-2">
|
|
<button
|
|
onClick={openInNewTab}
|
|
className="p-2 text-slate-300 hover:text-white hover:bg-slate-700 rounded transition-colors"
|
|
title="In neuem Tab oeffnen"
|
|
>
|
|
<ExternalLink className="w-4 h-4" />
|
|
</button>
|
|
<button
|
|
onClick={toggleFullscreen}
|
|
className="p-2 text-slate-300 hover:text-white hover:bg-slate-700 rounded transition-colors"
|
|
title="Vollbild beenden"
|
|
>
|
|
<Minimize2 className="w-4 h-4" />
|
|
</button>
|
|
</div>
|
|
</div>
|
|
<iframe
|
|
src={`${docsUrl}/${currentPath}`}
|
|
className="w-full h-full pt-12"
|
|
title="BreakPilot Compliance Documentation"
|
|
onLoad={handleIframeLoad}
|
|
/>
|
|
</div>
|
|
)
|
|
}
|
|
|
|
return (
|
|
<div className="space-y-6">
|
|
{/* Quick Links */}
|
|
<div className="bg-white border border-slate-200 rounded-xl p-4">
|
|
<h3 className="text-sm font-semibold text-slate-700 mb-3 flex items-center gap-2">
|
|
<Search className="w-4 h-4" />
|
|
Schnellzugriff
|
|
</h3>
|
|
<div className="grid grid-cols-2 md:grid-cols-3 lg:grid-cols-6 gap-2">
|
|
{quickLinks.map((link) => (
|
|
<button
|
|
key={link.path}
|
|
onClick={() => navigateTo(link.path)}
|
|
className="flex items-center gap-2 px-3 py-2 text-sm bg-slate-50 hover:bg-slate-100 border border-slate-200 rounded-lg transition-colors text-left"
|
|
>
|
|
<span>{link.icon}</span>
|
|
<span className="truncate">{link.name}</span>
|
|
</button>
|
|
))}
|
|
</div>
|
|
</div>
|
|
|
|
{/* Toolbar */}
|
|
<div className="flex items-center justify-between bg-white border border-slate-200 rounded-xl p-3">
|
|
<div className="flex items-center gap-2">
|
|
<BookOpen className="w-5 h-5 text-slate-500" />
|
|
<span className="text-sm font-medium text-slate-700">
|
|
BreakPilot Compliance Dokumentation
|
|
</span>
|
|
<span className="text-xs text-slate-400">
|
|
(MkDocs Material)
|
|
</span>
|
|
</div>
|
|
<div className="flex items-center gap-2">
|
|
<button
|
|
onClick={refreshDocs}
|
|
className="p-2 text-slate-500 hover:text-slate-700 hover:bg-slate-100 rounded-lg transition-colors"
|
|
title="Aktualisieren"
|
|
>
|
|
<RefreshCw className={`w-4 h-4 ${isLoading ? 'animate-spin' : ''}`} />
|
|
</button>
|
|
<button
|
|
onClick={openInNewTab}
|
|
className="p-2 text-slate-500 hover:text-slate-700 hover:bg-slate-100 rounded-lg transition-colors"
|
|
title="In neuem Tab oeffnen"
|
|
>
|
|
<ExternalLink className="w-4 h-4" />
|
|
</button>
|
|
<button
|
|
onClick={toggleFullscreen}
|
|
className="p-2 text-slate-500 hover:text-slate-700 hover:bg-slate-100 rounded-lg transition-colors"
|
|
title="Vollbild"
|
|
>
|
|
<Maximize2 className="w-4 h-4" />
|
|
</button>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Documentation Iframe */}
|
|
<div className="relative bg-white border border-slate-200 rounded-xl overflow-hidden" style={{ height: 'calc(100vh - 350px)', minHeight: '500px' }}>
|
|
{isLoading && (
|
|
<div className="absolute inset-0 bg-white flex items-center justify-center z-10">
|
|
<div className="flex flex-col items-center gap-3">
|
|
<div className="w-8 h-8 border-2 border-slate-300 border-t-slate-600 rounded-full animate-spin" />
|
|
<span className="text-sm text-slate-500">Dokumentation wird geladen...</span>
|
|
</div>
|
|
</div>
|
|
)}
|
|
<iframe
|
|
key={currentPath}
|
|
src={`${docsUrl}/${currentPath}`}
|
|
className="w-full h-full"
|
|
title="BreakPilot Compliance Documentation"
|
|
onLoad={handleIframeLoad}
|
|
/>
|
|
</div>
|
|
|
|
{/* Info Box */}
|
|
<div className="bg-slate-50 border border-slate-200 rounded-xl p-4">
|
|
<div className="flex items-start gap-3">
|
|
<div className="p-2 bg-slate-200 rounded-lg">
|
|
<ArrowRight className="w-4 h-4 text-slate-600" />
|
|
</div>
|
|
<div>
|
|
<h4 className="font-medium text-slate-800">Dokumentation bearbeiten</h4>
|
|
<p className="text-sm text-slate-600 mt-1">
|
|
Die Dokumentation befindet sich im Repository unter <code className="text-xs bg-slate-200 px-1.5 py-0.5 rounded">docs-src/</code>.
|
|
Nach Aenderungen muss der Docs-Container neu gebaut werden:
|
|
</p>
|
|
<div className="mt-2 text-xs text-slate-500 font-mono bg-slate-100 p-2 rounded">
|
|
docker compose --profile docs build docs && docker compose --profile docs up -d docs
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
)
|
|
}
|