'use client' import { useState, useEffect } from 'react' import { API_BASE } from '../_types' import type { Tab, Document, Version, ApiEmailTemplate, ApiGdprProcess, ConsentStats, DsrOverview, EmailTemplateData, } from '../_types' export function useConsentData(activeTab: Tab, selectedDocument: string) { const [documents, setDocuments] = useState([]) const [versions, setVersions] = useState([]) const [loading, setLoading] = useState(true) const [error, setError] = useState(null) // Stats state const [consentStats, setConsentStats] = useState({ activeConsents: 0, documentCount: 0, openDSRs: 0 }) // GDPR tab state const [dsrCounts, setDsrCounts] = useState>({}) const [dsrOverview, setDsrOverview] = useState({ open: 0, completed: 0, in_progress: 0, overdue: 0 }) // Email template editor state const [savedTemplates, setSavedTemplates] = useState>({}) // API-backed email templates and GDPR processes const [apiEmailTemplates, setApiEmailTemplates] = useState([]) const [apiGdprProcesses, setApiGdprProcesses] = useState([]) const [templatesLoading, setTemplatesLoading] = useState(false) const [gdprLoading, setGdprLoading] = useState(false) const [savingTemplateId, setSavingTemplateId] = useState(null) const [savingProcessId, setSavingProcessId] = useState(null) // Auth token (in production, get from auth context) const [authToken, setAuthToken] = useState('') useEffect(() => { const token = localStorage.getItem('bp_admin_token') if (token) { setAuthToken(token) } // Load saved email templates from localStorage try { const saved = localStorage.getItem('sdk-email-templates') if (saved) { setSavedTemplates(JSON.parse(saved)) } } catch { /* ignore */ } }, []) useEffect(() => { if (activeTab === 'documents') { loadDocuments() } else if (activeTab === 'versions' && selectedDocument) { loadVersions(selectedDocument) } else if (activeTab === 'stats') { loadStats() } else if (activeTab === 'gdpr') { loadGDPRData() loadApiGdprProcesses() } else if (activeTab === 'emails') { loadApiEmailTemplates() } // eslint-disable-next-line react-hooks/exhaustive-deps }, [activeTab, selectedDocument, authToken]) async function loadApiEmailTemplates() { setTemplatesLoading(true) try { const res = await fetch('/api/sdk/v1/consent-templates') if (res.ok) { const data = await res.json() setApiEmailTemplates(Array.isArray(data) ? data : []) } } catch (err) { console.error('Failed to load email templates from API:', err) } finally { setTemplatesLoading(false) } } async function loadApiGdprProcesses() { setGdprLoading(true) try { const res = await fetch('/api/sdk/v1/consent-templates/gdpr-processes') if (res.ok) { const data = await res.json() setApiGdprProcesses(Array.isArray(data) ? data : []) } } catch (err) { console.error('Failed to load GDPR processes from API:', err) } finally { setGdprLoading(false) } } async function saveApiEmailTemplate(template: { id: string; subject: string; body: string }) { setSavingTemplateId(template.id) try { const res = await fetch(`/api/sdk/v1/consent-templates/${template.id}`, { method: 'PUT', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ subject: template.subject, body: template.body }), }) if (res.ok) { const updated = await res.json() setApiEmailTemplates(prev => prev.map(t => t.id === updated.id ? updated : t)) } } catch (err) { console.error('Failed to save email template:', err) } finally { setSavingTemplateId(null) } } async function saveApiGdprProcess(process: { id: string; title: string; description: string }) { setSavingProcessId(process.id) try { const res = await fetch(`/api/sdk/v1/consent-templates/gdpr-processes/${process.id}`, { method: 'PUT', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ title: process.title, description: process.description }), }) if (res.ok) { const updated = await res.json() setApiGdprProcesses(prev => prev.map(p => p.id === updated.id ? updated : p)) } } catch (err) { console.error('Failed to save GDPR process:', err) } finally { setSavingProcessId(null) } } async function loadDocuments() { setLoading(true) setError(null) try { const res = await fetch(`${API_BASE}/documents`, { headers: authToken ? { 'Authorization': `Bearer ${authToken}` } : {} }) if (res.ok) { const data = await res.json() setDocuments(data.documents || []) } else { const errorData = await res.json().catch(() => ({})) setError(errorData.error || 'Fehler beim Laden der Dokumente') } } catch { setError('Verbindungsfehler zum Server') } finally { setLoading(false) } } async function loadVersions(docId: string) { setLoading(true) setError(null) try { const res = await fetch(`${API_BASE}/documents/${docId}/versions`, { headers: authToken ? { 'Authorization': `Bearer ${authToken}` } : {} }) if (res.ok) { const data = await res.json() setVersions(data.versions || []) } else { const errorData = await res.json().catch(() => ({})) setError(errorData.error || 'Fehler beim Laden der Versionen') } } catch { setError('Verbindungsfehler zum Server') } finally { setLoading(false) } } async function loadStats() { try { const token = localStorage.getItem('bp_admin_token') const [statsRes, docsRes] = await Promise.all([ fetch(`${API_BASE}/stats`, { headers: token ? { 'Authorization': `Bearer ${token}` } : {} }), fetch(`${API_BASE}/documents`, { headers: token ? { 'Authorization': `Bearer ${token}` } : {} }), ]) let activeConsents = 0 let documentCount = 0 let openDSRs = 0 if (statsRes.ok) { const statsData = await statsRes.json() activeConsents = statsData.total_consents || statsData.active_consents || 0 } if (docsRes.ok) { const docsData = await docsRes.json() documentCount = (docsData.documents || []).length } // Try to get DSR count try { const dsrRes = await fetch('/api/sdk/v1/compliance/dsr', { headers: { 'X-Tenant-ID': localStorage.getItem('bp_tenant_id') || '', 'X-User-ID': localStorage.getItem('bp_user_id') || '', } }) if (dsrRes.ok) { const dsrData = await dsrRes.json() const dsrs = dsrData.dsrs || [] openDSRs = dsrs.filter((r: any) => r.status !== 'completed' && r.status !== 'rejected').length } } catch { /* DSR endpoint might not be available */ } setConsentStats({ activeConsents, documentCount, openDSRs }) } catch (err) { console.error('Failed to load stats:', err) } } async function loadGDPRData() { try { const res = await fetch('/api/sdk/v1/compliance/dsr', { headers: { 'X-Tenant-ID': localStorage.getItem('bp_tenant_id') || '', 'X-User-ID': localStorage.getItem('bp_user_id') || '', } }) if (!res.ok) return const data = await res.json() const dsrs = data.dsrs || [] const now = new Date() // Count per article type const counts: Record = {} const typeMapping: Record = { 'access': '15', 'rectification': '16', 'erasure': '17', 'restriction': '18', 'portability': '20', 'objection': '21', } for (const dsr of dsrs) { if (dsr.status === 'completed' || dsr.status === 'rejected') continue const article = typeMapping[dsr.request_type] if (article) { counts[article] = (counts[article] || 0) + 1 } } setDsrCounts(counts) // Calculate overview const open = dsrs.filter((r: any) => r.status === 'received' || r.status === 'verified').length const completed = dsrs.filter((r: any) => r.status === 'completed').length const in_progress = dsrs.filter((r: any) => r.status === 'in_progress').length const overdue = dsrs.filter((r: any) => { if (r.status === 'completed' || r.status === 'rejected') return false const deadline = r.extended_deadline_at ? new Date(r.extended_deadline_at) : new Date(r.deadline_at) return deadline < now }).length setDsrOverview({ open, completed, in_progress, overdue }) } catch (err) { console.error('Failed to load GDPR data:', err) } } function saveEmailTemplate(template: EmailTemplateData) { const updated = { ...savedTemplates, [template.key]: template } setSavedTemplates(updated) localStorage.setItem('sdk-email-templates', JSON.stringify(updated)) } return { documents, versions, loading, error, setError, consentStats, dsrCounts, dsrOverview, savedTemplates, saveEmailTemplate, apiEmailTemplates, apiGdprProcesses, templatesLoading, gdprLoading, savingTemplateId, savingProcessId, saveApiEmailTemplate, saveApiGdprProcess, loadApiEmailTemplates, authToken, setAuthToken, } }