Skip to content

Commit

Permalink
refactor: simplify admin
Browse files Browse the repository at this point in the history
  • Loading branch information
nehalist committed Feb 6, 2024
1 parent fe518dc commit 617e377
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 149 deletions.
58 changes: 0 additions & 58 deletions src/app/[locale]/admin/chart.tsx

This file was deleted.

35 changes: 19 additions & 16 deletions src/app/[locale]/admin/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { ReactNode } from "react";
import { Link } from "@/lib/navigation";
import { Container } from "@/components/container";

const nav = [
{
Expand All @@ -10,22 +11,24 @@ const nav = [

export default function AdminLayout({ children }: { children: ReactNode }) {
return (
<div className="flex w-full gap-5 mt-5">
<div className="w-64">
<ul role="list" className="-mx-2 space-y-1">
{nav.map(item => (
<li key={item.href}>
<Link
href={item.href}
className="text-gray-700 dark:text-gray-300 hover:text-green-600 hover:bg-gray-50 dark:hover:bg-gray-900 group flex gap-x-3 rounded-md p-2 pl-3 text-snm leading-6 font-semibold"
>
{item.label}
</Link>
</li>
))}
</ul>
<Container>
<div className="flex w-full gap-5 mt-5">
<div className="w-64">
<ul role="list" className="-mx-2 space-y-1">
{nav.map(item => (
<li key={item.href}>
<Link
href={item.href}
className="text-gray-700 dark:text-gray-300 hover:text-green-600 hover:bg-gray-50 dark:hover:bg-gray-900 group flex gap-x-3 rounded-md p-2 pl-3 text-snm leading-6 font-semibold"
>
{item.label}
</Link>
</li>
))}
</ul>
</div>
<div className="flex-1">{children}</div>
</div>
<div className="flex-1">{children}</div>
</div>
</Container>
);
}
115 changes: 40 additions & 75 deletions src/app/[locale]/admin/page.tsx
Original file line number Diff line number Diff line change
@@ -1,72 +1,30 @@
import { getCurrentUser } from "@/lib/session";
import { redirect } from "@/lib/navigation";
import { db } from "@/db";
import { users } from "@/db/schema";
import { count, gt, sql } from "drizzle-orm";
import { eachDayOfInterval, isEqual } from "date-fns";
import { Card, CardBody, CardHeader } from "@nextui-org/card";
import { AdminDashboardChart } from "@/app/[locale]/admin/chart";

export async function getDashboardData() {
const recentUsers = await db
.select({
createdAt: sql<string>`date_trunc
('day',
${users.createdAt}
)`,
count: sql<number>`cast(count(
${users.id}
)
as
int
)`,
})
.from(users)
.where(
gt(
users.createdAt,
sql`NOW
() - INTERVAL '30 days'`,
),
)
.groupBy(
sql`date_trunc
('day',
${users.createdAt}
)`,
);
const [totalUsers] = await db.select({ count: count() }).from(users);

const course = eachDayOfInterval({
start: new Date(new Date().setDate(new Date().getDate() - 30)),
end: new Date(),
})
.reverse()
.reduce<{
days: Array<{ date: string; count: number }>;
remaining: number;
}>(
(acc, day) => {
const countOnDay =
recentUsers.find(u => isEqual(new Date(u.createdAt), day))?.count ||
0;

return {
days: [
...acc.days,
{
date: day.toISOString(),
count: acc.remaining - countOnDay,
},
],
remaining: acc.remaining - countOnDay,
};
},
{ days: [], remaining: totalUsers.count },
);
import { db } from "@/db";
import { leagues, matches, memberships, teams, users } from "@/db/schema";
import { eq, sql } from "drizzle-orm";

async function getStats() {
return {
userCourse: course.days.reverse(),
leagues: {
active: await db
.select({ count: sql<number>`count(*)::int` })
.from(leagues)
.where(eq(leagues.status, "active")),
finished: await db
.select({ count: sql<number>`count(*)::int` })
.from(leagues)
.where(eq(leagues.status, "finished")),
},
memberships: await db
.select({ count: sql<number>`count(*)::int` })
.from(memberships),
users: await db.select({ count: sql<number>`count(*)::int` }).from(users),
teams: await db.select({ count: sql<number>`count(*)::int` }).from(teams),
matches: await db
.select({ count: sql<number>`count(*)::int` })
.from(matches),
};
}

Expand All @@ -75,27 +33,34 @@ export default async function Admin() {
if (user?.role !== "admin") {
return redirect("/");
}
const data = await getDashboardData();
const stats = await getStats();

return (
<div className="flex flex-col gap-3">
<Card>
<CardBody>
<AdminDashboardChart data={data} />
</CardBody>
</Card>
<div className="grid grid-cols-3 gap-3">
<div>
<p>It's a very poor admin, but it's a start.</p>
<div className="grid grid-cols-3 gap-3 mt-3">
<Card>
<CardHeader>Total users</CardHeader>
<CardBody>...</CardBody>
<CardBody>{stats.users[0].count}</CardBody>
</Card>
<Card>
<CardHeader>Total teams</CardHeader>
<CardBody>...</CardBody>
<CardBody>{stats.teams[0].count}</CardBody>
</Card>
<Card>
<CardHeader>Total memberships</CardHeader>
<CardBody>{stats.memberships[0].count}</CardBody>
</Card>
<Card>
<CardHeader>Total leagues</CardHeader>
<CardBody>
{stats.leagues.active[0].count} active,{" "}
{stats.leagues.finished[0].count} finished
</CardBody>
</Card>
<Card>
<CardHeader>Total matches</CardHeader>
<CardBody>...</CardBody>
<CardBody>{stats.matches[0].count}</CardBody>
</Card>
</div>
</div>
Expand Down

0 comments on commit 617e377

Please sign in to comment.