All checks were successful
Deploy Development / deploy (push) Successful in 40s
Test Suite / pytest-backend (push) Successful in 35s
Test Suite / lint-backend (push) Successful in 0s
Test Suite / build-frontend (push) Successful in 12s
Test Suite / playwright-tests (push) Successful in 59s
- Updated app version to 0.8.96 with a new build date of 2026-05-12. - Improved legal documents functionality with a live preview feature alongside the editor. - Added modal for full document preview and updated CSS styles for better layout. - Enhanced the AdminLegalDocumentsPage to support rendering previews of legal documents. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
112 lines
3.3 KiB
JavaScript
112 lines
3.3 KiB
JavaScript
import { useEffect } from 'react'
|
|
import LegalDocumentBody from './LegalDocumentBody'
|
|
import { legalSectionNumber } from '../utils/legalPdfExport'
|
|
|
|
/** Inhalt wie auf der öffentlichen Rechtstextseite (inkl. §-Nummerierung). */
|
|
export function LegalDocumentPublicPreviewContent({
|
|
title,
|
|
sections,
|
|
showDraftNotice = true,
|
|
metaLine,
|
|
}) {
|
|
const safeTitle = (title || '').trim() || 'Ohne Titel'
|
|
|
|
return (
|
|
<div className="legal-admin-preview-inner">
|
|
{showDraftNotice && (
|
|
<div
|
|
className="card"
|
|
style={{
|
|
marginBottom: '1.25rem',
|
|
borderLeft: '4px solid var(--warn)',
|
|
background: 'var(--surface)',
|
|
}}
|
|
>
|
|
<strong style={{ color: 'var(--text1)' }}>Vorschau</strong>
|
|
<p style={{ margin: '0.35rem 0 0', fontSize: '0.88rem', color: 'var(--text2)' }}>
|
|
So erscheint der Text für Besucher nach Veröffentlichung (Markdown wird gerendert, §-Nummern wie online).
|
|
</p>
|
|
</div>
|
|
)}
|
|
{metaLine && (
|
|
<p style={{ fontSize: '0.85rem', color: 'var(--text3)', margin: '0 0 1rem' }}>{metaLine}</p>
|
|
)}
|
|
<h1 style={{ margin: '0 0 1.5rem', color: 'var(--text1)', fontSize: '1.5rem' }}>{safeTitle}</h1>
|
|
{(sections || []).map((section, i) => (
|
|
<div key={i} style={{ marginBottom: '1.75rem' }}>
|
|
<h2 style={{ fontSize: '1.05rem', marginBottom: '0.4rem', color: 'var(--text1)' }}>
|
|
{section.heading?.trim()
|
|
? `${legalSectionNumber(i)} ${section.heading}`
|
|
: legalSectionNumber(i)}
|
|
</h2>
|
|
<LegalDocumentBody content={section.content} />
|
|
</div>
|
|
))}
|
|
{sections?.length === 0 && (
|
|
<p style={{ color: 'var(--text3)', fontSize: '0.9rem' }}>Noch keine Abschnitte.</p>
|
|
)}
|
|
</div>
|
|
)
|
|
}
|
|
|
|
/**
|
|
* Modal: gerenderte Rechtstext-Vorschau (Editor oder gespeicherte Version).
|
|
*/
|
|
export function LegalPreviewModal({
|
|
open,
|
|
onClose,
|
|
title,
|
|
sections,
|
|
metaLine,
|
|
loading,
|
|
showDraftNotice = true,
|
|
}) {
|
|
useEffect(() => {
|
|
if (!open) return
|
|
const onKey = (e) => {
|
|
if (e.key === 'Escape') onClose()
|
|
}
|
|
window.addEventListener('keydown', onKey)
|
|
return () => window.removeEventListener('keydown', onKey)
|
|
}, [open, onClose])
|
|
|
|
if (!open) return null
|
|
|
|
return (
|
|
<div
|
|
className="legal-preview-modal-backdrop"
|
|
role="presentation"
|
|
onClick={onClose}
|
|
>
|
|
<div
|
|
className="legal-preview-modal"
|
|
role="dialog"
|
|
aria-modal="true"
|
|
aria-labelledby="legal-preview-modal-title"
|
|
onClick={(e) => e.stopPropagation()}
|
|
>
|
|
<div className="legal-preview-modal__header">
|
|
<h3 id="legal-preview-modal-title" style={{ margin: 0, fontSize: '1.05rem' }}>
|
|
Öffentliche Darstellung
|
|
</h3>
|
|
<button type="button" className="btn btn-secondary" onClick={onClose}>
|
|
Schließen
|
|
</button>
|
|
</div>
|
|
<div className="legal-preview-modal__body">
|
|
{loading ? (
|
|
<div className="spinner" style={{ margin: '2rem auto' }} />
|
|
) : (
|
|
<LegalDocumentPublicPreviewContent
|
|
title={title}
|
|
sections={sections}
|
|
metaLine={metaLine}
|
|
showDraftNotice={showDraftNotice}
|
|
/>
|
|
)}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
)
|
|
}
|