Skip to content

Commit fd2564a

Browse files
refactor: Enhance Dashboard with new Solving Statistics and Performance Metrics sections; add Submission Timeline and improve StatItem layout
1 parent 225f9a5 commit fd2564a

File tree

1 file changed

+151
-35
lines changed

1 file changed

+151
-35
lines changed

app/dashboard/page.tsx

+151-35
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,28 @@ import { useLeetcodeStore } from "@/store/LeetcodeStore/useLeetcodeStore";
55
import { Badge } from "@/components/ui/badge";
66
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
77
import { Skeleton } from "@/components/ui/skeleton";
8-
import { Github, Linkedin, Twitter, Award, Book, Star } from "lucide-react";
8+
import {
9+
Github,
10+
Linkedin,
11+
Twitter,
12+
Award,
13+
Book,
14+
Star,
15+
Target,
16+
Timer,
17+
Trophy,
18+
TrendingUp,
19+
CheckCircle,
20+
XCircle,
21+
Calendar
22+
} from "lucide-react";
23+
924
export default function Dashboard() {
1025
const { fetchLeetcodeUserProfile, leetcodeUserProfile } = useLeetcodeStore();
1126
React.useEffect(() => {
1227
fetchLeetcodeUserProfile();
1328
}, [fetchLeetcodeUserProfile]);
29+
1430
if (!leetcodeUserProfile) {
1531
return <DashboardSkeleton />;
1632
}
@@ -48,46 +64,98 @@ export default function Dashboard() {
4864
</div>
4965
</CardHeader>
5066
<CardContent className="pt-6">
51-
<div className="grid gap-6 md:grid-cols-2">
52-
<div className="space-y-4">
53-
<h3 className="text-xl font-semibold mb-3">Statistics</h3>
54-
<div className="grid grid-cols-2 gap-4">
55-
<StatItem
56-
icon={<Book className="w-5 h-5" />}
57-
value={
58-
leetcodeUserProfile.submitStats.acSubmissionNum[0].count ||
59-
0
60-
}
61-
label="Problems Solved"
62-
/>
63-
<StatItem
64-
icon={<Award className="w-5 h-5" />}
65-
value={leetcodeUserProfile.contributions.points}
66-
label="Contribution Points"
67-
/>
68-
<StatItem
69-
icon={<Star className="w-5 h-5" />}
70-
value={leetcodeUserProfile.profile.starRating}
71-
label="Star Rating"
72-
/>
73-
<StatItem
74-
icon={<Award className="w-5 h-5" />}
75-
value={leetcodeUserProfile.profile.ranking}
76-
label="Global Ranking"
77-
/>
67+
{/* New Additional Dashboard Sections */}
68+
<div className="mt-8">
69+
<div className="grid gap-6 md:grid-cols-2">
70+
<div className="space-y-4">
71+
<h3 className="text-xl font-semibold mb-3 flex items-center">
72+
<Trophy className="w-5 h-5 mr-2 text-primary" />
73+
Solving Statistics
74+
</h3>
75+
<div className="grid grid-cols-2 gap-4">
76+
<StatItem
77+
icon={<Book className="w-5 h-5 text-blue-500" />}
78+
value={
79+
leetcodeUserProfile.submitStats.acSubmissionNum[0].count ||
80+
0
81+
}
82+
label="Total Solved"
83+
subtitle={`${(
84+
(leetcodeUserProfile.submitStats.acSubmissionNum[0].count /
85+
leetcodeUserProfile.submitStats.totalSubmissionNum[0].count) *
86+
100
87+
).toFixed(1)}% success rate`}
88+
/>
89+
<StatItem
90+
icon={<Target className="w-5 h-5 text-green-500" />}
91+
value={
92+
leetcodeUserProfile.submitStats.acSubmissionNum[1].count ||
93+
0
94+
}
95+
label="Easy Problems"
96+
subtitle={`${leetcodeUserProfile.submitStats.acSubmissionNum[1].submissions} submissions`}
97+
/>
98+
<StatItem
99+
icon={<Target className="w-5 h-5 text-yellow-500" />}
100+
value={
101+
leetcodeUserProfile.submitStats.acSubmissionNum[2].count ||
102+
0
103+
}
104+
label="Medium Problems"
105+
subtitle={`${leetcodeUserProfile.submitStats.acSubmissionNum[2].submissions} submissions`}
106+
/>
107+
<StatItem
108+
icon={<Target className="w-5 h-5 text-red-500" />}
109+
value={
110+
leetcodeUserProfile.submitStats.acSubmissionNum[3].count ||
111+
0
112+
}
113+
label="Hard Problems"
114+
subtitle={`${leetcodeUserProfile.submitStats.acSubmissionNum[3].submissions} submissions`}
115+
/>
116+
</div>
117+
</div>
118+
<div className="space-y-4">
119+
<h3 className="text-xl font-semibold mb-3 flex items-center">
120+
<Award className="w-5 h-5 mr-2 text-primary" />
121+
Performance Metrics
122+
</h3>
123+
<div className="grid grid-cols-2 gap-4">
124+
<StatItem
125+
icon={<TrendingUp className="w-5 h-5 text-purple-500" />}
126+
value={leetcodeUserProfile.profile.ranking}
127+
label="Global Ranking"
128+
subtitle="Current Position"
129+
/>
130+
<StatItem
131+
icon={<Star className="w-5 h-5 text-yellow-500" />}
132+
value={leetcodeUserProfile.profile.starRating}
133+
label="Contest Rating"
134+
subtitle={`Level ${Math.floor(leetcodeUserProfile.profile.starRating / 500) + 1}`}
135+
/>
136+
<StatItem
137+
icon={<CheckCircle className="w-5 h-5 text-green-500" />}
138+
value={leetcodeUserProfile.contributions.points}
139+
label="Contribution Points"
140+
subtitle="Community Impact"
141+
/>
142+
</div>
78143
</div>
79144
</div>
145+
<br></br>
146+
{/* Original Badges */}
147+
<div className="grid gap-6 md:grid-cols-3">
80148
<div className="space-y-4">
81-
<h3 className="text-xl font-semibold mb-3">Recent Badges</h3>
149+
<h3 className="text-xl font-semibold mb-6">Recent Badges</h3>
82150
<div className="grid grid-cols-2 sm:grid-cols-3 gap-3">
83-
{leetcodeUserProfile.badges.slice(0, 6).map((badge) => (
151+
{leetcodeUserProfile.badges.slice(0, 5).map((badge) => (
84152
<div
85153
key={badge.id}
86154
className="flex flex-col items-center p-2 bg-secondary rounded-lg"
87155
>
88156
<div className="relative w-12 h-12 mb-2">
89157
<Image
90-
src={badge.icon || "/placeholder.svg"}
158+
src={badge.icon}
91159
alt={badge.displayName}
92160
fill
93161
className="object-contain"
@@ -101,6 +169,25 @@ export default function Dashboard() {
101169
</div>
102170
</div>
103171
</div>
172+
{/* Submission Timeline */}
173+
<div className="mt-8">
174+
<h3 className="text-xl font-semibold mb-4 flex items-center">
175+
<Timer className="w-5 h-5 mr-2 text-primary" />
176+
Submission Timeline
177+
</h3>
178+
<div className="bg-secondary/30 rounded-lg p-4">
179+
<div className="grid grid-cols-2 md:grid-cols-4 gap-4">
180+
<TimelineStat
181+
label="All Time"
182+
value={leetcodeUserProfile.submitStats.totalSubmissionNum[0].count}
183+
total={leetcodeUserProfile.submitStats.totalSubmissionNum[0].count}
184+
/>
185+
</div>
186+
</div>
187+
</div>
188+
</div>
189+
190+
{/* Social Links */}
104191
<div className="flex justify-center gap-6 mt-8">
105192
<SocialLink
106193
href={leetcodeUserProfile.githubUrl}
@@ -120,25 +207,53 @@ export default function Dashboard() {
120207
</div>
121208
);
122209
}
210+
123211
function StatItem({
124212
icon,
125213
value,
126214
label,
215+
subtitle,
127216
}: {
128217
icon: React.ReactNode;
129218
value: number;
130219
label: string;
220+
subtitle?: string;
131221
}) {
132222
return (
133-
<div className="flex items-center space-x-3 bg-secondary/50 rounded-lg p-3">
134-
{icon}
223+
<div className="flex items-center space-x-3 bg-secondary/50 rounded-lg p-4 hover:bg-secondary/70 transition-colors">
224+
<div className="p-2 bg-background rounded-full">{icon}</div>
135225
<div>
136-
<div className="text-2xl font-bold">{value}</div>
137-
<div className="text-sm text-muted-foreground">{label}</div>
226+
<div className="text-2xl font-bold">{value.toLocaleString()}</div>
227+
<div className="text-sm font-medium">{label}</div>
228+
{subtitle && (
229+
<div className="text-xs text-muted-foreground">{subtitle}</div>
230+
)}
231+
</div>
232+
</div>
233+
);
234+
}
235+
236+
function TimelineStat({
237+
label,
238+
value,
239+
total,
240+
}: {
241+
label: string;
242+
value: number;
243+
total: number;
244+
}) {
245+
const percentage = ((value / total) * 100).toFixed(1);
246+
return (
247+
<div className="text-center">
248+
<div className="text-sm font-medium text-muted-foreground">{label}</div>
249+
<div className="text-xl font-bold">{value.toLocaleString()}</div>
250+
<div className="text-xs text-muted-foreground">
251+
{percentage}% of total
138252
</div>
139253
</div>
140254
);
141255
}
256+
142257
function SocialLink({ href, icon }: { href: string; icon: React.ReactNode }) {
143258
if (!href) return null;
144259
return (
@@ -152,6 +267,7 @@ function SocialLink({ href, icon }: { href: string; icon: React.ReactNode }) {
152267
</a>
153268
);
154269
}
270+
155271
function DashboardSkeleton() {
156272
return (
157273
<div className="flex flex-col min-h-screen bg-gradient-to-b from-gray-100 to-gray-200 dark:from-gray-900 dark:to-gray-800 p-4 sm:p-6 md:p-8">

0 commit comments

Comments
 (0)