Skip to content

Commit a9c050e

Browse files
committed
Added shadcn to match the theme of the website
1 parent eebafc3 commit a9c050e

File tree

3 files changed

+264
-45
lines changed

3 files changed

+264
-45
lines changed

src/app/dashboard/page.tsx

Lines changed: 71 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,14 @@
11
"use client";
22

3+
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
4+
import {
5+
Table,
6+
TableBody,
7+
TableCell,
8+
TableHead,
9+
TableHeader,
10+
TableRow,
11+
} from "@/components/ui/table";
312
import React from "react";
413
import {
514
LineChart,
@@ -38,7 +47,7 @@ export default function DashboardPage() {
3847
wpm: 80,
3948
},
4049
{
41-
gameId: "cljvlqsj8000408l4ahr36soj",
50+
gameId: "cljvlqsj8000448ewhr36soj",
4251
date: "08/02/2023",
4352
accuracy: 78,
4453
errors: 2,
@@ -68,11 +77,13 @@ export default function DashboardPage() {
6877
// All achievements and the progress of finishing it. NOTE: This should be sorted on progress.
6978
const achievements = [
7079
{
80+
id: "cljvlqsj8000408l4ahr36soj",
7181
title: "First race",
7282
description: "Started a race",
7383
progress: 100,
7484
},
7585
{
86+
id: "cljvlqsj8000408l4ahr36sok",
7687
title: "Play 10 races",
7788
description: "Play a total of 10 races online",
7889
progress: 33,
@@ -81,14 +92,18 @@ export default function DashboardPage() {
8192

8293
return (
8394
<>
84-
<h1 className="text-4xl m-6 font-bold text-center max-[600px]:mb-10">Dashboard</h1>
95+
<h1 className="text-4xl m-6 font-bold text-center max-[600px]:mb-10">
96+
Dashboard
97+
</h1>
8598
<div className="flex max-[600px]:flex-col justify-center items-center w-screen h-[50vh] gap-6 m-2">
86-
<div className="w-[47.5%] max-[600px]:w-[100%] max-[600px]:mr-4 h-full max-[600px]:h-[50%] rounded-lg border-gray-400 border-2 border-opacity-50 max-[600px]:ml-4">
87-
<h2 className="text-2xl font-bold text-center m-2">Accuracy</h2>
99+
<Card className="w-[47.5%] max-[600px]:w-[100%] max-[600px]:mr-4 h-full max-[600px]:h-[50%]">
100+
<CardHeader>
101+
<CardTitle className="text-center m-2">Accuracy</CardTitle>
102+
</CardHeader>
88103
<ResponsiveContainer height="100%">
89104
<LineChart
90105
data={accuracyData}
91-
margin={{ right: 25, left: 25, bottom: 50 }}
106+
margin={{ right: 25, left: 25, bottom: 100 }}
92107
>
93108
<CartesianGrid strokeDasharray="3 3" />
94109
<XAxis dataKey="gameNumber" />
@@ -103,15 +118,15 @@ export default function DashboardPage() {
103118
/>
104119
</LineChart>
105120
</ResponsiveContainer>
106-
</div>
107-
<div className="w-[47.5%] max-[600px]:w-[100%] h-full max-[600px]:h-[50%] rounded-lg border-gray-400 border-2 border-opacity-50 max-[600px]:mr-4 max-[600px]:ml-4 max-[600px]:mb-6">
108-
<h2 className="text-2xl font-bold text-center m-2">
109-
Words per minute
110-
</h2>
121+
</Card>
122+
<Card className="w-[47.5%] max-[600px]:w-[100%] h-full max-[600px]:h-[50%] max-[600px]:mr-4 max-[600px]:ml-4 max-[600px]:mb-6">
123+
<CardHeader>
124+
<CardTitle className="text-center m-2">Words per minute</CardTitle>
125+
</CardHeader>
111126
<ResponsiveContainer height="100%">
112127
<ComposedChart
113128
data={wpmData}
114-
margin={{ right: 25, left: 25, bottom: 50 }}
129+
margin={{ right: 25, left: 25, bottom: 100 }}
115130
>
116131
<CartesianGrid strokeDasharray="3 3" />
117132
<XAxis dataKey="gameNumber" />
@@ -126,43 +141,54 @@ export default function DashboardPage() {
126141
/>
127142
</ComposedChart>
128143
</ResponsiveContainer>
129-
</div>
144+
</Card>
130145
</div>
131146
<div className="flex max-[850px]:flex-col justify-center items-center w-screen min-[850px]:h-[50vh] gap-4 m-4">
132-
<div className="w-[55vw] max-[850px]:w-[100vw] min-[850px]:h-[50vh] rounded-lg border-gray-400 border-2 border-opacity-50 mr-4 p-4">
133-
<h2 className="text-2xl font-bold text-center m-2">Recent Races</h2>
134-
<table className="w-full text-center max-[600px]:text-sm">
135-
<tr>
136-
<th className="max-[900px]:hidden">Game ID</th>
137-
<th>Errors</th>
138-
<th>Accuracy</th>
139-
<th>Wpm</th>
140-
<th>Date</th>
141-
</tr>
142-
{recentGames.map((game) => {
143-
return (
144-
<tr className="m-10">
145-
<td className="max-[900px]:hidden">{game.gameId}</td>
146-
<td className="text-red-600 hover:text-red-500">
147-
{game.wpm} Errors
148-
</td>
149-
<td>{game.accuracy}%</td>
150-
<td>{game.wpm} Wpm</td>
151-
<td>{game.date}</td>
152-
</tr>
153-
);
154-
})}
155-
</table>
156-
</div>
157-
<div className="w-[40vw] max-[850px]:w-screen min-[850px]:h-[50vh] rounded-lg border-gray-400 border-2 border-opacity-50 mr-4">
147+
<Card className="w-[55vw] max-[850px]:w-[100vw] min-[850px]:h-[50vh] mr-4 p-4">
148+
<CardHeader>
149+
<CardTitle className="text-center m-2">Recent Races</CardTitle>
150+
</CardHeader>
151+
<Table className="w-full max-[600px]:text-sm">
152+
<TableHeader>
153+
<TableRow>
154+
<TableHead className="max-[900px]:hidden">Game ID</TableHead>
155+
<TableHead>Errors</TableHead>
156+
<TableHead>Accuracy</TableHead>
157+
<TableHead>Wpm</TableHead>
158+
<TableHead>Date</TableHead>
159+
</TableRow>
160+
</TableHeader>
161+
<TableBody>
162+
{recentGames.map((game) => {
163+
return (
164+
<TableRow key={game.gameId}>
165+
<TableCell className="max-[900px]:hidden">
166+
{game.gameId}
167+
</TableCell>
168+
<TableCell className="text-red-600 hover:text-red-500">
169+
{game.wpm} Errors
170+
</TableCell>
171+
<TableCell>{game.accuracy}%</TableCell>
172+
<TableCell>{game.wpm} Wpm</TableCell>
173+
<TableCell>{game.date}</TableCell>
174+
</TableRow>
175+
);
176+
})}
177+
</TableBody>
178+
</Table>
179+
</Card>
180+
<Card className="w-[40vw] max-[850px]:w-screen min-[850px]:h-[50vh] mr-4">
158181
<h2 className="text-2xl font-bold text-center m-2">Achievements</h2>
159182
{achievements.map((achievement) => {
160183
return (
161-
<div className="border-gray-500 border-2 border-opacity-50 rounded-lg m-4 p-4 flex justify-between">
162-
<div>
163-
<p className="font-bold min-[850px]:text-xl text-md">{achievement.title}</p>
164-
<p className="font-normal min-[850px]:text-xs text-sm">{achievement.description}</p>
165-
</div>
184+
<Card
185+
className="m-4 p-4 flex justify-between"
186+
key={achievement.id}
187+
>
188+
<CardHeader>
189+
<CardTitle>{achievement.title}</CardTitle>
190+
<CardDescription>{achievement.description}</CardDescription>
191+
</CardHeader>
166192
{achievement.progress > 50 ? (
167193
<p className="font-normal text-green-500 mt-auto mb-auto">
168194
{achievement.progress}%
@@ -172,10 +198,10 @@ export default function DashboardPage() {
172198
{achievement.progress}%
173199
</p>
174200
)}
175-
</div>
201+
</Card>
176202
);
177203
})}
178-
</div>
204+
</Card>
179205
</div>
180206
</>
181207
);

src/components/ui/card.tsx

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
import * as React from "react"
2+
3+
import { cn } from "@/lib/utils"
4+
5+
const Card = React.forwardRef<
6+
HTMLDivElement,
7+
React.HTMLAttributes<HTMLDivElement>
8+
>(({ className, ...props }, ref) => (
9+
<div
10+
ref={ref}
11+
className={cn(
12+
"rounded-lg border bg-card text-card-foreground shadow-sm",
13+
className
14+
)}
15+
{...props}
16+
/>
17+
))
18+
Card.displayName = "Card"
19+
20+
const CardHeader = React.forwardRef<
21+
HTMLDivElement,
22+
React.HTMLAttributes<HTMLDivElement>
23+
>(({ className, ...props }, ref) => (
24+
<div
25+
ref={ref}
26+
className={cn("flex flex-col space-y-1.5 p-6", className)}
27+
{...props}
28+
/>
29+
))
30+
CardHeader.displayName = "CardHeader"
31+
32+
const CardTitle = React.forwardRef<
33+
HTMLParagraphElement,
34+
React.HTMLAttributes<HTMLHeadingElement>
35+
>(({ className, ...props }, ref) => (
36+
<h3
37+
ref={ref}
38+
className={cn(
39+
"text-2xl font-semibold leading-none tracking-tight",
40+
className
41+
)}
42+
{...props}
43+
/>
44+
))
45+
CardTitle.displayName = "CardTitle"
46+
47+
const CardDescription = React.forwardRef<
48+
HTMLParagraphElement,
49+
React.HTMLAttributes<HTMLParagraphElement>
50+
>(({ className, ...props }, ref) => (
51+
<p
52+
ref={ref}
53+
className={cn("text-sm text-muted-foreground", className)}
54+
{...props}
55+
/>
56+
))
57+
CardDescription.displayName = "CardDescription"
58+
59+
const CardContent = React.forwardRef<
60+
HTMLDivElement,
61+
React.HTMLAttributes<HTMLDivElement>
62+
>(({ className, ...props }, ref) => (
63+
<div ref={ref} className={cn("p-6 pt-0", className)} {...props} />
64+
))
65+
CardContent.displayName = "CardContent"
66+
67+
const CardFooter = React.forwardRef<
68+
HTMLDivElement,
69+
React.HTMLAttributes<HTMLDivElement>
70+
>(({ className, ...props }, ref) => (
71+
<div
72+
ref={ref}
73+
className={cn(" flex items-center p-6 pt-0", className)}
74+
{...props}
75+
/>
76+
))
77+
CardFooter.displayName = "CardFooter"
78+
79+
export { Card, CardHeader, CardFooter, CardTitle, CardDescription, CardContent }

src/components/ui/table.tsx

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
import * as React from "react"
2+
3+
import { cn } from "@/lib/utils"
4+
5+
const Table = React.forwardRef<
6+
HTMLTableElement,
7+
React.HTMLAttributes<HTMLTableElement>
8+
>(({ className, ...props }, ref) => (
9+
<div className="w-full overflow-auto">
10+
<table
11+
ref={ref}
12+
className={cn("w-full caption-bottom text-sm", className)}
13+
{...props}
14+
/>
15+
</div>
16+
))
17+
Table.displayName = "Table"
18+
19+
const TableHeader = React.forwardRef<
20+
HTMLTableSectionElement,
21+
React.HTMLAttributes<HTMLTableSectionElement>
22+
>(({ className, ...props }, ref) => (
23+
<thead ref={ref} className={cn("[&_tr]:border-b", className)} {...props} />
24+
))
25+
TableHeader.displayName = "TableHeader"
26+
27+
const TableBody = React.forwardRef<
28+
HTMLTableSectionElement,
29+
React.HTMLAttributes<HTMLTableSectionElement>
30+
>(({ className, ...props }, ref) => (
31+
<tbody
32+
ref={ref}
33+
className={cn("[&_tr:last-child]:border-0", className)}
34+
{...props}
35+
/>
36+
))
37+
TableBody.displayName = "TableBody"
38+
39+
const TableFooter = React.forwardRef<
40+
HTMLTableSectionElement,
41+
React.HTMLAttributes<HTMLTableSectionElement>
42+
>(({ className, ...props }, ref) => (
43+
<tfoot
44+
ref={ref}
45+
className={cn("bg-primary font-medium text-primary-foreground", className)}
46+
{...props}
47+
/>
48+
))
49+
TableFooter.displayName = "TableFooter"
50+
51+
const TableRow = React.forwardRef<
52+
HTMLTableRowElement,
53+
React.HTMLAttributes<HTMLTableRowElement>
54+
>(({ className, ...props }, ref) => (
55+
<tr
56+
ref={ref}
57+
className={cn(
58+
"border-b transition-colors hover:bg-muted/50 data-[state=selected]:bg-muted",
59+
className
60+
)}
61+
{...props}
62+
/>
63+
))
64+
TableRow.displayName = "TableRow"
65+
66+
const TableHead = React.forwardRef<
67+
HTMLTableCellElement,
68+
React.ThHTMLAttributes<HTMLTableCellElement>
69+
>(({ className, ...props }, ref) => (
70+
<th
71+
ref={ref}
72+
className={cn(
73+
"h-12 px-4 text-left align-middle font-medium text-muted-foreground [&:has([role=checkbox])]:pr-0",
74+
className
75+
)}
76+
{...props}
77+
/>
78+
))
79+
TableHead.displayName = "TableHead"
80+
81+
const TableCell = React.forwardRef<
82+
HTMLTableCellElement,
83+
React.TdHTMLAttributes<HTMLTableCellElement>
84+
>(({ className, ...props }, ref) => (
85+
<td
86+
ref={ref}
87+
className={cn("p-4 align-middle [&:has([role=checkbox])]:pr-0", className)}
88+
{...props}
89+
/>
90+
))
91+
TableCell.displayName = "TableCell"
92+
93+
const TableCaption = React.forwardRef<
94+
HTMLTableCaptionElement,
95+
React.HTMLAttributes<HTMLTableCaptionElement>
96+
>(({ className, ...props }, ref) => (
97+
<caption
98+
ref={ref}
99+
className={cn("mt-4 text-sm text-muted-foreground", className)}
100+
{...props}
101+
/>
102+
))
103+
TableCaption.displayName = "TableCaption"
104+
105+
export {
106+
Table,
107+
TableHeader,
108+
TableBody,
109+
TableFooter,
110+
TableHead,
111+
TableRow,
112+
TableCell,
113+
TableCaption,
114+
}

0 commit comments

Comments
 (0)