diff --git a/frontend/src/pages/ShiftPlans/ShiftPlanView.tsx b/frontend/src/pages/ShiftPlans/ShiftPlanView.tsx index 206951d..6538bcd 100644 --- a/frontend/src/pages/ShiftPlans/ShiftPlanView.tsx +++ b/frontend/src/pages/ShiftPlans/ShiftPlanView.tsx @@ -1,5 +1,5 @@ // frontend/src/pages/ShiftPlans/ShiftPlanView.tsx -import React, { useState, useEffect } from 'react'; +import React, { useState, useEffect, useRef } from 'react'; import { useParams, useNavigate } from 'react-router-dom'; import { useAuth } from '../../contexts/AuthContext'; import { shiftPlanService } from '../../services/shiftPlanService'; @@ -56,6 +56,12 @@ const ShiftPlanView: React.FC = () => { const [showAssignmentPreview, setShowAssignmentPreview] = useState(false); const [recreating, setRecreating] = useState(false); const [exporting, setExporting] = useState(false); + const [exportDropdownOpen, setExportDropdownOpen] = useState(false); + const [selectedExportType, setSelectedExportType] = useState(''); + const [showExportButton, setShowExportButton] = useState(false); + const [dropdownWidth, setDropdownWidth] = useState(0); + + const dropdownRef = useRef(null); useEffect(() => { loadShiftPlanData(); @@ -90,6 +96,13 @@ const ShiftPlanView: React.FC = () => { }; }, []); + // Measure dropdown width when it opens + useEffect(() => { + if (exportDropdownOpen && dropdownRef.current) { + setDropdownWidth(dropdownRef.current.offsetWidth); + } + }, [exportDropdownOpen]); + // Add this useEffect to debug state changes useEffect(() => { console.log('🔍 STATE DEBUG - showAssignmentPreview:', showAssignmentPreview); @@ -242,64 +255,51 @@ const ShiftPlanView: React.FC = () => { }; }; - const handleExportExcel = async () => { - if (!shiftPlan) return; + const handleExport = async () => { + if (!shiftPlan || !selectedExportType) return; try { setExporting(true); - // Call the export service - const blob = await shiftPlanService.exportShiftPlanToExcel(shiftPlan.id); + let blob: Blob; + if (selectedExportType === 'PDF') { + // Call the PDF export service + blob = await shiftPlanService.exportShiftPlanToPDF(shiftPlan.id); + } else { + // Call the Excel export service + blob = await shiftPlanService.exportShiftPlanToExcel(shiftPlan.id); + } // Use file-saver to download the file - saveAs(blob, `Schichtplan_${shiftPlan.name}_${new Date().toISOString().split('T')[0]}.xlsx`); + const fileExtension = selectedExportType.toLowerCase(); + saveAs(blob, `Schichtplan_${shiftPlan.name}_${new Date().toISOString().split('T')[0]}.${fileExtension}`); showNotification({ type: 'success', title: 'Export erfolgreich', - message: 'Der Schichtplan wurde als Excel-Datei exportiert.' + message: `Der Schichtplan wurde als ${selectedExportType}-Datei exportiert.` }); + // Reset export state + setSelectedExportType(''); + setShowExportButton(false); + } catch (error) { - console.error('Error exporting to Excel:', error); + console.error(`Error exporting to ${selectedExportType}:`, error); showNotification({ type: 'error', title: 'Export fehlgeschlagen', - message: 'Der Excel-Export konnte nicht durchgeführt werden.' + message: `Der ${selectedExportType}-Export konnte nicht durchgeführt werden.` }); } finally { setExporting(false); } }; - const handleExportPDF = async () => { - if (!shiftPlan) return; - - try { - setExporting(true); - - // Call the PDF export service - const blob = await shiftPlanService.exportShiftPlanToPDF(shiftPlan.id); - - // Use file-saver to download the file - saveAs(blob, `Schichtplan_${shiftPlan.name}_${new Date().toISOString().split('T')[0]}.pdf`); - - showNotification({ - type: 'success', - title: 'Export erfolgreich', - message: 'Der Schichtplan wurde als PDF exportiert.' - }); - - } catch (error) { - console.error('Error exporting to PDF:', error); - showNotification({ - type: 'error', - title: 'Export fehlgeschlagen', - message: 'Der PDF-Export konnte nicht durchgeführt werden.' - }); - } finally { - setExporting(false); - } + const handleExportTypeSelect = (type: string) => { + setSelectedExportType(type); + setExportDropdownOpen(false); + setShowExportButton(true); }; const loadShiftPlanData = async () => { @@ -460,14 +460,6 @@ const ShiftPlanView: React.FC = () => { console.log('- Shift Patterns:', shiftPlan.shifts?.length || 0); console.log('- Scheduled Shifts:', scheduledShifts.length); - // DEBUG: Show shift pattern IDs - /*if (shiftPlan.shifts) { - console.log('📋 SHIFT PATTERN IDs:'); - shiftPlan.shifts.forEach((shift, index) => { - console.log(` ${index + 1}. ${shift.id} (Day ${shift.dayOfWeek}, TimeSlot ${shift.timeSlotId})`); - }); - }*/ - const constraints = { enforceNoTraineeAlone: true, enforceExperiencedWithChef: true, @@ -1084,6 +1076,78 @@ const ShiftPlanView: React.FC = () => { + + {/* Export Dropdown - Only show when plan is published */} + {shiftPlan?.status === 'published' && ( +
+
+ {/* Export Dropdown */} +
+ +
+ + {/* Export Button */} + {showExportButton && ( + + )} +
+
+ )} ); }; @@ -1125,48 +1189,6 @@ const ShiftPlanView: React.FC = () => {
- {shiftPlan.status === 'published' && hasRole(['admin', 'maintenance']) && ( - <> - - - - - )} - {/* "Zuweisungen neu berechnen" button */} {shiftPlan.status === 'published' && hasRole(['admin', 'maintenance']) && (