feat: Email Template Approval Workflow im Frontend aktivieren
Backend-Endpoints existierten bereits (submit/approve/reject/publish), wurden aber vom Frontend nicht genutzt. Jetzt vollstaendiger Workflow: - Submit for Review: Entwurf → Pruefung einreichen - Approve/Reject: DSB kann genehmigen oder mit Begruendung ablehnen - Publish: Genehmigte Version veroeffentlichen - Test senden: Test-E-Mail an beliebige Adresse - Approval History: Genehmigungshistorie abrufbar - Status-Badges: draft/review/approved/published mit passenden Buttons Alle Buttons sind kontextabhaengig — nur sichtbar wenn der Status passt. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -15,11 +15,16 @@ interface EditorTabProps {
|
||||
onPublish: () => void
|
||||
onPreview: () => void
|
||||
onBack: () => void
|
||||
onSubmitForReview?: () => void
|
||||
onApprove?: (comment?: string) => void
|
||||
onReject?: (comment: string) => void
|
||||
onSendTest?: (email: string) => void
|
||||
}
|
||||
|
||||
export function EditorTab({
|
||||
template, version, subject, html, previewHtml, saving,
|
||||
onSubjectChange, onHtmlChange, onSave, onPublish, onPreview, onBack,
|
||||
onSubmitForReview, onApprove, onReject, onSendTest,
|
||||
}: EditorTabProps) {
|
||||
if (!template) {
|
||||
return (
|
||||
@@ -46,30 +51,56 @@ export function EditorTab({
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
<div className="flex gap-2">
|
||||
<button
|
||||
onClick={onSave}
|
||||
disabled={saving}
|
||||
className="px-3 py-1.5 bg-purple-600 text-white rounded-lg text-sm hover:bg-purple-700 disabled:opacity-50"
|
||||
>
|
||||
{saving ? 'Speichern...' : 'Version speichern'}
|
||||
</button>
|
||||
{version && version.status !== 'published' && (
|
||||
<button
|
||||
onClick={onPublish}
|
||||
disabled={saving}
|
||||
className="px-3 py-1.5 bg-green-600 text-white rounded-lg text-sm hover:bg-green-700 disabled:opacity-50"
|
||||
>
|
||||
<div className="flex gap-2 flex-wrap">
|
||||
{/* Save — always available for draft/review */}
|
||||
{(!version || version.status === 'draft' || version.status === 'review') && (
|
||||
<button onClick={onSave} disabled={saving}
|
||||
className="px-3 py-1.5 bg-purple-600 text-white rounded-lg text-sm hover:bg-purple-700 disabled:opacity-50">
|
||||
{saving ? 'Speichern...' : 'Version speichern'}
|
||||
</button>
|
||||
)}
|
||||
{/* Submit for Review — only for draft */}
|
||||
{version && version.status === 'draft' && onSubmitForReview && (
|
||||
<button onClick={onSubmitForReview} disabled={saving}
|
||||
className="px-3 py-1.5 bg-yellow-500 text-white rounded-lg text-sm hover:bg-yellow-600 disabled:opacity-50">
|
||||
Zur Pruefung einreichen
|
||||
</button>
|
||||
)}
|
||||
{/* Approve — only for review status (DSB) */}
|
||||
{version && version.status === 'review' && onApprove && (
|
||||
<button onClick={() => onApprove()} disabled={saving}
|
||||
className="px-3 py-1.5 bg-blue-600 text-white rounded-lg text-sm hover:bg-blue-700 disabled:opacity-50">
|
||||
Genehmigen
|
||||
</button>
|
||||
)}
|
||||
{/* Reject — only for review status (DSB) */}
|
||||
{version && version.status === 'review' && onReject && (
|
||||
<button onClick={() => { const c = prompt('Ablehnungsgrund:'); if (c) onReject(c) }} disabled={saving}
|
||||
className="px-3 py-1.5 bg-red-500 text-white rounded-lg text-sm hover:bg-red-600 disabled:opacity-50">
|
||||
Ablehnen
|
||||
</button>
|
||||
)}
|
||||
{/* Publish — only for approved */}
|
||||
{version && version.status === 'approved' && (
|
||||
<button onClick={onPublish} disabled={saving}
|
||||
className="px-3 py-1.5 bg-green-600 text-white rounded-lg text-sm hover:bg-green-700 disabled:opacity-50">
|
||||
Publizieren
|
||||
</button>
|
||||
)}
|
||||
{/* Preview + Test — always when version exists */}
|
||||
{version && (
|
||||
<button
|
||||
onClick={onPreview}
|
||||
className="px-3 py-1.5 border border-gray-300 text-gray-700 rounded-lg text-sm hover:bg-gray-50"
|
||||
>
|
||||
Vorschau
|
||||
</button>
|
||||
<>
|
||||
<button onClick={onPreview}
|
||||
className="px-3 py-1.5 border border-gray-300 text-gray-700 rounded-lg text-sm hover:bg-gray-50">
|
||||
Vorschau
|
||||
</button>
|
||||
{onSendTest && (
|
||||
<button onClick={() => { const e = prompt('Test-E-Mail an:'); if (e) onSendTest(e) }}
|
||||
className="px-3 py-1.5 border border-blue-300 text-blue-700 rounded-lg text-sm hover:bg-blue-50">
|
||||
Test senden
|
||||
</button>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user