11/**
22 * Dashboard Page
33 *
4- * Protected dashboard page that shows user information and logout functionality .
4+ * Protected dashboard page with modern shadcn/ui components and professional design .
55 */
66
77"use client" ;
@@ -11,8 +11,11 @@ import { useRouter } from 'next/navigation';
1111import { ProtectedRoute } from '@/components/auth/ProtectedRoute' ;
1212import { useAuth } from '@/components/auth/AuthProvider' ;
1313import { BentoGrid } from '@/components/dashboard/bento-grid' ;
14+ import { Button } from '@/components/ui/button' ;
15+ import { Card , CardContent , CardDescription , CardHeader , CardTitle } from '@/components/ui/card' ;
16+ import { Badge } from '@/components/ui/badge' ;
1417import { api } from '@/lib/api' ;
15- import { CloudArrowUpIcon , FolderOpenIcon , QuestionMarkCircleIcon } from "@heroicons/ react/24/outline" ;
18+ import { FolderIcon , CheckCircleIcon , ClockIcon , AlertCircleIcon , LogOutIcon } from 'lucide- react' ;
1619import type { Project } from '../../../../shared/api-contract' ;
1720
1821function DashboardContent ( ) {
@@ -80,87 +83,124 @@ function DashboardContent() {
8083 } ;
8184
8285 return (
83- < div className = "min-h-screen bg-gradient-to-br from-indigo-50 via-white to-indigo-50 dark:from-gray-900 dark:via-gray-800 dark:to-gray-900" >
84- < div className = "max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-8" >
85- < div className = "flex flex-col gap-8" >
86- { /* Welcome Header */ }
87- < div className = "flex flex-col items-center gap-2 mb-2" >
88- < h1 className = "text-3xl md:text-4xl font-bold text-indigo-700 dark:text-indigo-400 tracking-tight" > Welcome back, { user ?. name || 'User' } !</ h1 >
89- < p className = "text-base md:text-lg text-gray-700 dark:text-gray-200" > Your SmartQuery dashboard</ p >
90- </ div >
91- { /* User Info Card */ }
92- < div className = "w-full bg-white dark:bg-gray-950 rounded-2xl shadow-xl p-6 flex flex-col gap-4" >
93- < h3 className = "text-lg font-semibold text-indigo-700 dark:text-indigo-200 mb-2" > User Information</ h3 >
94- < div className = "grid grid-cols-1 gap-4 md:grid-cols-2" >
95- < div >
96- < dt className = "text-sm font-medium text-gray-500 dark:text-gray-400" > Name</ dt >
97- < dd className = "mt-1 text-base text-gray-900 dark:text-gray-100" > { user ?. name } </ dd >
98- </ div >
99- < div >
100- < dt className = "text-sm font-medium text-gray-500 dark:text-gray-400" > Email</ dt >
101- < dd className = "mt-1 text-base text-gray-900 dark:text-gray-100" > { user ?. email } </ dd >
86+ < div className = "min-h-screen bg-background" >
87+ < div className = "border-b" >
88+ < div className = "max-w-7xl mx-auto px-4 sm:px-6 lg:px-8" >
89+ < div className = "flex h-16 items-center justify-between" >
90+ < div className = "flex items-center space-x-4" >
91+ < h1 className = "text-xl font-semibold" > SmartQuery</ h1 >
10292 </ div >
103- < div >
104- < dt className = "text-sm font-medium text-gray-500 dark:text-gray-400" > User ID</ dt >
105- < dd className = "mt-1 text-base text-gray-900 dark:text-gray-100" > { user ?. id } </ dd >
106- </ div >
107- < div >
108- < dt className = "text-sm font-medium text-gray-500 dark:text-gray-400" > Member Since</ dt >
109- < dd className = "mt-1 text-base text-gray-900 dark:text-gray-100" > { user ?. created_at ? new Date ( user . created_at ) . toLocaleDateString ( ) : 'N/A' } </ dd >
93+ < div className = "flex items-center space-x-4" >
94+ < span className = "text-sm text-muted-foreground" > Welcome back, { user ?. name || 'User' } </ span >
95+ < Button variant = "outline" size = "sm" onClick = { handleLogout } >
96+ < LogOutIcon className = "h-4 w-4 mr-2" />
97+ Sign Out
98+ </ Button >
11099 </ div >
111100 </ div >
112101 </ div >
113- { /* Stats Cards */ }
114- < div className = "grid grid-cols-1 gap-6 md:grid-cols-3" >
115- < div className = "bg-white dark:bg-gray-950 rounded-2xl shadow-xl p-6 flex flex-col items-center" >
116- < div className = "w-12 h-12 bg-indigo-200 dark:bg-indigo-700 rounded-full flex items-center justify-center mb-2" >
117- < FolderOpenIcon className = "w-7 h-7 text-indigo-700 dark:text-indigo-200" />
118- </ div >
119- < div className = "text-lg font-semibold text-indigo-700 dark:text-indigo-200" > Total Projects</ div >
120- < div className = "text-2xl font-bold text-gray-900 dark:text-gray-100 mt-1" > { isLoading ? '...' : total } </ div >
121- </ div >
122- < div className = "bg-white dark:bg-gray-950 rounded-2xl shadow-xl p-6 flex flex-col items-center" >
123- < div className = "w-12 h-12 bg-green-200 dark:bg-green-700 rounded-full flex items-center justify-center mb-2" >
124- < CloudArrowUpIcon className = "w-7 h-7 text-green-700 dark:text-green-200" />
125- </ div >
126- < div className = "text-lg font-semibold text-green-700 dark:text-green-200" > Ready Projects</ div >
127- < div className = "text-2xl font-bold text-gray-900 dark:text-gray-100 mt-1" > { isLoading ? '...' : ready } </ div >
102+ </ div >
103+
104+ < div className = "max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-8" >
105+ < div className = "space-y-8" >
106+ { /* User Info Card */ }
107+ < Card >
108+ < CardHeader >
109+ < CardTitle className = "text-lg" > Account Information</ CardTitle >
110+ < CardDescription >
111+ Your SmartQuery account details and membership information
112+ </ CardDescription >
113+ </ CardHeader >
114+ < CardContent >
115+ < dl className = "grid grid-cols-1 gap-4 sm:grid-cols-2" >
116+ < div className = "space-y-1" >
117+ < dt className = "text-sm font-medium text-muted-foreground" > Name</ dt >
118+ < dd className = "text-sm" > { user ?. name } </ dd >
119+ </ div >
120+ < div className = "space-y-1" >
121+ < dt className = "text-sm font-medium text-muted-foreground" > Email</ dt >
122+ < dd className = "text-sm" > { user ?. email } </ dd >
123+ </ div >
124+ < div className = "space-y-1" >
125+ < dt className = "text-sm font-medium text-muted-foreground" > User ID</ dt >
126+ < dd className = "text-sm font-mono" > { user ?. id } </ dd >
127+ </ div >
128+ < div className = "space-y-1" >
129+ < dt className = "text-sm font-medium text-muted-foreground" > Member Since</ dt >
130+ < dd className = "text-sm" > { user ?. created_at ? new Date ( user . created_at ) . toLocaleDateString ( ) : 'N/A' } </ dd >
131+ </ div >
132+ </ dl >
133+ </ CardContent >
134+ </ Card >
135+ { /* Stats Cards */ }
136+ < div className = "grid gap-4 md:grid-cols-3" >
137+ < Card >
138+ < CardContent className = "p-6" >
139+ < div className = "flex items-center space-x-2" >
140+ < div className = "p-2 bg-primary/10 rounded-lg" >
141+ < FolderIcon className = "h-4 w-4 text-primary" />
142+ </ div >
143+ < div className = "space-y-1" >
144+ < p className = "text-sm font-medium text-muted-foreground" > Total Projects</ p >
145+ < p className = "text-2xl font-bold" > { isLoading ? '...' : total } </ p >
146+ </ div >
147+ </ div >
148+ </ CardContent >
149+ </ Card >
150+ < Card >
151+ < CardContent className = "p-6" >
152+ < div className = "flex items-center space-x-2" >
153+ < div className = "p-2 bg-green-100 dark:bg-green-900/20 rounded-lg" >
154+ < CheckCircleIcon className = "h-4 w-4 text-green-600 dark:text-green-400" />
155+ </ div >
156+ < div className = "space-y-1" >
157+ < p className = "text-sm font-medium text-muted-foreground" > Ready Projects</ p >
158+ < p className = "text-2xl font-bold" > { isLoading ? '...' : ready } </ p >
159+ </ div >
160+ </ div >
161+ </ CardContent >
162+ </ Card >
163+ < Card >
164+ < CardContent className = "p-6" >
165+ < div className = "flex items-center space-x-2" >
166+ < div className = "p-2 bg-yellow-100 dark:bg-yellow-900/20 rounded-lg" >
167+ < ClockIcon className = "h-4 w-4 text-yellow-600 dark:text-yellow-400" />
168+ </ div >
169+ < div className = "space-y-1" >
170+ < p className = "text-sm font-medium text-muted-foreground" > Processing</ p >
171+ < p className = "text-2xl font-bold" > { isLoading ? '...' : processing } </ p >
172+ </ div >
173+ </ div >
174+ </ CardContent >
175+ </ Card >
128176 </ div >
129- < div className = "bg-white dark:bg-gray-950 rounded-2xl shadow-xl p-6 flex flex-col items-center" >
130- < div className = "w-12 h-12 bg-yellow-200 dark:bg-yellow-700 rounded-full flex items-center justify-center mb-2" >
131- < QuestionMarkCircleIcon className = "w-7 h-7 text-yellow-700 dark:text-yellow-200" />
177+ { /* Error Display */ }
178+ { error && (
179+ < Card className = "border-destructive" >
180+ < CardContent className = "p-4" >
181+ < div className = "flex items-center space-x-2" >
182+ < AlertCircleIcon className = "h-4 w-4 text-destructive" />
183+ < p className = "text-sm text-destructive" > { error } </ p >
184+ </ div >
185+ </ CardContent >
186+ </ Card >
187+ ) }
188+
189+ { /* Projects Section */ }
190+ < div className = "space-y-4" >
191+ < div className = "flex items-center justify-between" >
192+ < div >
193+ < h2 className = "text-2xl font-bold tracking-tight" > Your Projects</ h2 >
194+ < p className = "text-muted-foreground" > Manage and query your CSV datasets</ p >
195+ </ div >
132196 </ div >
133- < div className = "text-lg font-semibold text-yellow-700 dark:text-yellow-200" > Processing</ div >
134- < div className = "text-2xl font-bold text-gray-900 dark:text-gray-100 mt-1" > { isLoading ? '...' : processing } </ div >
135- </ div >
136- </ div >
137- { /* Error Display */ }
138- { error && (
139- < div className = "w-full bg-red-50 dark:bg-red-950 border border-red-200 dark:border-red-800 rounded-xl p-4" >
140- < p className = "text-red-700 dark:text-red-200" > { error } </ p >
197+ < BentoGrid
198+ projects = { projects }
199+ isLoading = { isLoading }
200+ onProjectsUpdate = { fetchProjects }
201+ onProjectClick = { ( projectId ) => router . push ( `/workspace/${ projectId } ` ) }
202+ />
141203 </ div >
142- ) }
143-
144- { /* Projects Grid */ }
145- < div className = "w-full" >
146- < h3 className = "text-xl font-semibold text-gray-900 dark:text-gray-100 mb-6" > Your Projects</ h3 >
147- < BentoGrid
148- projects = { projects }
149- isLoading = { isLoading }
150- onProjectsUpdate = { fetchProjects }
151- onProjectClick = { ( projectId ) => router . push ( `/workspace/${ projectId } ` ) }
152- />
153- </ div >
154-
155- { /* Sign Out Button */ }
156- < div className = "flex justify-center mt-4" >
157- < button
158- onClick = { handleLogout }
159- className = "py-2 px-6 rounded-xl bg-red-500 text-white font-semibold text-base hover:bg-red-600 transition-colors shadow"
160- >
161- Sign Out
162- </ button >
163- </ div >
164204 </ div >
165205 </ div >
166206 </ div >
0 commit comments