First version of media manager

This commit is contained in:
2025-07-07 14:48:37 +00:00
parent 2127c3a753
commit 43306130f7
12 changed files with 373 additions and 23 deletions

View File

@@ -1,3 +1,4 @@
@import "../node_modules/@syncfusion/ej2-react-filemanager/styles/material.css";
@import "../node_modules/@syncfusion/ej2-base/styles/material.css";
@import "../node_modules/@syncfusion/ej2-buttons/styles/material.css";
@import "../node_modules/@syncfusion/ej2-calendars/styles/material.css";

View File

@@ -129,7 +129,7 @@ const App: React.FC = () => (
<Route path="ressourcen" element={<Ressourcen />} />
<Route path="Infoscreens" element={<Infoscreens />} />
<Route path="infoscr_groups" element={<Infoscreen_groups />} />
<Route path="medien" element={<Medien />} />
<Route path="medien" element={<Media />} />
<Route path="benutzer" element={<Benutzer />} />
<Route path="einstellungen" element={<Einstellungen />} />
</Route>
@@ -146,6 +146,6 @@ import Appointments from './appointments';
import Ressourcen from './ressourcen';
import Infoscreens from './clients';
import Infoscreen_groups from './infoscreen_groups';
import Medien from './medien';
import Media from './media';
import Benutzer from './benutzer';
import Einstellungen from './einstellungen';

View File

@@ -0,0 +1,27 @@
import React from 'react';
interface CustomMediaInfoPanelProps {
mediaId: string;
title: string;
description: string;
eventId?: string;
onSave: (data: { title: string; description: string; eventId?: string }) => void;
}
const CustomMediaInfoPanel: React.FC<CustomMediaInfoPanelProps> = ({
mediaId,
title,
description,
eventId,
onSave,
}) => {
// Hier kannst du Formularfelder und Logik für die Bearbeitung einbauen
return (
<div>
<h3>Medien-Informationen bearbeiten</h3>
{/* Formularfelder für Titel, Beschreibung, Event-Zuordnung */}
</div>
);
};
export default CustomMediaInfoPanel;

100
dashboard/src/media.tsx Normal file
View File

@@ -0,0 +1,100 @@
import React, { useEffect, useState } from 'react';
import CustomMediaInfoPanel from './components/CustomMediaInfoPanel';
import {
FileManagerComponent,
Inject,
NavigationPane,
DetailsView,
Toolbar,
} from '@syncfusion/ej2-react-filemanager';
const hostUrl = '/api/eventmedia/filemanager/'; // Dein Backend-Endpunkt für FileManager
interface MediaItem {
id: string;
file_path: string;
url: string;
description: string;
eventId?: string;
}
const Media: React.FC = () => {
const [mediaList, setMediaList] = useState<MediaItem[]>([]);
const [selectedMedia, setSelectedMedia] = useState<MediaItem | null>(null);
// Medien vom Server laden
useEffect(() => {
fetch('/api/eventmedia')
.then(res => res.json())
.then(setMediaList);
}, []);
// Upload-Handler (vereinfachtes Beispiel)
const handleUpload = async (e: React.ChangeEvent<HTMLInputElement>) => {
if (!e.target.files?.length) return;
const formData = new FormData();
formData.append('file', e.target.files[0]);
await fetch('/api/eventmedia/upload', { method: 'POST', body: formData });
// Nach Upload neu laden
const res = await fetch('/api/eventmedia');
setMediaList(await res.json());
};
// Speichern von Metadaten/Event-Zuordnung
const handleSave = async (data: { title: string; description: string; eventId?: string }) => {
if (!selectedMedia) return;
await fetch(`/api/eventmedia/${selectedMedia.id}`, {
method: 'PUT',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(data),
});
// Nach dem Speichern neu laden
const res = await fetch('/api/eventmedia');
setMediaList(await res.json());
};
return (
<div>
<h2 className="text-xl font-bold mb-4">Medien</h2>
<FileManagerComponent
ajaxSettings={{
url: hostUrl + 'operations',
getImageUrl: hostUrl + 'get-image',
uploadUrl: hostUrl + 'upload',
downloadUrl: hostUrl + 'download',
}}
toolbarSettings={{
items: [
'NewFolder',
'Upload',
'Download',
'Rename',
'Delete',
'SortBy',
'Refresh',
'Details',
],
}}
contextMenuSettings={{
file: ['Open', '|', 'Download', '|', 'Rename', 'Delete', '|', 'Details'],
folder: ['Open', '|', 'Rename', 'Delete', '|', 'Details'],
layout: ['SortBy', 'Refresh', '|', 'View', 'Details'],
}}
allowMultiSelection={false}
>
<Inject services={[NavigationPane, DetailsView, Toolbar]} />
</FileManagerComponent>
{selectedMedia && (
<CustomMediaInfoPanel
mediaId={selectedMedia.id}
title={selectedMedia.url}
description={selectedMedia.description}
eventId={selectedMedia.eventId}
onSave={handleSave}
/>
)}
</div>
);
};
export default Media;

View File

@@ -1,8 +0,0 @@
import React from 'react';
const Medien: React.FC = () => (
<div>
<h2 className="text-xl font-bold mb-4">Medien</h2>
<p>Willkommen im Infoscreen-Management Medien.</p>
</div>
);
export default Medien;