From 85928150d58e1c0a154117ed49851658e202f948 Mon Sep 17 00:00:00 2001 From: FmaresWGU Date: Thu, 7 May 2026 15:49:33 -0700 Subject: [PATCH] Rework dashboard into overview page, improve post-generation UX - Replace duplicate Dashboard/Upload pages with a real overview: stats cards (sheets + total labels), recent sheets table with per-row download and delete, empty state for new users - Add 'View in Inventory' link to label generation success banner so users know where their sheets went after generating - Rename 'Upload Labels' nav item to 'Create Labels' for clarity - Restrict column mapping onboarding tour to /upload only - Extract DashboardPage wrapper in App.tsx for consistency --- frontend-vite/react-ts/src/App.tsx | 13 +- .../src/components/ColumnMappingTour.tsx | 2 +- .../react-ts/src/components/Sidebar.tsx | 21 +- .../react-ts/src/components/dashboard.tsx | 202 +++++++++++++++++- .../react-ts/src/components/labelUploader.tsx | 20 +- 5 files changed, 226 insertions(+), 32 deletions(-) diff --git a/frontend-vite/react-ts/src/App.tsx b/frontend-vite/react-ts/src/App.tsx index c8600d8..64f021a 100644 --- a/frontend-vite/react-ts/src/App.tsx +++ b/frontend-vite/react-ts/src/App.tsx @@ -22,6 +22,17 @@ function PageViewTracker() { return null; } +function DashboardPage() { + return ( +
+ +
+ +
+
+ ); +} + function UploadPage() { return (
@@ -55,7 +66,7 @@ function App() { path="/dashboard" element={ - + } /> diff --git a/frontend-vite/react-ts/src/components/ColumnMappingTour.tsx b/frontend-vite/react-ts/src/components/ColumnMappingTour.tsx index b635431..e79eb41 100644 --- a/frontend-vite/react-ts/src/components/ColumnMappingTour.tsx +++ b/frontend-vite/react-ts/src/components/ColumnMappingTour.tsx @@ -6,7 +6,7 @@ import { BARCODE_COLUMN_HELP, TEXT_FIELDS_HELP, HEADER_ROW_HELP } from './column import type { HelpContent } from './columnMappingHelp'; const TOUR_KEY = 'lgu_col_map_tour_v1'; -const ALLOWED_ROUTES = ['/dashboard', '/upload']; +const ALLOWED_ROUTES = ['/upload']; const steps: HelpContent[] = [ { diff --git a/frontend-vite/react-ts/src/components/Sidebar.tsx b/frontend-vite/react-ts/src/components/Sidebar.tsx index 266dcd2..088a2c0 100644 --- a/frontend-vite/react-ts/src/components/Sidebar.tsx +++ b/frontend-vite/react-ts/src/components/Sidebar.tsx @@ -4,7 +4,7 @@ import axios from 'axios'; import { ScanBarcode, LayoutDashboard, - Upload, + Plus, Package, HelpCircle, LogOut, @@ -20,26 +20,11 @@ interface SidebarProps { function Sidebar({ activeOverride }: SidebarProps) { const location = useLocation(); const navigate = useNavigate(); - const [userEmail, setUserEmail] = useState(''); const [mobileOpen, setMobileOpen] = useState(false); const API_URL = import.meta.env.VITE_API_URL || 'http://localhost:5000'; const currentPath = activeOverride || location.pathname; - useEffect(() => { - const fetchUser = async () => { - try { - const res = await axios.get(`${API_URL}/auth/status`, { withCredentials: true }); - if (res.data.authenticated && res.data.email) { - setUserEmail(res.data.email); - } - } catch { - // ignore - } - }; - fetchUser(); - }, []); - // Close drawer on route change useEffect(() => { setMobileOpen(false); @@ -66,7 +51,7 @@ function Sidebar({ activeOverride }: SidebarProps) { const navItems = [ { label: 'Dashboard', icon: LayoutDashboard, path: '/dashboard' }, - { label: 'Upload Labels', icon: Upload, path: '/upload' }, + { label: 'Create Labels', icon: Plus, path: '/upload' }, { label: 'Inventory', icon: Package, path: '/inventory' }, { label: 'Help', icon: HelpCircle, path: '/help' }, ]; @@ -105,7 +90,7 @@ function Sidebar({ activeOverride }: SidebarProps) {

- {userEmail || 'User'} + User

+ + + {/* Stats */} +
+
+

{loading ? '—' : sheets.length}

+

Sheets Generated

+
+
+

{loading ? '—' : totalLabels.toLocaleString()}

+

Total Labels

+
+
+ + {error && ( +
+ +

{error}

+
+ )} + + {/* Recent Sheets */} +
+
+

Recent Sheets

+ {sheets.length > 0 && ( + + )} +
+ +
+ {loading ? ( +
Loading...
+ ) : recentSheets.length === 0 ? ( +
+

No sheets yet.

+ +
+ ) : ( + + + + + + + + + + + + {recentSheets.map((sheet) => ( + + + + + + + + ))} + +
FileLabelsSheetsCreated
+
+ + + {sheet.original_filename} + +
+
{sheet.label_count}{sheet.sheet_count}{formatDate(sheet.created_at)} +
+ + +
+
+ )} +
+
); } diff --git a/frontend-vite/react-ts/src/components/labelUploader.tsx b/frontend-vite/react-ts/src/components/labelUploader.tsx index 2d8304f..76b0c1a 100644 --- a/frontend-vite/react-ts/src/components/labelUploader.tsx +++ b/frontend-vite/react-ts/src/components/labelUploader.tsx @@ -1,8 +1,9 @@ import { useState, useRef } from 'react'; import type { ChangeEvent } from 'react'; +import { useNavigate } from 'react-router-dom'; import axios from 'axios'; import { - Upload, AlertCircle, CheckCircle2, Plus, X, + Upload, AlertCircle, CheckCircle2, Plus, X, ArrowRight, } from 'lucide-react'; import { usePostHog } from '@posthog/react'; import LabelPreview from './LabelPreview'; @@ -30,6 +31,7 @@ interface PreviewData { const MAX_FILE_SIZE = 50 * 1024 * 1024 function LabelUploader() { + const navigate = useNavigate(); const posthog = usePostHog(); const [file, setFile] = useState(null); const [loading, setLoading] = useState(false); @@ -128,7 +130,7 @@ function LabelUploader() { }); setFile(null); setPreviewData(null); if (fileInputRef.current) fileInputRef.current.value = ''; - setTimeout(() => { setSuccess(''); setUploadProgress(0); setProcessingStatus(''); }, 5000); + setUploadProgress(0); setProcessingStatus(''); } catch (err) { setUploadProgress(0); setProcessingStatus(''); if (axios.isAxiosError(err)) { @@ -237,9 +239,17 @@ function LabelUploader() { )} {success && ( -
- -

{success}

+
+
+ +

{success}

+
+
)}