141 lines
5.0 KiB
React
141 lines
5.0 KiB
React
|
|
/**
|
|||
|
|
* Gemeinsamer Medienvorschau-Dialog.
|
|||
|
|
*
|
|||
|
|
* Props:
|
|||
|
|
* title – Anzeigename des Mediums (Dateiname o.ä.)
|
|||
|
|
* media – Medienobjekt (mime_type, embed_url, asset_legal_hold_active, media_type)
|
|||
|
|
* fileUrl – Bereits aufgelöste Datei-URL (null für Embed-only-Medien)
|
|||
|
|
* onClose – Pflicht
|
|||
|
|
* onReport – optional; wenn gesetzt, erscheint "Melden"-Button
|
|||
|
|
* onEdit – optional; wenn gesetzt, erscheint "Bearbeiten"-Button
|
|||
|
|
*/
|
|||
|
|
import React from 'react'
|
|||
|
|
|
|||
|
|
export default function MediaPreviewModal({ title, media, fileUrl, onClose, onReport, onEdit }) {
|
|||
|
|
const mlow = (media?.mime_type || '').toLowerCase()
|
|||
|
|
const isHeic = mlow.includes('heic') || mlow.includes('heif')
|
|||
|
|
const isImage = !isHeic && (media?.mime_type?.startsWith('image/') || media?.media_type === 'image')
|
|||
|
|
const isVideo = media?.mime_type?.startsWith('video/') || media?.media_type === 'video'
|
|||
|
|
const isPdf = mlow.includes('pdf')
|
|||
|
|
const isLegalHold = !!media?.asset_legal_hold_active
|
|||
|
|
const canReport = onReport && !isLegalHold
|
|||
|
|
|
|||
|
|
function handleBackdrop(e) {
|
|||
|
|
if (e.target === e.currentTarget) onClose()
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function handleKeyDown(e) {
|
|||
|
|
if (e.key === 'Escape') onClose()
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return (
|
|||
|
|
<div
|
|||
|
|
role="dialog"
|
|||
|
|
aria-modal="true"
|
|||
|
|
aria-label="Medienvorschau"
|
|||
|
|
style={{
|
|||
|
|
position: 'fixed',
|
|||
|
|
inset: 0,
|
|||
|
|
background: 'rgba(0,0,0,0.55)',
|
|||
|
|
zIndex: 1100,
|
|||
|
|
overflow: 'auto',
|
|||
|
|
padding: '16px',
|
|||
|
|
display: 'flex',
|
|||
|
|
alignItems: 'center',
|
|||
|
|
justifyContent: 'center',
|
|||
|
|
}}
|
|||
|
|
onClick={handleBackdrop}
|
|||
|
|
onKeyDown={handleKeyDown}
|
|||
|
|
>
|
|||
|
|
<div
|
|||
|
|
className="card"
|
|||
|
|
style={{ maxWidth: 720, width: '100%', maxHeight: '90vh', overflow: 'auto', padding: '1.25rem' }}
|
|||
|
|
onClick={(e) => e.stopPropagation()}
|
|||
|
|
>
|
|||
|
|
{/* Header */}
|
|||
|
|
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: '1rem', gap: '0.5rem' }}>
|
|||
|
|
<h3 style={{ margin: 0, fontSize: '1rem', fontWeight: 600, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>
|
|||
|
|
{title || 'Vorschau'}
|
|||
|
|
</h3>
|
|||
|
|
<div style={{ display: 'flex', gap: '0.4rem', flexShrink: 0 }}>
|
|||
|
|
{canReport && (
|
|||
|
|
<button type="button" className="btn btn-secondary" style={{ fontSize: '0.85rem', padding: '5px 10px' }} onClick={onReport}>
|
|||
|
|
Melden
|
|||
|
|
</button>
|
|||
|
|
)}
|
|||
|
|
{onEdit && (
|
|||
|
|
<button type="button" className="btn btn-secondary" style={{ fontSize: '0.85rem', padding: '5px 10px' }} onClick={onEdit}>
|
|||
|
|
Bearbeiten
|
|||
|
|
</button>
|
|||
|
|
)}
|
|||
|
|
<button
|
|||
|
|
type="button"
|
|||
|
|
className="btn btn-secondary"
|
|||
|
|
style={{ fontSize: '0.85rem', padding: '5px 10px' }}
|
|||
|
|
onClick={onClose}
|
|||
|
|
aria-label="Schließen"
|
|||
|
|
>
|
|||
|
|
✕
|
|||
|
|
</button>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
{/* Body */}
|
|||
|
|
{isLegalHold ? (
|
|||
|
|
<p style={{ color: 'var(--danger)', fontSize: '0.9rem' }}>
|
|||
|
|
Dieses Medium ist gesperrt und steht nicht zur Verfügung.
|
|||
|
|
</p>
|
|||
|
|
) : media?.embed_url ? (
|
|||
|
|
<p style={{ fontSize: '14px', wordBreak: 'break-all' }}>
|
|||
|
|
<a href={media.embed_url} target="_blank" rel="noreferrer">{media.embed_url}</a>
|
|||
|
|
</p>
|
|||
|
|
) : isHeic ? (
|
|||
|
|
<div>
|
|||
|
|
<p style={{ color: 'var(--text2)', fontSize: '0.9rem' }}>
|
|||
|
|
HEIC/HEIF — in diesem Browser oft keine eingebettete Vorschau. Zum Ansehen herunterladen oder im neuen Tab öffnen.
|
|||
|
|
</p>
|
|||
|
|
{fileUrl && (
|
|||
|
|
<a className="btn btn-secondary" href={fileUrl} target="_blank" rel="noopener noreferrer">
|
|||
|
|
Datei öffnen
|
|||
|
|
</a>
|
|||
|
|
)}
|
|||
|
|
</div>
|
|||
|
|
) : isImage ? (
|
|||
|
|
<img
|
|||
|
|
key={media?.id}
|
|||
|
|
alt=""
|
|||
|
|
src={fileUrl}
|
|||
|
|
style={{ maxWidth: '100%', borderRadius: '8px', maxHeight: '70vh', objectFit: 'contain', display: 'block' }}
|
|||
|
|
/>
|
|||
|
|
) : isVideo ? (
|
|||
|
|
<video
|
|||
|
|
key={media?.id}
|
|||
|
|
src={fileUrl}
|
|||
|
|
controls
|
|||
|
|
playsInline
|
|||
|
|
preload="metadata"
|
|||
|
|
style={{ width: '100%', borderRadius: '8px', maxHeight: '70vh' }}
|
|||
|
|
>
|
|||
|
|
Wiedergabe nicht unterstützt.
|
|||
|
|
</video>
|
|||
|
|
) : isPdf ? (
|
|||
|
|
<div>
|
|||
|
|
<p style={{ color: 'var(--text2)', fontSize: '0.9rem' }}>PDF — zur Ansicht im neuen Tab öffnen.</p>
|
|||
|
|
{fileUrl && (
|
|||
|
|
<a className="btn btn-secondary" href={fileUrl} target="_blank" rel="noopener noreferrer">
|
|||
|
|
PDF öffnen
|
|||
|
|
</a>
|
|||
|
|
)}
|
|||
|
|
</div>
|
|||
|
|
) : fileUrl ? (
|
|||
|
|
<p style={{ fontSize: '14px' }}>
|
|||
|
|
<a href={fileUrl} target="_blank" rel="noreferrer">Datei öffnen</a>
|
|||
|
|
</p>
|
|||
|
|
) : (
|
|||
|
|
<p style={{ color: 'var(--text2)', fontSize: '0.9rem' }}>Keine Vorschau verfügbar.</p>
|
|||
|
|
)}
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
)
|
|||
|
|
}
|