- Add dashboard stats API endpoint with key metrics - Add stat-card component for displaying metrics - Add occupancy-chart component for court occupancy visualization - Add recent-bookings component for today's bookings list - Add quick-actions component for common admin actions - Update dashboard page with full implementation Stats include: today's bookings, revenue, occupancy rate, active members, pending bookings, and upcoming tournaments. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
152 lines
4.1 KiB
TypeScript
152 lines
4.1 KiB
TypeScript
"use client";
|
|
|
|
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
|
|
import { Button } from "@/components/ui/button";
|
|
import Link from "next/link";
|
|
|
|
interface QuickAction {
|
|
label: string;
|
|
href: string;
|
|
icon: React.ReactNode;
|
|
color: string;
|
|
description: string;
|
|
}
|
|
|
|
const quickActions: QuickAction[] = [
|
|
{
|
|
label: "Nueva Reserva",
|
|
href: "/bookings",
|
|
icon: (
|
|
<svg
|
|
className="w-6 h-6"
|
|
fill="none"
|
|
stroke="currentColor"
|
|
viewBox="0 0 24 24"
|
|
>
|
|
<path
|
|
strokeLinecap="round"
|
|
strokeLinejoin="round"
|
|
strokeWidth={2}
|
|
d="M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z"
|
|
/>
|
|
</svg>
|
|
),
|
|
color: "bg-blue-500 hover:bg-blue-600",
|
|
description: "Crear una nueva reserva de cancha",
|
|
},
|
|
{
|
|
label: "Abrir Caja",
|
|
href: "/pos",
|
|
icon: (
|
|
<svg
|
|
className="w-6 h-6"
|
|
fill="none"
|
|
stroke="currentColor"
|
|
viewBox="0 0 24 24"
|
|
>
|
|
<path
|
|
strokeLinecap="round"
|
|
strokeLinejoin="round"
|
|
strokeWidth={2}
|
|
d="M17 9V7a2 2 0 00-2-2H5a2 2 0 00-2 2v6a2 2 0 002 2h2m2 4h10a2 2 0 002-2v-6a2 2 0 00-2-2H9a2 2 0 00-2 2v6a2 2 0 002 2zm7-5a2 2 0 11-4 0 2 2 0 014 0z"
|
|
/>
|
|
</svg>
|
|
),
|
|
color: "bg-green-500 hover:bg-green-600",
|
|
description: "Iniciar turno de caja registradora",
|
|
},
|
|
{
|
|
label: "Nueva Venta",
|
|
href: "/pos",
|
|
icon: (
|
|
<svg
|
|
className="w-6 h-6"
|
|
fill="none"
|
|
stroke="currentColor"
|
|
viewBox="0 0 24 24"
|
|
>
|
|
<path
|
|
strokeLinecap="round"
|
|
strokeLinejoin="round"
|
|
strokeWidth={2}
|
|
d="M16 11V7a4 4 0 00-8 0v4M5 9h14l1 12H4L5 9z"
|
|
/>
|
|
</svg>
|
|
),
|
|
color: "bg-purple-500 hover:bg-purple-600",
|
|
description: "Registrar venta en el punto de venta",
|
|
},
|
|
{
|
|
label: "Registrar Cliente",
|
|
href: "/clients",
|
|
icon: (
|
|
<svg
|
|
className="w-6 h-6"
|
|
fill="none"
|
|
stroke="currentColor"
|
|
viewBox="0 0 24 24"
|
|
>
|
|
<path
|
|
strokeLinecap="round"
|
|
strokeLinejoin="round"
|
|
strokeWidth={2}
|
|
d="M18 9v3m0 0v3m0-3h3m-3 0h-3m-2-5a4 4 0 11-8 0 4 4 0 018 0zM3 20a6 6 0 0112 0v1H3v-1z"
|
|
/>
|
|
</svg>
|
|
),
|
|
color: "bg-orange-500 hover:bg-orange-600",
|
|
description: "Agregar un nuevo cliente al sistema",
|
|
},
|
|
];
|
|
|
|
export function QuickActions() {
|
|
return (
|
|
<Card>
|
|
<CardHeader className="pb-2">
|
|
<CardTitle className="text-lg flex items-center gap-2">
|
|
<svg
|
|
className="w-5 h-5 text-primary-500"
|
|
fill="none"
|
|
stroke="currentColor"
|
|
viewBox="0 0 24 24"
|
|
>
|
|
<path
|
|
strokeLinecap="round"
|
|
strokeLinejoin="round"
|
|
strokeWidth={2}
|
|
d="M13 10V3L4 14h7v7l9-11h-7z"
|
|
/>
|
|
</svg>
|
|
Acciones Rapidas
|
|
</CardTitle>
|
|
</CardHeader>
|
|
<CardContent>
|
|
<div className="grid grid-cols-2 md:grid-cols-4 gap-4">
|
|
{quickActions.map((action) => (
|
|
<Link key={action.label} href={action.href}>
|
|
<Button
|
|
variant="ghost"
|
|
className="w-full h-auto flex flex-col items-center gap-3 p-4 hover:bg-primary-50 border border-primary-100 rounded-lg transition-all hover:shadow-md group"
|
|
>
|
|
<div
|
|
className={`w-12 h-12 rounded-full flex items-center justify-center text-white transition-transform group-hover:scale-110 ${action.color}`}
|
|
>
|
|
{action.icon}
|
|
</div>
|
|
<div className="text-center">
|
|
<p className="font-medium text-primary-800 text-sm">
|
|
{action.label}
|
|
</p>
|
|
<p className="text-xs text-primary-500 mt-1 line-clamp-2">
|
|
{action.description}
|
|
</p>
|
|
</div>
|
|
</Button>
|
|
</Link>
|
|
))}
|
|
</div>
|
|
</CardContent>
|
|
</Card>
|
|
);
|
|
}
|