|
|
@@ -1,4 +1,5 @@
|
|
|
-import { Routes, Route, Navigate } from 'react-router-dom';
|
|
|
+import { useEffect, useCallback } from 'react';
|
|
|
+import { Routes, Route, Navigate, useNavigate } from 'react-router-dom';
|
|
|
import { useAuth } from '@picobaas/client/react';
|
|
|
import Layout from './components/Layout';
|
|
|
import HomePage from './pages/HomePage';
|
|
|
@@ -10,6 +11,33 @@ import ImageDetailPage from './pages/ImageDetailPage';
|
|
|
import SharedImagePage from './pages/SharedImagePage';
|
|
|
import ImageAnalyticsPage from './pages/ImageAnalyticsPage';
|
|
|
|
|
|
+// Hook to handle session expiry - auto logout when session expires
|
|
|
+function useSessionExpiry() {
|
|
|
+ const { logout, isAuthenticated } = useAuth();
|
|
|
+ const navigate = useNavigate();
|
|
|
+
|
|
|
+ const handleSessionExpired = useCallback(async (event: Event) => {
|
|
|
+ const customEvent = event as CustomEvent<{ reason: string }>;
|
|
|
+ console.warn('Session expired:', customEvent.detail?.reason);
|
|
|
+
|
|
|
+ // Only handle if user was authenticated
|
|
|
+ if (isAuthenticated) {
|
|
|
+ await logout();
|
|
|
+ navigate('/login', {
|
|
|
+ replace: true,
|
|
|
+ state: { message: 'Your session has expired. Please log in again.' }
|
|
|
+ });
|
|
|
+ }
|
|
|
+ }, [logout, navigate, isAuthenticated]);
|
|
|
+
|
|
|
+ useEffect(() => {
|
|
|
+ window.addEventListener('baas:session-expired', handleSessionExpired);
|
|
|
+ return () => {
|
|
|
+ window.removeEventListener('baas:session-expired', handleSessionExpired);
|
|
|
+ };
|
|
|
+ }, [handleSessionExpired]);
|
|
|
+}
|
|
|
+
|
|
|
// Protected route wrapper
|
|
|
function ProtectedRoute({ children }: { children: React.ReactNode }) {
|
|
|
const { isAuthenticated, isLoading } = useAuth();
|
|
|
@@ -30,6 +58,9 @@ function ProtectedRoute({ children }: { children: React.ReactNode }) {
|
|
|
}
|
|
|
|
|
|
function App() {
|
|
|
+ // Auto-logout when session expires
|
|
|
+ useSessionExpiry();
|
|
|
+
|
|
|
return (
|
|
|
<Routes>
|
|
|
{/* Public routes */}
|