karbe/src/app/admin/page.tsx
Claude Integration 6eed6bffc8
All checks were successful
CI / test (pull_request) Successful in 2m0s
fix(ci): 5 erreurs ESLint Next 16 (Date.now impure, <a> vers /admin, setState dans effect)
2026-06-01 04:18:49 +00:00

103 lines
3.8 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import Link from "next/link";
import { formatEur, getAdminKpis } from "@/lib/admin/kpis";
import { KPICard } from "@/components/admin/KPICard";
export const dynamic = "force-dynamic";
export default async function AdminDashboard() {
const kpis = await getAdminKpis();
return (
<div className="mx-auto max-w-6xl">
<header className="mb-6 mt-2">
<h1 className="text-2xl font-semibold text-zinc-900">Tableau de bord</h1>
<p className="mt-1 text-sm text-zinc-500">
Vue d&apos;ensemble de l&apos;activité Karbé. Données live (cache 0).
</p>
</header>
<section className="grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3">
<KPICard
label="Réservations cette semaine"
value={kpis.bookingsThisWeek}
hint="Toutes statuts confondus, démarrage dans la semaine en cours."
tone="info"
/>
<KPICard
label="Réservations confirmées · 30 j"
value={kpis.bookingsConfirmed30d}
hint="CONFIRMED + paiement SUCCEEDED, démarrage J-30."
tone="ok"
/>
<KPICard
label="Revenus reversés · 30 j"
value={formatEur(kpis.revenue30dCents)}
hint="Somme des montants confirmés (reversement loueurs)."
tone="ok"
/>
<KPICard
label="Occupation moyenne · 30 j"
value={`${kpis.occupancyPct} %`}
hint="Nuits réservées / (carbets publiés × 30)."
tone={kpis.occupancyPct > 50 ? "ok" : "neutral"}
/>
<KPICard
label="Nouveaux comptes · 30 j"
value={kpis.newUsers30d}
hint="Inscriptions tous rôles confondus."
tone="info"
/>
<KPICard
label="Carbets publiés"
value={kpis.publishedCarbets}
hint="Catalogue actif (status PUBLISHED)."
tone="neutral"
/>
<KPICard
label="Avis à modérer"
value={kpis.reviewsToModerate}
hint="Aucune réponse de l&apos;hôte enregistrée."
tone={kpis.reviewsToModerate > 5 ? "warn" : "neutral"}
/>
</section>
<section className="mt-10 rounded-lg border border-zinc-200 bg-white p-5 shadow-sm">
<h2 className="text-sm font-semibold uppercase tracking-wider text-zinc-500">
Raccourcis fréquents
</h2>
<ul className="mt-3 grid grid-cols-1 gap-2 text-sm sm:grid-cols-2 lg:grid-cols-3">
<li>
<Link href="/admin/carbets" className="block rounded border border-zinc-200 px-3 py-2 hover:border-zinc-300 hover:bg-zinc-50">
Gérer les carbets
</Link>
</li>
<li>
<Link href="/admin/bookings" className="block rounded border border-zinc-200 px-3 py-2 hover:border-zinc-300 hover:bg-zinc-50">
Voir les réservations
</Link>
</li>
<li>
<Link href="/admin/content-pages" className="block rounded border border-zinc-200 px-3 py-2 hover:border-zinc-300 hover:bg-zinc-50">
Éditer les pages
</Link>
</li>
<li>
<Link href="/admin/plugins" className="block rounded border border-zinc-200 px-3 py-2 hover:border-zinc-300 hover:bg-zinc-50">
Activer / désactiver des plugins
</Link>
</li>
<li>
<Link href="/admin/users" className="block rounded border border-zinc-200 px-3 py-2 hover:border-zinc-300 hover:bg-zinc-50">
Modérer les utilisateurs
</Link>
</li>
<li>
<Link href="/admin/settings" className="block rounded border border-zinc-200 px-3 py-2 hover:border-zinc-300 hover:bg-zinc-50">
Paramètres
</Link>
</li>
</ul>
</section>
</div>
);
}