feat: translate reports page to English
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -89,39 +89,39 @@ export default function ReportsPage() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
setDailyRevenue([
|
setDailyRevenue([
|
||||||
{ date: "Lun", bookings: 4200, sales: 1800, total: 6000 },
|
{ date: "Mon", bookings: 4200, sales: 1800, total: 6000 },
|
||||||
{ date: "Mar", bookings: 3800, sales: 1200, total: 5000 },
|
{ date: "Tue", bookings: 3800, sales: 1200, total: 5000 },
|
||||||
{ date: "Mié", bookings: 4500, sales: 2100, total: 6600 },
|
{ date: "Wed", bookings: 4500, sales: 2100, total: 6600 },
|
||||||
{ date: "Jue", bookings: 5200, sales: 1900, total: 7100 },
|
{ date: "Thu", bookings: 5200, sales: 1900, total: 7100 },
|
||||||
{ date: "Vie", bookings: 6800, sales: 3200, total: 10000 },
|
{ date: "Fri", bookings: 6800, sales: 3200, total: 10000 },
|
||||||
{ date: "Sáb", bookings: 8500, sales: 4100, total: 12600 },
|
{ date: "Sat", bookings: 8500, sales: 4100, total: 12600 },
|
||||||
{ date: "Dom", bookings: 7200, sales: 3500, total: 10700 },
|
{ date: "Sun", bookings: 7200, sales: 3500, total: 10700 },
|
||||||
]);
|
]);
|
||||||
|
|
||||||
setTopProducts([
|
setTopProducts([
|
||||||
{ name: "Agua", quantity: 245, revenue: 4900 },
|
{ name: "Water", quantity: 245, revenue: 4900 },
|
||||||
{ name: "Gatorade", quantity: 180, revenue: 6300 },
|
{ name: "Gatorade", quantity: 180, revenue: 6300 },
|
||||||
{ name: "Cerveza", quantity: 156, revenue: 7020 },
|
{ name: "Beer", quantity: 156, revenue: 7020 },
|
||||||
{ name: "Pelotas HEAD", quantity: 42, revenue: 7560 },
|
{ name: "Pickleballs", quantity: 42, revenue: 7560 },
|
||||||
{ name: "Raqueta alquiler", quantity: 38, revenue: 3800 },
|
{ name: "Paddle Rental", quantity: 38, revenue: 3800 },
|
||||||
]);
|
]);
|
||||||
|
|
||||||
setCourtStats([
|
setCourtStats([
|
||||||
{ name: "Cancha 1", site: "Sede Norte", bookings: 68, revenue: 20400, occupancy: 72 },
|
{ name: "Court 1", site: "North Site", bookings: 68, revenue: 20400, occupancy: 72 },
|
||||||
{ name: "Cancha 2", site: "Sede Norte", bookings: 54, revenue: 16200, occupancy: 58 },
|
{ name: "Court 2", site: "North Site", bookings: 54, revenue: 16200, occupancy: 58 },
|
||||||
{ name: "Cancha 1", site: "Sede Centro", bookings: 72, revenue: 21600, occupancy: 76 },
|
{ name: "Court 1", site: "Central Site", bookings: 72, revenue: 21600, occupancy: 76 },
|
||||||
{ name: "Cancha 2", site: "Sede Centro", bookings: 61, revenue: 18300, occupancy: 65 },
|
{ name: "Court 2", site: "Central Site", bookings: 61, revenue: 18300, occupancy: 65 },
|
||||||
{ name: "Cancha 1", site: "Sede Sur", bookings: 48, revenue: 14400, occupancy: 51 },
|
{ name: "Court 1", site: "South Site", bookings: 48, revenue: 14400, occupancy: 51 },
|
||||||
{ name: "Cancha 2", site: "Sede Sur", bookings: 39, revenue: 11700, occupancy: 42 },
|
{ name: "Court 2", site: "South Site", bookings: 39, revenue: 11700, occupancy: 42 },
|
||||||
]);
|
]);
|
||||||
|
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
const formatCurrency = (amount: number) => {
|
const formatCurrency = (amount: number) => {
|
||||||
return new Intl.NumberFormat("es-MX", {
|
return new Intl.NumberFormat("en-US", {
|
||||||
style: "currency",
|
style: "currency",
|
||||||
currency: "MXN",
|
currency: "USD",
|
||||||
minimumFractionDigits: 0,
|
minimumFractionDigits: 0,
|
||||||
}).format(amount);
|
}).format(amount);
|
||||||
};
|
};
|
||||||
@@ -133,8 +133,8 @@ export default function ReportsPage() {
|
|||||||
{/* Header */}
|
{/* Header */}
|
||||||
<div className="flex flex-col sm:flex-row justify-between items-start sm:items-center gap-4">
|
<div className="flex flex-col sm:flex-row justify-between items-start sm:items-center gap-4">
|
||||||
<div>
|
<div>
|
||||||
<h1 className="text-2xl font-bold text-primary-800">Reportes</h1>
|
<h1 className="text-2xl font-bold text-primary-800">Reports</h1>
|
||||||
<p className="text-primary-600">Análisis y estadísticas del negocio</p>
|
<p className="text-primary-600">Business analysis and statistics</p>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex gap-3">
|
<div className="flex gap-3">
|
||||||
<select
|
<select
|
||||||
@@ -142,14 +142,14 @@ export default function ReportsPage() {
|
|||||||
onChange={(e) => setDateRange(e.target.value)}
|
onChange={(e) => setDateRange(e.target.value)}
|
||||||
className="rounded-lg border border-primary-200 bg-white px-3 py-2 text-sm focus:border-primary focus:outline-none"
|
className="rounded-lg border border-primary-200 bg-white px-3 py-2 text-sm focus:border-primary focus:outline-none"
|
||||||
>
|
>
|
||||||
<option value="week">Última semana</option>
|
<option value="week">Last week</option>
|
||||||
<option value="month">Último mes</option>
|
<option value="month">Last month</option>
|
||||||
<option value="quarter">Último trimestre</option>
|
<option value="quarter">Last quarter</option>
|
||||||
<option value="year">Último año</option>
|
<option value="year">Last year</option>
|
||||||
</select>
|
</select>
|
||||||
<Button variant="outline" className="gap-2">
|
<Button variant="outline" className="gap-2">
|
||||||
<Download className="h-4 w-4" />
|
<Download className="h-4 w-4" />
|
||||||
Exportar
|
Export
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -157,28 +157,28 @@ export default function ReportsPage() {
|
|||||||
{/* KPI Cards */}
|
{/* KPI Cards */}
|
||||||
<div className="grid gap-4 md:grid-cols-2 lg:grid-cols-4">
|
<div className="grid gap-4 md:grid-cols-2 lg:grid-cols-4">
|
||||||
<StatCard
|
<StatCard
|
||||||
title="Ingresos Totales"
|
title="Total Revenue"
|
||||||
value={formatCurrency(stats.totalRevenue)}
|
value={formatCurrency(stats.totalRevenue)}
|
||||||
change={stats.revenueChange}
|
change={stats.revenueChange}
|
||||||
icon={DollarSign}
|
icon={DollarSign}
|
||||||
loading={loading}
|
loading={loading}
|
||||||
/>
|
/>
|
||||||
<StatCard
|
<StatCard
|
||||||
title="Reservas"
|
title="Bookings"
|
||||||
value={stats.totalBookings.toString()}
|
value={stats.totalBookings.toString()}
|
||||||
change={stats.bookingsChange}
|
change={stats.bookingsChange}
|
||||||
icon={Calendar}
|
icon={Calendar}
|
||||||
loading={loading}
|
loading={loading}
|
||||||
/>
|
/>
|
||||||
<StatCard
|
<StatCard
|
||||||
title="Clientes Activos"
|
title="Active Players"
|
||||||
value={stats.totalClients.toString()}
|
value={stats.totalClients.toString()}
|
||||||
change={stats.clientsChange}
|
change={stats.clientsChange}
|
||||||
icon={Users}
|
icon={Users}
|
||||||
loading={loading}
|
loading={loading}
|
||||||
/>
|
/>
|
||||||
<StatCard
|
<StatCard
|
||||||
title="Ocupación Promedio"
|
title="Average Occupancy"
|
||||||
value={`${stats.avgOccupancy}%`}
|
value={`${stats.avgOccupancy}%`}
|
||||||
change={stats.occupancyChange}
|
change={stats.occupancyChange}
|
||||||
icon={Clock}
|
icon={Clock}
|
||||||
@@ -193,7 +193,7 @@ export default function ReportsPage() {
|
|||||||
<CardHeader>
|
<CardHeader>
|
||||||
<CardTitle className="flex items-center gap-2">
|
<CardTitle className="flex items-center gap-2">
|
||||||
<BarChart3 className="h-5 w-5 text-primary" />
|
<BarChart3 className="h-5 w-5 text-primary" />
|
||||||
Ingresos por Día
|
Revenue by Day
|
||||||
</CardTitle>
|
</CardTitle>
|
||||||
</CardHeader>
|
</CardHeader>
|
||||||
<CardContent>
|
<CardContent>
|
||||||
@@ -224,11 +224,11 @@ export default function ReportsPage() {
|
|||||||
<div className="flex items-center gap-4 pt-2 border-t">
|
<div className="flex items-center gap-4 pt-2 border-t">
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
<div className="w-3 h-3 rounded bg-primary" />
|
<div className="w-3 h-3 rounded bg-primary" />
|
||||||
<span className="text-xs text-primary-600">Reservas</span>
|
<span className="text-xs text-primary-600">Bookings</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
<div className="w-3 h-3 rounded bg-accent" />
|
<div className="w-3 h-3 rounded bg-accent" />
|
||||||
<span className="text-xs text-primary-600">Ventas</span>
|
<span className="text-xs text-primary-600">Sales</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -239,7 +239,7 @@ export default function ReportsPage() {
|
|||||||
{/* Top Products */}
|
{/* Top Products */}
|
||||||
<Card>
|
<Card>
|
||||||
<CardHeader>
|
<CardHeader>
|
||||||
<CardTitle>Productos Más Vendidos</CardTitle>
|
<CardTitle>Top Selling Products</CardTitle>
|
||||||
</CardHeader>
|
</CardHeader>
|
||||||
<CardContent>
|
<CardContent>
|
||||||
{loading ? (
|
{loading ? (
|
||||||
@@ -261,7 +261,7 @@ export default function ReportsPage() {
|
|||||||
</span>
|
</span>
|
||||||
<div className="flex-1">
|
<div className="flex-1">
|
||||||
<p className="font-medium text-primary-800">{product.name}</p>
|
<p className="font-medium text-primary-800">{product.name}</p>
|
||||||
<p className="text-xs text-primary-500">{product.quantity} unidades</p>
|
<p className="text-xs text-primary-500">{product.quantity} units</p>
|
||||||
</div>
|
</div>
|
||||||
<span className="font-semibold text-primary-800">
|
<span className="font-semibold text-primary-800">
|
||||||
{formatCurrency(product.revenue)}
|
{formatCurrency(product.revenue)}
|
||||||
@@ -277,7 +277,7 @@ export default function ReportsPage() {
|
|||||||
{/* Courts Performance */}
|
{/* Courts Performance */}
|
||||||
<Card>
|
<Card>
|
||||||
<CardHeader>
|
<CardHeader>
|
||||||
<CardTitle>Rendimiento por Cancha</CardTitle>
|
<CardTitle>Court Performance</CardTitle>
|
||||||
</CardHeader>
|
</CardHeader>
|
||||||
<CardContent>
|
<CardContent>
|
||||||
{loading ? (
|
{loading ? (
|
||||||
@@ -291,11 +291,11 @@ export default function ReportsPage() {
|
|||||||
<table className="w-full">
|
<table className="w-full">
|
||||||
<thead>
|
<thead>
|
||||||
<tr className="border-b border-primary-100">
|
<tr className="border-b border-primary-100">
|
||||||
<th className="text-left py-3 px-4 text-sm font-medium text-primary-700">Cancha</th>
|
<th className="text-left py-3 px-4 text-sm font-medium text-primary-700">Court</th>
|
||||||
<th className="text-left py-3 px-4 text-sm font-medium text-primary-700">Sede</th>
|
<th className="text-left py-3 px-4 text-sm font-medium text-primary-700">Site</th>
|
||||||
<th className="text-center py-3 px-4 text-sm font-medium text-primary-700">Reservas</th>
|
<th className="text-center py-3 px-4 text-sm font-medium text-primary-700">Bookings</th>
|
||||||
<th className="text-right py-3 px-4 text-sm font-medium text-primary-700">Ingresos</th>
|
<th className="text-right py-3 px-4 text-sm font-medium text-primary-700">Revenue</th>
|
||||||
<th className="text-center py-3 px-4 text-sm font-medium text-primary-700">Ocupación</th>
|
<th className="text-center py-3 px-4 text-sm font-medium text-primary-700">Occupancy</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
@@ -337,34 +337,34 @@ export default function ReportsPage() {
|
|||||||
<div className="grid gap-4 md:grid-cols-3">
|
<div className="grid gap-4 md:grid-cols-3">
|
||||||
<Card>
|
<Card>
|
||||||
<CardHeader className="pb-2">
|
<CardHeader className="pb-2">
|
||||||
<CardTitle className="text-base">Mejor Día</CardTitle>
|
<CardTitle className="text-base">Best Day</CardTitle>
|
||||||
</CardHeader>
|
</CardHeader>
|
||||||
<CardContent>
|
<CardContent>
|
||||||
<p className="text-2xl font-bold text-primary-800">Sábado</p>
|
<p className="text-2xl font-bold text-primary-800">Saturday</p>
|
||||||
<p className="text-sm text-primary-600">
|
<p className="text-sm text-primary-600">
|
||||||
{formatCurrency(12600)} en ingresos promedio
|
{formatCurrency(12600)} in average revenue
|
||||||
</p>
|
</p>
|
||||||
</CardContent>
|
</CardContent>
|
||||||
</Card>
|
</Card>
|
||||||
<Card>
|
<Card>
|
||||||
<CardHeader className="pb-2">
|
<CardHeader className="pb-2">
|
||||||
<CardTitle className="text-base">Hora Pico</CardTitle>
|
<CardTitle className="text-base">Peak Hour</CardTitle>
|
||||||
</CardHeader>
|
</CardHeader>
|
||||||
<CardContent>
|
<CardContent>
|
||||||
<p className="text-2xl font-bold text-primary-800">18:00 - 20:00</p>
|
<p className="text-2xl font-bold text-primary-800">18:00 - 20:00</p>
|
||||||
<p className="text-sm text-primary-600">
|
<p className="text-sm text-primary-600">
|
||||||
85% de ocupación en este horario
|
85% occupancy during this time slot
|
||||||
</p>
|
</p>
|
||||||
</CardContent>
|
</CardContent>
|
||||||
</Card>
|
</Card>
|
||||||
<Card>
|
<Card>
|
||||||
<CardHeader className="pb-2">
|
<CardHeader className="pb-2">
|
||||||
<CardTitle className="text-base">Ticket Promedio</CardTitle>
|
<CardTitle className="text-base">Average Ticket</CardTitle>
|
||||||
</CardHeader>
|
</CardHeader>
|
||||||
<CardContent>
|
<CardContent>
|
||||||
<p className="text-2xl font-bold text-primary-800">{formatCurrency(368)}</p>
|
<p className="text-2xl font-bold text-primary-800">{formatCurrency(368)}</p>
|
||||||
<p className="text-sm text-primary-600">
|
<p className="text-sm text-primary-600">
|
||||||
Por visita (reserva + consumo)
|
Per visit (booking + consumption)
|
||||||
</p>
|
</p>
|
||||||
</CardContent>
|
</CardContent>
|
||||||
</Card>
|
</Card>
|
||||||
@@ -419,7 +419,7 @@ function StatCard({
|
|||||||
{isPositive ? "+" : ""}
|
{isPositive ? "+" : ""}
|
||||||
{change}%
|
{change}%
|
||||||
</span>
|
</span>
|
||||||
<span className="text-xs text-primary-500">vs período anterior</span>
|
<span className="text-xs text-primary-500">vs previous period</span>
|
||||||
</div>
|
</div>
|
||||||
</CardContent>
|
</CardContent>
|
||||||
</Card>
|
</Card>
|
||||||
|
|||||||
Reference in New Issue
Block a user