'use client'
/**
* PrivacyPolicyPreview Component
*
* Zeigt eine Vorschau der generierten Datenschutzerklaerung.
*/
import { useState } from 'react'
import {
FileText,
Download,
Globe,
Eye,
Code,
ChevronDown,
ChevronRight,
Copy,
Check,
} from 'lucide-react'
import {
GeneratedPrivacyPolicy,
PrivacyPolicySection,
SupportedLanguage,
ExportFormat,
} from '@/lib/sdk/einwilligungen/types'
// =============================================================================
// TYPES
// =============================================================================
interface PrivacyPolicyPreviewProps {
policy: GeneratedPrivacyPolicy | null
isLoading?: boolean
language: SupportedLanguage
format: ExportFormat
onLanguageChange: (language: SupportedLanguage) => void
onFormatChange: (format: ExportFormat) => void
onGenerate: () => void
onDownload?: (format: ExportFormat) => void
}
// =============================================================================
// MAIN COMPONENT
// =============================================================================
export function PrivacyPolicyPreview({
policy,
isLoading = false,
language,
format,
onLanguageChange,
onFormatChange,
onGenerate,
onDownload,
}: PrivacyPolicyPreviewProps) {
const [viewMode, setViewMode] = useState<'preview' | 'source'>('preview')
const [expandedSections, setExpandedSections] = useState>(new Set())
const [copied, setCopied] = useState(false)
const toggleSection = (sectionId: string) => {
setExpandedSections((prev) => {
const next = new Set(prev)
if (next.has(sectionId)) {
next.delete(sectionId)
} else {
next.add(sectionId)
}
return next
})
}
const expandAll = () => {
if (policy) {
setExpandedSections(new Set(policy.sections.map((s) => s.id)))
}
}
const collapseAll = () => {
setExpandedSections(new Set())
}
const copyToClipboard = async () => {
if (policy?.content) {
await navigator.clipboard.writeText(policy.content)
setCopied(true)
setTimeout(() => setCopied(false), 2000)
}
}
return (
{/* Controls */}
{/* Language Selector */}
{/* Format Selector */}
{/* View Mode Toggle */}
{policy && onDownload && (
)}
{/* Content */}
{policy ? (
{/* Header */}
{language === 'de' ? 'Datenschutzerklaerung' : 'Privacy Policy'}
Version {policy.version} |{' '}
{new Date(policy.generatedAt).toLocaleDateString(
language === 'de' ? 'de-DE' : 'en-US'
)}
|
{viewMode === 'source' && (
<>
|
>
)}
{/* Sections */}
{viewMode === 'preview' ? (
{policy.sections.map((section) => {
const isExpanded = expandedSections.has(section.id)
return (
{isExpanded && (
{section.isGenerated && (
Automatisch aus Datenpunkten generiert
)}
)}
)
})}
) : (
)}
) : (
Keine Datenschutzerklaerung generiert
Waehlen Sie die gewuenschten Datenpunkte aus und klicken Sie auf "Generieren", um eine
Datenschutzerklaerung zu erstellen.
)}
)
}
/**
* Formatiert Markdown-aehnlichen Content zu HTML
*/
function formatContent(content: string): string {
return content
.replace(/### (.+)/g, '$1
')
.replace(/## (.+)/g, '$1
')
.replace(/\*\*(.+?)\*\*/g, '$1')
.replace(/\n\n/g, '
')
.replace(/\n- /g, '
- ')
.replace(/
- (.+?)(?=
- |<\/p>|$)/g, '
- $1
')
.replace(/(- ]*>.*?<\/li>)+/g, '')
.replace(/<\/ul>
]*>/g, '')
.replace(/\n/g, '
')
}
export default PrivacyPolicyPreview