'use client'
/**
* Cookie Banner Configuration Page
*
* Konfiguriert den Cookie-Banner basierend auf dem Datenpunktkatalog.
*/
import { useState, useEffect, useMemo } from 'react'
import { useSDK } from '@/lib/sdk'
import { StepHeader, STEP_EXPLANATIONS } from '@/components/sdk/StepHeader'
import {
EinwilligungenProvider,
useEinwilligungen,
} from '@/lib/sdk/einwilligungen/context'
import {
generateCookieBannerConfig,
generateEmbedCode,
DEFAULT_COOKIE_BANNER_TEXTS,
DEFAULT_COOKIE_BANNER_STYLING,
} from '@/lib/sdk/einwilligungen/generator/cookie-banner'
import {
CookieBannerConfig,
CookieBannerStyling,
CookieBannerTexts,
SupportedLanguage,
} from '@/lib/sdk/einwilligungen/types'
import {
Cookie,
Settings,
Palette,
Code,
Copy,
Check,
Eye,
ArrowLeft,
Monitor,
Smartphone,
Tablet,
ChevronDown,
ChevronRight,
ExternalLink,
} from 'lucide-react'
import Link from 'next/link'
// =============================================================================
// STYLING FORM
// =============================================================================
interface StylingFormProps {
styling: CookieBannerStyling
onChange: (styling: CookieBannerStyling) => void
}
function StylingForm({ styling, onChange }: StylingFormProps) {
const handleChange = (field: keyof CookieBannerStyling, value: string | number) => {
onChange({ ...styling, [field]: value })
}
return (
{/* Position */}
{(['BOTTOM', 'TOP', 'CENTER'] as const).map((pos) => (
))}
{/* Theme */}
{(['LIGHT', 'DARK'] as const).map((theme) => (
))}
{/* Colors */}
{/* Border Radius & Max Width */}
)
}
// =============================================================================
// TEXTS FORM
// =============================================================================
interface TextsFormProps {
texts: CookieBannerTexts
language: SupportedLanguage
onChange: (texts: CookieBannerTexts) => void
}
function TextsForm({ texts, language, onChange }: TextsFormProps) {
const handleChange = (field: keyof CookieBannerTexts, value: string) => {
onChange({
...texts,
[field]: { ...texts[field], [language]: value },
})
}
const fields: { key: keyof CookieBannerTexts; label: string; multiline?: boolean }[] = [
{ key: 'title', label: 'Titel' },
{ key: 'description', label: 'Beschreibung', multiline: true },
{ key: 'acceptAll', label: 'Alle akzeptieren Button' },
{ key: 'rejectAll', label: 'Nur notwendige Button' },
{ key: 'customize', label: 'Einstellungen Button' },
{ key: 'save', label: 'Speichern Button' },
{ key: 'privacyPolicyLink', label: 'Datenschutz-Link Text' },
]
return (
{fields.map(({ key, label, multiline }) => (
{multiline ? (
))}
)
}
// =============================================================================
// BANNER PREVIEW
// =============================================================================
interface BannerPreviewProps {
config: CookieBannerConfig | null
language: SupportedLanguage
device: 'desktop' | 'tablet' | 'mobile'
}
function BannerPreview({ config, language, device }: BannerPreviewProps) {
const [showDetails, setShowDetails] = useState(false)
if (!config) {
return (
Konfiguration wird geladen...
)
}
const isDark = config.styling.theme === 'DARK'
const bgColor = isDark ? '#1e293b' : config.styling.backgroundColor || '#ffffff'
const textColor = isDark ? '#f1f5f9' : config.styling.textColor || '#1e293b'
const deviceWidths = {
desktop: '100%',
tablet: '768px',
mobile: '375px',
}
return (
{/* Simulated Browser */}
{/* Page Content */}
{/* Placeholder Content */}
{/* Overlay */}
{/* Cookie Banner */}
{config.texts.title[language]}
{config.texts.description[language]}
{showDetails && (
{config.categories.map((cat) => (
{cat.name[language]}
{cat.description[language]}
))}
)}
{config.texts.privacyPolicyLink[language]}
)
}
// =============================================================================
// EMBED CODE VIEWER
// =============================================================================
interface EmbedCodeViewerProps {
config: CookieBannerConfig | null
}
function EmbedCodeViewer({ config }: EmbedCodeViewerProps) {
const [activeTab, setActiveTab] = useState<'script' | 'html' | 'css' | 'js'>('script')
const [copied, setCopied] = useState(false)
const embedCode = useMemo(() => {
if (!config) return null
return generateEmbedCode(config, '/datenschutz')
}, [config])
const copyToClipboard = async (text: string) => {
await navigator.clipboard.writeText(text)
setCopied(true)
setTimeout(() => setCopied(false), 2000)
}
if (!embedCode) {
return (
Embed-Code wird generiert...
)
}
const tabs = [
{ id: 'script', label: 'Script-Tag', content: embedCode.scriptTag },
{ id: 'html', label: 'HTML', content: embedCode.html },
{ id: 'css', label: 'CSS', content: embedCode.css },
{ id: 'js', label: 'JavaScript', content: embedCode.js },
] as const
const currentContent = tabs.find((t) => t.id === activeTab)?.content || ''
return (
{/* Tabs */}
{tabs.map((tab) => (
))}
{/* Code */}
{currentContent}
{/* Integration Instructions */}
{activeTab === 'script' && (
Integration: Fuegen Sie den Script-Tag in den{' '}
<head> oder vor dem
schliessenden{' '}
</body>-Tag ein.
)}
)
}
// =============================================================================
// CATEGORY LIST
// =============================================================================
interface CategoryListProps {
config: CookieBannerConfig | null
language: SupportedLanguage
}
function CategoryList({ config, language }: CategoryListProps) {
const [expandedCategories, setExpandedCategories] = useState>(new Set())
if (!config) return null
const toggleCategory = (id: string) => {
setExpandedCategories((prev) => {
const next = new Set(prev)
if (next.has(id)) {
next.delete(id)
} else {
next.add(id)
}
return next
})
}
return (
{config.categories.map((cat) => {
const isExpanded = expandedCategories.has(cat.id)
return (
{isExpanded && (
{cat.description[language]}
{cat.cookies.length > 0 && (
Cookies
{cat.cookies.map((cookie, idx) => (
{cookie.name}
({cookie.provider})
{cookie.expiry}
))}
)}
)}
)
})}
)
}
// =============================================================================
// MAIN CONTENT
// =============================================================================
function CookieBannerContent() {
const { state } = useSDK()
const { allDataPoints } = useEinwilligungen()
const [styling, setStyling] = useState(DEFAULT_COOKIE_BANNER_STYLING)
const [texts, setTexts] = useState(DEFAULT_COOKIE_BANNER_TEXTS)
const [language, setLanguage] = useState('de')
const [activeTab, setActiveTab] = useState<'styling' | 'texts' | 'embed' | 'categories'>('styling')
const [device, setDevice] = useState<'desktop' | 'tablet' | 'mobile'>('desktop')
const config = useMemo(() => {
return generateCookieBannerConfig(
state.tenantId || 'demo',
allDataPoints,
texts,
styling
)
}, [state.tenantId, allDataPoints, texts, styling])
const cookieDataPoints = useMemo(
() => allDataPoints.filter((dp) => dp.cookieCategory !== null),
[allDataPoints]
)
return (
{/* Back Link */}
Zurueck zum Katalog
{/* Header */}
Cookie-Banner Konfiguration
Konfigurieren Sie Ihren DSGVO-konformen Cookie-Banner.
{/* Stats */}
Kategorien
{config?.categories.length || 0}
Cookie-Datenpunkte
{cookieDataPoints.length}
Erforderlich
{config?.categories.filter((c) => c.isRequired).length || 0}
Optional
{config?.categories.filter((c) => !c.isRequired).length || 0}
{/* Two Column Layout */}
{/* Left: Configuration */}
{/* Tabs */}
{[
{ id: 'styling', label: 'Design', icon: Palette },
{ id: 'texts', label: 'Texte', icon: Settings },
{ id: 'categories', label: 'Kategorien', icon: Cookie },
{ id: 'embed', label: 'Embed-Code', icon: Code },
].map(({ id, label, icon: Icon }) => (
))}
{/* Tab Content */}
{activeTab === 'styling' && (
)}
{activeTab === 'texts' && (
)}
{activeTab === 'categories' && (
)}
{activeTab === 'embed' && }
{/* Right: Preview */}
{/* Device Selector */}
Vorschau
{[
{ id: 'desktop', icon: Monitor },
{ id: 'tablet', icon: Tablet },
{ id: 'mobile', icon: Smartphone },
].map(({ id, icon: Icon }) => (
))}
{/* Preview */}
)
}
// =============================================================================
// MAIN PAGE
// =============================================================================
export default function CookieBannerPage() {
return (
)
}