Files
breakpilot-compliance/admin-compliance/app/sdk/consent-management/page.tsx
T
Benjamin Admin bb1f5d6c94 feat: Document Workflow wiring + Email system consolidation
Document Workflow:
- "Als Version speichern" button in Document Generator preview
- Creates document + version via /legal-documents/documents API
- Saved documents appear in /sdk/workflow module
- Status indicator (saving/saved/error) in toolbar

Email Consolidation:
- consent-management Emails tab now redirects to /sdk/email-templates
- Single source of truth for all email templates
- Old tab replaced with redirect card explaining the change

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-04 07:57:33 +02:00

215 lines
7.6 KiB
TypeScript

'use client'
/**
* Consent Management Page (SDK Version)
*
* Admin interface for managing:
* - Documents (AGB, Privacy, etc.)
* - Document Versions
* - Email Templates
* - GDPR Processes (Art. 15-21)
* - Statistics
*/
import { useState } from 'react'
import { useRouter } from 'next/navigation'
import { useSDK } from '@/lib/sdk'
import StepHeader from '@/components/sdk/StepHeader/StepHeader'
import type { Tab, EmailTemplateData } from './_types'
import { useConsentData } from './_hooks/useConsentData'
import { DocumentsTab } from './_components/DocumentsTab'
import { VersionsTab } from './_components/VersionsTab'
import { EmailsTab } from './_components/EmailsTab'
import { GdprTab } from './_components/GdprTab'
import { StatsTab } from './_components/StatsTab'
import { ConsentTemplateCreateModal } from './_components/ConsentTemplateCreateModal'
import { EmailTemplateEditModal, EmailTemplatePreviewModal } from './_components/EmailTemplateModals'
import { DeadlineTab } from './_components/DeadlineTab'
import { IntegrationStubs } from './_components/IntegrationStubs'
export default function ConsentManagementPage() {
const { state } = useSDK()
const router = useRouter()
const [activeTab, setActiveTab] = useState<Tab>('documents')
const [showCreateTemplateModal, setShowCreateTemplateModal] = useState(false)
const [selectedDocument, setSelectedDocument] = useState<string>('')
const [editingTemplate, setEditingTemplate] = useState<EmailTemplateData | null>(null)
const [previewTemplate, setPreviewTemplate] = useState<EmailTemplateData | null>(null)
const {
documents, versions, loading, error, setError,
consentStats, dsrCounts, dsrOverview,
savedTemplates, saveEmailTemplate,
apiEmailTemplates, apiGdprProcesses,
templatesLoading, gdprLoading,
savingTemplateId, savingProcessId,
saveApiEmailTemplate, saveApiGdprProcess,
loadApiEmailTemplates,
submitVersionForReview, approveVersion, rejectVersion, publishVersion,
authToken, setAuthToken,
} = useConsentData(activeTab, selectedDocument)
const tabs: { id: Tab; label: string }[] = [
{ id: 'documents', label: 'Dokumente' },
{ id: 'versions', label: 'Versionen' },
{ id: 'emails', label: 'E-Mail Vorlagen' },
{ id: 'gdpr', label: 'DSGVO Prozesse' },
{ id: 'stats', label: 'Statistiken' },
{ id: 'deadlines', label: 'Fristen' },
{ id: 'integrations', label: 'Integrationen' },
]
return (
<div className="space-y-6">
<StepHeader stepId="consent-management" showProgress={true} />
{/* Token Input */}
{!authToken && (
<div className="bg-white rounded-xl border border-slate-200 p-4">
<label className="block text-sm font-medium text-slate-700 mb-2">
Admin Token
</label>
<input
type="password"
placeholder="JWT Token eingeben..."
className="w-full px-3 py-2 border border-slate-300 rounded-lg text-sm"
onChange={(e) => {
setAuthToken(e.target.value)
localStorage.setItem('bp_admin_token', e.target.value)
}}
/>
</div>
)}
{/* Tabs */}
<div>
<div className="flex gap-1 bg-slate-100 p-1 rounded-lg w-fit">
{tabs.map((tab) => (
<button
key={tab.id}
onClick={() => setActiveTab(tab.id)}
className={`px-4 py-2 text-sm font-medium rounded-md transition-colors ${
activeTab === tab.id
? 'bg-white text-slate-900 shadow-sm'
: 'text-slate-600 hover:text-slate-900'
}`}
>
{tab.label}
</button>
))}
</div>
</div>
{/* Content */}
<div>
{error && (
<div className="mb-4 p-4 bg-red-50 border border-red-200 text-red-700 rounded-lg">
{error}
<button
onClick={() => setError(null)}
className="ml-4 text-red-500 hover:text-red-700"
>
X
</button>
</div>
)}
<div className="bg-white rounded-xl border border-slate-200 shadow-sm">
{activeTab === 'documents' && (
<DocumentsTab
loading={loading}
documents={documents}
setSelectedDocument={setSelectedDocument}
setActiveTab={setActiveTab}
/>
)}
{activeTab === 'versions' && (
<VersionsTab
loading={loading}
documents={documents}
versions={versions}
selectedDocument={selectedDocument}
setSelectedDocument={setSelectedDocument}
onSubmitReview={submitVersionForReview}
onApprove={approveVersion}
onReject={rejectVersion}
onPublish={publishVersion}
/>
)}
{activeTab === 'emails' && (
<div className="bg-purple-50 border border-purple-200 rounded-xl p-8 text-center">
<div className="w-14 h-14 mx-auto mb-4 bg-purple-100 rounded-xl flex items-center justify-center">
<svg className="w-7 h-7 text-purple-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M3 8l7.89 5.26a2 2 0 002.22 0L21 8M5 19h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z" />
</svg>
</div>
<h3 className="font-semibold text-gray-900 mb-2">E-Mail-Templates wurden zentralisiert</h3>
<p className="text-sm text-gray-600 mb-4">
Alle E-Mail-Vorlagen (DSR, Consent, Breach, Training, etc.) werden jetzt zentral
im E-Mail-Template-Modul verwaltet mit Versionierung, Freigabe-Workflow und Audit-Log.
</p>
<button
onClick={() => router.push('/sdk/email-templates')}
className="px-6 py-2.5 bg-purple-600 text-white text-sm font-medium rounded-lg hover:bg-purple-700 transition-colors"
>
Zu E-Mail-Templates
</button>
</div>
)}
{activeTab === 'gdpr' && (
<GdprTab
router={router}
apiGdprProcesses={apiGdprProcesses}
gdprLoading={gdprLoading}
savingProcessId={savingProcessId}
saveApiGdprProcess={saveApiGdprProcess}
dsrCounts={dsrCounts}
dsrOverview={dsrOverview}
/>
)}
{activeTab === 'stats' && <StatsTab consentStats={consentStats} />}
{activeTab === 'deadlines' && <DeadlineTab />}
{activeTab === 'integrations' && <IntegrationStubs />}
</div>
</div>
{/* Email Template Edit Modal */}
{editingTemplate && (
<EmailTemplateEditModal
editingTemplate={editingTemplate}
onChange={setEditingTemplate}
onClose={() => setEditingTemplate(null)}
onSave={(tpl) => {
saveEmailTemplate(tpl)
setEditingTemplate(null)
}}
/>
)}
{/* Consent Template Create Modal */}
{showCreateTemplateModal && (
<ConsentTemplateCreateModal
onClose={() => setShowCreateTemplateModal(false)}
onSuccess={() => { setShowCreateTemplateModal(false); loadApiEmailTemplates() }}
/>
)}
{/* Email Template Preview Modal */}
{previewTemplate && (
<EmailTemplatePreviewModal
previewTemplate={previewTemplate}
onClose={() => setPreviewTemplate(null)}
/>
)}
</div>
)
}