From 28a781517c34bf5621c3d05498598785ce028232 Mon Sep 17 00:00:00 2001 From: Andrei Date: Wed, 8 Oct 2025 08:30:22 +0000 Subject: [PATCH] fix: Improve admin authentication flow and fix MUI Grid warnings Authentication fixes: - Add isAuthenticated() method to ApiClient to check token presence - Add useEffect in AdminLayout to redirect to login if no token found - Fix logout to not fail when token is expired/invalid (401) - Properly handle logout errors by clearing tokens locally - Clear tokens and redirect to /login on 401 refresh token failure UI/UX fixes: - Replace all deprecated MUI Grid v1 with CSS Grid layout - Remove Grid import since it's no longer used - Fix Grid warnings: item, xs, sm, md props deprecated in MUI v7 - Use responsive CSS Grid with gridTemplateColumns for all layouts Security improvements: - Check authentication status on every page load - Auto-redirect to login if no valid session exists - Handle expired tokens gracefully without breaking logout flow --- parentflow-admin/src/app/page.tsx | 189 ++++++++---------- .../src/components/AdminLayout.tsx | 9 +- parentflow-admin/src/lib/api-client.ts | 12 +- 3 files changed, 105 insertions(+), 105 deletions(-) diff --git a/parentflow-admin/src/app/page.tsx b/parentflow-admin/src/app/page.tsx index 6987233..e6aaa5f 100644 --- a/parentflow-admin/src/app/page.tsx +++ b/parentflow-admin/src/app/page.tsx @@ -3,7 +3,6 @@ import { useState, useEffect } from 'react'; import { Box, - Grid, Paper, Typography, Card, @@ -198,104 +197,91 @@ export default function DashboardPage() { {/* Stats Cards */} - - - } - title="Total Users" - value={stats.totalUsers} - change={5.2} - color="primary" - /> - - - } - title="Families" - value={stats.totalFamilies} - change={3.1} - color="secondary" - /> - - - } - title="Children" - value={stats.totalChildren} - change={4.5} - color="info" - /> - - - } - title="Activities Today" - value={stats.activitiesLogged} - change={12.3} - color="success" - /> - - + + } + title="Total Users" + value={stats.totalUsers} + change={5.2} + color="primary" + /> + } + title="Families" + value={stats.totalFamilies} + change={3.1} + color="secondary" + /> + } + title="Children" + value={stats.totalChildren} + change={4.5} + color="info" + /> + } + title="Activities Today" + value={stats.activitiesLogged} + change={12.3} + color="success" + /> + {/* Charts Row */} - - - - - User Growth (Last 30 Days) - - - - - - - - - - - - - - - - Activity Distribution - - - - `${name} ${(percent * 100).toFixed(0)}%`} - outerRadius={80} - fill="#8884d8" - dataKey="value" - > - {activityData.map((entry, index) => ( - - ))} - - - - - - - + + + + User Growth (Last 30 Days) + + + + + + + + + + + + + + Activity Distribution + + + + `${name} ${(percent * 100).toFixed(0)}%`} + outerRadius={80} + fill="#8884d8" + dataKey="value" + > + {activityData.map((entry, index) => ( + + ))} + + + + + + {/* Recent Activity and System Status */} - - - - - Recent Users - + + + + Recent Users + {recentUsers.map((user) => ( @@ -319,12 +305,10 @@ export default function DashboardPage() { ))} - - - - - System Status - + + + System Status + @@ -376,8 +360,7 @@ export default function DashboardPage() { - - + ); diff --git a/parentflow-admin/src/components/AdminLayout.tsx b/parentflow-admin/src/components/AdminLayout.tsx index 72e0037..ffd148f 100644 --- a/parentflow-admin/src/components/AdminLayout.tsx +++ b/parentflow-admin/src/components/AdminLayout.tsx @@ -1,6 +1,6 @@ 'use client'; -import { useState, ReactNode } from 'react'; +import { useState, useEffect, ReactNode } from 'react'; import { useRouter, usePathname } from 'next/navigation'; import { Box, @@ -45,6 +45,13 @@ export default function AdminLayout({ children }: AdminLayoutProps) { const [mobileOpen, setMobileOpen] = useState(false); const [anchorEl, setAnchorEl] = useState(null); + // Check authentication on mount + useEffect(() => { + if (!apiClient.isAuthenticated()) { + router.push('/login'); + } + }, [router]); + const handleDrawerToggle = () => { setMobileOpen(!mobileOpen); }; diff --git a/parentflow-admin/src/lib/api-client.ts b/parentflow-admin/src/lib/api-client.ts index e03341b..f97b6fa 100644 --- a/parentflow-admin/src/lib/api-client.ts +++ b/parentflow-admin/src/lib/api-client.ts @@ -134,12 +134,22 @@ class ApiClient { async logout() { try { - await this.request('POST', '/auth/logout'); + // Only try to call logout endpoint if we have a token + if (this.token) { + await this.request('POST', '/auth/logout'); + } + } catch (error) { + // Ignore errors on logout - we'll clear tokens anyway + console.log('Logout request failed, clearing tokens locally'); } finally { this.clearTokens(); } } + isAuthenticated(): boolean { + return !!this.token; + } + async getCurrentAdmin() { return this.request('GET', '/auth/me'); }