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>
97 lines
3.2 KiB
TypeScript
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"><head></code> oder vor dem
|
|
schliessenden{' '}
|
|
<code className="bg-amber-100 px-1 rounded"></body></code>-Tag ein.
|
|
</p>
|
|
</div>
|
|
)}
|
|
</div>
|
|
)
|
|
}
|