Add hourly detail charts for single-day ranges
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 46s

This commit is contained in:
Cauê Faleiros
2026-06-30 14:51:44 -03:00
parent 6a414a5bf4
commit ae7736019f
4 changed files with 178 additions and 20 deletions

View File

@@ -15,6 +15,13 @@ const CHART_DETAIL_BAR_COLOR = 'var(--chart-detail-bar)';
const WEEKDAY_BAR_COLOR = '#25C2FF';
const HOUR_BAR_COLOR = '#52DFA0';
const formatDateKey = (date: Date) => {
const year = date.getFullYear();
const month = String(date.getMonth() + 1).padStart(2, '0');
const day = String(date.getDate()).padStart(2, '0');
return `${year}-${month}-${day}`;
};
type CustomTooltipProps = {
active?: boolean;
payload?: Array<{ value: number }>;
@@ -239,6 +246,7 @@ const ClientDetails = () => {
const hasWeekdayPattern = purchaseWeekdays.some(day => day.value > 0);
const hasHourPattern = purchaseHours.some(hour => hour.value > 0);
const isRefreshing = isLoading && Boolean(details);
const isSingleDayRange = formatDateKey(dateRange.start) === formatDateKey(dateRange.end);
return (
<div className="space-y-6">
@@ -323,7 +331,9 @@ const ClientDetails = () => {
</div>
<div className="bg-white dark:bg-dark-card border border-zinc-200 dark:border-dark-border rounded-2xl p-6 shadow-sm">
<h3 className="text-lg font-bold mb-8 text-zinc-900 dark:text-dark-text">Gasto por Data</h3>
<h3 className="text-lg font-bold mb-8 text-zinc-900 dark:text-dark-text">
Gasto por {isSingleDayRange ? 'Horário' : 'Data'}
</h3>
{chartData.length === 0 ? (
<div className="flex h-[320px] items-center justify-center text-sm font-semibold text-zinc-500 dark:text-dark-muted">
Nenhum gasto no período selecionado.
@@ -331,7 +341,7 @@ const ClientDetails = () => {
) : (
<div className="h-[320px] w-full">
<ResponsiveContainer width="100%" height="100%">
<AreaChart data={chartData} margin={{ top: 5, right: 30, left: 20, bottom: 80 }}>
<AreaChart data={chartData} margin={{ top: 5, right: 30, left: 20, bottom: isSingleDayRange ? 24 : 80 }}>
<defs>
<linearGradient id="clientSpendGradient" x1="0" y1="0" x2="0" y2="1">
<stop offset="5%" stopColor={CHART_DETAIL_BAR_COLOR} stopOpacity={0.38} />
@@ -345,10 +355,10 @@ const ClientDetails = () => {
fontSize={10}
tickLine={false}
axisLine={false}
interval={0}
angle={-45}
textAnchor="end"
height={80}
interval={isSingleDayRange ? 2 : 0}
angle={isSingleDayRange ? 0 : -45}
textAnchor={isSingleDayRange ? 'middle' : 'end'}
height={isSingleDayRange ? 24 : 80}
/>
<YAxis stroke={CHART_AXIS_COLOR} fontSize={12} tickLine={false} axisLine={false} tickFormatter={(value) => formatCurrency(Number(value))} />
<Tooltip content={<CustomTooltip />} cursor={{ fill: CHART_CURSOR_COLOR }} />

View File

@@ -12,6 +12,13 @@ const CHART_AXIS_COLOR = 'var(--chart-axis)';
const CHART_CURSOR_COLOR = 'var(--chart-cursor)';
const CHART_DETAIL_BAR_COLOR = 'var(--chart-detail-bar)';
const formatDateKey = (date: Date) => {
const year = date.getFullYear();
const month = String(date.getMonth() + 1).padStart(2, '0');
const day = String(date.getDate()).padStart(2, '0');
return `${year}-${month}-${day}`;
};
type CustomTooltipProps = {
active?: boolean;
payload?: Array<{ value: number }>;
@@ -126,6 +133,7 @@ const ProductDetails = () => {
const { productInfo, chartData, totalSold, totalRevenue } = details;
const isRefreshing = isLoading && Boolean(details);
const isSingleDayRange = formatDateKey(dateRange.start) === formatDateKey(dateRange.end);
return (
<div className="space-y-6">
@@ -177,10 +185,12 @@ const ProductDetails = () => {
</div>
<div className="bg-white dark:bg-dark-card border border-zinc-200 dark:border-dark-border rounded-2xl p-6 shadow-sm">
<h3 className="text-lg font-bold mb-8 text-zinc-900 dark:text-dark-text">Volume de Vendas por Data</h3>
<h3 className="text-lg font-bold mb-8 text-zinc-900 dark:text-dark-text">
Volume de Vendas por {isSingleDayRange ? 'Horário' : 'Data'}
</h3>
<div className="h-[400px] w-full">
<ResponsiveContainer width="100%" height="100%">
<AreaChart data={chartData} margin={{ top: 5, right: 30, left: 20, bottom: 80 }}>
<AreaChart data={chartData} margin={{ top: 5, right: 30, left: 20, bottom: isSingleDayRange ? 24 : 80 }}>
<defs>
<linearGradient id="productVolumeGradient" x1="0" y1="0" x2="0" y2="1">
<stop offset="5%" stopColor={CHART_DETAIL_BAR_COLOR} stopOpacity={0.38} />
@@ -190,10 +200,10 @@ const ProductDetails = () => {
<CartesianGrid strokeDasharray="3 3" stroke={CHART_GRID_COLOR} vertical={false} />
<XAxis
dataKey="date" stroke={CHART_AXIS_COLOR} fontSize={10} tickLine={false} axisLine={false}
interval={0}
angle={-45}
textAnchor="end"
height={80}
interval={isSingleDayRange ? 2 : 0}
angle={isSingleDayRange ? 0 : -45}
textAnchor={isSingleDayRange ? 'middle' : 'end'}
height={isSingleDayRange ? 24 : 80}
/>
<YAxis stroke={CHART_AXIS_COLOR} fontSize={12} tickLine={false} axisLine={false} />
<Tooltip content={<CustomTooltip />} cursor={{ fill: CHART_CURSOR_COLOR }} />