import { RiArrowDownSFill, RiArrowUpSFill, RiExternalLinkLine, RiPieChartLine, RiWallet3Line, } from "@remixicon/react"; import Link from "next/link"; import MoneyValues from "@/components/money-values"; import type { ExpensesByCategoryData } from "@/lib/dashboard/categories/expenses-by-category"; import { getIconComponent } from "@/lib/utils/icons"; import { formatPeriodForUrl } from "@/lib/utils/period"; import { WidgetEmptyState } from "../widget-empty-state"; type ExpensesByCategoryWidgetProps = { data: ExpensesByCategoryData; period: string; }; const buildInitials = (value: string) => { const parts = value.trim().split(/\s+/).filter(Boolean); if (parts.length === 0) { return "CT"; } if (parts.length === 1) { const firstPart = parts[0]; return firstPart ? firstPart.slice(0, 2).toUpperCase() : "CT"; } const firstChar = parts[0]?.[0] ?? ""; const secondChar = parts[1]?.[0] ?? ""; return `${firstChar}${secondChar}`.toUpperCase() || "CT"; }; const formatPercentage = (value: number) => { return `${Math.abs(value).toFixed(0)}%`; }; export function ExpensesByCategoryWidget({ data, period, }: ExpensesByCategoryWidgetProps) { const periodParam = formatPeriodForUrl(period); if (data.categories.length === 0) { return ( } title="Nenhuma despesa encontrada" description="Quando houver despesas registradas, elas aparecerão aqui." /> ); } return (
{data.categories.map((category) => { const IconComponent = category.categoryIcon ? getIconComponent(category.categoryIcon) : null; const initials = buildInitials(category.categoryName); const hasIncrease = category.percentageChange !== null && category.percentageChange > 0; const hasDecrease = category.percentageChange !== null && category.percentageChange < 0; const hasBudget = category.budgetAmount !== null; const budgetExceeded = hasBudget && category.budgetUsedPercentage !== null && category.budgetUsedPercentage > 100; const formatCurrency = (value: number) => new Intl.NumberFormat("pt-BR", { style: "currency", currency: "BRL", }).format(value); const exceededAmount = budgetExceeded && category.budgetAmount ? category.currentAmount - category.budgetAmount : 0; return (
{IconComponent ? ( ) : ( {initials} )}
{category.categoryName}
{formatPercentage(category.percentageOfTotal)} da despesa total
{category.percentageChange !== null && ( {hasIncrease && } {hasDecrease && } {formatPercentage(category.percentageChange)} )}
{hasBudget && category.budgetUsedPercentage !== null && (
{budgetExceeded ? ( <> {formatPercentage(category.budgetUsedPercentage)} do limite - excedeu em {formatCurrency(exceededAmount)} ) : ( <> {formatPercentage(category.budgetUsedPercentage)} do limite )}
)}
); })}
); }