From 0c7a69ffe0882cf7f294405cd185e560b2f8845f Mon Sep 17 00:00:00 2001 From: Z User Date: Mon, 10 Aug 2026 20:36:02 +0000 Subject: [PATCH] Add calendar event filter tabs and grading analytics view MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Calendar Enhancement: - Added event filter tabs to ProfessionalCalendar: 'Alle' | 'Prüfungen' | 'Veranstaltungen' | 'Ferien' These replace the removed exam-calendar and school-events nav entries - Added filteredEvents useMemo for efficient filtering - Localized view tabs to German (Monat/Woche/Agenda) Grading Enhancement: - Added Analytics view to UnifiedGradingPanel (3rd view mode) This replaces the removed grade-analytics nav entry - Shows: Durchschnitt, Bestehensquote, Noten gesamt, Fächer - Subject breakdown with progress bars - Grade distribution histogram (5 buckets) - Added ListIcon and TrendingUp icons to view switcher --- src/components/professional-calendar.tsx | 43 ++++++++-- src/components/unified-grading-panel.tsx | 100 ++++++++++++++++++++++- 2 files changed, 133 insertions(+), 10 deletions(-) diff --git a/src/components/professional-calendar.tsx b/src/components/professional-calendar.tsx index 0b4adc8..1d34bd2 100644 --- a/src/components/professional-calendar.tsx +++ b/src/components/professional-calendar.tsx @@ -94,6 +94,7 @@ export function ProfessionalCalendar({ const [isCreating, setIsCreating] = useState(false); const [draggedEvent, setDraggedEvent] = useState(null); const [view, setView] = useState<'month' | 'week' | 'day' | 'agenda'>(variant); + const [eventFilter, setEventFilter] = useState<'all' | 'exams' | 'events' | 'holidays'>('all'); const contextMenuRef = useRef<{ x: number; y: number } | null>(null); const dateLocale = locale === 'de' ? deLocale : enLocale; @@ -132,9 +133,21 @@ export function ProfessionalCalendar({ }, [events, monthStart, monthEnd]); // Get events for a specific date + // Filtered events based on the active filter tab + const filteredEvents = useMemo(() => { + if (eventFilter === 'all') return events; + const filterMap: Record = { + exams: ['EXAM', 'TEST', 'ASSESSMENT'], + events: ['EVENT', 'ACTIVITY', 'MEETING', 'TRIP'], + holidays: ['HOLIDAY', 'BREAK'], + }; + const types = filterMap[eventFilter] || []; + return events.filter(e => types.includes(e.type?.toUpperCase() || '')); + }, [events, eventFilter]); + const getEventsForDate = useCallback((date: Date): CalendarEvent[] => { - return CalendarManager.getEventsForDate(events, date); - }, [events]); + return CalendarManager.getEventsForDate(filteredEvents, date); + }, [filteredEvents]); // Handle event creation const handleCreateEvent = useCallback( @@ -342,13 +355,25 @@ export function ProfessionalCalendar({ {/* View tabs */} - setView(v as any)}> - - Month - Week - Agenda - - +
+ setView(v as any)}> + + Monat + Woche + Agenda + + + + {/* Event filter tabs (replaces exam-calendar and school-events) */} + setEventFilter(v as any)}> + + Alle + Prüfungen + Veranstaltungen + Ferien + + +
@@ -486,8 +573,18 @@ export function UnifiedGradingPanel({ variant={viewType === 'list' ? 'default' : 'ghost'} onClick={() => setViewType('list')} className="flex-1" + title="Liste" > - + + + @@ -497,6 +594,7 @@ export function UnifiedGradingPanel({ {viewType === 'grid' && renderDesktopView()} {viewType === 'list' && renderListView()} + {viewType === 'analytics' && renderAnalyticsView()} {/* Edit grade dialog */}