diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index 9d0b366..fd4c5db 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -3,6 +3,7 @@ import { Layout, useSelectedWeek } from './components/Layout'; import { WeekPlanner } from './components/WeekPlanner'; import { ProductList } from './components/ProductList'; import { InfoPage } from './components/InfoPage'; +import { ErrorBoundary } from './components/ErrorBoundary'; import { useProducts } from './hooks/useProducts'; import './styles/globals.css'; @@ -68,6 +69,7 @@ function ProductsPage() { // Main App Component function App() { return ( +
@@ -87,6 +89,7 @@ function App() {
+
); } diff --git a/frontend/src/components/ErrorBoundary.tsx b/frontend/src/components/ErrorBoundary.tsx new file mode 100644 index 0000000..a2c10e0 --- /dev/null +++ b/frontend/src/components/ErrorBoundary.tsx @@ -0,0 +1,58 @@ +import { Component, ErrorInfo, ReactNode } from 'react'; + +interface Props { + children: ReactNode; +} + +interface State { + hasError: boolean; + error: Error | null; +} + +export class ErrorBoundary extends Component { + constructor(props: Props) { + super(props); + this.state = { hasError: false, error: null }; + } + + static getDerivedStateFromError(error: Error): State { + return { hasError: true, error }; + } + + componentDidCatch(error: Error, errorInfo: ErrorInfo) { + console.error('ErrorBoundary caught:', error, errorInfo); + } + + render() { + if (this.state.hasError) { + return ( +
+
+ + + +

+ Etwas ist schiefgelaufen +

+

+ Ein unerwarteter Fehler ist aufgetreten. Bitte laden Sie die Seite neu. +

+ {this.state.error && ( +

+ {this.state.error.message} +

+ )} + +
+
+ ); + } + + return this.props.children; + } +} diff --git a/frontend/src/components/WeekPlanner.tsx b/frontend/src/components/WeekPlanner.tsx index 132aeb0..b12d032 100644 --- a/frontend/src/components/WeekPlanner.tsx +++ b/frontend/src/components/WeekPlanner.tsx @@ -85,8 +85,8 @@ export function WeekPlanner({ year, week, className = '' }: WeekPlannerProps) { setPdfSuccess(null); try { - const result = await ExportPDF(weekPlan.id, ''); - setPdfSuccess(result || 'PDF wurde erfolgreich erstellt.'); + await ExportPDF(weekPlan.id, ''); + setPdfSuccess('PDF wurde erfolgreich erstellt.'); // Success-Nachricht nach 5 Sekunden ausblenden setTimeout(() => { diff --git a/frontend/src/hooks/useProducts.ts b/frontend/src/hooks/useProducts.ts index aa4513c..6571b79 100644 --- a/frontend/src/hooks/useProducts.ts +++ b/frontend/src/hooks/useProducts.ts @@ -66,7 +66,9 @@ export function useProducts() { data.additiveIds ); - setProducts(prev => [...prev, newProduct]); + if (newProduct) { + setProducts(prev => [...prev, newProduct]); + } return newProduct; } catch (err) { setError(err instanceof Error ? err.message : 'Fehler beim Erstellen des Produkts'); @@ -90,7 +92,9 @@ export function useProducts() { data.additiveIds ); - setProducts(prev => prev.map(p => p.id === id ? updatedProduct : p)); + if (updatedProduct) { + setProducts(prev => prev.map(p => p.id === id ? updatedProduct : p)); + } return updatedProduct; } catch (err) { setError(err instanceof Error ? err.message : 'Fehler beim Bearbeiten des Produkts'); diff --git a/frontend/src/hooks/useWeekPlan.ts b/frontend/src/hooks/useWeekPlan.ts index 3ef3e74..0052280 100644 --- a/frontend/src/hooks/useWeekPlan.ts +++ b/frontend/src/hooks/useWeekPlan.ts @@ -96,11 +96,12 @@ export function useWeekPlan(year: number, week: number) { groupLabel ?? null ); - // State aktualisieren - setWeekPlan(prev => prev ? { - ...prev, - entries: [...prev.entries, newEntry] - } : null); + if (newEntry) { + setWeekPlan(prev => prev ? { + ...prev, + entries: [...prev.entries, newEntry] + } : null); + } return newEntry; } catch (err) { @@ -138,11 +139,12 @@ export function useWeekPlan(year: number, week: number) { // Go: UpdatePlanEntry(id int, productID *int, customText *string, groupLabel *string) const updatedEntry = await UpdatePlanEntry(entryId, productId ?? null, customText ?? null, groupLabel ?? null); - // State aktualisieren - setWeekPlan(prev => prev ? { - ...prev, - entries: prev.entries.map(e => e.id === entryId ? updatedEntry : e) - } : null); + if (updatedEntry) { + setWeekPlan(prev => prev ? { + ...prev, + entries: prev.entries.map(e => e.id === entryId ? updatedEntry : e) + } : null); + } return updatedEntry; } catch (err) {