Redesenha top clientes por horas

This commit is contained in:
codex-bot 2025-10-23 16:54:43 -03:00
parent 34018bed04
commit 25321224a6

View file

@ -15,8 +15,9 @@ import { Input } from "@/components/ui/input"
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select" import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"
import { usePersistentCompanyFilter } from "@/lib/use-company-filter" import { usePersistentCompanyFilter } from "@/lib/use-company-filter"
import { Progress } from "@/components/ui/progress" import { Progress } from "@/components/ui/progress"
import { Bar, BarChart, CartesianGrid, XAxis } from "recharts" import { Bar, BarChart, CartesianGrid, XAxis, YAxis } from "recharts"
import { ChartContainer, ChartTooltip, ChartTooltipContent } from "@/components/ui/chart" import { ChartContainer, ChartLegend, ChartLegendContent, ChartTooltip, ChartTooltipContent } from "@/components/ui/chart"
import type { ChartConfig } from "@/components/ui/chart"
import { formatHoursCompact } from "@/lib/utils" import { formatHoursCompact } from "@/lib/utils"
type HoursItem = { type HoursItem = {
@ -32,11 +33,13 @@ type HoursItem = {
const topClientsChartConfig = { const topClientsChartConfig = {
internas: { internas: {
label: "Horas internas", label: "Horas internas",
color: "var(--chart-1)",
}, },
externas: { externas: {
label: "Horas externas", label: "Horas externas",
color: "var(--chart-2)",
}, },
} } satisfies ChartConfig
export function HoursReport() { export function HoursReport() {
const [timeRange, setTimeRange] = useState("90d") const [timeRange, setTimeRange] = useState("90d")
@ -95,6 +98,19 @@ export function HoursReport() {
}), }),
[filtered] [filtered]
) )
const topClientsData = useMemo(
() =>
filteredWithComputed
.slice()
.sort((a, b) => b.total - a.total)
.slice(0, 10)
.map((row) => ({
name: row.name,
internas: row.internal,
externas: row.external,
})),
[filteredWithComputed]
)
return ( return (
<div className="space-y-6"> <div className="space-y-6">
@ -107,24 +123,26 @@ export function HoursReport() {
{!filteredWithComputed || filteredWithComputed.length === 0 ? ( {!filteredWithComputed || filteredWithComputed.length === 0 ? (
<p className="rounded-lg border border-dashed border-slate-200 p-6 text-sm text-neutral-500">Sem dados para o período.</p> <p className="rounded-lg border border-dashed border-slate-200 p-6 text-sm text-neutral-500">Sem dados para o período.</p>
) : ( ) : (
<ChartContainer config={topClientsChartConfig} className="aspect-auto h-[260px] w-full"> <ChartContainer config={topClientsChartConfig} className="aspect-auto h-[320px] w-full">
<BarChart <BarChart
data={filteredWithComputed data={topClientsData}
.slice() layout="vertical"
.sort((a, b) => b.total - a.total) margin={{ top: 16, right: 24, bottom: 16, left: 0 }}
.slice(0, 10) barCategoryGap={12}
.map((r) => ({ name: r.name, internas: r.internal, externas: r.external }))}
margin={{ top: 8, left: 20, right: 20, bottom: 56 }}
barCategoryGap={32}
> >
<CartesianGrid vertical={false} /> <CartesianGrid horizontal vertical={false} />
<XAxis dataKey="name" tickLine={false} axisLine={false} tickMargin={24} interval={0} angle={-30} height={80} /> <XAxis
<Bar dataKey="internas" stackId="a" fill="var(--chart-1)" radius={[4, 4, 0, 0]} barSize={28} /> type="number"
<Bar dataKey="externas" stackId="a" fill="var(--chart-2)" radius={[4, 4, 0, 0]} barSize={28} /> tickLine={false}
axisLine={false}
tickFormatter={(value) => formatHoursCompact(Number(value))}
/>
<YAxis dataKey="name" type="category" tickLine={false} axisLine={false} width={180} />
<ChartTooltip <ChartTooltip
content={ content={
<ChartTooltipContent <ChartTooltipContent
className="w-[200px]" className="w-[220px]"
labelFormatter={(value) => <span className="font-semibold text-foreground">{String(value)}</span>}
formatter={(value, name) => ( formatter={(value, name) => (
<> <>
<span className="text-muted-foreground"> <span className="text-muted-foreground">
@ -136,6 +154,9 @@ export function HoursReport() {
/> />
} }
/> />
<ChartLegend content={<ChartLegendContent />} />
<Bar dataKey="internas" stackId="hours" fill="var(--color-internas)" radius={[8, 0, 0, 8]} barSize={18} />
<Bar dataKey="externas" stackId="hours" fill="var(--color-externas)" radius={[0, 8, 8, 0]} barSize={18} />
</BarChart> </BarChart>
</ChartContainer> </ChartContainer>
)} )}