group color shown in CustomEventModal
add functionality for edit of events
This commit is contained in:
@@ -97,3 +97,9 @@ export async function deleteClient(uuid: string) {
|
|||||||
if (!res.ok) throw new Error('Fehler beim Entfernen des Clients');
|
if (!res.ok) throw new Error('Fehler beim Entfernen des Clients');
|
||||||
return await res.json();
|
return await res.json();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function fetchMediaById(mediaId: number | string) {
|
||||||
|
const response = await fetch(`/api/eventmedia/${mediaId}`);
|
||||||
|
if (!response.ok) throw new Error('Fehler beim Laden der Mediainformationen');
|
||||||
|
return await response.json();
|
||||||
|
}
|
||||||
|
|||||||
@@ -23,3 +23,18 @@ export async function deleteEvent(eventId: string) {
|
|||||||
if (!res.ok || data.error) throw new Error(data.error || 'Fehler beim Löschen des Termins');
|
if (!res.ok || data.error) throw new Error(data.error || 'Fehler beim Löschen des Termins');
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface UpdateEventPayload {
|
||||||
|
[key: string]: unknown;
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function updateEvent(eventId: string, payload: UpdateEventPayload) {
|
||||||
|
const res = await fetch(`/api/events/${encodeURIComponent(eventId)}`, {
|
||||||
|
method: 'PUT',
|
||||||
|
headers: { 'Content-Type': 'application/json' },
|
||||||
|
body: JSON.stringify(payload),
|
||||||
|
});
|
||||||
|
const data = await res.json();
|
||||||
|
if (!res.ok || data.error) throw new Error(data.error || 'Fehler beim Aktualisieren des Termins');
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ import { fetchGroups } from './apiGroups';
|
|||||||
import { getGroupColor } from './groupColors';
|
import { getGroupColor } from './groupColors';
|
||||||
import { deleteEvent } from './apiEvents';
|
import { deleteEvent } from './apiEvents';
|
||||||
import CustomEventModal from './components/CustomEventModal';
|
import CustomEventModal from './components/CustomEventModal';
|
||||||
|
import { fetchMediaById } from './apiClients';
|
||||||
|
|
||||||
// Typ für Gruppe ergänzen
|
// Typ für Gruppe ergänzen
|
||||||
type Group = {
|
type Group = {
|
||||||
@@ -25,13 +26,16 @@ type Group = {
|
|||||||
name: string;
|
name: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Typ für Event hinzufügen
|
// Typ für Event ergänzen
|
||||||
type Event = {
|
type Event = {
|
||||||
Id: string;
|
Id: string;
|
||||||
Subject: string;
|
Subject: string;
|
||||||
StartTime: Date;
|
StartTime: Date;
|
||||||
EndTime: Date;
|
EndTime: Date;
|
||||||
IsAllDay: boolean;
|
IsAllDay: boolean;
|
||||||
|
MediaId?: string | number; // Nur die MediaId wird gespeichert!
|
||||||
|
SlideshowInterval?: number;
|
||||||
|
WebsiteUrl?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
type RawEvent = {
|
type RawEvent = {
|
||||||
@@ -40,6 +44,9 @@ type RawEvent = {
|
|||||||
StartTime: string;
|
StartTime: string;
|
||||||
EndTime: string;
|
EndTime: string;
|
||||||
IsAllDay: boolean;
|
IsAllDay: boolean;
|
||||||
|
MediaId?: string | number; // Nur die MediaId wird gespeichert!
|
||||||
|
SlideshowInterval?: number;
|
||||||
|
WebsiteUrl?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
import * as de from 'cldr-data/main/de/ca-gregorian.json';
|
import * as de from 'cldr-data/main/de/ca-gregorian.json';
|
||||||
@@ -98,6 +105,7 @@ const Appointments: React.FC = () => {
|
|||||||
const [modalOpen, setModalOpen] = useState(false);
|
const [modalOpen, setModalOpen] = useState(false);
|
||||||
const [modalInitialData, setModalInitialData] = useState({});
|
const [modalInitialData, setModalInitialData] = useState({});
|
||||||
const [schedulerKey, setSchedulerKey] = useState(0);
|
const [schedulerKey, setSchedulerKey] = useState(0);
|
||||||
|
const [editMode, setEditMode] = useState(false); // NEU: Editiermodus
|
||||||
|
|
||||||
// Gruppen laden
|
// Gruppen laden
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@@ -122,6 +130,7 @@ const Appointments: React.FC = () => {
|
|||||||
StartTime: new Date(e.StartTime.endsWith('Z') ? e.StartTime : e.StartTime + 'Z'),
|
StartTime: new Date(e.StartTime.endsWith('Z') ? e.StartTime : e.StartTime + 'Z'),
|
||||||
EndTime: new Date(e.EndTime.endsWith('Z') ? e.EndTime : e.EndTime + 'Z'),
|
EndTime: new Date(e.EndTime.endsWith('Z') ? e.EndTime : e.EndTime + 'Z'),
|
||||||
IsAllDay: e.IsAllDay,
|
IsAllDay: e.IsAllDay,
|
||||||
|
MediaId: e.MediaId,
|
||||||
}));
|
}));
|
||||||
setEvents(mapped);
|
setEvents(mapped);
|
||||||
})
|
})
|
||||||
@@ -156,7 +165,23 @@ const Appointments: React.FC = () => {
|
|||||||
<button
|
<button
|
||||||
className="e-btn e-success mb-4"
|
className="e-btn e-success mb-4"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setModalInitialData({});
|
const now = new Date();
|
||||||
|
// Runde auf die nächste halbe Stunde
|
||||||
|
const minutes = now.getMinutes();
|
||||||
|
const roundedMinutes = minutes < 30 ? 30 : 0;
|
||||||
|
const startTime = new Date(now);
|
||||||
|
startTime.setMinutes(roundedMinutes, 0, 0);
|
||||||
|
if (roundedMinutes === 0) startTime.setHours(startTime.getHours() + 1);
|
||||||
|
|
||||||
|
const endTime = new Date(startTime);
|
||||||
|
endTime.setMinutes(endTime.getMinutes() + 30);
|
||||||
|
|
||||||
|
setModalInitialData({
|
||||||
|
startDate: startTime,
|
||||||
|
startTime: startTime,
|
||||||
|
endTime: endTime,
|
||||||
|
});
|
||||||
|
setEditMode(false);
|
||||||
setModalOpen(true);
|
setModalOpen(true);
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
@@ -164,19 +189,22 @@ const Appointments: React.FC = () => {
|
|||||||
</button>
|
</button>
|
||||||
<CustomEventModal
|
<CustomEventModal
|
||||||
open={modalOpen}
|
open={modalOpen}
|
||||||
onClose={() => setModalOpen(false)}
|
onClose={() => {
|
||||||
|
setModalOpen(false);
|
||||||
|
setEditMode(false); // Editiermodus zurücksetzen
|
||||||
|
}}
|
||||||
onSave={async () => {
|
onSave={async () => {
|
||||||
setModalOpen(false);
|
setModalOpen(false);
|
||||||
console.log('onSave wird aufgerufen');
|
setEditMode(false);
|
||||||
if (selectedGroupId) {
|
if (selectedGroupId) {
|
||||||
const data = await fetchEvents(selectedGroupId);
|
const data = await fetchEvents(selectedGroupId);
|
||||||
console.log('Events nach Save:', data);
|
|
||||||
const mapped: Event[] = data.map((e: RawEvent) => ({
|
const mapped: Event[] = data.map((e: RawEvent) => ({
|
||||||
Id: e.Id,
|
Id: e.Id,
|
||||||
Subject: e.Subject,
|
Subject: e.Subject,
|
||||||
StartTime: new Date(e.StartTime.endsWith('Z') ? e.StartTime : e.StartTime + 'Z'),
|
StartTime: new Date(e.StartTime.endsWith('Z') ? e.StartTime : e.StartTime + 'Z'),
|
||||||
EndTime: new Date(e.EndTime.endsWith('Z') ? e.EndTime : e.EndTime + 'Z'),
|
EndTime: new Date(e.EndTime.endsWith('Z') ? e.EndTime : e.EndTime + 'Z'),
|
||||||
IsAllDay: e.IsAllDay,
|
IsAllDay: e.IsAllDay,
|
||||||
|
MediaId: e.MediaId,
|
||||||
}));
|
}));
|
||||||
setEvents(mapped);
|
setEvents(mapped);
|
||||||
setSchedulerKey(prev => prev + 1); // <-- Key erhöhen
|
setSchedulerKey(prev => prev + 1); // <-- Key erhöhen
|
||||||
@@ -184,6 +212,8 @@ const Appointments: React.FC = () => {
|
|||||||
}}
|
}}
|
||||||
initialData={modalInitialData}
|
initialData={modalInitialData}
|
||||||
groupName={groups.find(g => g.id === selectedGroupId) ?? { id: selectedGroupId, name: '' }}
|
groupName={groups.find(g => g.id === selectedGroupId) ?? { id: selectedGroupId, name: '' }}
|
||||||
|
groupColor={selectedGroupId ? getGroupColor(selectedGroupId, groups) : undefined}
|
||||||
|
editMode={editMode} // NEU: Prop für Editiermodus
|
||||||
/>
|
/>
|
||||||
<ScheduleComponent
|
<ScheduleComponent
|
||||||
key={schedulerKey} // <-- dynamischer Key
|
key={schedulerKey} // <-- dynamischer Key
|
||||||
@@ -201,8 +231,63 @@ const Appointments: React.FC = () => {
|
|||||||
startTime: args.startTime,
|
startTime: args.startTime,
|
||||||
endTime: args.endTime,
|
endTime: args.endTime,
|
||||||
});
|
});
|
||||||
|
setEditMode(false); // NEU: kein Editiermodus
|
||||||
setModalOpen(true);
|
setModalOpen(true);
|
||||||
}}
|
}}
|
||||||
|
popupOpen={async args => {
|
||||||
|
if (args.type === 'Editor') {
|
||||||
|
args.cancel = true;
|
||||||
|
const event = args.data;
|
||||||
|
console.log('Event zum Bearbeiten:', event);
|
||||||
|
let media = null;
|
||||||
|
if (event.MediaId) {
|
||||||
|
try {
|
||||||
|
const mediaData = await fetchMediaById(event.MediaId);
|
||||||
|
media = {
|
||||||
|
id: mediaData.id,
|
||||||
|
path: mediaData.file_path,
|
||||||
|
name: mediaData.name || mediaData.url,
|
||||||
|
};
|
||||||
|
} catch (err) {
|
||||||
|
console.error('Fehler beim Laden der Mediainfos:', err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
setModalInitialData({
|
||||||
|
Id: event.Id,
|
||||||
|
title: event.Subject,
|
||||||
|
startDate: event.StartTime,
|
||||||
|
startTime: event.StartTime,
|
||||||
|
endTime: event.EndTime,
|
||||||
|
description: event.Description ?? '',
|
||||||
|
type: event.Type ?? 'presentation',
|
||||||
|
repeat: event.Repeat ?? false,
|
||||||
|
weekdays: event.Weekdays ?? [],
|
||||||
|
repeatUntil: event.RepeatUntil ?? null,
|
||||||
|
skipHolidays: event.SkipHolidays ?? false,
|
||||||
|
media, // Metadaten werden nur bei Bedarf geladen!
|
||||||
|
slideshowInterval: event.SlideshowInterval ?? 10,
|
||||||
|
websiteUrl: event.WebsiteUrl ?? '',
|
||||||
|
});
|
||||||
|
console.log('Modal initial data:', {
|
||||||
|
Id: event.Id,
|
||||||
|
title: event.Subject,
|
||||||
|
startDate: event.StartTime,
|
||||||
|
startTime: event.StartTime,
|
||||||
|
endTime: event.EndTime,
|
||||||
|
description: event.Description ?? '',
|
||||||
|
type: event.Type ?? 'presentation',
|
||||||
|
repeat: event.Repeat ?? false,
|
||||||
|
weekdays: event.Weekdays ?? [],
|
||||||
|
repeatUntil: event.RepeatUntil ?? null,
|
||||||
|
skipHolidays: event.SkipHolidays ?? false,
|
||||||
|
media, // Metadaten werden nur bei Bedarf geladen!
|
||||||
|
slideshowInterval: event.SlideshowInterval ?? 10,
|
||||||
|
websiteUrl: event.WebsiteUrl ?? '',
|
||||||
|
});
|
||||||
|
setEditMode(true);
|
||||||
|
setModalOpen(true);
|
||||||
|
}
|
||||||
|
}}
|
||||||
eventRendered={(args: EventRenderedArgs) => {
|
eventRendered={(args: EventRenderedArgs) => {
|
||||||
if (selectedGroupId && args.data && args.data.Id) {
|
if (selectedGroupId && args.data && args.data.Id) {
|
||||||
const groupColor = getGroupColor(selectedGroupId, groups);
|
const groupColor = getGroupColor(selectedGroupId, groups);
|
||||||
@@ -233,6 +318,7 @@ const Appointments: React.FC = () => {
|
|||||||
StartTime: new Date(e.StartTime),
|
StartTime: new Date(e.StartTime),
|
||||||
EndTime: new Date(e.EndTime),
|
EndTime: new Date(e.EndTime),
|
||||||
IsAllDay: e.IsAllDay,
|
IsAllDay: e.IsAllDay,
|
||||||
|
MediaId: e.MediaId,
|
||||||
}));
|
}));
|
||||||
setEvents(mapped);
|
setEvents(mapped);
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import { DatePickerComponent, TimePickerComponent } from '@syncfusion/ej2-react-
|
|||||||
import { DropDownListComponent, MultiSelectComponent } from '@syncfusion/ej2-react-dropdowns';
|
import { DropDownListComponent, MultiSelectComponent } from '@syncfusion/ej2-react-dropdowns';
|
||||||
import { CheckBoxComponent } from '@syncfusion/ej2-react-buttons';
|
import { CheckBoxComponent } from '@syncfusion/ej2-react-buttons';
|
||||||
import CustomSelectUploadEventModal from './CustomSelectUploadEventModal';
|
import CustomSelectUploadEventModal from './CustomSelectUploadEventModal';
|
||||||
|
import { updateEvent } from '../apiEvents';
|
||||||
|
|
||||||
type CustomEventData = {
|
type CustomEventData = {
|
||||||
title: string;
|
title: string;
|
||||||
@@ -17,14 +18,20 @@ type CustomEventData = {
|
|||||||
weekdays: number[];
|
weekdays: number[];
|
||||||
repeatUntil: Date | null;
|
repeatUntil: Date | null;
|
||||||
skipHolidays: boolean;
|
skipHolidays: boolean;
|
||||||
|
media?: { id: string; path: string; name: string } | null; // <--- ergänzt
|
||||||
|
slideshowInterval?: number; // <--- ergänzt
|
||||||
|
websiteUrl?: string; // <--- ergänzt
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Typ für initialData erweitern, damit Id unterstützt wird
|
||||||
type CustomEventModalProps = {
|
type CustomEventModalProps = {
|
||||||
open: boolean;
|
open: boolean;
|
||||||
onClose: () => void;
|
onClose: () => void;
|
||||||
onSave: (eventData: CustomEventData) => void;
|
onSave: (eventData: CustomEventData) => void;
|
||||||
initialData?: Partial<CustomEventData>;
|
initialData?: Partial<CustomEventData> & { Id?: string }; // <--- Id ergänzen
|
||||||
groupName: string | { id: string | null; name: string };
|
groupName: string | { id: string | null; name: string };
|
||||||
|
groupColor?: string;
|
||||||
|
editMode?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
const weekdayOptions = [
|
const weekdayOptions = [
|
||||||
@@ -50,7 +57,9 @@ const CustomEventModal: React.FC<CustomEventModalProps> = ({
|
|||||||
onClose,
|
onClose,
|
||||||
onSave,
|
onSave,
|
||||||
initialData = {},
|
initialData = {},
|
||||||
groupName, // <--- NEU
|
groupName,
|
||||||
|
groupColor,
|
||||||
|
editMode,
|
||||||
}) => {
|
}) => {
|
||||||
const [title, setTitle] = React.useState(initialData.title || '');
|
const [title, setTitle] = React.useState(initialData.title || '');
|
||||||
const [startDate, setStartDate] = React.useState(initialData.startDate || null);
|
const [startDate, setStartDate] = React.useState(initialData.startDate || null);
|
||||||
@@ -65,14 +74,19 @@ const CustomEventModal: React.FC<CustomEventModalProps> = ({
|
|||||||
const [repeatUntil, setRepeatUntil] = React.useState(initialData.repeatUntil || null);
|
const [repeatUntil, setRepeatUntil] = React.useState(initialData.repeatUntil || null);
|
||||||
const [skipHolidays, setSkipHolidays] = React.useState(initialData.skipHolidays || false);
|
const [skipHolidays, setSkipHolidays] = React.useState(initialData.skipHolidays || false);
|
||||||
const [errors, setErrors] = React.useState<{ [key: string]: string }>({});
|
const [errors, setErrors] = React.useState<{ [key: string]: string }>({});
|
||||||
const [media, setMedia] = React.useState<{ id: string; path: string; name: string } | null>(null);
|
// --- KORREKTUR: Media, SlideshowInterval, WebsiteUrl aus initialData übernehmen ---
|
||||||
|
const [media, setMedia] = React.useState<{ id: string; path: string; name: string } | null>(
|
||||||
|
initialData.media ?? null
|
||||||
|
);
|
||||||
const [pendingMedia, setPendingMedia] = React.useState<{
|
const [pendingMedia, setPendingMedia] = React.useState<{
|
||||||
id: string;
|
id: string;
|
||||||
path: string;
|
path: string;
|
||||||
name: string;
|
name: string;
|
||||||
} | null>(null);
|
} | null>(null);
|
||||||
const [slideshowInterval, setSlideshowInterval] = React.useState<number>(10);
|
const [slideshowInterval, setSlideshowInterval] = React.useState<number>(
|
||||||
const [websiteUrl, setWebsiteUrl] = React.useState<string>('');
|
initialData.slideshowInterval ?? 10
|
||||||
|
);
|
||||||
|
const [websiteUrl, setWebsiteUrl] = React.useState<string>(initialData.websiteUrl ?? '');
|
||||||
const [mediaModalOpen, setMediaModalOpen] = React.useState(false);
|
const [mediaModalOpen, setMediaModalOpen] = React.useState(false);
|
||||||
|
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
@@ -81,15 +95,16 @@ const CustomEventModal: React.FC<CustomEventModalProps> = ({
|
|||||||
setStartDate(initialData.startDate || null);
|
setStartDate(initialData.startDate || null);
|
||||||
setStartTime(initialData.startTime || new Date(0, 0, 0, 9, 0));
|
setStartTime(initialData.startTime || new Date(0, 0, 0, 9, 0));
|
||||||
setEndTime(initialData.endTime || new Date(0, 0, 0, 9, 30));
|
setEndTime(initialData.endTime || new Date(0, 0, 0, 9, 30));
|
||||||
setType(initialData.type ?? 'presentation'); // Immer 'presentation' als Default
|
setType(initialData.type ?? 'presentation');
|
||||||
setDescription(initialData.description || '');
|
setDescription(initialData.description || '');
|
||||||
setRepeat(initialData.repeat || false);
|
setRepeat(initialData.repeat || false);
|
||||||
setWeekdays(initialData.weekdays || []);
|
setWeekdays(initialData.weekdays || []);
|
||||||
setRepeatUntil(initialData.repeatUntil || null);
|
setRepeatUntil(initialData.repeatUntil || null);
|
||||||
setSkipHolidays(initialData.skipHolidays || false);
|
setSkipHolidays(initialData.skipHolidays || false);
|
||||||
setMedia(null);
|
// --- KORREKTUR: Media, SlideshowInterval, WebsiteUrl aus initialData übernehmen ---
|
||||||
setSlideshowInterval(10);
|
setMedia(initialData.media ?? null);
|
||||||
setWebsiteUrl('');
|
setSlideshowInterval(initialData.slideshowInterval ?? 10);
|
||||||
|
setWebsiteUrl(initialData.websiteUrl ?? '');
|
||||||
}
|
}
|
||||||
}, [open, initialData]);
|
}, [open, initialData]);
|
||||||
|
|
||||||
@@ -124,10 +139,8 @@ const CustomEventModal: React.FC<CustomEventModalProps> = ({
|
|||||||
|
|
||||||
setErrors({});
|
setErrors({});
|
||||||
|
|
||||||
// group_id ist jetzt wirklich die ID (z.B. als prop übergeben)
|
|
||||||
const group_id = typeof groupName === 'object' && groupName !== null ? groupName.id : groupName;
|
const group_id = typeof groupName === 'object' && groupName !== null ? groupName.id : groupName;
|
||||||
|
|
||||||
// Daten für das Backend zusammenstellen
|
|
||||||
const payload: CustomEventData & { [key: string]: unknown } = {
|
const payload: CustomEventData & { [key: string]: unknown } = {
|
||||||
group_id,
|
group_id,
|
||||||
title,
|
title,
|
||||||
@@ -175,17 +188,24 @@ const CustomEventModal: React.FC<CustomEventModalProps> = ({
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const res = await fetch('/api/events', {
|
let res;
|
||||||
method: 'POST',
|
if (editMode && initialData && typeof initialData.Id === 'string') {
|
||||||
headers: { 'Content-Type': 'application/json' },
|
// UPDATE statt CREATE
|
||||||
body: JSON.stringify(payload),
|
res = await updateEvent(initialData.Id, payload);
|
||||||
});
|
|
||||||
if (res.ok) {
|
|
||||||
onSave(payload);
|
|
||||||
onClose();
|
|
||||||
} else {
|
} else {
|
||||||
const err = await res.json();
|
// CREATE
|
||||||
setErrors({ api: err.error || 'Fehler beim Speichern' });
|
res = await fetch('/api/events', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: { 'Content-Type': 'application/json' },
|
||||||
|
body: JSON.stringify(payload),
|
||||||
|
});
|
||||||
|
res = await res.json();
|
||||||
|
}
|
||||||
|
if (res.success) {
|
||||||
|
onSave(payload);
|
||||||
|
onClose(); // <--- Box nach erfolgreichem Speichern schließen
|
||||||
|
} else {
|
||||||
|
setErrors({ api: res.error || 'Fehler beim Speichern' });
|
||||||
}
|
}
|
||||||
} catch {
|
} catch {
|
||||||
setErrors({ api: 'Netzwerkfehler beim Speichern' });
|
setErrors({ api: 'Netzwerkfehler beim Speichern' });
|
||||||
@@ -199,10 +219,21 @@ const CustomEventModal: React.FC<CustomEventModalProps> = ({
|
|||||||
visible={open}
|
visible={open}
|
||||||
width="800px"
|
width="800px"
|
||||||
header={() => (
|
header={() => (
|
||||||
<div>
|
<div
|
||||||
Neuen Termin anlegen
|
style={{
|
||||||
|
background: groupColor || '#f5f5f5',
|
||||||
|
padding: '8px 16px',
|
||||||
|
borderRadius: '6px 6px 0 0',
|
||||||
|
color: '#fff',
|
||||||
|
fontWeight: 600,
|
||||||
|
fontSize: 20,
|
||||||
|
display: 'flex',
|
||||||
|
alignItems: 'center',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{editMode ? 'Termin bearbeiten' : 'Neuen Termin anlegen'}
|
||||||
{groupName && (
|
{groupName && (
|
||||||
<span style={{ fontWeight: 400, fontSize: 16, marginLeft: 16, color: '#888' }}>
|
<span style={{ fontWeight: 400, fontSize: 16, marginLeft: 16, color: '#fff' }}>
|
||||||
für Raumgruppe: <b>{typeof groupName === 'object' ? groupName.name : groupName}</b>
|
für Raumgruppe: <b>{typeof groupName === 'object' ? groupName.name : groupName}</b>
|
||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -163,3 +163,21 @@ def find_by_filename():
|
|||||||
'file_path': media.file_path,
|
'file_path': media.file_path,
|
||||||
'url': media.url
|
'url': media.url
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
|
@eventmedia_bp.route('/<int:media_id>', methods=['GET'])
|
||||||
|
def get_media_by_id(media_id):
|
||||||
|
session = Session()
|
||||||
|
media = session.query(EventMedia).get(media_id)
|
||||||
|
if not media:
|
||||||
|
session.close()
|
||||||
|
return jsonify({'error': 'Not found'}), 404
|
||||||
|
result = {
|
||||||
|
'id': media.id,
|
||||||
|
'file_path': media.file_path,
|
||||||
|
'url': media.url,
|
||||||
|
'name': media.url, # oder ein anderes Feld für den Namen
|
||||||
|
'media_type': media.media_type.name if media.media_type else None
|
||||||
|
}
|
||||||
|
session.close()
|
||||||
|
return jsonify(result)
|
||||||
|
|||||||
@@ -27,11 +27,14 @@ def get_events():
|
|||||||
for e in events:
|
for e in events:
|
||||||
result.append({
|
result.append({
|
||||||
"Id": str(e.id),
|
"Id": str(e.id),
|
||||||
"GroupId": e.group_id, # geändert: gibt group_id zurück
|
"GroupId": e.group_id,
|
||||||
"Subject": e.title,
|
"Subject": e.title,
|
||||||
"StartTime": e.start.isoformat() if e.start else None,
|
"StartTime": e.start.isoformat() if e.start else None,
|
||||||
"EndTime": e.end.isoformat() if e.end else None,
|
"EndTime": e.end.isoformat() if e.end else None,
|
||||||
"IsAllDay": False,
|
"IsAllDay": False,
|
||||||
|
"MediaId": e.event_media_id, # <--- Media-ID zurückgeben
|
||||||
|
"SlideshowInterval": e.slideshow_interval,
|
||||||
|
"WebsiteUrl": None, # Optional: für Website-Typ
|
||||||
})
|
})
|
||||||
session.close()
|
session.close()
|
||||||
return jsonify(result)
|
return jsonify(result)
|
||||||
@@ -115,3 +118,29 @@ def create_event():
|
|||||||
session.add(event)
|
session.add(event)
|
||||||
session.commit()
|
session.commit()
|
||||||
return jsonify({"success": True, "event_id": event.id})
|
return jsonify({"success": True, "event_id": event.id})
|
||||||
|
|
||||||
|
|
||||||
|
@events_bp.route("/<event_id>", methods=["PUT"])
|
||||||
|
def update_event(event_id):
|
||||||
|
data = request.json
|
||||||
|
session = Session()
|
||||||
|
event = session.query(Event).filter_by(id=event_id).first()
|
||||||
|
if not event:
|
||||||
|
session.close()
|
||||||
|
return jsonify({"error": "Termin nicht gefunden"}), 404
|
||||||
|
|
||||||
|
event.title = data.get("title", event.title)
|
||||||
|
event.description = data.get("description", event.description)
|
||||||
|
event.start = datetime.fromisoformat(
|
||||||
|
data["start"]) if "start" in data else event.start
|
||||||
|
event.end = datetime.fromisoformat(
|
||||||
|
data["end"]) if "end" in data else event.end
|
||||||
|
event.event_type = data.get("event_type", event.event_type)
|
||||||
|
event.event_media_id = data.get("event_media_id", event.event_media_id)
|
||||||
|
event.slideshow_interval = data.get(
|
||||||
|
"slideshow_interval", event.slideshow_interval)
|
||||||
|
event.created_by = data.get("created_by", event.created_by)
|
||||||
|
session.commit()
|
||||||
|
event_id_return = event.id # <-- ID vor session.close() speichern!
|
||||||
|
session.close()
|
||||||
|
return jsonify({"success": True, "event_id": event_id_return})
|
||||||
|
|||||||
Reference in New Issue
Block a user