Files
breakpilot-compliance/admin-compliance/app/sdk/cookie-banner/_components/SiteSelector.tsx
T
Benjamin Admin 36d9f929c6 feat: Cookie-Banner Verarbeiter-Tabelle + Multi-Site UI (F9 + F3)
F9: Verarbeiter-Tabelle
- VendorTable.tsx: 82+ vendors grouped by category with expandable cookie details
- EmbeddableVendorHTML.tsx: Copy-pasteable HTML table for privacy policy
- Tab system: Konfiguration | Verarbeiter | Einbettung

F3: Multi-Site UI
- SiteSelector.tsx: Domain dropdown with "Neue Seite anlegen" dialog
- useCookieBanner hook extended with sites management
- Config/vendors reload per selected site

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-03 20:40:18 +02:00

77 lines
3.1 KiB
TypeScript

'use client'
import { useState } from 'react'
interface Site {
id: string
site_id: string
site_name: string
site_url: string
is_active: boolean
}
interface SiteSelectorProps {
sites: Site[]
activeSiteId: string | null
onSiteChange: (siteId: string) => void
onCreateSite: (data: { site_id: string; site_name: string; site_url: string }) => Promise<void>
}
export function SiteSelector({ sites, activeSiteId, onSiteChange, onCreateSite }: SiteSelectorProps) {
const [showCreate, setShowCreate] = useState(false)
const [newSite, setNewSite] = useState({ site_id: '', site_name: '', site_url: '' })
const [creating, setCreating] = useState(false)
const handleCreate = async () => {
if (!newSite.site_id || !newSite.site_name) return
setCreating(true)
try {
await onCreateSite(newSite)
setNewSite({ site_id: '', site_name: '', site_url: '' })
setShowCreate(false)
} finally {
setCreating(false)
}
}
return (
<div className="bg-white rounded-xl border border-gray-200 p-4">
<div className="flex items-center gap-4">
<div className="flex-1">
<label className="block text-xs font-medium text-gray-500 mb-1">Website / Domain</label>
<select value={activeSiteId || ''} onChange={e => onSiteChange(e.target.value)}
className="w-full px-3 py-2 text-sm border border-gray-200 rounded-lg focus:ring-1 focus:ring-purple-500 bg-white">
{sites.length === 0 && <option value="">Keine Sites konfiguriert</option>}
{sites.map(s => (
<option key={s.site_id} value={s.site_id}>
{s.site_name} ({s.site_url || s.site_id})
</option>
))}
</select>
</div>
<button onClick={() => setShowCreate(!showCreate)}
className="mt-5 px-3 py-2 text-sm bg-purple-50 text-purple-600 border border-purple-200 rounded-lg hover:bg-purple-100">
+ Neue Seite
</button>
</div>
{showCreate && (
<div className="mt-4 pt-4 border-t border-gray-100 grid grid-cols-3 gap-3">
<input value={newSite.site_id} onChange={e => setNewSite({ ...newSite, site_id: e.target.value })}
placeholder="Site-ID (z.B. main-website)" className="px-3 py-2 text-sm border border-gray-200 rounded-lg" />
<input value={newSite.site_name} onChange={e => setNewSite({ ...newSite, site_name: e.target.value })}
placeholder="Name (z.B. Hauptwebsite)" className="px-3 py-2 text-sm border border-gray-200 rounded-lg" />
<div className="flex gap-2">
<input value={newSite.site_url} onChange={e => setNewSite({ ...newSite, site_url: e.target.value })}
placeholder="URL (z.B. https://example.com)" className="flex-1 px-3 py-2 text-sm border border-gray-200 rounded-lg" />
<button onClick={handleCreate} disabled={creating || !newSite.site_id}
className="px-3 py-2 text-sm bg-purple-600 text-white rounded-lg hover:bg-purple-700 disabled:opacity-50">
{creating ? '...' : 'Anlegen'}
</button>
</div>
</div>
)}
</div>
)
}