Skip to content

Commit 3416cd1

Browse files
committed
feat: dashboard page ui
1 parent 7c48304 commit 3416cd1

File tree

8 files changed

+140
-764
lines changed

8 files changed

+140
-764
lines changed

web/next.config.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import type { NextConfig } from "next";
22

33
const nextConfig: NextConfig = {
44
images: {
5-
domains: ["lh3.googleusercontent.com"],
5+
domains: ["lh3.googleusercontent.com","avatars.githubusercontent.com"],
66
}
77
};
88

web/src/app/dashboard/[repoId]/canvas/page.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ const DependencyDetective = () => {
2323
const [isSidebarOpen, setIsSidebarOpen] = useState(false);
2424

2525
return (
26-
<div className="flex h-full w-full flex-col bg-neutral-50 dark:bg-black">
26+
<div className="flex h-full w-full flex-col bg-neutral-50 dark:bg-black py-2">
2727
{/* Header/Toolbar */}
2828
<header className="flex h-16 shrink-0 items-center justify-between border-b border-neutral-200 dark:border-neutral-800 bg-white dark:bg-zinc-950 px-4">
2929
<div className="flex items-center gap-4">

web/src/app/dashboard/page.tsx

Lines changed: 71 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -1,75 +1,85 @@
11
'use client';
22

3-
import { authClient } from '@/lib/auth-client';
43
import { useState, useEffect } from 'react';
4+
import { Input } from "@/components/ui/input";
5+
import { Search } from 'lucide-react';
6+
import { DashboardSkeleton } from '@/features/dashboard/skeleton';
7+
import { RepositoryCard } from '@/features/dashboard/repo-card';
8+
import { ConnectGitHubView } from '@/features/dashboard/connect-github';
59

6-
export default function GitHubIntegration() {
7-
const [accounts, setAccounts] = useState<any[]>([]);
8-
const [loading, setLoading] = useState(true);
10+
const MOCK_REPOS = [
11+
{ id: 1, title: 'Code Lens Pro', issueNumber: '#55', branch: 'main', avatar: 'https://avatars.githubusercontent.com/u/9919?s=40&v=4' },
12+
{ id: 2, title: 'Design System V2', issueNumber: '#102', branch: 'main', avatar: 'https://avatars.githubusercontent.com/u/1024025?s=40&v=4' },
13+
{ id: 3, title: 'API Service Refactor', issueNumber: '#89', branch: 'feat/new-auth', avatar: 'https://avatars.githubusercontent.com/u/9919?s=40&v=4' },
14+
{ id: 4, title: 'Documentation Site', issueNumber: '#21', branch: 'docs-update', avatar: 'https://avatars.githubusercontent.com/u/1024025?s=40&v=4' },
15+
{ id: 5, title: 'Mobile App POC', issueNumber: '#12', branch: 'main', avatar: 'https://avatars.githubusercontent.com/u/9919?s=40&v=4' },
16+
{ id: 6, title: 'E2E Testing Suite', issueNumber: '#76', branch: 'ci/playwright', avatar: 'https://avatars.githubusercontent.com/u/1024025?s=40&v=4' },
17+
];
918

10-
useEffect(() => {
11-
const fetchAccounts = async () => {
12-
try {
13-
const { data: accountsList, error } = await authClient.listAccounts();
14-
if (accountsList) {
15-
console.log('Accounts:', accountsList);
16-
setAccounts(accountsList);
17-
}
18-
if (error) {
19-
console.error('Failed to fetch accounts:', error);
20-
}
21-
} catch (error) {
22-
console.error('Failed to fetch accounts:', error);
23-
} finally {
24-
setLoading(false);
25-
}
19+
export default function GitHubIntegrationPage() {
20+
const [accounts, setAccounts] = useState<any[]>([]);
21+
const [searchQuery, setSearchQuery] = useState('');
22+
const [isLoading, setIsLoading] = useState(true);
23+
24+
useEffect(() => {
25+
const fetchAccounts = async () => {
26+
await new Promise(resolve => setTimeout(resolve, 1000));
27+
setAccounts([{ providerId: 'github', accountId: 'user-123' }]);
28+
setIsLoading(false);
29+
};
30+
fetchAccounts();
31+
}, []);
32+
33+
const isConnected = !!accounts.find(acc => acc.providerId === 'github');
34+
35+
const connectGitHub = async () => {
36+
setIsLoading(true);
37+
await new Promise(resolve => setTimeout(resolve, 1500));
38+
setAccounts([{ providerId: 'github', accountId: 'user-123' }]);
39+
setIsLoading(false);
2640
};
2741

28-
fetchAccounts();
29-
}, []);
42+
const filteredRepos = MOCK_REPOS.filter(repo =>
43+
repo.title.toLowerCase().includes(searchQuery.toLowerCase())
44+
);
3045

31-
const githubAccount = accounts.find(
32-
(account) => account.providerId === 'github'
33-
);
34-
const isConnected = !!githubAccount;
46+
if (isLoading) {
47+
return <DashboardSkeleton />;
48+
}
3549

36-
const connectGitHub = async () => {
37-
try {
38-
await authClient.linkSocial({
39-
provider: 'github',
40-
callbackURL: '/dashboard',
41-
});
42-
} catch (error) {
43-
console.error('Failed to connect GitHub:', error);
50+
if (!isConnected) {
51+
return <ConnectGitHubView onConnect={connectGitHub} />;
4452
}
45-
};
4653

47-
if (loading) {
48-
return <div className="p-6">Loading accounts...</div>;
49-
}
54+
return (
55+
<div className="h-full w-full bg-black text-white p-4 md:p-8 flex flex-col">
56+
{/* --- Header --- */}
57+
<header className="flex-shrink-0 pb-6 border-b border-zinc-800/60">
58+
<h1 className="text-xl font-medium text-neutral-100">GitHub Repositories</h1>
59+
<p className="text-neutral-400 mt-1 text-sm">
60+
View and manage repositories connected to your GitHub account.
61+
</p>
62+
</header>
5063

51-
return (
52-
<div className="p-6 border rounded-lg">
53-
{isConnected && githubAccount ? (
54-
<div className="space-y-2">
55-
<h3 className="text-lg font-semibold">✅ GitHub Connected</h3>
56-
<p>Account ID: {githubAccount.accountId}</p>
57-
<p>Provider: {githubAccount.providerId}</p>
58-
</div>
59-
) : (
60-
<div className="space-y-4">
61-
<h3 className="text-lg font-semibold">Connect GitHub</h3>
62-
<p className="text-sm text-muted-foreground">
63-
Connect your GitHub account to access private repositories
64-
</p>
65-
<button
66-
onClick={connectGitHub}
67-
className="px-4 py-2 bg-black text-white rounded-md hover:bg-gray-800"
68-
>
69-
Connect GitHub Account
70-
</button>
64+
{/* --- Toolbar with Search --- */}
65+
<div className="flex-shrink-0 py-4">
66+
<div className="relative">
67+
<Search className="absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-neutral-500" />
68+
<Input
69+
placeholder="Filter repositories..."
70+
className="pl-9 h-10 bg-zinc-900 border-zinc-700 text-neutral-100 placeholder:text-neutral-500"
71+
value={searchQuery}
72+
onChange={(e) => setSearchQuery(e.target.value)}
73+
/>
74+
</div>
75+
</div>
76+
77+
{/* --- Repository Grid --- */}
78+
<div className="overflow-y-auto grid grid-cols-1 md:grid-cols-3 gap-6 pt-6">
79+
{filteredRepos.map(repo => (
80+
<RepositoryCard key={repo.id} repo={repo} />
81+
))}
82+
</div>
7183
</div>
72-
)}
73-
</div>
74-
);
84+
);
7585
}

0 commit comments

Comments
 (0)