Files
breakpilot-compliance/admin-compliance/app/sdk/einwilligungen/_hooks/useBannerConsents.ts
T
Benjamin Admin bdbc30e47b feat(cmp): unified consent view — Website-Besucher + Login-Nutzer tabs
Merges two separate consent views into one unified page at /sdk/einwilligungen:
- Tab "Website-Besucher": device-based banner consents with site selector
- Tab "Login-Nutzer": user-based DSGVO consents (existing, unchanged)

Backend:
- New endpoint GET /admin/consents for paginated banner consent records
- Fix: categories JSON string parsing (was iterating chars instead of array)

CMP Dashboard:
- Dynamic site selector replacing hardcoded "preview-test-site"

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-10 22:41:56 +02:00

74 lines
2.0 KiB
TypeScript

import { useState, useEffect, useCallback } from 'react'
import { BannerConsentRecord, BannerConsentStats, BannerSite, PAGE_SIZE } from '../_types'
const BANNER_API = '/api/sdk/v1/banner'
const TENANT_ID = '9282a473-5c95-4b3a-bf78-0ecc0ec71d3e'
const HEADERS = { 'x-tenant-id': TENANT_ID }
function fb(path: string) {
return fetch(`${BANNER_API}/${path}`, { headers: HEADERS })
.then(r => r.ok ? r.json() : null)
.catch(() => null)
}
export function useBannerConsents() {
const [records, setRecords] = useState<BannerConsentRecord[]>([])
const [sites, setSites] = useState<BannerSite[]>([])
const [selectedSite, setSelectedSite] = useState<string>('')
const [stats, setStats] = useState<BannerConsentStats | null>(null)
const [currentPage, setCurrentPage] = useState(1)
const [totalRecords, setTotalRecords] = useState(0)
const [loading, setLoading] = useState(true)
// Load sites on mount
useEffect(() => {
fb('admin/sites').then(data => {
const list = Array.isArray(data) ? data : []
setSites(list)
if (list.length > 0) {
setSelectedSite(list[0].site_id)
}
setLoading(false)
})
}, [])
// Load consents + stats when site or page changes
const loadData = useCallback(async () => {
if (!selectedSite) return
setLoading(true)
const offset = (currentPage - 1) * PAGE_SIZE
const [consentsData, statsData] = await Promise.all([
fb(`admin/consents?site_id=${selectedSite}&limit=${PAGE_SIZE}&offset=${offset}`),
fb(`admin/stats/${selectedSite}`),
])
if (consentsData) {
setRecords(consentsData.consents || [])
setTotalRecords(consentsData.total || 0)
}
setStats(statsData)
setLoading(false)
}, [selectedSite, currentPage])
useEffect(() => {
loadData()
}, [loadData])
const changeSite = (siteId: string) => {
setSelectedSite(siteId)
setCurrentPage(1)
}
return {
records,
sites,
selectedSite,
changeSite,
stats,
currentPage,
setCurrentPage,
totalRecords,
loading,
reload: loadData,
}
}