From 2f7e1e50adb76562d07d724c9c56d5313bea5b6a Mon Sep 17 00:00:00 2001 From: Lars Date: Mon, 11 May 2026 18:08:57 +0200 Subject: [PATCH] feat(P-13): add content reporting functionality with modal and update version to 0.8.88 --- backend/version.py | 13 +- .../ExerciseAttachmentMediaStrip.jsx | 29 +++ .../src/components/ReportContentModal.jsx | 195 ++++++++++++++++++ frontend/src/pages/MediaLibraryPage.jsx | 43 +++- frontend/src/version.js | 4 +- 5 files changed, 280 insertions(+), 4 deletions(-) create mode 100644 frontend/src/components/ReportContentModal.jsx diff --git a/backend/version.py b/backend/version.py index 23aaf67..06d1d39 100644 --- a/backend/version.py +++ b/backend/version.py @@ -1,6 +1,6 @@ # Shinkan Jinkendo Version Information -APP_VERSION = "0.8.87" +APP_VERSION = "0.8.88" BUILD_DATE = "2026-05-11" DB_SCHEMA_VERSION = "20260511052" @@ -30,10 +30,19 @@ MODULE_VERSIONS = { "membership": "1.0.0", "catalogs": "1.5.0", # Updated: Trainer Contexts API (Migration 012) "maturity_models": "1.4.0", # matrix_stack_bundle: vollständiger Katalog+Modelle+Bindings Export/Import - "content_reports": "1.0.0", # P-13: Content-Melde-Backend (DSA-konform, Inbox-Integration, P-11 Legal Hold) + "content_reports": "1.1.0", # P-13: Melde-Button in Medienbibliothek + ExerciseAttachmentMediaStrip } CHANGELOG = [ + { + "version": "0.8.88", + "date": "2026-05-11", + "changes": [ + "Feat P-13: Melde-Button in Medienbibliothek (Grid + Liste) — öffnet ReportContentModal; nur aktive Medien ohne Legal Hold.", + "Feat P-13: Melde-Link an jedem Medium in ExerciseAttachmentMediaStrip (Lesemodus Übung).", + "Feat P-13: ReportContentModal — wiederverwendbares Formular (Grund, Beschreibung, Name, E-Mail, Gutglaubenserklärung); Vorausfüllung für eingeloggte Nutzer.", + ], + }, { "version": "0.8.87", "date": "2026-05-11", diff --git a/frontend/src/components/ExerciseAttachmentMediaStrip.jsx b/frontend/src/components/ExerciseAttachmentMediaStrip.jsx index 503868a..aa6d697 100644 --- a/frontend/src/components/ExerciseAttachmentMediaStrip.jsx +++ b/frontend/src/components/ExerciseAttachmentMediaStrip.jsx @@ -4,6 +4,7 @@ import React, { useMemo, useState } from 'react' import ExerciseMediaEmbed from './ExerciseMediaEmbed' import ExerciseMediaThumbTile from './ExerciseMediaThumbTile' +import ReportContentModal from './ReportContentModal' import { resolveExerciseMediaFileUrl } from '../utils/exerciseMediaUrl' import { collectInlineExerciseMediaIdsFromExercise, @@ -15,6 +16,7 @@ function isTrashHidden(m) { export default function ExerciseAttachmentMediaStrip({ exerciseId, exercise }) { const [preview, setPreview] = useState(null) + const [reportTarget, setReportTarget] = useState(null) const inlineIds = useMemo(() => collectInlineExerciseMediaIdsFromExercise(exercise), [exercise]) const orphans = useMemo(() => { @@ -56,10 +58,37 @@ export default function ExerciseAttachmentMediaStrip({ exerciseId, exercise }) { + {(m.asset_lifecycle_state || 'active') === 'active' && !m.asset_legal_hold_active && ( + + )} ) })} + {reportTarget && ( + setReportTarget(null)} + /> + )} + {preview && (
{ if (e.target === e.currentTarget) onClose() }} + > +
+
+

Inhalt melden

+ +
+ + {targetLabel && ( +

+ {targetType === 'media_asset' ? 'Medium' : 'Übung'}: {targetLabel} +

+ )} + + {success ? ( +
+

Meldung eingegangen.

+

+ Deine Meldung wurde gespeichert und wird von unseren Moderatoren geprüft. Vielen Dank. +

+ +
+ ) : ( +
+
+ + +
+ +
+ +