fix: Unwrap matrix event object in ShiftMatrixTable and EventEditorPage to fix Invalid Date and form initialization
This commit is contained in:
Vendored
+1
-1
@@ -11,7 +11,7 @@
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@500;600;700&family=JetBrains+Mono:wght@400;500;600;700&family=Plus+Jakarta+Sans:wght@400;500;600;700;800&display=swap" rel="stylesheet">
|
||||
<title>Schichtplaner — Veranstaltungsschichtpläne</title>
|
||||
<script type="module" crossorigin src="/assets/index-RWm1c0SS.js"></script>
|
||||
<script type="module" crossorigin src="/assets/index-CgCRSgos.js"></script>
|
||||
<link rel="stylesheet" crossorigin href="/assets/index-BIEZThrv.css">
|
||||
</head>
|
||||
<body class="bg-paper text-main font-sans antialiased min-h-screen">
|
||||
|
||||
@@ -27,15 +27,23 @@ export default function ShiftMatrixTable({
|
||||
window.removeEventListener('storage', handleUpdate);
|
||||
};
|
||||
}, []);
|
||||
if (!event || !event.task_areas || event.task_areas.length === 0) {
|
||||
const eventObj = event?.event || event || {};
|
||||
const taskAreas = event?.task_areas || eventObj?.task_areas || [];
|
||||
|
||||
const createdById = typeof eventObj.created_by === 'object' ? eventObj.created_by?.id : eventObj.created_by;
|
||||
const isGuest = !user;
|
||||
const isCoManager = user && eventObj?.co_managers && eventObj.co_managers.some(cm => (typeof cm === 'object' ? cm.id === user.id : cm === user.id));
|
||||
const isManager = user && (user.is_admin_user || user.is_staff || user.is_superuser || createdById === user.id || isCoManager);
|
||||
|
||||
if (!eventObj || !taskAreas || taskAreas.length === 0) {
|
||||
return (
|
||||
<div className="hallmark-panel rounded-sm p-12 text-center border border-grid font-mono">
|
||||
<Clock className="w-8 h-8 text-muted mx-auto mb-3" />
|
||||
<h3 className="font-serif text-xl font-bold text-main uppercase">Keine Aufgabenfelder vorhanden</h3>
|
||||
<p className="text-xs text-muted mt-1 mb-4">[ Event hat noch keine definierten Aufgabenfelder oder Schichten ]</p>
|
||||
{user && (user.is_admin_user || user.is_staff || user.is_superuser || event?.created_by === user.id || event?.created_by?.id === user.id || (event?.co_managers && event.co_managers.some(cm => (typeof cm === 'object' ? cm.id === user.id : cm === user.id)))) && onEditEvent && (
|
||||
{isManager && onEditEvent && (
|
||||
<button
|
||||
onClick={() => onEditEvent(event)}
|
||||
onClick={() => onEditEvent(eventObj)}
|
||||
className="px-4 py-2 rounded-sm bg-indigo-500/10 hover:bg-indigo-500/20 text-indigo-400 border border-indigo-500/30 font-bold text-xs inline-flex items-center gap-2"
|
||||
>
|
||||
<Edit3 className="w-4 h-4" /> SCHICHTEN & BEREICHE ANLEGEN
|
||||
@@ -45,10 +53,6 @@ export default function ShiftMatrixTable({
|
||||
);
|
||||
}
|
||||
|
||||
const isGuest = !user;
|
||||
const isCoManager = user && event?.co_managers && event.co_managers.some(cm => (typeof cm === 'object' ? cm.id === user.id : cm === user.id));
|
||||
const isManager = user && (user.is_admin_user || user.is_staff || user.is_superuser || event?.created_by === user.id || event?.created_by?.id === user.id || isCoManager);
|
||||
|
||||
return (
|
||||
<div className="space-y-6">
|
||||
{/* Event Header Panel */}
|
||||
@@ -56,37 +60,37 @@ export default function ShiftMatrixTable({
|
||||
<div className="space-y-1 font-mono">
|
||||
<div className="flex flex-wrap items-center gap-2 text-xs text-muted mb-1">
|
||||
<span className="bg-subtle px-2.5 py-0.5 rounded-sm border border-grid font-bold text-main">
|
||||
{new Date(event.start_date).toLocaleDateString('de-DE')} — {new Date(event.end_date).toLocaleDateString('de-DE')}
|
||||
{eventObj.start_date ? new Date(eventObj.start_date).toLocaleDateString('de-DE') : '—'} — {eventObj.end_date ? new Date(eventObj.end_date).toLocaleDateString('de-DE') : '—'}
|
||||
</span>
|
||||
{event.location && (
|
||||
{eventObj.location && (
|
||||
<span className="flex items-center gap-1 text-muted">
|
||||
<MapPin className="w-3.5 h-3.5 shrink-0" />
|
||||
{event.location}
|
||||
{eventObj.location}
|
||||
</span>
|
||||
)}
|
||||
{event.is_active === false && (
|
||||
{eventObj.is_active === false && (
|
||||
<span className="px-2 py-0.5 rounded-sm bg-amber-500/10 text-amber-500 border border-amber-500/20 font-bold">
|
||||
[ DEAKTIVIERT ]
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
<h2 className="font-serif text-3xl sm:text-4xl font-bold uppercase tracking-tight text-main">{event.title}</h2>
|
||||
{event.description && <p className="text-xs font-sans text-muted max-w-2xl mt-1">{event.description}</p>}
|
||||
<h2 className="font-serif text-3xl sm:text-4xl font-bold uppercase tracking-tight text-main">{eventObj.title}</h2>
|
||||
{eventObj.description && <p className="text-xs font-sans text-muted max-w-2xl mt-1">{eventObj.description}</p>}
|
||||
</div>
|
||||
|
||||
<div className="flex items-center gap-2 no-print font-mono text-xs shrink-0">
|
||||
{isManager && onEditEvent && (
|
||||
<button
|
||||
onClick={() => onEditEvent(event)}
|
||||
onClick={() => onEditEvent(eventObj)}
|
||||
className="px-3.5 py-1.5 rounded-sm bg-indigo-500/10 hover:bg-indigo-500/20 text-indigo-400 border border-indigo-500/30 transition flex items-center gap-1.5 font-bold"
|
||||
title="Schichten und Aufgabenbereiche für diese Veranstaltung bearbeiten"
|
||||
>
|
||||
<Edit3 className="w-3.5 h-3.5" /> SCHICHTEN BEARBEITEN
|
||||
</button>
|
||||
)}
|
||||
{user && (user.is_admin_user || user.is_staff || user.is_superuser || event?.created_by === user.id || event?.created_by?.id === user.id) && onDeleteEvent && (
|
||||
{isManager && onDeleteEvent && (
|
||||
<button
|
||||
onClick={() => onDeleteEvent(event)}
|
||||
onClick={() => onDeleteEvent(eventObj)}
|
||||
className="px-3.5 py-1.5 rounded-sm bg-red-500/10 hover:bg-red-500/20 text-red-400 border border-red-500/30 transition flex items-center gap-1.5 font-bold"
|
||||
title="Diese Veranstaltung unwiderruflich löschen"
|
||||
>
|
||||
@@ -141,7 +145,7 @@ export default function ShiftMatrixTable({
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody className="divide-y divide-grid text-xs font-sans">
|
||||
{event.task_areas.map((area) => {
|
||||
{taskAreas.map((area) => {
|
||||
if (!area.shifts || area.shifts.length === 0) {
|
||||
return (
|
||||
<tr key={`area-${area.id}`}>
|
||||
|
||||
@@ -7,16 +7,18 @@ import { apiFetch } from '../api/client';
|
||||
export default function EventEditorPage({ eventToEdit, skills, user, onBack, onSubmit, onDeleteEvent }) {
|
||||
const loadedEventIdRef = useRef(undefined);
|
||||
|
||||
const [eventId, setEventId] = useState(eventToEdit?.id || null);
|
||||
const [title, setTitle] = useState(eventToEdit?.title || '');
|
||||
const [description, setDescription] = useState(eventToEdit?.description || '');
|
||||
const [location, setLocation] = useState(eventToEdit?.location || '');
|
||||
const [startDate, setStartDate] = useState(eventToEdit?.start_date || new Date().toISOString().split('T')[0]);
|
||||
const [endDate, setEndDate] = useState(eventToEdit?.end_date || new Date().toISOString().split('T')[0]);
|
||||
const targetEvent = eventToEdit?.event ? { ...eventToEdit.event, task_areas: eventToEdit.task_areas || eventToEdit.event.task_areas } : eventToEdit;
|
||||
|
||||
const [eventId, setEventId] = useState(targetEvent?.id || null);
|
||||
const [title, setTitle] = useState(targetEvent?.title || '');
|
||||
const [description, setDescription] = useState(targetEvent?.description || '');
|
||||
const [location, setLocation] = useState(targetEvent?.location || '');
|
||||
const [startDate, setStartDate] = useState(targetEvent?.start_date || new Date().toISOString().split('T')[0]);
|
||||
const [endDate, setEndDate] = useState(targetEvent?.end_date || new Date().toISOString().split('T')[0]);
|
||||
|
||||
// Co-managers state
|
||||
const [coManagerIds, setCoManagerIds] = useState(
|
||||
eventToEdit?.co_managers ? eventToEdit.co_managers.map(u => (typeof u === 'object' ? u.id : u)) : []
|
||||
targetEvent?.co_managers ? targetEvent.co_managers.map(u => (typeof u === 'object' ? u.id : u)) : []
|
||||
);
|
||||
const [allUsers, setAllUsers] = useState([]);
|
||||
|
||||
@@ -28,32 +30,32 @@ export default function EventEditorPage({ eventToEdit, skills, user, onBack, onS
|
||||
useEffect(() => {
|
||||
fetchUsers();
|
||||
|
||||
const currentId = eventToEdit?.id || null;
|
||||
const currentId = targetEvent?.id || null;
|
||||
|
||||
// Only populate form fields if eventId changed or initial load
|
||||
if (loadedEventIdRef.current !== currentId) {
|
||||
loadedEventIdRef.current = currentId;
|
||||
|
||||
if (eventToEdit) {
|
||||
setEventId(eventToEdit.id);
|
||||
setTitle(eventToEdit.title || '');
|
||||
setDescription(eventToEdit.description || '');
|
||||
setLocation(eventToEdit.location || '');
|
||||
setStartDate(eventToEdit.start_date || new Date().toISOString().split('T')[0]);
|
||||
setEndDate(eventToEdit.end_date || new Date().toISOString().split('T')[0]);
|
||||
if (targetEvent) {
|
||||
setEventId(targetEvent.id);
|
||||
setTitle(targetEvent.title || '');
|
||||
setDescription(targetEvent.description || '');
|
||||
setLocation(targetEvent.location || '');
|
||||
setStartDate(targetEvent.start_date || new Date().toISOString().split('T')[0]);
|
||||
setEndDate(targetEvent.end_date || new Date().toISOString().split('T')[0]);
|
||||
setCoManagerIds(
|
||||
eventToEdit.co_managers ? eventToEdit.co_managers.map(u => (typeof u === 'object' ? u.id : u)) : []
|
||||
targetEvent.co_managers ? targetEvent.co_managers.map(u => (typeof u === 'object' ? u.id : u)) : []
|
||||
);
|
||||
|
||||
if (eventToEdit.task_areas && eventToEdit.task_areas.length > 0) {
|
||||
const formattedAreas = eventToEdit.task_areas.map(ta => ({
|
||||
if (targetEvent.task_areas && targetEvent.task_areas.length > 0) {
|
||||
const formattedAreas = targetEvent.task_areas.map(ta => ({
|
||||
id: ta.id,
|
||||
name: ta.name,
|
||||
description: ta.description || '',
|
||||
shifts: (ta.shifts || []).map(s => ({
|
||||
id: s.id,
|
||||
title: s.title,
|
||||
date: s.date || eventToEdit.start_date,
|
||||
date: s.date || targetEvent.start_date,
|
||||
start_time: s.start_time,
|
||||
end_time: s.end_time,
|
||||
max_participants: s.max_participants || 1,
|
||||
|
||||
Reference in New Issue
Block a user