Skip to content

Commit b339358

Browse files
author
raineer
committed
preserved dark mode styling
1 parent 6fc229d commit b339358

2 files changed

Lines changed: 170 additions & 15 deletions

File tree

Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
"use client";
2+
3+
import { UserCheck, UserX, Users, UserCog, FolderKanban, UserPen } from "lucide-react";
4+
import { cn } from "@/lib/utils";
5+
6+
// Icon mapping
7+
const ICON_MAP = {
8+
UserCheck,
9+
UserX,
10+
Users,
11+
UserCog,
12+
FolderKanban,
13+
UserPen,
14+
} as const;
15+
16+
type IconName = keyof typeof ICON_MAP;
17+
18+
interface AdminDashboardStatsCardProps {
19+
title: string;
20+
count?: number;
21+
description: string;
22+
iconName: IconName;
23+
colorTheme: "blue" | "red" | "orange" | "purple" | "cyan" | "green";
24+
className?: string;
25+
}
26+
27+
// ORIGINAL theme config - DARK RICH COLORS (not pale)
28+
const THEME_CONFIGS = {
29+
blue: {
30+
card: "bg-white dark:bg-gradient-to-br dark:from-blue-950 dark:via-slate-900 dark:to-slate-950",
31+
border: "border-gray-200 dark:border-blue-900/30",
32+
overlay: "dark:from-blue-500/10",
33+
iconBg: "bg-blue-500/10 group-hover:bg-blue-500/20",
34+
iconColor: "text-blue-500",
35+
},
36+
red: {
37+
card: "bg-white dark:bg-gradient-to-br dark:from-red-950 dark:via-slate-900 dark:to-slate-950",
38+
border: "border-gray-200 dark:border-red-900/30",
39+
overlay: "dark:from-red-500/10",
40+
iconBg: "bg-red-500/10 group-hover:bg-red-500/20",
41+
iconColor: "text-red-500",
42+
},
43+
orange: {
44+
card: "bg-white dark:bg-gradient-to-br dark:from-orange-950 dark:via-slate-900 dark:to-slate-950",
45+
border: "border-gray-200 dark:border-orange-900/30",
46+
overlay: "dark:from-orange-500/10",
47+
iconBg: "bg-orange-500/10 group-hover:bg-orange-500/20",
48+
iconColor: "text-orange-500",
49+
},
50+
purple: {
51+
card: "bg-white dark:bg-gradient-to-br dark:from-purple-950 dark:via-slate-900 dark:to-slate-950",
52+
border: "border-gray-200 dark:border-purple-900/30",
53+
overlay: "dark:from-purple-500/10",
54+
iconBg: "bg-purple-500/10 group-hover:bg-purple-500/20",
55+
iconColor: "text-purple-500",
56+
},
57+
cyan: {
58+
card: "bg-white dark:bg-gradient-to-br dark:from-cyan-950 dark:via-slate-900 dark:to-slate-950",
59+
border: "border-gray-200 dark:border-cyan-900/30",
60+
overlay: "dark:from-cyan-500/10",
61+
iconBg: "bg-cyan-500/10 group-hover:bg-cyan-500/20",
62+
iconColor: "text-cyan-500",
63+
},
64+
green: {
65+
card: "bg-white dark:bg-gradient-to-br dark:from-green-950 dark:via-slate-900 dark:to-slate-950",
66+
border: "border-gray-200 dark:border-green-900/30",
67+
overlay: "dark:from-green-500/10",
68+
iconBg: "bg-green-500/10 group-hover:bg-green-500/20",
69+
iconColor: "text-green-500",
70+
},
71+
} as const;
72+
73+
export default function AdminDashboardStatsCard({
74+
title,
75+
count,
76+
description,
77+
iconName,
78+
colorTheme,
79+
className,
80+
}: AdminDashboardStatsCardProps) {
81+
const theme = THEME_CONFIGS[colorTheme];
82+
const Icon = ICON_MAP[iconName];
83+
84+
return (
85+
<div
86+
className={cn(
87+
"group relative overflow-hidden rounded-lg border transition-all hover:shadow-lg",
88+
theme.card,
89+
theme.border,
90+
className
91+
)}
92+
>
93+
{/* Overlay - only visible in dark mode */}
94+
<div className={cn(
95+
"absolute inset-0 bg-gradient-to-br to-transparent pointer-events-none opacity-0 dark:opacity-100",
96+
theme.overlay
97+
)} />
98+
99+
{/* Header */}
100+
<div className="relative flex flex-row items-center justify-between space-y-0 p-6 pb-2">
101+
<div className="space-y-1">
102+
<p className="text-sm font-medium text-muted-foreground">
103+
{title}
104+
</p>
105+
</div>
106+
<div className={cn(
107+
"rounded-lg p-2 transition-colors",
108+
theme.iconBg,
109+
theme.iconColor
110+
)}>
111+
<Icon className="h-4 w-4" />
112+
</div>
113+
</div>
114+
115+
{/* Content */}
116+
<div className="relative p-6 pt-0">
117+
<div className="text-2xl font-bold">
118+
{count !== undefined ? count.toLocaleString() : "N/A"}
119+
</div>
120+
<p className="text-xs text-muted-foreground">
121+
{description}
122+
</p>
123+
</div>
124+
</div>
125+
);
126+
}

‎apps/codebility/app/home/admin-dashboard/page.tsx‎

Lines changed: 44 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,11 @@ import H1 from "@/components/shared/dashboard/H1";
22
import { getOrSetCache } from "@/lib/server/redis-cache";
33
import { cacheKeys } from "@/lib/server/redis-cache-keys";
44
import { createClientServerComponent } from "@/utils/supabase/server";
5-
import PageContainer from "../_components/PageContainer";
65

76
import AdminDashboardApplicantStatusPie from "./_components/AdminDashboardApplicantStatusPie";
87
import AdminDashboardMonthlyApplicantsLineChart from "./_components/AdminDashboardMonthlyApplicantsLineChart";
98
import AdminDashboardProjectsPie from "./_components/AdminDashboardProjectsPie";
10-
import AdminDashboardTotalActiveIntern from "./_components/AdminDashboardTotalActiveIntern";
11-
import AdminDashboardTotalAdmin from "./_components/AdminDashboardTotalAdmin";
12-
import AdminDashboardTotalCodev from "./_components/AdminDashboardTotalCodev";
13-
import AdminDashboardTotalInactiveIntern from "./_components/AdminDashboardTotalInactiveIntern";
14-
import AdminDashboardTotalMentor from "./_components/AdminDashboardTotalMentor";
15-
import AdminDashboardTotalProjects from "./_components/AdminDashboardTotalProject";
9+
import AdminDashboardStatsCard from "./_components/AdminDashboardStatsCard";
1610

1711
// Force dynamic rendering to avoid prerender errors with Supabase env vars
1812
export const dynamic = "force-dynamic";
@@ -153,19 +147,54 @@ export default async function AdminDashboard() {
153147
</div>
154148
</div>
155149

156-
{/* Metrics Grid */}
150+
{/* Metrics Grid - UPDATED TO USE SHARED COMPONENT */}
157151
<div className="grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-6">
158-
<AdminDashboardTotalActiveIntern
152+
<AdminDashboardStatsCard
153+
title="Total Active Interns"
159154
count={dashboardData?.activeInterns}
155+
description="Currently active interns"
156+
iconName="UserCheck"
157+
colorTheme="blue"
160158
/>
161-
<AdminDashboardTotalInactiveIntern
159+
160+
<AdminDashboardStatsCard
161+
title="Total Inactive Interns"
162162
count={dashboardData?.inactiveInterns}
163+
description="Currently inactive interns"
164+
iconName="UserX"
165+
colorTheme="red"
163166
/>
164-
<AdminDashboardTotalCodev count={dashboardData?.codevs} />
165-
<AdminDashboardTotalAdmin count={dashboardData?.admins} />
166-
<AdminDashboardTotalMentor count={dashboardData?.mentors} />
167-
<AdminDashboardTotalProjects
167+
168+
<AdminDashboardStatsCard
169+
title="Total Codevs"
170+
count={dashboardData?.codevs}
171+
description="Registered developers"
172+
iconName="Users"
173+
colorTheme="green"
174+
/>
175+
176+
<AdminDashboardStatsCard
177+
title="Total Admins"
178+
count={dashboardData?.admins}
179+
description="System administrators"
180+
iconName="UserCog"
181+
colorTheme="purple"
182+
/>
183+
184+
<AdminDashboardStatsCard
185+
title="Total Mentors"
186+
count={dashboardData?.mentors}
187+
description="Active mentors"
188+
iconName="UserPen"
189+
colorTheme="orange"
190+
/>
191+
192+
<AdminDashboardStatsCard
193+
title="Total Projects"
168194
count={dashboardData?.projectTotalCount}
195+
description="Active projects"
196+
iconName="FolderKanban"
197+
colorTheme="cyan"
169198
/>
170199
</div>
171200

@@ -187,4 +216,4 @@ export default async function AdminDashboard() {
187216
</div>
188217
</div>
189218
);
190-
}
219+
}

0 commit comments

Comments
 (0)