garage-erp/apps/dashboard/modules/home/income-expense-chart.tsx
2026-04-01 15:34:50 +03:00

107 lines
4.1 KiB
TypeScript

"use client"
import {
Area,
AreaChart,
CartesianGrid,
XAxis,
YAxis,
} from "recharts"
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/shared/components/ui/card"
import {
ChartContainer,
ChartTooltip,
ChartTooltipContent,
type ChartConfig,
} from "@/shared/components/ui/chart"
import type { DashboardData } from "./use-dashboard-data"
const chartConfig = {
income: {
label: "Income",
color: "var(--color-emerald-500, #10b981)",
},
expense: {
label: "Expense",
color: "var(--color-red-500, #ef4444)",
},
} satisfies ChartConfig
type Props = { data: DashboardData }
export function IncomeExpenseChart({ data }: Props) {
const series = data.chart?.series ?? []
const currency = data.chart?.currency ?? ""
const chartData = series.map((item) => ({
date: item.date ?? "",
income: item.income ?? 0,
expense: item.expense ?? 0,
}))
return (
<Card>
<CardHeader>
<CardTitle>Income vs Expenses</CardTitle>
<CardDescription>
Financial trend over the selected period ({currency})
</CardDescription>
</CardHeader>
<CardContent>
<ChartContainer config={chartConfig} className="h-75 w-full">
<AreaChart data={chartData} margin={{ top: 10, right: 10, left: 0, bottom: 0 }}>
<defs>
<linearGradient id="fillIncome" x1="0" y1="0" x2="0" y2="1">
<stop offset="5%" stopColor="var(--color-income)" stopOpacity={0.3} />
<stop offset="95%" stopColor="var(--color-income)" stopOpacity={0.05} />
</linearGradient>
<linearGradient id="fillExpense" x1="0" y1="0" x2="0" y2="1">
<stop offset="5%" stopColor="var(--color-expense)" stopOpacity={0.3} />
<stop offset="95%" stopColor="var(--color-expense)" stopOpacity={0.05} />
</linearGradient>
</defs>
<CartesianGrid strokeDasharray="3 3" className="stroke-muted" />
<XAxis
dataKey="date"
tickLine={false}
axisLine={false}
tickFormatter={(value: string) => {
const date = new Date(value)
return date.toLocaleDateString("en-US", { month: "short", day: "numeric" })
}}
/>
<YAxis tickLine={false} axisLine={false} tickFormatter={(v: number) => `${v.toLocaleString()}`} />
<ChartTooltip
content={
<ChartTooltipContent
labelFormatter={(value) => {
return new Date(value).toLocaleDateString("en-US", {
month: "long",
day: "numeric",
year: "numeric",
})
}}
/>
}
/>
<Area
type="monotone"
dataKey="income"
stroke="var(--color-income)"
fill="url(#fillIncome)"
strokeWidth={2}
/>
<Area
type="monotone"
dataKey="expense"
stroke="var(--color-expense)"
fill="url(#fillExpense)"
strokeWidth={2}
/>
</AreaChart>
</ChartContainer>
</CardContent>
</Card>
)
}