feat: add forgejo_error_reporter plugin for automatic error reporting to Forgejo issues
This commit is contained in:
+48
-12
@@ -5,27 +5,62 @@ import { setUnauthorizedHandler } from '@/api/client';
|
||||
import { useAuthStore } from '@/store/authStore';
|
||||
import { useThemeStore } from '@/store/themeStore';
|
||||
import { ErrorBoundary } from '@/components/common/ErrorBoundary';
|
||||
import { useToast } from '@/components/ui/Toast';
|
||||
import { useOnlineStatus } from '@/hooks/useOnlineStatus';
|
||||
|
||||
const queryClient = new QueryClient({
|
||||
defaultOptions: {
|
||||
queries: {
|
||||
retry: 1,
|
||||
staleTime: 5 * 60 * 1000,
|
||||
refetchOnWindowFocus: false,
|
||||
function QueryClientWrapper({ children }: { children: React.ReactNode }) {
|
||||
const toast = useToast();
|
||||
|
||||
const [queryClient] = React.useState(() => new QueryClient({
|
||||
defaultOptions: {
|
||||
queries: {
|
||||
retry: 1,
|
||||
staleTime: 5 * 60 * 1000,
|
||||
refetchOnWindowFocus: false,
|
||||
},
|
||||
mutations: {
|
||||
retry: 0,
|
||||
onError: (error: any) => {
|
||||
// Don't show toast for 401 (handled by auth)
|
||||
if (error?.status === 401) return;
|
||||
const msg = error?.detail || error?.message || 'Ein Fehler ist aufgetreten';
|
||||
toast.error(msg);
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
}));
|
||||
|
||||
return (
|
||||
<QueryClientProvider client={queryClient}>
|
||||
{children}
|
||||
</QueryClientProvider>
|
||||
);
|
||||
}
|
||||
|
||||
function OfflineBanner() {
|
||||
const isOnline = useOnlineStatus();
|
||||
|
||||
if (isOnline) return null;
|
||||
|
||||
return (
|
||||
<div className="fixed top-0 left-0 right-0 z-[200] bg-warning-500 text-white text-center py-2 px-4 text-sm font-medium shadow-md">
|
||||
Sie sind offline. Änderungen werden gespeichert wenn die Verbindung wiederhergestellt ist.
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default function App() {
|
||||
const { logout } = useAuthStore();
|
||||
const loadThemeFromStorage = useThemeStore((s) => s.loadFromStorage);
|
||||
const toast = useToast();
|
||||
|
||||
React.useEffect(() => {
|
||||
setUnauthorizedHandler(() => {
|
||||
toast.warning('Ihre Sitzung ist abgelaufen. Sie werden zur Anmeldung weitergeleitet.');
|
||||
logout();
|
||||
window.location.href = '/login';
|
||||
setTimeout(() => { window.location.href = '/login'; }, 1500);
|
||||
});
|
||||
}, [logout]);
|
||||
}, [logout, toast]);
|
||||
|
||||
// Load theme from localStorage on app start
|
||||
React.useEffect(() => {
|
||||
@@ -33,10 +68,11 @@ export default function App() {
|
||||
}, [loadThemeFromStorage]);
|
||||
|
||||
return (
|
||||
<QueryClientProvider client={queryClient}>
|
||||
<QueryClientWrapper>
|
||||
<OfflineBanner />
|
||||
<ErrorBoundary>
|
||||
<AppRouter />
|
||||
</ErrorBoundary>
|
||||
</QueryClientProvider>
|
||||
</QueryClientWrapper>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user