96 lines
3.3 KiB
TypeScript
96 lines
3.3 KiB
TypeScript
import type { Metadata } from "next";
|
|
import { cookies } from "next/headers";
|
|
import { redirect } from "next/navigation";
|
|
import Header from "@/components/Header";
|
|
import { getSession } from "@/lib/redis/session";
|
|
import { getAllSubscriptionTiers } from "@/lib/prisma/queries/subscription-tiers";
|
|
import { getUserById } from "@/lib/prisma/queries/users";
|
|
import { AdminPanelTabs } from "@/components/admin/AdminPanelTabs";
|
|
import { searchAdminItems } from "@/lib/prisma/queries/items";
|
|
|
|
export async function generateMetadata(): Promise<Metadata> {
|
|
return {
|
|
title: "Painel Administrativo",
|
|
description:
|
|
"Gerencie assinaturas, permissões e catalogação de itens exclusivos do Tibia Trade.",
|
|
};
|
|
}
|
|
|
|
export default async function AdminPage({
|
|
params,
|
|
searchParams,
|
|
}: {
|
|
params: Promise<{ locale: string }>;
|
|
searchParams:
|
|
| Promise<Record<string, string | string[]>>
|
|
| Record<string, string | string[]>;
|
|
}) {
|
|
const { locale } = await params;
|
|
const resolvedSearchParams =
|
|
searchParams instanceof Promise ? await searchParams : searchParams;
|
|
const tabParam = resolvedSearchParams?.tab;
|
|
const initialTab =
|
|
typeof tabParam === "string" && ["overview", "subscriptions", "items"].includes(tabParam)
|
|
? (tabParam as "overview" | "subscriptions" | "items")
|
|
: "overview";
|
|
|
|
const cookieStore = await cookies();
|
|
const sessionId = cookieStore.get("sessionId")?.value;
|
|
|
|
if (!sessionId) {
|
|
redirect(`/${locale}`);
|
|
}
|
|
|
|
const session = await getSession(sessionId);
|
|
if (!session || session.userId !== 1) {
|
|
redirect(`/${locale}`);
|
|
}
|
|
|
|
const [tiers, adminUser, initialItems] = await Promise.all([
|
|
getAllSubscriptionTiers(true),
|
|
getUserById(session.userId),
|
|
searchAdminItems({ page: 1, pageSize: 50 }),
|
|
]);
|
|
|
|
const normalizedTiers = tiers.map((tier) => {
|
|
const featureList = (tier.features ?? []) as Array<Record<string, any>>;
|
|
return {
|
|
...tier,
|
|
price_monthly: tier.price_monthly ? Number(tier.price_monthly) : null,
|
|
price_yearly: tier.price_yearly ? Number(tier.price_yearly) : null,
|
|
created_at: tier.created_at instanceof Date ? tier.created_at.toISOString() : tier.created_at,
|
|
updated_at: tier.updated_at instanceof Date ? tier.updated_at.toISOString() : tier.updated_at,
|
|
features: featureList.map((feature) => ({
|
|
...feature,
|
|
created_at:
|
|
feature.created_at instanceof Date ? feature.created_at.toISOString() : feature.created_at ?? null,
|
|
updated_at:
|
|
feature.updated_at instanceof Date ? feature.updated_at.toISOString() : feature.updated_at ?? null,
|
|
})),
|
|
};
|
|
});
|
|
|
|
return (
|
|
<div className="min-h-screen bg-background text-foreground">
|
|
<Header />
|
|
<main className="container mx-auto px-4 py-10 space-y-8">
|
|
<section className="space-y-2">
|
|
<h1 className="text-3xl font-bold tracking-tight">Painel administrativo</h1>
|
|
<p className="text-muted-foreground max-w-2xl">
|
|
Centralize a gestão de planos, permissões e o catálogo de itens. Utilize as abas para acessar cada área temática.
|
|
</p>
|
|
</section>
|
|
|
|
<AdminPanelTabs
|
|
adminUser={adminUser}
|
|
initialTiers={normalizedTiers}
|
|
itemsData={initialItems}
|
|
locale={locale}
|
|
initialTab={initialTab}
|
|
/>
|
|
</main>
|
|
</div>
|
|
);
|
|
}
|
|
|