refactor(dashboard): reorganizar módulos em subdiretórios e nova arquitetura de widgets

Arquivos de queries, helpers e controllers dispersos na raiz de dashboard/
foram movidos para subdiretórios temáticos (bills/, invoices/, notes/,
notifications/, overview/, payments/, goals-progress/, categories/).
~25 widgets monolíticos obsoletos removidos em favor de nova arquitetura
baseada em widget-registry com components/widgets/. Novos componentes:
category-breakdown-chart/list, goals-progress-item, percentage-change-indicator.
Imports atualizados em fetch-dashboard-data e transaction-filters limpos.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Felipe Coutinho
2026-04-20 17:51:56 +00:00
parent 3e80d5995b
commit ba05985725
99 changed files with 784 additions and 2055 deletions

View File

@@ -0,0 +1,48 @@
import type {
Budget,
BudgetCategory,
} from "@/features/budgets/components/types";
import type {
GoalProgressCategory,
GoalProgressItem,
GoalProgressStatus,
} from "@/features/dashboard/goals-progress/goals-progress-queries";
import { formatPercentage } from "@/shared/utils/percentage";
export const clampGoalProgress = (value: number, min: number, max: number) =>
Math.min(max, Math.max(min, value));
export const formatGoalProgressPercentage = (value: number, withSign = false) =>
formatPercentage(value, {
maximumFractionDigits: 1,
signDisplay: withSign ? "always" : "auto",
});
export const getGoalProgressStatusColorClass = (status: GoalProgressStatus) =>
status === "exceeded" ? "text-destructive" : "";
export const mapGoalProgressCategoriesToBudgetCategories = (
categories: GoalProgressCategory[],
): BudgetCategory[] =>
categories.map((category) => ({
id: category.id,
name: category.name,
icon: category.icon,
}));
export const mapGoalProgressItemToBudget = (
item: GoalProgressItem,
): Budget => ({
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,
});

View File

@@ -0,0 +1,28 @@
export type GoalProgressStatus = "on-track" | "critical" | "exceeded";
export type GoalProgressItem = {
id: string;
categoryId: string | null;
categoryName: string;
categoryIcon: string | null;
period: string;
createdAt: string;
budgetAmount: number;
spentAmount: number;
usedPercentage: number;
status: GoalProgressStatus;
};
export type GoalProgressCategory = {
id: string;
name: string;
icon: string | null;
};
export type GoalsProgressData = {
items: GoalProgressItem[];
categories: GoalProgressCategory[];
totalBudgets: number;
exceededCount: number;
criticalCount: number;
};

View File

@@ -0,0 +1,59 @@
"use client";
import { useMemo, useState } from "react";
import type {
Budget,
BudgetCategory,
} from "@/features/budgets/components/types";
import {
mapGoalProgressCategoriesToBudgetCategories,
mapGoalProgressItemToBudget,
} from "@/features/dashboard/goals-progress/goals-progress-helpers";
import type {
GoalProgressItem,
GoalsProgressData,
} from "@/features/dashboard/goals-progress/goals-progress-queries";
type GoalsProgressWidgetController = {
selectedBudget: Budget | null;
editOpen: boolean;
categories: BudgetCategory[];
defaultPeriod: string;
handleEdit: (item: GoalProgressItem) => void;
handleEditOpenChange: (open: boolean) => void;
};
export function useGoalsProgressWidgetController(
data: GoalsProgressData,
): GoalsProgressWidgetController {
const [editOpen, setEditOpen] = useState(false);
const [selectedBudget, setSelectedBudget] = useState<Budget | null>(null);
const categories = useMemo<BudgetCategory[]>(
() => mapGoalProgressCategoriesToBudgetCategories(data.categories),
[data.categories],
);
const defaultPeriod = data.items[0]?.period ?? "";
const handleEdit = (item: GoalProgressItem) => {
setSelectedBudget(mapGoalProgressItemToBudget(item));
setEditOpen(true);
};
const handleEditOpenChange = (open: boolean) => {
setEditOpen(open);
if (!open) {
setSelectedBudget(null);
}
};
return {
selectedBudget,
editOpen,
categories,
defaultPeriod,
handleEdit,
handleEditOpenChange,
};
}