import Link from "next/link";
import { redirect } from "next/navigation";
import { desc, eq } from "drizzle-orm";
import { auth } from "@/auth";
import { db } from "@/db";
import { activityLog, members, membershipRequests, promotions } from "@/db/schema";
import { isStaff } from "@/lib/rbac";
export const dynamic = "force-dynamic";
function StatCard({
label,
value,
hint,
valueColor = "#13324F",
hintColor = "#9a8d72",
}: {
label: string;
value: number | string;
hint: string;
valueColor?: string;
hintColor?: string;
}) {
return (
);
}
export default async function DashboardPage() {
const session = await auth();
if (!isStaff(session?.user.role)) {
redirect("/backend/espace");
}
const [activeMembers, livePromos, pendingPromos, requests, activity] = await Promise.all([
db.select({ id: members.id }).from(members).where(eq(members.status, "active")),
db.select({ id: promotions.id }).from(promotions).where(eq(promotions.status, "live")),
db.select({ id: promotions.id }).from(promotions).where(eq(promotions.status, "pending")),
db.select({ id: membershipRequests.id }).from(membershipRequests).where(eq(membershipRequests.status, "new")),
db.select().from(activityLog).orderBy(desc(activityLog.createdAt)).limit(6),
]);
const pendingCount = pendingPromos.length;
function timeAgo(date: Date) {
const diff = Date.now() - new Date(date).getTime();
const h = Math.floor(diff / 3_600_000);
if (h < 1) return "à l'instant";
if (h < 24) return `il y a ${h} h`;
const d = Math.floor(h / 24);
return d === 1 ? "hier" : `il y a ${d} j`;
}
return (
Activité récente
{activity.length === 0 && (
Aucune activité récente.
)}
{activity.map((a) => (
))}
Promotions à modérer
{pendingCount} en attente de validation.
Ouvrir la modération
Espace adhérent
);
}