From 0870dab760cc68fe2787985810a4d24cf1ba09dc Mon Sep 17 00:00:00 2001 From: admin-valentin Date: Sat, 1 Aug 2026 21:00:10 +0000 Subject: [PATCH] feat(CC-057): add Consent Management page with toggle switches per purpose + history --- src/app/dashboard/privacy/consents/page.tsx | 185 ++++++++++++++++++++ 1 file changed, 185 insertions(+) create mode 100644 src/app/dashboard/privacy/consents/page.tsx diff --git a/src/app/dashboard/privacy/consents/page.tsx b/src/app/dashboard/privacy/consents/page.tsx new file mode 100644 index 0000000..c5f059b --- /dev/null +++ b/src/app/dashboard/privacy/consents/page.tsx @@ -0,0 +1,185 @@ +'use client'; + +import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'; +import { apiFetch } from '../../../../lib/api'; +import { useSession } from '../../../../components/session-provider'; + +interface ConsentRecord { + id: string; + purpose: string; + grantedAt: string; + revokedAt: string | null; +} + +const PURPOSES = [ + { + id: 'ai_analysis', + label: 'Analiză AI a datelor personale', + desc: 'Permite AI Gateway să proceseze datele din CEO OS pentru recomandări, rezumate și analiză predictivă.', + category: 'AI & Automatizare', + }, + { + id: 'intelligence_enrichment', + label: 'Îmbogățire cu date externe', + desc: 'Permite corelarea profilului tău de business cu date externe (B2B intelligence, legal, market).', + category: 'AI & Automatizare', + }, + { + id: 'notification_analytics', + label: 'Analiticp notificări', + desc: 'Urmărire date de interacțiune cu notificările pentru optimizarea prioritizării și frecvenței.', + category: 'Notificări', + }, + { + id: 'data_export', + label: 'Export și portabilitate date', + desc: 'Permite exportul datelor tale în formate portabile (CSV, JSON) pentru migrare sau audit extern.', + category: 'Portabilitate', + }, + { + id: 'third_party_integration', + label: 'Integrări cu servicii terțe', + desc: 'Transmiterea selectivă a datelor către servicii integrate (ERP, contabilitate, CRM) pentru sincronizare.', + category: 'Integrări', + }, + { + id: 'research_processing', + label: 'Procesare Research Briefs', + desc: 'Generarea automată de rezumate și analiză AI pentru research briefs legate de organizații.', + category: 'AI & Automatizare', + }, +]; + +export default function ConsentsPage() { + const { activeTenant } = useSession(); + const tenantId = activeTenant?.tenantId ?? ''; + const qc = useQueryClient(); + + const { data: records = [], isLoading } = useQuery({ + queryKey: ['consents', tenantId], + queryFn: () => apiFetch('/v1/consents', { tenantId }), + enabled: Boolean(tenantId), + }); + + const activePurposes = new Set( + records.filter((r) => !r.revokedAt).map((r) => r.purpose), + ); + + const { mutate: toggleConsent, isPending } = useMutation({ + mutationFn: ({ purpose, active }: { purpose: string; active: boolean }) => + apiFetch( + active ? '/v1/consents/revoke' : '/v1/consents/grant', + { method: 'POST', body: { purpose }, tenantId }, + ), + onSuccess: () => qc.invalidateQueries({ queryKey: ['consents', tenantId] }), + }); + + const categories = [...new Set(PURPOSES.map((p) => p.category))]; + + return ( +
+
+

Consimțăminte

+

+ Controlezi exact ce procesări de date ai autorizat. Poți revoca oricând. +

+
+ + {isLoading ? ( +
Se încarcă…
+ ) : ( +
+ {categories.map((category) => ( +
+

+ {category} +

+
+ {PURPOSES.filter((p) => p.category === category).map((purpose) => { + const isActive = activePurposes.has(purpose.id); + const record = records.find((r) => r.purpose === purpose.id && !r.revokedAt); + + return ( +
+
+
+

{purpose.label}

+ {isActive && ( + + ACTIV + + )} +
+

{purpose.desc}

+ {record && ( +

+ Acordat la {new Date(record.grantedAt).toLocaleDateString('ro-RO', { + day: 'numeric', month: 'long', year: 'numeric', + })} +

+ )} +
+ +
+ ); + })} +
+
+ ))} + + {/* History */} + {records.filter((r) => r.revokedAt).length > 0 && ( +
+

+ Istoricul consimțămintelor +

+
+ {records.filter((r) => r.revokedAt).map((r) => ( +
+
+

+ {PURPOSES.find((p) => p.id === r.purpose)?.label ?? r.purpose} +

+

+ Acordat {new Date(r.grantedAt).toLocaleDateString('ro-RO')} + {' · '}Revocat {new Date(r.revokedAt!).toLocaleDateString('ro-RO')} +

+
+ + REVOCAT + +
+ ))} +
+
+ )} + +
+

+ Drepturile tale: Poți retrage orice consimțământ în orice moment. + Revocarea nu afectează procesările anterioare efectuate legal. Datele procesate pe baza consimțământului + revocat nu sunt șterse automat — trimite o cerere de ștergere din secțiunea Export & Ștergere. +

+
+
+ )} +
+ ); +}