Agent-completed splits committed after agents hit rate limits before committing their work. All 4 pages now under 500 LOC: - consent-management: 1303 -> 193 LOC (+ 7 _components, _hooks, _data, _types) - control-library: 1210 -> 298 LOC (+ _components, _types) - incidents: 1150 -> 373 LOC (+ _components) - training: 1127 -> 366 LOC (+ _components) Verification: next build clean (142 pages generated). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
118 lines
4.8 KiB
TypeScript
118 lines
4.8 KiB
TypeScript
'use client'
|
|
|
|
import type { EmailTemplateData } from '../_types'
|
|
|
|
export function EmailTemplateEditModal({
|
|
editingTemplate,
|
|
onChange,
|
|
onClose,
|
|
onSave,
|
|
}: {
|
|
editingTemplate: EmailTemplateData
|
|
onChange: (tpl: EmailTemplateData) => void
|
|
onClose: () => void
|
|
onSave: (tpl: EmailTemplateData) => void
|
|
}) {
|
|
return (
|
|
<div className="fixed inset-0 bg-black/50 flex items-center justify-center z-50">
|
|
<div className="bg-white rounded-xl shadow-xl max-w-2xl w-full mx-4 max-h-[90vh] overflow-y-auto">
|
|
<div className="px-6 py-4 border-b border-slate-200 flex items-center justify-between">
|
|
<h3 className="font-semibold text-slate-900">E-Mail Vorlage bearbeiten</h3>
|
|
<button onClick={onClose} className="text-slate-400 hover:text-slate-600">
|
|
<svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M6 18L18 6M6 6l12 12" />
|
|
</svg>
|
|
</button>
|
|
</div>
|
|
<div className="p-6 space-y-4">
|
|
<div>
|
|
<label className="block text-sm font-medium text-slate-700 mb-1">Betreff</label>
|
|
<input
|
|
type="text"
|
|
value={editingTemplate.subject}
|
|
onChange={(e) => onChange({ ...editingTemplate, subject: e.target.value })}
|
|
className="w-full px-3 py-2 border border-slate-300 rounded-lg text-sm"
|
|
/>
|
|
</div>
|
|
<div>
|
|
<label className="block text-sm font-medium text-slate-700 mb-1">Inhalt</label>
|
|
<textarea
|
|
value={editingTemplate.body}
|
|
onChange={(e) => onChange({ ...editingTemplate, body: e.target.value })}
|
|
rows={12}
|
|
className="w-full px-3 py-2 border border-slate-300 rounded-lg text-sm font-mono"
|
|
/>
|
|
</div>
|
|
<div className="bg-slate-50 rounded-lg p-3">
|
|
<div className="text-xs font-medium text-slate-500 mb-1">Verfuegbare Platzhalter:</div>
|
|
<div className="flex flex-wrap gap-2">
|
|
{['{{name}}', '{{email}}', '{{referenceNumber}}', '{{date}}', '{{deadline}}', '{{company}}'].map(v => (
|
|
<span key={v} className="px-2 py-0.5 bg-purple-100 text-purple-700 rounded text-xs font-mono">{v}</span>
|
|
))}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div className="px-6 py-4 border-t border-slate-200 flex justify-end gap-3">
|
|
<button onClick={onClose} className="px-4 py-2 text-sm text-slate-600 hover:bg-slate-100 rounded-lg">
|
|
Abbrechen
|
|
</button>
|
|
<button
|
|
onClick={() => onSave(editingTemplate)}
|
|
className="px-4 py-2 text-sm text-white bg-purple-600 hover:bg-purple-700 rounded-lg font-medium"
|
|
>
|
|
Speichern
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
)
|
|
}
|
|
|
|
export function EmailTemplatePreviewModal({
|
|
previewTemplate,
|
|
onClose,
|
|
}: {
|
|
previewTemplate: EmailTemplateData
|
|
onClose: () => void
|
|
}) {
|
|
const substitute = (text: string) =>
|
|
text
|
|
.replace(/\{\{name\}\}/g, 'Max Mustermann')
|
|
.replace(/\{\{email\}\}/g, 'max@example.de')
|
|
.replace(/\{\{referenceNumber\}\}/g, 'DSR-2025-000001')
|
|
.replace(/\{\{date\}\}/g, new Date().toLocaleDateString('de-DE'))
|
|
.replace(/\{\{deadline\}\}/g, '30 Tage')
|
|
.replace(/\{\{company\}\}/g, 'BreakPilot GmbH')
|
|
|
|
return (
|
|
<div className="fixed inset-0 bg-black/50 flex items-center justify-center z-50">
|
|
<div className="bg-white rounded-xl shadow-xl max-w-2xl w-full mx-4 max-h-[90vh] overflow-y-auto">
|
|
<div className="px-6 py-4 border-b border-slate-200 flex items-center justify-between">
|
|
<h3 className="font-semibold text-slate-900">Vorschau</h3>
|
|
<button onClick={onClose} className="text-slate-400 hover:text-slate-600">
|
|
<svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M6 18L18 6M6 6l12 12" />
|
|
</svg>
|
|
</button>
|
|
</div>
|
|
<div className="p-6 space-y-4">
|
|
<div className="bg-slate-50 rounded-lg p-4">
|
|
<div className="text-xs text-slate-500 mb-1">Betreff:</div>
|
|
<div className="font-medium text-slate-900">
|
|
{substitute(previewTemplate.subject)}
|
|
</div>
|
|
</div>
|
|
<div className="border border-slate-200 rounded-lg p-4 whitespace-pre-wrap text-sm text-slate-700">
|
|
{substitute(previewTemplate.body)}
|
|
</div>
|
|
</div>
|
|
<div className="px-6 py-4 border-t border-slate-200 flex justify-end">
|
|
<button onClick={onClose} className="px-4 py-2 text-sm text-slate-600 hover:bg-slate-100 rounded-lg">
|
|
Schliessen
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
)
|
|
}
|