Skip to content

Commit b685eb8

Browse files
committed
feat: user_dashboard
1 parent b1e6822 commit b685eb8

File tree

13 files changed

+2149
-964
lines changed

13 files changed

+2149
-964
lines changed

frontend/app/dashboard/page.tsx

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
import { Diamond, Box, Activity, ShieldCheck } from "lucide-react";
2+
import { MetricCard } from "@/components/dashboard/MetricCard";
3+
import { BalanceSection } from "@/components/dashboard/BalanceSection";
4+
import { StakedChart } from "@/components/dashboard/StakedChart";
5+
import { PredictionList } from "@/components/dashboard/PredictionList";
6+
import { PoolsList } from "@/components/dashboard/PoolsList";
7+
8+
export default function DashboardPage() {
9+
return (
10+
<div className="min-h-screen bg-[#0A0A0A] p-6 lg:p-8 space-y-8">
11+
{/* Header */}
12+
<div className="space-y-1">
13+
<h1 className="text-3xl font-bold text-white">My Dashboard</h1>
14+
<p className="text-zinc-400 text-sm">
15+
Lorem ipsum dolor sit amet consectetur. Non eget non odio lobortis odio.
16+
</p>
17+
</div>
18+
19+
{/* Metric Cards Grid */}
20+
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4">
21+
<MetricCard
22+
title="Total Earned"
23+
value="1,255"
24+
icon={<Diamond />}
25+
change="65% increase"
26+
changeType="positive"
27+
/>
28+
<MetricCard
29+
title="Active Pool"
30+
value="75"
31+
icon={<Box />}
32+
change="+7 new add"
33+
changeType="positive" // Using positive usage for green color
34+
/>
35+
<MetricCard
36+
title="Win Rate"
37+
value="65%"
38+
icon={<Activity />}
39+
change="7.8% Growth"
40+
changeType="positive"
41+
/>
42+
<MetricCard
43+
title="Reputation Score"
44+
value={
45+
<span className="flex items-end gap-1">
46+
<span className="text-[#84CC16]">3.5</span>
47+
<span className="text-lg text-zinc-500 font-normal mb-1">/5.0</span>
48+
</span>
49+
}
50+
icon={<ShieldCheck />}
51+
change="70% accuracy"
52+
changeType="neutral"
53+
/>
54+
</div>
55+
56+
{/* Charts Section */}
57+
<div className="grid grid-cols-1 lg:grid-cols-3 gap-6">
58+
<div className="lg:col-span-1 h-[320px]">
59+
<BalanceSection />
60+
</div>
61+
<div className="lg:col-span-2 h-[320px]">
62+
<StakedChart />
63+
</div>
64+
</div>
65+
66+
{/* Activity Section */}
67+
<div className="grid grid-cols-1 lg:grid-cols-3 gap-6">
68+
<div className="lg:col-span-1">
69+
<PredictionList />
70+
</div>
71+
<div className="lg:col-span-2">
72+
<PoolsList />
73+
</div>
74+
</div>
75+
</div>
76+
);
77+
}

frontend/app/globals.css

Lines changed: 3 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
@import "tailwindcss";
1+
@tailwind base;
2+
@tailwind components;
3+
@tailwind utilities;
24

35
:root {
46
--background: #ffffff;
@@ -28,29 +30,6 @@
2830
--info: 199 89% 48%;
2931
}
3032

31-
@theme inline {
32-
--color-background: var(--background);
33-
--color-foreground: var(--foreground);
34-
--color-primary: hsl(var(--primary));
35-
--color-primary-foreground: hsl(var(--primary-foreground));
36-
--color-secondary: hsl(var(--secondary));
37-
--color-secondary-foreground: hsl(var(--secondary-foreground));
38-
--color-destructive: hsl(var(--destructive));
39-
--color-destructive-foreground: hsl(var(--destructive-foreground));
40-
--color-muted: hsl(var(--muted));
41-
--color-muted-foreground: hsl(var(--muted-foreground));
42-
--color-accent: hsl(var(--accent));
43-
--color-accent-foreground: hsl(var(--accent-foreground));
44-
--color-border: hsl(var(--border));
45-
--color-input: hsl(var(--input));
46-
--color-ring: hsl(var(--ring));
47-
--color-success: hsl(var(--success));
48-
--color-warning: hsl(var(--warning));
49-
--color-info: hsl(var(--info));
50-
--font-sans: var(--font-geist-sans);
51-
--font-mono: var(--font-geist-mono);
52-
}
53-
5433
@media (prefers-color-scheme: dark) {
5534
:root {
5635
--background: #0a0a0a;
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import { ArrowUpRight } from "lucide-react";
2+
import { Button } from "@/components/ui/button";
3+
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
4+
5+
export function BalanceSection() {
6+
return (
7+
<Card className="bg-[#121212] border-none text-white h-full relative overflow-hidden">
8+
<CardHeader>
9+
<CardTitle className="text-zinc-400 font-medium text-sm">Total Balance</CardTitle>
10+
</CardHeader>
11+
<CardContent className="space-y-6 relative z-10">
12+
<div>
13+
<h2 className="text-5xl font-bold font-mono tracking-tighter mb-4">$15,255.25</h2>
14+
<div className="inline-flex items-center px-4 py-2 rounded-full bg-zinc-900 border border-white/5">
15+
<span className="text-zinc-400 mr-2">Rewards:</span>
16+
<span className="font-bold text-white font-mono">$1,255.68</span>
17+
</div>
18+
</div>
19+
20+
<div className="flex gap-4">
21+
<Button className="bg-primary hover:bg-primary/90 text-black min-w-[140px] rounded-xl h-12 text-base font-medium group">
22+
Withdrawal
23+
<ArrowUpRight className="ml-2 w-4 h-4 transition-transform group-hover:translate-x-0.5 group-hover:-translate-y-0.5" />
24+
</Button>
25+
<Button className="bg-primary hover:bg-primary text-black border-transparent hover:border-transparent min-w-[140px] rounded-xl h-12 text-base font-medium group bg-[#37B7C3] hover:opacity-90">
26+
27+
Claim
28+
<ArrowUpRight className="ml-2 w-4 h-4 transition-transform group-hover:translate-x-0.5 group-hover:-translate-y-0.5" />
29+
</Button>
30+
</div>
31+
</CardContent>
32+
</Card>
33+
);
34+
}
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
import { ArrowUpRight, ArrowDownRight, Minus } from "lucide-react";
2+
import { cn } from "@/lib/utils";
3+
import { Card, CardContent } from "@/components/ui/card";
4+
5+
interface MetricCardProps {
6+
title: string;
7+
value: React.ReactNode;
8+
icon: React.ReactNode;
9+
change?: string;
10+
changeType?: "positive" | "negative" | "neutral";
11+
subtext?: string;
12+
}
13+
14+
export function MetricCard({
15+
title,
16+
value,
17+
icon,
18+
change,
19+
changeType = "neutral",
20+
subtext,
21+
}: MetricCardProps) {
22+
return (
23+
<Card className="bg-[#121212] border-none text-white relative overflow-hidden group">
24+
<CardContent className="p-6 flex items-start justify-between relative z-10">
25+
<div className="flex items-start gap-4">
26+
<div className="bg-[#1E1E1E]/50 p-3 rounded-xl border border-white/5 backdrop-blur-sm">
27+
<div className="text-primary [&>svg]:w-6 [&>svg]:h-6">{icon}</div>
28+
</div>
29+
<div className="space-y-1">
30+
<p className="text-xs font-medium text-muted-foreground uppercase tracking-wider">
31+
{title}
32+
</p>
33+
<h3 className="text-3xl font-bold font-mono tracking-tight">{value}</h3>
34+
{(change || subtext) && (
35+
<div
36+
className={cn(
37+
"flex items-center text-xs font-medium mt-1 w-fit px-2 py-1 rounded-full",
38+
changeType === "positive" && "text-emerald-400 bg-emerald-400/10",
39+
changeType === "negative" && "text-rose-400 bg-rose-400/10",
40+
changeType === "neutral" && "text-blue-400 bg-blue-400/10"
41+
)}
42+
>
43+
{changeType === "positive" && <ArrowUpRight className="w-3 h-3 mr-1" />}
44+
{changeType === "negative" && <ArrowDownRight className="w-3 h-3 mr-1" />}
45+
{changeType === "neutral" && <Minus className="w-3 h-3 mr-1" />}
46+
{change || subtext}
47+
</div>
48+
)}
49+
</div>
50+
</div>
51+
</CardContent>
52+
{/* Background gradient effect */}
53+
<div className="absolute top-0 right-0 -mt-4 -mr-4 w-24 h-24 bg-primary/5 rounded-full blur-3xl group-hover:bg-primary/10 transition-colors duration-500" />
54+
</Card>
55+
);
56+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
2+
3+
export function PoolsList() {
4+
return (
5+
<Card className="bg-[#121212] border-none text-white h-full min-h-[400px]">
6+
<CardHeader>
7+
<CardTitle className="text-lg font-medium">Created Pools</CardTitle>
8+
</CardHeader>
9+
<CardContent>
10+
<div className="flex items-center justify-center h-[300px] text-zinc-600">
11+
{/* Empty state placeholder */}
12+
<p>No pools created yet</p>
13+
</div>
14+
</CardContent>
15+
</Card>
16+
);
17+
}
Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
"use client";
2+
3+
import { useState } from "react";
4+
import { cn } from "@/lib/utils";
5+
import { Card, CardContent } from "@/components/ui/card";
6+
import { Button } from "@/components/ui/button";
7+
import { ChefHat, ChevronRight, Users, Copy } from "lucide-react";
8+
import Image from "next/image";
9+
10+
interface Prediction {
11+
id: string;
12+
title: string;
13+
date: string;
14+
potentialPayout: string;
15+
stake: string;
16+
odd: string;
17+
idNo: string;
18+
creator: string;
19+
participants: number;
20+
status: "Pending" | "Completed";
21+
}
22+
23+
const activePredictions: Prediction[] = [
24+
{
25+
id: "1",
26+
title: "125,000 or above",
27+
date: "18-04-2025 21:43",
28+
potentialPayout: "179.52 strk",
29+
stake: "100 strk",
30+
odd: "2.54",
31+
idNo: "19133DK",
32+
creator: "Best Al this mon...",
33+
participants: 185,
34+
status: "Pending"
35+
}
36+
];
37+
38+
export function PredictionList() {
39+
const [activeTab, setActiveTab] = useState<"active" | "past">("active");
40+
41+
return (
42+
<div className="space-y-6">
43+
<div className="flex items-center gap-8 border-b border-zinc-800 pb-1">
44+
<button
45+
onClick={() => setActiveTab("active")}
46+
className={cn(
47+
"pb-3 text-sm font-medium transition-colors relative",
48+
activeTab === "active" ? "text-primary" : "text-muted-foreground hover:text-white"
49+
)}
50+
>
51+
Active Prediction
52+
{activeTab === "active" && (
53+
<span className="absolute bottom-0 left-0 w-full h-0.5 bg-primary" />
54+
)}
55+
<span className="ml-2 bg-[#37B7C3] text-[#121212] text-[10px] font-bold px-1.5 py-0.5 rounded-full relative -top-0.5">
56+
6
57+
</span>
58+
</button>
59+
<button
60+
onClick={() => setActiveTab("past")}
61+
className={cn(
62+
"pb-3 text-sm font-medium transition-colors relative",
63+
activeTab === "past" ? "text-primary" : "text-muted-foreground hover:text-white"
64+
)}
65+
>
66+
Past Predictions
67+
{activeTab === "past" && (
68+
<span className="absolute bottom-0 left-0 w-full h-0.5 bg-primary" />
69+
)}
70+
</button>
71+
</div>
72+
73+
<div className="space-y-4">
74+
{activeTab === "active" ? (
75+
activePredictions.map((prediction) => (
76+
<Card key={prediction.id} className="bg-[#1E1E1E] border-none text-white overflow-hidden">
77+
<CardContent className="p-0">
78+
{/* Header */}
79+
<div className="p-4 flex items-center justify-between border-b border-white/5">
80+
<div>
81+
<h4 className="font-bold text-base">{prediction.title}</h4>
82+
<p className="text-zinc-500 text-xs mt-1">{prediction.date}</p>
83+
</div>
84+
<div className="flex items-center gap-2">
85+
<span className="text-emerald-400 text-xs font-bold">{prediction.status}</span>
86+
<ChevronRight className="w-4 h-4 text-zinc-500" />
87+
</div>
88+
</div>
89+
90+
{/* Stats */}
91+
<div className="p-4 space-y-3">
92+
<div className="flex justify-between items-center text-sm">
93+
<span className="text-zinc-400">Potential Payout:</span>
94+
<span className="font-bold font-mono text-lg">{prediction.potentialPayout}</span>
95+
</div>
96+
<div className="flex justify-between items-center text-sm">
97+
<span className="text-zinc-400">Stake</span>
98+
<span className="text-white">{prediction.stake}</span>
99+
</div>
100+
<div className="flex justify-between items-center text-sm">
101+
<span className="text-zinc-400">Odd</span>
102+
<span className="text-white">{prediction.odd}</span>
103+
</div>
104+
<div className="flex justify-between items-center text-sm">
105+
<span className="text-zinc-400">ID No.</span>
106+
<div className="flex items-center gap-2 text-white">
107+
{prediction.idNo}
108+
<Copy className="w-3 h-3 text-zinc-500 cursor-pointer hover:text-white" />
109+
</div>
110+
</div>
111+
</div>
112+
113+
{/* Footer */}
114+
<div className="p-4 bg-zinc-900/50 flex items-center justify-between">
115+
<div className="flex items-center gap-2">
116+
<div className="w-8 h-8 rounded-lg bg-indigo-500/20 flex items-center justify-center text-indigo-400">
117+
<ChefHat className="w-5 h-5" />
118+
</div>
119+
<span className="text-sm font-medium text-zinc-300">{prediction.creator}</span>
120+
</div>
121+
<div className="flex items-center gap-1 text-zinc-400 text-sm">
122+
<Users className="w-4 h-4" />
123+
<span>{prediction.participants}</span>
124+
</div>
125+
</div>
126+
</CardContent>
127+
</Card>
128+
))
129+
) : (
130+
<div className="text-center py-10 text-zinc-500">
131+
No past predictions found
132+
</div>
133+
)}
134+
</div>
135+
</div>
136+
);
137+
}

0 commit comments

Comments
 (0)