Files
speiseplan/frontend/src/components/Layout.tsx
clawd e146442513 v0.2.0 — Phase 2: Frontend (React + Tailwind)
- Sidebar with KW navigation (← KW → arrows)
- WeekPlanner: 5-column grid (Mo-Fr), Frühstück + Vesper slots
- ProductList: searchable table with allergen/additive badges
- ProductForm: create/edit with AllergenPicker + AdditivePicker
- ProductSearch: autocomplete dropdown for plan entries
- DayColumn + MealSlot + EntryCard components
- SpecialDayDialog: Feiertag/Schließtag marking
- InfoPage: version display + update check
- Layout with responsive sidebar
- BITV 2.0: aria-labels, focus indicators, min 16px, WCAG AA contrasts
- All UI text in German
2026-02-20 10:05:01 +00:00

87 lines
2.5 KiB
TypeScript

import { useState, createContext, useContext } from 'react';
import { Outlet, useNavigate } from 'react-router-dom';
import { Sidebar } from './Sidebar';
import { getCurrentWeek } from '../lib/weekHelper';
import { useWeekPlan } from '../hooks/useWeekPlan';
// Context für die ausgewählte Woche
interface WeekContextType {
selectedWeek: { year: number; week: number };
setSelectedWeek: (week: { year: number; week: number }) => void;
}
const WeekContext = createContext<WeekContextType | null>(null);
export function Layout() {
const navigate = useNavigate();
const currentWeek = getCurrentWeek();
const [selectedWeek, setSelectedWeek] = useState(currentWeek);
const { createWeekPlan, copyWeekPlan } = useWeekPlan(selectedWeek.year, selectedWeek.week);
// Handle week change navigation
const handleWeekChange = (year: number, week: number) => {
setSelectedWeek({ year, week });
// Navigate to home if not already there
if (window.location.pathname !== '/') {
navigate('/');
}
};
// Handle creating new week plan
const handleCreateWeek = async (year: number, week: number) => {
try {
await createWeekPlan();
// Success handled by the hook
} catch (error) {
console.error('Fehler beim Erstellen des Wochenplans:', error);
}
};
// Handle copying week plan
const handleCopyWeek = async (srcYear: number, srcWeek: number) => {
try {
await copyWeekPlan(srcYear, srcWeek);
// Success handled by the hook
} catch (error) {
console.error('Fehler beim Kopieren des Wochenplans:', error);
}
};
return (
<WeekContext.Provider value={{ selectedWeek, setSelectedWeek }}>
<div className="flex h-screen bg-gray-50">
{/* Sidebar */}
<Sidebar
currentYear={selectedWeek.year}
currentWeek={selectedWeek.week}
onWeekChange={handleWeekChange}
onCreateWeek={handleCreateWeek}
onCopyWeek={handleCopyWeek}
/>
{/* Main Content */}
<main
className="flex-1 overflow-auto focus:outline-none"
id="main-content"
role="main"
aria-label="Hauptinhalt"
tabIndex={-1}
>
<div className="p-6 h-full">
<Outlet />
</div>
</main>
</div>
</WeekContext.Provider>
);
}
// Hook for accessing the selected week in child components
export function useSelectedWeek() {
const context = useContext(WeekContext);
if (!context) {
return getCurrentWeek();
}
return context.selectedWeek;
}