"use client"; import { RiFundsLine, RiPencilLine } from "@remixicon/react"; import { useCallback, useMemo, useState } from "react"; import { CategoryIconBadge } from "@/components/categorias/category-icon-badge"; import MoneyValues from "@/components/money-values"; import { BudgetDialog } from "@/components/orcamentos/budget-dialog"; import type { Budget, BudgetCategory } from "@/components/orcamentos/types"; import { Button } from "@/components/ui/button"; import { Progress } from "@/components/ui/progress"; import type { GoalsProgressData } from "@/lib/dashboard/goals-progress"; import { WidgetEmptyState } from "../widget-empty-state"; type GoalsProgressWidgetProps = { data: GoalsProgressData; }; const clamp = (value: number, min: number, max: number) => Math.min(max, Math.max(min, value)); const formatPercentage = (value: number, withSign = false) => `${new Intl.NumberFormat("pt-BR", { minimumFractionDigits: 0, maximumFractionDigits: 1, ...(withSign ? { signDisplay: "always" as const } : {}), }).format(value)}%`; export function GoalsProgressWidget({ data }: GoalsProgressWidgetProps) { const [editOpen, setEditOpen] = useState(false); const [selectedBudget, setSelectedBudget] = useState(null); const categories = useMemo( () => data.categories.map((category) => ({ id: category.id, name: category.name, icon: category.icon, })), [data.categories], ); const defaultPeriod = data.items[0]?.period ?? ""; const handleEdit = useCallback((item: GoalsProgressData["items"][number]) => { setSelectedBudget({ id: item.id, amount: item.budgetAmount, spent: item.spentAmount, period: item.period, createdAt: item.createdAt, category: item.categoryId ? { id: item.categoryId, name: item.categoryName, icon: item.categoryIcon, } : null, }); setEditOpen(true); }, []); const handleEditOpenChange = useCallback((open: boolean) => { setEditOpen(open); if (!open) { setSelectedBudget(null); } }, []); if (data.items.length === 0) { return ( } title="Nenhum orçamento para o período" description="Cadastre orçamentos para acompanhar o progresso das metas." /> ); } return (
    {data.items.map((item, index) => { const statusColor = item.status === "exceeded" ? "text-destructive" : ""; const progressValue = clamp(item.usedPercentage, 0, 100); const percentageDelta = item.usedPercentage - 100; return (
  • {item.categoryName}

    de{" "}

    {formatPercentage(percentageDelta, true)}
  • ); })}
); }