From dd1d78e6add8b261ee56d410bca234896c44840b Mon Sep 17 00:00:00 2001 From: eddy Date: Wed, 15 Apr 2026 15:17:11 +0200 Subject: [PATCH] stabile version --- src/App.jsx | 262 +++++++++--------- src/components/ErrorBoundary.jsx | 29 ++ src/components/Layout.jsx | 12 +- src/pages/Attraction/AttractionPage.jsx | 6 +- src/pages/Attraction/EditAttractionPage.jsx | 13 +- src/pages/Auth/UsersPage.jsx | 6 +- src/pages/Company/CompanyPage.jsx | 4 +- src/pages/Company/EditCompanyPage.jsx | 22 +- src/pages/News/CreateNewsPage.jsx | 19 +- src/pages/Notification/PushPage.jsx | 16 +- .../Organization/EditOrganizationPage.jsx | 24 +- src/pages/Organization/OrganizationPage.jsx | 2 +- 12 files changed, 248 insertions(+), 167 deletions(-) create mode 100644 src/components/ErrorBoundary.jsx diff --git a/src/App.jsx b/src/App.jsx index 700c6df..8ef80fc 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -1,4 +1,4 @@ -import { BrowserRouter, Routes, Route, Navigate } from 'react-router-dom'; +import {BrowserRouter, Routes, Route} from 'react-router-dom'; import { createTheme, ThemeProvider, CssBaseline } from '@mui/material'; import { AuthProvider } from './context/AuthContext'; import PrivateRoute from './components/PrivateRoute'; @@ -19,139 +19,139 @@ import EditCompanyPage from "./pages/Company/EditCompanyPage.jsx"; import CalenderPostPage from "./pages/Calender/CalenderPostPage.jsx"; const theme = createTheme({ - palette: { - mode: 'light', - primary: { main: '#1976d2' }, - background: { default: '#f5f5f5' }, - }, - shape: { borderRadius: 8 }, - typography: { - fontFamily: '"Inter", "Roboto", "Helvetica", "Arial", sans-serif', - }, - components: { - MuiButton: { - styleOverrides: { - root: { textTransform: 'none', fontWeight: 500 }, - }, + palette: { + mode: 'light', + primary: { main: '#1976d2' }, + background: { default: '#f5f5f5' }, }, - MuiCard: { - styleOverrides: { - root: { boxShadow: '0 1px 3px rgba(0,0,0,0.08)', border: '1px solid #e0e0e0' }, - }, + shape: { borderRadius: 8 }, + typography: { + fontFamily: '"Inter", "Roboto", "Helvetica", "Arial", sans-serif', + }, + components: { + MuiButton: { + styleOverrides: { + root: { textTransform: 'none', fontWeight: 500 }, + }, + }, + MuiCard: { + styleOverrides: { + root: { boxShadow: '0 1px 3px rgba(0,0,0,0.08)', border: '1px solid #e0e0e0' }, + }, + }, }, - }, }); export default function App() { - return ( - - - - - - } /> - } /> - - - - } - > - } /> - - - - } - /> - - - - } - /> - - - - } - /> - - - - } - /> - - - - } - /> - - - - } - /> - - - - } - /> - - - - } - /> - - - - } - /> - - - - } - /> - - - - } - /> - - - - - - ); + return ( + + + + + + } /> + } /> + + + + } + > + } /> + + + + } + /> + + + + } + /> + + + + } + /> + + + + } + /> + + + + } + /> + + + + } + /> + + + + } + /> + + + + } + /> + + + + } + /> + + + + } + /> + + + + } + /> + + + + + + ); } \ No newline at end of file diff --git a/src/components/ErrorBoundary.jsx b/src/components/ErrorBoundary.jsx new file mode 100644 index 0000000..6c198a9 --- /dev/null +++ b/src/components/ErrorBoundary.jsx @@ -0,0 +1,29 @@ +import { Component } from 'react'; + +class ErrorBoundary extends Component { + constructor(props) { + super(props); + this.state = { hasError: false, error: null }; + } + + static getDerivedStateFromError(error) { + return { hasError: true, error }; + } + + render() { + if (this.state.hasError) { + return ( +
+

Etwas ist schiefgelaufen.

+

{this.state.error?.message || 'Unbekannter Fehler'}

+ +
+ ); + } + return this.props.children; + } +} + +export default ErrorBoundary; \ No newline at end of file diff --git a/src/components/Layout.jsx b/src/components/Layout.jsx index 47be6ea..b394833 100644 --- a/src/components/Layout.jsx +++ b/src/components/Layout.jsx @@ -14,6 +14,7 @@ import CalendarMonthIcon from '@mui/icons-material/CalendarMonth'; import HomeIcon from '@mui/icons-material/Home'; import StoreIcon from '@mui/icons-material/Store'; import { useAuth } from '../context/AuthContext'; +import ErrorBoundary from './ErrorBoundary'; const DRAWER_WIDTH = 240; @@ -34,9 +35,9 @@ const navCategories = [ { label: 'Reporter', items: [ - { label: 'Neuigkeiten', path: '/posts', icon: , roles: ['ADMIN', 'REPORTER'] }, - { label: 'Kalendereinträge', path: '/calenderPosts', icon: , roles: ['ADMIN', 'REPORTER'] }, - { label: 'Sehenswürdigkeiten', path: '/attractions', icon: , roles: ['ADMIN', 'REPORTER'] }, + { label: 'Neuigkeiten', path: '/posts', icon: , roles: ['ADMIN', 'REPORTER'] }, + { label: 'Kalendereinträge', path: '/calenderPosts', icon: , roles: ['ADMIN', 'REPORTER'] }, + { label: 'Sehenswürdigkeiten', path: '/attractions', icon: , roles: ['ADMIN', 'REPORTER'] }, ], }, { @@ -173,8 +174,11 @@ export default function Layout() { + - + + + diff --git a/src/pages/Attraction/AttractionPage.jsx b/src/pages/Attraction/AttractionPage.jsx index 6cb099c..838cd91 100644 --- a/src/pages/Attraction/AttractionPage.jsx +++ b/src/pages/Attraction/AttractionPage.jsx @@ -31,7 +31,7 @@ export default function AttractionPage() { const { data } = await axiosInstance.get('/attraction'); setRows(data); } catch (err) { - setError(err.response?.data?.message ?? 'Fehler beim laden der Attractions'); + setError(err.response?.data?.error ?? 'Fehler beim laden der Attractions'); } finally { setLoading(false); @@ -61,7 +61,7 @@ export default function AttractionPage() { handleCreateClose(); } catch (err) { - setCreatingError(err.response?.data?.message ?? 'Erstellen fehlgeschlagen'); + setCreatingError(err.response?.data?.error ?? 'Erstellen fehlgeschlagen'); } finally { setCreating(false); } @@ -80,7 +80,7 @@ export default function AttractionPage() { await axiosInstance.delete(`/attraction/${id}`); setRows((prev) => prev.filter((r) => r.id !== id)); } catch(err){ - alert(err.response?.data?.message ?? 'Löschen fehlgeschlagen'); + alert(err.response?.data?.error ?? 'Löschen fehlgeschlagen'); } }; diff --git a/src/pages/Attraction/EditAttractionPage.jsx b/src/pages/Attraction/EditAttractionPage.jsx index 97b8dc0..07355fd 100644 --- a/src/pages/Attraction/EditAttractionPage.jsx +++ b/src/pages/Attraction/EditAttractionPage.jsx @@ -60,7 +60,8 @@ export default function EditAttractionPage() { setTitleImageUrl(imgs[0] || null); setOtherImageUrls(imgs.slice(1)); } catch (err) { - setError(err.response?.data?.message ?? 'Fehler beim Laden der Sehenswürdigkeit'); + const msg = err.response?.data?.error; + setError(typeof msg === 'string' ? msg : 'Fehler beim Laden der Sehenswürdigkeit'); } }; fetchData(); @@ -135,7 +136,8 @@ export default function EditAttractionPage() { }); navigate('/attractions'); } catch (err) { - setError(err.response?.data?.message ?? 'Fehler beim Speichern'); + const msg = err.response?.data?.error; + setError(typeof msg === 'string' ? msg : 'Fehler beim Speichern'); setSaving(false); } }; @@ -155,8 +157,11 @@ export default function EditAttractionPage() { - {error && {error}} - + {error && ( + + {typeof error === 'string' ? error : JSON.stringify(error)} + + )} prev.filter((r) => r.id !== id)); } catch (err){ - alert(err.response?.data?.message ?? 'Löschen fehlgeschlagen'); + alert(err.response?.data?.error ?? 'Löschen fehlgeschlagen'); } }; diff --git a/src/pages/Company/EditCompanyPage.jsx b/src/pages/Company/EditCompanyPage.jsx index 2e55117..cbf6b7b 100644 --- a/src/pages/Company/EditCompanyPage.jsx +++ b/src/pages/Company/EditCompanyPage.jsx @@ -70,7 +70,9 @@ export default function EditCompanyPage() { setTitleImageUrl(imgs[0] || null); setOtherImageUrls(imgs.slice(1)); } catch (err) { - setError(err.response?.data || 'Fehler beim Laden'); + // ✅ err.response.data kann ein Objekt sein → .error extrahieren + const serverMessage = err.response?.data?.error || err.response?.data; + setError(typeof serverMessage === 'string' ? serverMessage : 'Fehler beim Laden'); } }; fetchData(); @@ -143,9 +145,15 @@ export default function EditCompanyPage() { await axiosInstance.put(`/company/${id}`, formData, { headers: { 'Content-Type': undefined } }); + navigate('/companies'); } catch (err) { - setError(err.response?.data || 'Fehler beim Speichern'); + // ✅ Fehlermeldung korrekt aus Axios-Response extrahieren + const serverMessage = err.response?.data?.error || err.response?.data; + const message = typeof serverMessage === 'string' + ? serverMessage + : err.message || 'Fehler beim Speichern'; + setError(message); setSaving(false); } }; @@ -165,8 +173,11 @@ export default function EditCompanyPage() { - {error && {error}} - + {error && ( + + {typeof error === 'string' ? error : JSON.stringify(error)} + + )} @@ -224,7 +235,6 @@ export default function EditCompanyPage() { {titleImageFile ? titleImageFile.name : titleImageUrl} - {/* Titelbild tauschen ohne zu löschen */}