Files
breakpilot-compliance/admin-compliance/app/sdk/einwilligungen/cookie-banner/_components/EmbedCodeViewer.tsx
Sharang Parnerkar 9096aad693 refactor(admin): split audit-checklist, cookie-banner, escalations pages
Each page.tsx was 750-780 LOC. Extracted React components to _components/
and custom hooks to _hooks/ next to each page.tsx. All three pages are now
under 215 LOC (well within the 500 LOC hard cap). Zero behavior changes.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-16 13:06:45 +02:00

97 lines
3.2 KiB
TypeScript

'use client'
import { useState, useMemo } from 'react'
import { Copy, Check } from 'lucide-react'
import { CookieBannerConfig } from '@/lib/sdk/einwilligungen/types'
import { generateEmbedCode } from '@/lib/sdk/einwilligungen/generator/cookie-banner'
interface EmbedCodeViewerProps {
config: CookieBannerConfig | null
}
export 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 (
<div className="flex items-center justify-center h-48 bg-slate-100 rounded-xl">
<p className="text-slate-400">Embed-Code wird generiert...</p>
</div>
)
}
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 (
<div className="border border-slate-200 rounded-xl overflow-hidden">
<div className="flex border-b border-slate-200 bg-slate-50">
{tabs.map((tab) => (
<button
key={tab.id}
onClick={() => setActiveTab(tab.id)}
className={`px-4 py-2 text-sm font-medium transition-colors ${
activeTab === tab.id
? 'bg-white text-indigo-600 border-b-2 border-indigo-600 -mb-px'
: 'text-slate-600 hover:text-slate-900'
}`}
>
{tab.label}
</button>
))}
</div>
<div className="relative">
<pre className="p-4 bg-slate-900 text-slate-100 text-sm font-mono overflow-x-auto max-h-[400px]">
{currentContent}
</pre>
<button
onClick={() => copyToClipboard(currentContent)}
className="absolute top-3 right-3 flex items-center gap-1.5 px-3 py-1.5 bg-slate-800 hover:bg-slate-700 text-slate-200 rounded-lg text-xs"
>
{copied ? (
<>
<Check className="w-3.5 h-3.5 text-green-400" />
Kopiert
</>
) : (
<>
<Copy className="w-3.5 h-3.5" />
Kopieren
</>
)}
</button>
</div>
{activeTab === 'script' && (
<div className="p-4 bg-amber-50 border-t border-amber-200">
<p className="text-sm text-amber-800">
<strong>Integration:</strong> Fuegen Sie den Script-Tag in den{' '}
<code className="bg-amber-100 px-1 rounded">&lt;head&gt;</code> oder vor dem
schliessenden{' '}
<code className="bg-amber-100 px-1 rounded">&lt;/body&gt;</code>-Tag ein.
</p>
</div>
)}
</div>
)
}