Skip to content

Commit a1f86e1

Browse files
committed
Updated dashboard
1 parent ab1e8a9 commit a1f86e1

6 files changed

Lines changed: 188 additions & 141 deletions

File tree

frontend/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,8 @@
4444
"@testing-library/react": "^16.3.0",
4545
"@testing-library/user-event": "^14.6.1",
4646
"@types/node": "^20",
47-
"@types/react": "^18",
48-
"@types/react-dom": "^18",
47+
"@types/react": "^18.3.24",
48+
"@types/react-dom": "^18.3.7",
4949
"@vitejs/plugin-react": "^4.3.4",
5050
"@vitest/coverage-v8": "^2.1.9",
5151
"autoprefixer": "^10.4.16",

frontend/src/app/dashboard/page.tsx

Lines changed: 116 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
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';
1111
import { ProtectedRoute } from '@/components/auth/ProtectedRoute';
1212
import { useAuth } from '@/components/auth/AuthProvider';
1313
import { 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';
1417
import { api } from '@/lib/api';
15-
import { CloudArrowUpIcon, FolderOpenIcon, QuestionMarkCircleIcon } from "@heroicons/react/24/outline";
18+
import { FolderIcon, CheckCircleIcon, ClockIcon, AlertCircleIcon, LogOutIcon } from 'lucide-react';
1619
import type { Project } from '../../../../shared/api-contract';
1720

1821
function 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>

frontend/src/components/dashboard/bento-grid.tsx

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -37,23 +37,23 @@ export function BentoGrid({ projects, isLoading, onProjectsUpdate, onProjectClic
3737

3838
if (isLoading) {
3939
return (
40-
<div className="grid grid-cols-1 gap-6 md:grid-cols-2 lg:grid-cols-3">
40+
<div className="grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3">
4141
{Array.from({ length: 6 }).map((_, i) => (
4242
<div
4343
key={i}
44-
className="bg-white dark:bg-gray-950 rounded-2xl shadow-lg border border-gray-200 dark:border-gray-700 h-48 animate-pulse"
44+
className="rounded-lg border bg-card h-40 animate-pulse"
4545
>
4646
<div className="p-6">
4747
<div className="flex items-center gap-3 mb-4">
48-
<div className="w-10 h-10 bg-gray-200 dark:bg-gray-700 rounded-lg" />
48+
<div className="w-8 h-8 bg-muted rounded-lg" />
4949
<div className="space-y-2">
50-
<div className="h-4 bg-gray-200 dark:bg-gray-700 rounded w-24" />
51-
<div className="h-3 bg-gray-200 dark:bg-gray-700 rounded w-16" />
50+
<div className="h-4 bg-muted rounded w-24" />
51+
<div className="h-3 bg-muted rounded w-16" />
5252
</div>
5353
</div>
5454
<div className="space-y-2">
55-
<div className="h-3 bg-gray-200 dark:bg-gray-700 rounded w-full" />
56-
<div className="h-3 bg-gray-200 dark:bg-gray-700 rounded w-3/4" />
55+
<div className="h-3 bg-muted rounded w-full" />
56+
<div className="h-3 bg-muted rounded w-3/4" />
5757
</div>
5858
</div>
5959
</div>
@@ -64,7 +64,7 @@ export function BentoGrid({ projects, isLoading, onProjectsUpdate, onProjectClic
6464

6565
return (
6666
<>
67-
<div className="grid grid-cols-1 gap-6 md:grid-cols-2 lg:grid-cols-3 auto-rows-max">
67+
<div className="grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3">
6868
<NewProjectTile onClick={() => setIsModalOpen(true)} />
6969

7070
{projects.map((project) => (
Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,34 @@
11
"use client";
22

33
import React from 'react';
4-
import { PlusIcon } from '@heroicons/react/24/outline';
4+
import { Card, CardContent } from '@/components/ui/card';
5+
import { Plus } from 'lucide-react';
56

67
interface NewProjectTileProps {
78
onClick: () => void;
89
}
910

1011
export function NewProjectTile({ onClick }: NewProjectTileProps) {
1112
return (
12-
<div
13+
<Card
1314
onClick={onClick}
14-
className="bg-white dark:bg-gray-950 rounded-2xl shadow-lg hover:shadow-xl transition-all duration-200 cursor-pointer border-2 border-dashed border-gray-300 dark:border-gray-600 hover:border-indigo-400 dark:hover:border-indigo-500 group min-h-[200px] flex items-center justify-center"
15+
className="cursor-pointer border-2 border-dashed border-muted-foreground/25 hover:border-primary/50 transition-colors group h-40 flex items-center justify-center"
1516
>
16-
<div className="text-center">
17-
<div className="w-16 h-16 bg-indigo-100 dark:bg-indigo-900 rounded-full flex items-center justify-center mx-auto mb-4 group-hover:bg-indigo-200 dark:group-hover:bg-indigo-800 transition-colors">
18-
<PlusIcon className="w-8 h-8 text-indigo-600 dark:text-indigo-400" />
17+
<CardContent className="p-6">
18+
<div className="text-center space-y-2">
19+
<div className="w-12 h-12 bg-primary/10 rounded-lg flex items-center justify-center mx-auto group-hover:bg-primary/20 transition-colors">
20+
<Plus className="h-5 w-5 text-primary" />
21+
</div>
22+
<div>
23+
<h3 className="font-medium text-sm mb-1">
24+
New Project
25+
</h3>
26+
<p className="text-xs text-muted-foreground">
27+
Upload a CSV file to get started
28+
</p>
29+
</div>
1930
</div>
20-
<h3 className="font-semibold text-gray-900 dark:text-gray-100 text-lg mb-2">
21-
New Project
22-
</h3>
23-
<p className="text-gray-500 dark:text-gray-400 text-sm">
24-
Upload a CSV file to get started
25-
</p>
26-
</div>
27-
</div>
31+
</CardContent>
32+
</Card>
2833
);
2934
}

0 commit comments

Comments
 (0)