bdbc30e47b
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>
74 lines
2.0 KiB
TypeScript
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,
|
|
}
|
|
}
|