shinkan-jinkendo/frontend/src/components/LegalDocumentPreview.jsx
Lars 98edb282ed
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
chore: bump version to 0.8.96 and enhance legal document features
- 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>
2026-05-12 11:22:01 +02:00

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>
)
}