refactor: faxina arquitetural — código morto, identificadores em inglês e estrutura padronizada

Refatoração estrutural sem mudanças funcionais. Saldo líquido: −428 linhas.

Removido:
- 14 funções/constantes mortas verificadas via grep no repo todo: validateCategoriaOwnership,
  getInstallmentAnticipationsAction, getAnticipationDetailsAction, formatDecimalForDb,
  currencyFormatterNoCents, optionalDecimalSchema, formatMonthLabel,
  getGoalProgressStatusColorClass, MONTH_PERIOD_PARAM, calculateRemainingInstallments,
  e 5 funções fetch* não usadas em inbox/queries.ts.
- 1 tipo morto (ImportRow) + 2 órfãos consequentes (InstallmentAnticipationWithRelations,
  GoalProgressStatus convertido em interno).
- ~30 export keywords desnecessários (símbolos usados apenas no próprio arquivo).
- Re-exports mortos em barrels: EstablishmentLogoPicker, CategoryReportSkeleton,
  WidgetSkeleton, toNameKey.
- Arquivo features/reports/types.ts (barrel inteiro era órfão).

Padronizado (PT-BR→EN em identificadores expostos):
- 4 constantes globais (LANCAMENTOS_* → TRANSACTIONS_*).
- 12 tipos/interfaces (Lancamento*/Pagador*/Estabelecimento* → equivalentes EN).
- 13 funções/components exportados (fetchPagador*, EstabelecimentoInput, PagadorInfoCard, etc.).
- 5 props cross-file (preLancamentosCount → inboxPendingCount, pagadorAvatarUrl → payerAvatarUrl, etc.).
- Mantidas em PT-BR conforme exceção do CLAUDE.md: variáveis locais (pagador, categoria,
  lancamento), accessor key pagadorName (persistida em preferências), strings de UI.

Reorganizado:
- transactions/: 14 helpers soltos na raiz movidos para lib/; barrel actions.ts reduzido
  de 76 linhas de wrappers para 14 linhas de re-exports puros; anticipation-actions.ts
  movido para actions/anticipation.ts.
- dashboard/: 8 helpers soltos consolidados em dashboard/lib/.
- reports/: 5 query files na raiz consolidados em reports/lib/.
- payers/: detail-actions.ts (21KB) e detail-queries.ts movidos para payers/lib/.
- shared/components/: 9 dos 16 componentes soltos agrupados em brand/, widgets/, feedback/.
- shared/lib/fetch-json.ts movido para shared/utils/fetch-json.ts.

Validação: pnpm exec tsc --noEmit (0 erros), biome check (0 issues), knip (sem unused).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
Felipe Coutinho
2026-05-06 18:42:54 +00:00
parent b9b843b9db
commit 7d0781b035
229 changed files with 415 additions and 872 deletions

View File

@@ -1,6 +1,6 @@
"use client";
import StatusDot from "@/shared/components/status-dot";
import StatusDot from "@/shared/components/feedback/status-dot";
import { getAccountTypeIcon } from "@/shared/utils/icons";
export function AccountTypeSelectContent({ label }: { label: string }) {

View File

@@ -8,7 +8,7 @@ import { toast } from "sonner";
import { deleteAccountAction } from "@/features/accounts/actions";
import { AccountCard } from "@/features/accounts/components/account-card";
import { ConfirmActionDialog } from "@/shared/components/confirm-action-dialog";
import { EmptyState } from "@/shared/components/empty-state";
import { EmptyState } from "@/shared/components/feedback/empty-state";
import { Button } from "@/shared/components/ui/button";
import { Card } from "@/shared/components/ui/card";
import {

View File

@@ -99,13 +99,13 @@ async function fetchAccountsByStatus(
return { accounts, logoOptions };
}
export async function fetchAccountsForUser(
async function fetchAccountsForUser(
userId: string,
): Promise<{ accounts: AccountData[]; logoOptions: string[] }> {
return fetchAccountsByStatus(userId, false);
}
export async function fetchInactiveForUser(
async function fetchInactiveForUser(
userId: string,
): Promise<{ accounts: AccountData[]; logoOptions: string[] }> {
return fetchAccountsByStatus(userId, true);

View File

@@ -154,7 +154,7 @@ export async function fetchAccountSummary(
};
}
export async function fetchAccountLancamentos(
export async function fetchAccountTransactions(
filters: SQL[],
settledOnly = true,
) {
@@ -167,7 +167,7 @@ export async function fetchAccountLancamentos(
});
}
export async function fetchAccountLancamentosPage(
export async function fetchAccountTransactionsPage(
filters: SQL[],
{
page,

View File

@@ -18,7 +18,7 @@ import { fetchTransactionDialogOptionsAction } from "@/features/transactions/act
import { TransactionDetailsDialog } from "@/features/transactions/components/dialogs/transaction-details-dialog";
import { TransactionDialog } from "@/features/transactions/components/dialogs/transaction-dialog/transaction-dialog";
import type { TransactionItem } from "@/features/transactions/components/types";
import { EmptyState } from "@/shared/components/empty-state";
import { EmptyState } from "@/shared/components/feedback/empty-state";
import { Card, CardContent } from "@/shared/components/ui/card";
import { cn } from "@/shared/utils/ui";

View File

@@ -2,11 +2,11 @@
import { useQuery } from "@tanstack/react-query";
import { useEffect, useRef, useState } from "react";
import { fetchJson } from "@/shared/lib/fetch-json";
import { fetchJson } from "@/shared/utils/fetch-json";
const ATTACHMENT_URL_STALE_TIME = 4 * 60 * 1000;
export const attachmentUrlQueryKey = (attachmentId: string) =>
const attachmentUrlQueryKey = (attachmentId: string) =>
["attachments", "url", attachmentId] as const;
export function useAttachmentUrlQuery(attachmentId: string, enabled: boolean) {

View File

@@ -3,7 +3,7 @@ import {
RiBarChart2Line,
RiShieldCheckLine,
} from "@remixicon/react";
import { Logo } from "@/shared/components/logo";
import { Logo } from "@/shared/components/brand/logo";
import { DotPattern } from "@/shared/components/ui/dot-pattern";
import { AuthSidebarInvoicesMock } from "./auth-sidebar-invoices-mock";

View File

@@ -8,7 +8,7 @@ import {
duplicatePreviousMonthBudgetsAction,
} from "@/features/budgets/actions";
import { ConfirmActionDialog } from "@/shared/components/confirm-action-dialog";
import { EmptyState } from "@/shared/components/empty-state";
import { EmptyState } from "@/shared/components/feedback/empty-state";
import { Button } from "@/shared/components/ui/button";
import { Card } from "@/shared/components/ui/card";
import { BudgetCard } from "./budget-card";

View File

@@ -26,7 +26,7 @@ type BudgetData = {
} | null;
};
export type CategoryOption = {
type CategoryOption = {
id: string;
name: string;
icon: string | null;

View File

@@ -4,7 +4,7 @@ import {
buildOptionSets,
buildSluggedFilters,
mapTransactionsData,
} from "@/features/transactions/page-helpers";
} from "@/features/transactions/lib/page-helpers";
import {
fetchRecentEstablishments,
fetchTransactionFilterSources,

View File

@@ -2,7 +2,7 @@
import { RiBankLine } from "@remixicon/react";
import Image from "next/image";
import StatusDot from "@/shared/components/status-dot";
import StatusDot from "@/shared/components/feedback/status-dot";
import { resolveCardBrandLogoSrc } from "@/shared/lib/cards/brand-assets";
import { resolveLogoSrc } from "@/shared/lib/logo";

View File

@@ -6,7 +6,7 @@ import { useMemo, useState } from "react";
import { toast } from "sonner";
import { deleteCardAction } from "@/features/cards/actions";
import { ConfirmActionDialog } from "@/shared/components/confirm-action-dialog";
import { EmptyState } from "@/shared/components/empty-state";
import { EmptyState } from "@/shared/components/feedback/empty-state";
import { Button } from "@/shared/components/ui/button";
import { Card as UiCard } from "@/shared/components/ui/card";
import {

View File

@@ -19,7 +19,7 @@ type CardData = {
accountName: string;
};
export type AccountSimple = {
type AccountSimple = {
id: string;
name: string;
logo: string | null;
@@ -121,7 +121,7 @@ async function fetchCardsByStatus(
return { cards: cardList, accounts, logoOptions };
}
export async function fetchCardsForUser(userId: string): Promise<{
async function fetchCardsForUser(userId: string): Promise<{
cards: CardData[];
accounts: AccountSimple[];
logoOptions: string[];
@@ -129,7 +129,7 @@ export async function fetchCardsForUser(userId: string): Promise<{
return fetchCardsByStatus(userId, false);
}
export async function fetchInactiveForUser(userId: string): Promise<{
async function fetchInactiveForUser(userId: string): Promise<{
cards: CardData[];
accounts: AccountSimple[];
logoOptions: string[];

View File

@@ -1,6 +1,6 @@
"use client";
import StatusDot from "@/shared/components/status-dot";
import StatusDot from "@/shared/components/feedback/status-dot";
export function TypeSelectContent({ label }: { label: string }) {
const isReceita = label === "Receita";

View File

@@ -3,7 +3,7 @@ import { type Category, categories } from "@/db/schema";
import type { CategoryType } from "@/shared/lib/categories/constants";
import { db } from "@/shared/lib/db";
export type CategoryData = {
type CategoryData = {
id: string;
name: string;
type: CategoryType;

View File

@@ -8,7 +8,7 @@ import {
} from "@/shared/utils/financial-dates";
export type BillDialogState = PaymentDialogState;
export type BillStatusDateItem = Pick<
type BillStatusDateItem = Pick<
DashboardBill,
"dueDate" | "boletoPaymentDate" | "isSettled"
>;

View File

@@ -1,6 +1,6 @@
import { and, desc, eq, isNull, ne, or, sql } from "drizzle-orm";
import { categories, financialAccounts, transactions } from "@/db/schema";
import { mapTransactionsData } from "@/features/transactions/page-helpers";
import { mapTransactionsData } from "@/features/transactions/lib/page-helpers";
import {
ACCOUNT_AUTO_INVOICE_NOTE_PREFIX,
INITIAL_BALANCE_NOTE,
@@ -17,7 +17,7 @@ import { getPreviousPeriod } from "@/shared/utils/period";
type MappedLancamentos = ReturnType<typeof mapTransactionsData>;
export type CategoryDetailData = {
type CategoryDetailData = {
category: {
id: string;
name: string;

View File

@@ -11,14 +11,14 @@ import {
formatPeriodMonthShort,
} from "@/shared/utils/period";
export type CategoryOption = {
type CategoryOption = {
id: string;
name: string;
icon: string | null;
type: "receita" | "despesa";
};
export type CategoryHistoryItem = {
type CategoryHistoryItem = {
id: string;
name: string;
icon: string | null;

View File

@@ -22,7 +22,7 @@ import {
excludeInitialBalanceWhenConfigured,
excludeRefundEntries,
excludeTransactionsFromExcludedAccounts,
} from "@/features/dashboard/transaction-filters";
} from "@/features/dashboard/lib/transaction-filters";
import { db } from "@/shared/lib/db";
import { getAdminPayerId } from "@/shared/lib/payers/get-admin-id";
import { safeToNumber as toNumber } from "@/shared/utils/number";

View File

@@ -1,10 +1,10 @@
export type CategoryOption = {
type CategoryOption = {
id: string;
name: string;
type: string;
};
export type CategoryTransaction = {
type CategoryTransaction = {
id: string;
name: string;
amount: number;

View File

@@ -14,8 +14,8 @@ import type {
} from "@/features/dashboard/bills/bills-queries";
import { AccountCardSelectContent } from "@/features/transactions/components/select-items";
import { EstablishmentLogo } from "@/shared/components/entity-avatar";
import { PaymentSuccess } from "@/shared/components/feedback/payment-success";
import MoneyValues from "@/shared/components/money-values";
import { PaymentSuccess } from "@/shared/components/payment-success";
import { Badge } from "@/shared/components/ui/badge";
import { Button } from "@/shared/components/ui/button";
import { Card } from "@/shared/components/ui/card";

View File

@@ -1,6 +1,6 @@
import { RiBarcodeFill } from "@remixicon/react";
import type { DashboardBill } from "@/features/dashboard/bills/bills-queries";
import { WidgetEmptyState } from "@/shared/components/widget-empty-state";
import { WidgetEmptyState } from "@/shared/components/widgets/widget-empty-state";
import { BillListItem } from "./bill-list-item";
type BillsListProps = {

View File

@@ -13,7 +13,7 @@ import {
TabsList,
TabsTrigger,
} from "@/shared/components/ui/tabs";
import { WidgetEmptyState } from "@/shared/components/widget-empty-state";
import { WidgetEmptyState } from "@/shared/components/widgets/widget-empty-state";
import { formatPeriodForUrl } from "@/shared/utils/period";
import { CategoryBreakdownChart } from "./category-breakdown-chart";
import { CategoryBreakdownList } from "./category-breakdown-list";

View File

@@ -40,8 +40,8 @@ import {
} from "@/features/dashboard/widget-registry/widget-config";
import { NoteDialog } from "@/features/notes/components/note-dialog";
import { TransactionDialog } from "@/features/transactions/components/dialogs/transaction-dialog/transaction-dialog";
import { ExpandableWidgetCard } from "@/shared/components/expandable-widget-card";
import { Button } from "@/shared/components/ui/button";
import { ExpandableWidgetCard } from "@/shared/components/widgets/expandable-widget-card";
type DashboardGridEditableProps = {
data: DashboardData;

View File

@@ -1,6 +1,6 @@
import { RiFundsLine } from "@remixicon/react";
import type { GoalProgressItem } from "@/features/dashboard/goals-progress/goals-progress-queries";
import { WidgetEmptyState } from "@/shared/components/widget-empty-state";
import { WidgetEmptyState } from "@/shared/components/widgets/widget-empty-state";
import { GoalProgressItem as GoalProgressListItem } from "./goals-progress-item";
type GoalsProgressListProps = {

View File

@@ -1,6 +1,6 @@
import { RiNumbersLine } from "@remixicon/react";
import type { InstallmentExpense } from "@/features/dashboard/expenses/installment-expenses-queries";
import { WidgetEmptyState } from "@/shared/components/widget-empty-state";
import { WidgetEmptyState } from "@/shared/components/widgets/widget-empty-state";
import { InstallmentExpenseListItem } from "./installment-expense-list-item";
type InstallmentExpensesListProps = {

View File

@@ -14,8 +14,8 @@ import type {
InvoicePaymentAccountOption,
} from "@/features/dashboard/invoices/invoices-queries";
import { AccountCardSelectContent } from "@/features/transactions/components/select-items";
import { PaymentSuccess } from "@/shared/components/feedback/payment-success";
import MoneyValues from "@/shared/components/money-values";
import { PaymentSuccess } from "@/shared/components/payment-success";
import { Badge } from "@/shared/components/ui/badge";
import { Button } from "@/shared/components/ui/button";
import { Card } from "@/shared/components/ui/card";

View File

@@ -1,6 +1,6 @@
import { RiBillLine } from "@remixicon/react";
import type { DashboardInvoice } from "@/features/dashboard/invoices/invoices-queries";
import { WidgetEmptyState } from "@/shared/components/widget-empty-state";
import { WidgetEmptyState } from "@/shared/components/widgets/widget-empty-state";
import { InvoiceListItem } from "./invoice-list-item";
type InvoicesListProps = {

View File

@@ -1,6 +1,6 @@
import { RiTodoLine } from "@remixicon/react";
import type { Note } from "@/features/notes/components/types";
import { WidgetEmptyState } from "@/shared/components/widget-empty-state";
import { WidgetEmptyState } from "@/shared/components/widgets/widget-empty-state";
import { NoteListItem } from "./note-list-item";
type NotesListProps = {

View File

@@ -1,5 +1,5 @@
import type { ReactNode } from "react";
import { WidgetEmptyState } from "@/shared/components/widget-empty-state";
import { WidgetEmptyState } from "@/shared/components/widgets/widget-empty-state";
import {
PaymentBreakdownListItem,
type PaymentBreakdownListItemData,

View File

@@ -1,5 +1,5 @@
import StatusDot from "@/shared/components/feedback/status-dot";
import MoneyValues from "@/shared/components/money-values";
import StatusDot from "@/shared/components/status-dot";
import { Progress } from "@/shared/components/ui/progress";
type PaymentStatusCategorySectionProps = {

View File

@@ -1,7 +1,7 @@
import { RiWallet3Line } from "@remixicon/react";
import type { PaymentStatusData } from "@/features/dashboard/payments/payment-status-queries";
import { CardContent } from "@/shared/components/ui/card";
import { WidgetEmptyState } from "@/shared/components/widget-empty-state";
import { WidgetEmptyState } from "@/shared/components/widgets/widget-empty-state";
import { PaymentStatusCategorySection } from "./payment-status-category-section";
type PaymentStatusWidgetViewProps = {

View File

@@ -6,7 +6,7 @@ import {
import { formatPercentage } from "@/shared/utils/percentage";
import { cn } from "@/shared/utils/ui";
export type PercentageChangeTrend = "up" | "down" | "flat";
type PercentageChangeTrend = "up" | "down" | "flat";
type PercentageChangeIndicatorProps = {
value?: number | null;

View File

@@ -14,7 +14,7 @@ import {
TooltipContent,
TooltipTrigger,
} from "@/shared/components/ui/tooltip";
import { WidgetEmptyState } from "@/shared/components/widget-empty-state";
import { WidgetEmptyState } from "@/shared/components/widgets/widget-empty-state";
import { formatDateOnly } from "@/shared/utils/date";
import { formatBytes } from "@/shared/utils/number";

View File

@@ -26,7 +26,7 @@ import {
PopoverContent,
PopoverTrigger,
} from "@/shared/components/ui/popover";
import { WidgetEmptyState } from "@/shared/components/widget-empty-state";
import { WidgetEmptyState } from "@/shared/components/widgets/widget-empty-state";
import { CATEGORY_COLORS } from "@/shared/utils/category-colors";
import { formatCurrency, formatCurrencyCompact } from "@/shared/utils/currency";
import { getIconComponent } from "@/shared/utils/icons";

View File

@@ -5,7 +5,7 @@ import type { DashboardCategoryBreakdownItem } from "@/features/dashboard/catego
import { PercentageChangeIndicator } from "@/features/dashboard/components/percentage-change-indicator";
import { CategoryIconBadge } from "@/shared/components/entity-avatar";
import MoneyValues from "@/shared/components/money-values";
import { WidgetEmptyState } from "@/shared/components/widget-empty-state";
import { WidgetEmptyState } from "@/shared/components/widgets/widget-empty-state";
import { formatPercentage } from "@/shared/utils/percentage";
type CategoryTrendsWidgetProps = {

View File

@@ -9,7 +9,7 @@ import Image from "next/image";
import { useRouter } from "next/navigation";
import { useMemo, useState } from "react";
import { toast } from "sonner";
import type { DashboardInboxSnapshot } from "@/features/dashboard/inbox-snapshot-queries";
import type { DashboardInboxSnapshot } from "@/features/dashboard/lib/inbox-snapshot-queries";
import type { DashboardWidgetQuickActionOptions } from "@/features/dashboard/widget-registry/widget-config";
import {
discardInboxItemAction,
@@ -19,7 +19,7 @@ import { TransactionDialog } from "@/features/transactions/components/dialogs/tr
import { ConfirmActionDialog } from "@/shared/components/confirm-action-dialog";
import MoneyValues from "@/shared/components/money-values";
import { Button } from "@/shared/components/ui/button";
import { WidgetEmptyState } from "@/shared/components/widget-empty-state";
import { WidgetEmptyState } from "@/shared/components/widgets/widget-empty-state";
import { resolveLogoSrc } from "@/shared/lib/logo";
const DEFAULT_INBOX_APP_LOGO = "/avatars/default_icon.png";

View File

@@ -9,7 +9,7 @@ import {
ChartContainer,
ChartTooltip,
} from "@/shared/components/ui/chart";
import { WidgetEmptyState } from "@/shared/components/widget-empty-state";
import { WidgetEmptyState } from "@/shared/components/widgets/widget-empty-state";
import { formatCurrency } from "@/shared/utils/currency";
type IncomeExpenseBalanceWidgetProps = {

View File

@@ -10,7 +10,7 @@ import Image from "next/image";
import Link from "next/link";
import { useTransition } from "react";
import { toast } from "sonner";
import type { DashboardAccount } from "@/features/dashboard/accounts-queries";
import type { DashboardAccount } from "@/features/dashboard/lib/accounts-queries";
import { updateMyAccountsWidgetPreference } from "@/features/dashboard/widget-registry/widget-actions";
import MoneyValues from "@/shared/components/money-values";
import { Badge } from "@/shared/components/ui/badge";
@@ -21,7 +21,7 @@ import {
TooltipContent,
TooltipTrigger,
} from "@/shared/components/ui/tooltip";
import { WidgetEmptyState } from "@/shared/components/widget-empty-state";
import { WidgetEmptyState } from "@/shared/components/widgets/widget-empty-state";
import { isAccountInactive } from "@/shared/lib/accounts/constants";
import { resolveLogoSrc } from "@/shared/lib/logo";
import { formatPeriodForUrl } from "@/shared/utils/period";

View File

@@ -7,14 +7,14 @@ import {
} from "@remixicon/react";
import Link from "next/link";
import { PercentageChangeIndicator } from "@/features/dashboard/components/percentage-change-indicator";
import type { DashboardPagador } from "@/features/dashboard/payers-queries";
import type { DashboardPagador } from "@/features/dashboard/lib/payers-queries";
import MoneyValues from "@/shared/components/money-values";
import {
Avatar,
AvatarFallback,
AvatarImage,
} from "@/shared/components/ui/avatar";
import { WidgetEmptyState } from "@/shared/components/widget-empty-state";
import { WidgetEmptyState } from "@/shared/components/widgets/widget-empty-state";
import { getAvatarSrc } from "@/shared/lib/payers/utils";
import { buildInitials } from "@/shared/utils/initials";

View File

@@ -12,7 +12,7 @@ import {
SelectTrigger,
SelectValue,
} from "@/shared/components/ui/select";
import { WidgetEmptyState } from "@/shared/components/widget-empty-state";
import { WidgetEmptyState } from "@/shared/components/widgets/widget-empty-state";
import { CATEGORY_TYPE_LABEL } from "@/shared/lib/categories/constants";
import { formatTransactionDate } from "@/shared/utils/date";

View File

@@ -2,7 +2,7 @@ import { RiRefreshLine } from "@remixicon/react";
import type { RecurringExpensesData } from "@/features/dashboard/expenses/recurring-expenses-queries";
import { EstablishmentLogo } from "@/shared/components/entity-avatar";
import MoneyValues from "@/shared/components/money-values";
import { WidgetEmptyState } from "@/shared/components/widget-empty-state";
import { WidgetEmptyState } from "@/shared/components/widgets/widget-empty-state";
type RecurringExpensesWidgetProps = {
data: RecurringExpensesData;

View File

@@ -3,7 +3,7 @@
import { RiArrowUpDoubleLine, RiStore2Line } from "@remixicon/react";
import { useState } from "react";
import type { TopExpensesData } from "@/features/dashboard/expenses/top-expenses-queries";
import type { TopEstablishmentsData } from "@/features/dashboard/top-establishments-queries";
import type { TopEstablishmentsData } from "@/features/dashboard/lib/top-establishments-queries";
import {
Tabs,
TabsContent,

View File

@@ -1,8 +1,8 @@
import { RiStore2Line } from "@remixicon/react";
import type { TopEstablishmentsData } from "@/features/dashboard/top-establishments-queries";
import type { TopEstablishmentsData } from "@/features/dashboard/lib/top-establishments-queries";
import { EstablishmentLogo } from "@/shared/components/entity-avatar";
import MoneyValues from "@/shared/components/money-values";
import { WidgetEmptyState } from "@/shared/components/widget-empty-state";
import { WidgetEmptyState } from "@/shared/components/widgets/widget-empty-state";
type TopEstablishmentsWidgetProps = {
data: TopEstablishmentsData;

View File

@@ -9,7 +9,7 @@ import type {
import { EstablishmentLogo } from "@/shared/components/entity-avatar";
import MoneyValues from "@/shared/components/money-values";
import { Switch } from "@/shared/components/ui/switch";
import { WidgetEmptyState } from "@/shared/components/widget-empty-state";
import { WidgetEmptyState } from "@/shared/components/widgets/widget-empty-state";
import { formatTransactionDate } from "@/shared/utils/date";
type TopExpensesWidgetProps = {

View File

@@ -31,7 +31,7 @@ function calculateDueDate(period: string, dueDay: string | null): Date | null {
}
}
export type InstallmentDetail = {
type InstallmentDetail = {
id: string;
currentInstallment: number;
amount: number;

View File

@@ -4,7 +4,7 @@ import {
formatLastInstallmentDate,
} from "@/shared/lib/installments/utils";
export type InstallmentExpenseDisplay = {
type InstallmentExpenseDisplay = {
compactLabel: string | null;
isLast: boolean;
remainingInstallments: number;
@@ -13,7 +13,7 @@ export type InstallmentExpenseDisplay = {
progress: number;
};
export const buildInstallmentCompactLabel = (
const buildInstallmentCompactLabel = (
currentInstallment: number | null,
installmentCount: number | null,
) => {
@@ -24,7 +24,7 @@ export const buildInstallmentCompactLabel = (
return null;
};
export const isInstallmentLast = (
const isInstallmentLast = (
currentInstallment: number | null,
installmentCount: number | null,
) => {
@@ -35,7 +35,7 @@ export const isInstallmentLast = (
return currentInstallment === installmentCount && installmentCount > 1;
};
export const calculateInstallmentRemainingCount = (
const calculateInstallmentRemainingCount = (
currentInstallment: number | null,
installmentCount: number | null,
) => {
@@ -46,7 +46,7 @@ export const calculateInstallmentRemainingCount = (
return Math.max(0, installmentCount - currentInstallment);
};
export const calculateInstallmentRemainingAmount = (
const calculateInstallmentRemainingAmount = (
amount: number,
currentInstallment: number | null,
installmentCount: number | null,
@@ -54,7 +54,7 @@ export const calculateInstallmentRemainingAmount = (
amount *
calculateInstallmentRemainingCount(currentInstallment, installmentCount);
export const formatInstallmentEndDate = (
const formatInstallmentEndDate = (
period: string,
currentInstallment: number | null,
installmentCount: number | null,
@@ -72,7 +72,7 @@ export const formatInstallmentEndDate = (
return formatLastInstallmentDate(lastDate);
};
export const buildInstallmentProgress = (
const buildInstallmentProgress = (
currentInstallment: number | null,
installmentCount: number | null,
) => {

View File

@@ -1,4 +1,4 @@
export type RecurringExpense = {
type RecurringExpense = {
id: string;
name: string;
amount: number;

View File

@@ -1,13 +1,13 @@
import { cacheLife, cacheTag } from "next/cache";
import { fetchAttachmentsForPeriod } from "@/features/attachments/queries";
import { fetchDashboardAccounts } from "./accounts-queries";
import { fetchDashboardCategoryOverview } from "./categories/category-overview-queries";
import { fetchDashboardInboxSnapshot } from "./inbox-snapshot-queries";
import { fetchDashboardInvoices } from "./invoices/invoices-queries";
import { fetchDashboardAccounts } from "./lib/accounts-queries";
import { fetchDashboardInboxSnapshot } from "./lib/inbox-snapshot-queries";
import { fetchDashboardPayers } from "./lib/payers-queries";
import { fetchDashboardNotes } from "./notes/notes-queries";
import { fetchDashboardCurrentPeriodOverview } from "./overview/current-period-overview-queries";
import { fetchDashboardPeriodOverview } from "./overview/period-overview-queries";
import { fetchDashboardPayers } from "./payers-queries";
async function fetchDashboardDataInternal(userId: string, period: string) {
const [

View File

@@ -5,7 +5,6 @@ import type {
import type {
GoalProgressCategory,
GoalProgressItem,
GoalProgressStatus,
} from "@/features/dashboard/goals-progress/goals-progress-queries";
import { formatPercentage } from "@/shared/utils/percentage";
@@ -18,9 +17,6 @@ export const formatGoalProgressPercentage = (value: number, withSign = false) =>
signDisplay: withSign ? "always" : "auto",
});
export const getGoalProgressStatusColorClass = (status: GoalProgressStatus) =>
status === "exceeded" ? "text-destructive" : "";
export const mapGoalProgressCategoriesToBudgetCategories = (
categories: GoalProgressCategory[],
): BudgetCategory[] =>

View File

@@ -1,4 +1,4 @@
export type GoalProgressStatus = "on-track" | "critical" | "exceeded";
type GoalProgressStatus = "on-track" | "critical" | "exceeded";
export type GoalProgressItem = {
id: string;

View File

@@ -55,7 +55,7 @@ type RawInvoiceBreakdownRow = {
amount: number | string | null;
};
export type InvoicePagadorBreakdown = {
type InvoicePagadorBreakdown = {
payerId: string | null;
pagadorName: string;
pagadorAvatar: string | null;

View File

@@ -1,4 +1,4 @@
import type { DashboardData } from "./fetch-dashboard-data";
import type { DashboardData } from "../fetch-dashboard-data";
/**
* Coleta todos os nomes de estabelecimentos exibidos nos widgets do

View File

@@ -3,7 +3,7 @@ import { cacheLife, cacheTag } from "next/cache";
import { cards, financialAccounts, inboxItems } from "@/db/schema";
import { db } from "@/shared/lib/db";
export type DashboardInboxItem = {
type DashboardInboxItem = {
id: string;
sourceAppName: string | null;
parsedName: string | null;

View File

@@ -8,11 +8,11 @@ import { getBusinessDateString } from "@/shared/utils/date";
import {
type DashboardNotificationsSnapshot,
fetchDashboardNotifications,
} from "./notifications/notifications-queries";
} from "../notifications/notifications-queries";
type DashboardNavbarData = {
pagadorAvatarUrl: string | null;
preLancamentosCount: number;
payerAvatarUrl: string | null;
inboxPendingCount: number;
notificationsSnapshot: DashboardNotificationsSnapshot;
};
@@ -39,7 +39,7 @@ async function fetchDashboardNavbarDataInternal(
userId: string,
): Promise<DashboardNavbarData> {
const currentPeriod = getBusinessDateString().slice(0, 7);
const [pagadorAvatarUrl, notificationsSnapshot, preLancamentosCount] =
const [payerAvatarUrl, notificationsSnapshot, inboxPendingCount] =
await Promise.all([
fetchAdminPayerAvatarUrl(userId),
fetchDashboardNotifications(userId, currentPeriod),
@@ -47,8 +47,8 @@ async function fetchDashboardNavbarDataInternal(
]);
return {
pagadorAvatarUrl,
preLancamentosCount,
payerAvatarUrl,
inboxPendingCount,
notificationsSnapshot,
};
}

View File

@@ -1,6 +1,6 @@
import { and, desc, eq, inArray, isNull, or, sql } from "drizzle-orm";
import { financialAccounts, payers, transactions } from "@/db/schema";
import { excludeTransactionsFromExcludedAccounts } from "@/features/dashboard/transaction-filters";
import { excludeTransactionsFromExcludedAccounts } from "@/features/dashboard/lib/transaction-filters";
import { ACCOUNT_AUTO_INVOICE_NOTE_PREFIX } from "@/shared/lib/accounts/constants";
import { db } from "@/shared/lib/db";
import { PAYER_ROLE_ADMIN } from "@/shared/lib/payers/constants";

View File

@@ -1,4 +1,4 @@
export type TopEstablishment = {
type TopEstablishment = {
id: string;
name: string;
amount: number;

View File

@@ -1,7 +1,7 @@
import type { DashboardNote } from "@/features/dashboard/notes/notes-queries";
import type { Note } from "@/features/notes/components/types";
export const mapDashboardNoteToNote = (note: DashboardNote): Note => ({
const mapDashboardNoteToNote = (note: DashboardNote): Note => ({
id: note.id,
title: note.title,
description: note.description,

View File

@@ -2,7 +2,7 @@ import { and, eq } from "drizzle-orm";
import { notes } from "@/db/schema";
import { db } from "@/shared/lib/db";
export type DashboardTask = {
type DashboardTask = {
id: string;
text: string;
completed: boolean;

View File

@@ -31,13 +31,7 @@ import {
getNextPeriod,
} from "@/shared/utils/period";
export type {
BudgetNotification,
BudgetStatus,
DashboardNotification,
DashboardNotificationsSnapshot,
NotificationType,
} from "@/shared/lib/types/notifications";
export type { DashboardNotificationsSnapshot } from "@/shared/lib/types/notifications";
const PAYMENT_METHOD_BOLETO = "Boleto";
const BUDGET_CRITICAL_THRESHOLD = 80;

View File

@@ -13,11 +13,11 @@ import type {
TopExpense,
TopExpensesData,
} from "@/features/dashboard/expenses/top-expenses-queries";
import type { TopEstablishmentsData } from "@/features/dashboard/lib/top-establishments-queries";
import { excludeTransactionsFromExcludedAccounts } from "@/features/dashboard/lib/transaction-filters";
import type { PaymentConditionsData } from "@/features/dashboard/payments/payment-conditions-queries";
import type { PaymentMethodsData } from "@/features/dashboard/payments/payment-methods-queries";
import type { PaymentStatusData } from "@/features/dashboard/payments/payment-status-queries";
import type { TopEstablishmentsData } from "@/features/dashboard/top-establishments-queries";
import { excludeTransactionsFromExcludedAccounts } from "@/features/dashboard/transaction-filters";
import {
ACCOUNT_AUTO_INVOICE_NOTE_PREFIX,
INITIAL_BALANCE_NOTE,

View File

@@ -1,16 +1,16 @@
import { and, asc, eq, gte, inArray, lte, sql } from "drizzle-orm";
import { financialAccounts, transactions } from "@/db/schema";
import type { DashboardCardMetrics } from "@/features/dashboard/overview/dashboard-metrics-queries";
import type {
IncomeExpenseBalanceData,
MonthData,
} from "@/features/dashboard/overview/income-expense-balance-queries";
import {
buildDashboardAdminFilters,
excludeAutoInvoiceEntries,
excludeInitialBalanceWhenConfigured,
excludeTransactionsFromExcludedAccounts,
} from "@/features/dashboard/transaction-filters";
} from "@/features/dashboard/lib/transaction-filters";
import type { DashboardCardMetrics } from "@/features/dashboard/overview/dashboard-metrics-queries";
import type {
IncomeExpenseBalanceData,
MonthData,
} from "@/features/dashboard/overview/income-expense-balance-queries";
import { REFUND_NOTE_PREFIX } from "@/shared/lib/accounts/constants";
import { db } from "@/shared/lib/db";
import { getAdminPayerId } from "@/shared/lib/payers/get-admin-id";

View File

@@ -1,10 +1,10 @@
import { cacheLife, cacheTag } from "next/cache";
import { fetchDashboardData } from "@/features/dashboard/fetch-dashboard-data";
import { fetchUserDashboardPreferences } from "@/features/dashboard/preferences-queries";
import { fetchUserDashboardPreferences } from "@/features/dashboard/lib/preferences-queries";
import {
buildOptionSets,
buildSluggedFilters,
} from "@/features/transactions/page-helpers";
} from "@/features/transactions/lib/page-helpers";
import {
fetchRecentEstablishments,
fetchTransactionFilterSources,
@@ -52,7 +52,7 @@ async function fetchDashboardQuickActionOptionsInternal(
};
}
export async function fetchDashboardQuickActionOptions(userId: string) {
async function fetchDashboardQuickActionOptions(userId: string) {
"use cache";
cacheTag(`dashboard-${userId}`);
cacheLife({ revalidate: 3 });

View File

@@ -1,4 +1,4 @@
export type PaymentConditionSummary = {
type PaymentConditionSummary = {
condition: string;
amount: number;
percentage: number;

View File

@@ -1,4 +1,4 @@
export type PaymentMethodSummary = {
type PaymentMethodSummary = {
paymentMethod: string;
amount: number;
percentage: number;

View File

@@ -1,4 +1,4 @@
export type PaymentStatusCategory = {
type PaymentStatusCategory = {
total: number;
confirmed: number;
pending: number;

View File

@@ -1,7 +1,7 @@
import { RiAtLine, RiCalendarEventLine } from "@remixicon/react";
import { format } from "date-fns";
import { ptBR } from "date-fns/locale";
import { EmptyState } from "@/shared/components/empty-state";
import { EmptyState } from "@/shared/components/feedback/empty-state";
import { Card } from "@/shared/components/ui/card";
import { InboxCard } from "./inbox-card";
import type { InboxItem } from "./types";

View File

@@ -4,10 +4,7 @@ import {
RiArrowRightDoubleLine,
RiArrowRightSLine,
} from "@remixicon/react";
import {
INBOX_DEFAULT_PAGE_SIZE,
INBOX_PAGE_SIZE_OPTIONS,
} from "@/features/inbox/page-helpers";
import { INBOX_PAGE_SIZE_OPTIONS } from "@/features/inbox/page-helpers";
import { Button } from "@/shared/components/ui/button";
import {
Select,
@@ -117,6 +114,3 @@ export function InboxPagination({
</div>
);
}
// Re-export para facilitar uso externo
export { INBOX_DEFAULT_PAGE_SIZE };

View File

@@ -1,5 +1,5 @@
import { TabsList, TabsTrigger } from "@/shared/components/ui/tabs";
import type { InboxStatus, InboxStatusCounts } from "./types";
import type { InboxStatusCounts } from "./types";
type InboxTabsProps = {
counts: InboxStatusCounts;
@@ -36,5 +36,3 @@ export function InboxTabs({ counts, isPending }: InboxTabsProps) {
</TabsList>
);
}
export type { InboxStatus, InboxStatusCounts };

View File

@@ -1,4 +1,4 @@
import type { SelectOption as LancamentoSelectOption } from "@/features/transactions/components/types";
import type { SelectOption as TransactionSelectOption } from "@/features/transactions/components/types";
export type InboxStatus = "pending" | "processed" | "discarded";
@@ -29,4 +29,4 @@ export type InboxPaginationState = {
};
// Re-export the lancamentos SelectOption for use in inbox components
export type SelectOption = LancamentoSelectOption;
export type SelectOption = TransactionSelectOption;

View File

@@ -7,9 +7,9 @@ export type ResolvedInboxSearchParams =
export const INBOX_DEFAULT_PAGE_SIZE = 12;
export const INBOX_PAGE_SIZE_OPTIONS = [12, 24, 48];
export const INBOX_STATUSES = ["pending", "processed", "discarded"] as const;
const INBOX_STATUSES = ["pending", "processed", "discarded"] as const;
export const getSingleParam = (
const getSingleParam = (
params: ResolvedInboxSearchParams,
key: string,
): string | null => {

View File

@@ -1,5 +1,5 @@
import { and, count, desc, eq } from "drizzle-orm";
import { cards, categories, financialAccounts, inboxItems } from "@/db/schema";
import { cards, financialAccounts, inboxItems } from "@/db/schema";
import type {
InboxItem,
InboxPaginationState,
@@ -10,29 +10,13 @@ import type {
import {
buildOptionSets,
buildSluggedFilters,
} from "@/features/transactions/page-helpers";
} from "@/features/transactions/lib/page-helpers";
import {
fetchRecentEstablishments,
fetchTransactionFilterSources,
} from "@/features/transactions/queries";
import { db } from "@/shared/lib/db";
export async function fetchInboxItems(
userId: string,
status: InboxStatus = "pending",
): Promise<InboxItem[]> {
const items = await db
.select()
.from(inboxItems)
.where(and(eq(inboxItems.userId, userId), eq(inboxItems.status, status)))
.orderBy(
desc(inboxItems.notificationTimestamp),
desc(inboxItems.createdAt),
);
return items;
}
export async function fetchInboxItemsPage(
userId: string,
status: InboxStatus,
@@ -126,65 +110,6 @@ export async function fetchInboxStatusCounts(
return counts;
}
export async function fetchInboxItemById(
userId: string,
itemId: string,
): Promise<InboxItem | null> {
const [item] = await db
.select()
.from(inboxItems)
.where(and(eq(inboxItems.id, itemId), eq(inboxItems.userId, userId)))
.limit(1);
return item ?? null;
}
export async function fetchCategoriesForSelect(
userId: string,
type?: string,
): Promise<SelectOption[]> {
const rows = await db
.select({ id: categories.id, name: categories.name })
.from(categories)
.where(
type
? and(eq(categories.userId, userId), eq(categories.type, type))
: eq(categories.userId, userId),
)
.orderBy(categories.name);
return rows.map((row) => ({ value: row.id, label: row.name }));
}
export async function fetchAccountsForSelect(
userId: string,
): Promise<SelectOption[]> {
const rows = await db
.select({ id: financialAccounts.id, name: financialAccounts.name })
.from(financialAccounts)
.where(
and(
eq(financialAccounts.userId, userId),
eq(financialAccounts.status, "ativo"),
),
)
.orderBy(financialAccounts.name);
return rows.map((row) => ({ value: row.id, label: row.name }));
}
export async function fetchCardsForSelect(
userId: string,
): Promise<(SelectOption & { lastDigits?: string })[]> {
const rows = await db
.select({ id: cards.id, name: cards.name })
.from(cards)
.where(and(eq(cards.userId, userId), eq(cards.status, "ativo")))
.orderBy(cards.name);
return rows.map((row) => ({ value: row.id, label: row.name }));
}
export async function fetchAppLogoMap(
userId: string,
): Promise<Record<string, string>> {

View File

@@ -1,32 +1,5 @@
"use server";
import { generateInsightsAction as generateInsightsActionImpl } from "./actions/generate";
import {
deleteSavedInsightsAction as deleteSavedInsightsActionImpl,
loadSavedInsightsAction as loadSavedInsightsActionImpl,
saveInsightsAction as saveInsightsActionImpl,
export { generateInsightsAction } from "./actions/generate";
export {
deleteSavedInsightsAction,
saveInsightsAction,
} from "./actions/storage";
export async function generateInsightsAction(
...args: Parameters<typeof generateInsightsActionImpl>
): ReturnType<typeof generateInsightsActionImpl> {
return generateInsightsActionImpl(...args);
}
export async function saveInsightsAction(
...args: Parameters<typeof saveInsightsActionImpl>
): ReturnType<typeof saveInsightsActionImpl> {
return saveInsightsActionImpl(...args);
}
export async function loadSavedInsightsAction(
...args: Parameters<typeof loadSavedInsightsActionImpl>
): ReturnType<typeof loadSavedInsightsActionImpl> {
return loadSavedInsightsActionImpl(...args);
}
export async function deleteSavedInsightsAction(
...args: Parameters<typeof deleteSavedInsightsActionImpl>
): ReturnType<typeof deleteSavedInsightsActionImpl> {
return deleteSavedInsightsActionImpl(...args);
}

View File

@@ -5,10 +5,7 @@ import { z } from "zod";
import { savedInsights } from "@/db/schema";
import { getUser } from "@/shared/lib/auth/server";
import { db } from "@/shared/lib/db";
import {
type InsightsResponse,
InsightsResponseSchema,
} from "@/shared/lib/schemas/insights";
import type { InsightsResponse } from "@/shared/lib/schemas/insights";
import type { ActionResult } from "./types";
const periodSchema = z
@@ -115,62 +112,6 @@ export async function saveInsightsAction(
}
}
export async function loadSavedInsightsAction(period: string): Promise<
ActionResult<{
insights: InsightsResponse;
modelId: string;
createdAt: Date;
} | null>
> {
try {
const user = await getUser();
const validatedPeriod = periodSchema.safeParse(period);
if (!validatedPeriod.success) {
return {
success: false,
error: validatedPeriod.error.issues[0]?.message ?? "Período inválido",
};
}
period = validatedPeriod.data;
const result = await db
.select()
.from(savedInsights)
.where(
and(
eq(savedInsights.userId, user.id),
eq(savedInsights.period, period),
),
)
.limit(1);
if (result.length === 0) {
return {
success: true,
data: null,
};
}
const saved = result[0];
const insights = InsightsResponseSchema.parse(JSON.parse(saved.data));
return {
success: true,
data: {
insights,
modelId: saved.modelId,
createdAt: saved.createdAt,
},
};
} catch (error) {
console.error("Error loading saved insights:", error);
return {
success: false,
error: "Erro ao carregar análise salva. Tente novamente.",
};
}
}
export async function deleteSavedInsightsAction(
period: string,
): Promise<ActionResult<void>> {

View File

@@ -21,7 +21,7 @@ import {
savedInsightsQueryKey,
useSavedInsights,
} from "@/features/insights/hooks/use-saved-insights";
import { EmptyState } from "@/shared/components/empty-state";
import { EmptyState } from "@/shared/components/feedback/empty-state";
import { Alert, AlertDescription } from "@/shared/components/ui/alert";
import { Button } from "@/shared/components/ui/button";
import { Card, CardContent, CardHeader } from "@/shared/components/ui/card";

View File

@@ -3,8 +3,8 @@
import { useQuery } from "@tanstack/react-query";
import { z } from "zod";
import type { SavedInsightsRecord } from "@/features/insights/queries";
import { fetchJson } from "@/shared/lib/fetch-json";
import { InsightsResponseSchema } from "@/shared/lib/schemas/insights";
import { fetchJson } from "@/shared/utils/fetch-json";
const savedInsightsRecordSchema = z.object({
insights: InsightsResponseSchema,

View File

@@ -11,8 +11,8 @@ import {
updatePaymentDateAction,
} from "@/features/invoices/actions";
import { AccountCardSelectContent } from "@/features/transactions/components/select-items";
import StatusDot from "@/shared/components/feedback/status-dot";
import MoneyValues from "@/shared/components/money-values";
import StatusDot from "@/shared/components/status-dot";
import { Badge } from "@/shared/components/ui/badge";
import { Button } from "@/shared/components/ui/button";
import { Card, CardContent } from "@/shared/components/ui/card";

View File

@@ -3,7 +3,7 @@
import { RiArrowRightSLine, RiMenuLine } from "@remixicon/react";
import Link from "next/link";
import { useState } from "react";
import { Logo } from "@/shared/components/logo";
import { Logo } from "@/shared/components/brand/logo";
import { Button } from "@/shared/components/ui/button";
import {
Sheet,

View File

@@ -28,7 +28,7 @@ import {
} from "@remixicon/react";
import type { ComponentType } from "react";
export type FeatureItem = {
type FeatureItem = {
icon: ComponentType<{ className?: string; style?: React.CSSProperties }>;
title: string;
description: string;

View File

@@ -5,7 +5,7 @@ import { useState } from "react";
import { toast } from "sonner";
import { archiveNoteAction, deleteNoteAction } from "@/features/notes/actions";
import { ConfirmActionDialog } from "@/shared/components/confirm-action-dialog";
import { EmptyState } from "@/shared/components/empty-state";
import { EmptyState } from "@/shared/components/feedback/empty-state";
import { Button } from "@/shared/components/ui/button";
import { Card } from "@/shared/components/ui/card";
import {

View File

@@ -1,4 +1,4 @@
export type NoteType = "nota" | "tarefa";
type NoteType = "nota" | "tarefa";
export interface Task {
id: string;

View File

@@ -2,13 +2,13 @@ import { and, eq } from "drizzle-orm";
import { type Note, notes } from "@/db/schema";
import { db } from "@/shared/lib/db";
export type Task = {
type Task = {
id: string;
text: string;
completed: boolean;
};
export type NoteData = {
type NoteData = {
id: string;
title: string;
description: string;
@@ -43,7 +43,7 @@ function toNoteData(note: Note): NoteData {
};
}
export async function fetchNotesForUser(userId: string): Promise<NoteData[]> {
async function fetchNotesForUser(userId: string): Promise<NoteData[]> {
const noteRows = await db.query.notes.findMany({
where: and(eq(notes.userId, userId), eq(notes.archived, false)),
orderBy: (table, { desc }) => [desc(table.createdAt)],
@@ -63,9 +63,7 @@ export async function fetchAllNotesForUser(
return { activeNotes, archivedNotes };
}
export async function fetchArchivedForUser(
userId: string,
): Promise<NoteData[]> {
async function fetchArchivedForUser(userId: string): Promise<NoteData[]> {
const noteRows = await db.query.notes.findMany({
where: and(eq(notes.userId, userId), eq(notes.archived, true)),
orderBy: (table, { desc }) => [desc(table.createdAt)],

View File

@@ -2,16 +2,16 @@ import { RiBankCard2Line } from "@remixicon/react";
import Image from "next/image";
import MoneyValues from "@/shared/components/money-values";
import { CardContent } from "@/shared/components/ui/card";
import { WidgetEmptyState } from "@/shared/components/widget-empty-state";
import { WidgetEmptyState } from "@/shared/components/widgets/widget-empty-state";
import { resolveLogoSrc } from "@/shared/lib/logo";
import type { PayerCardUsageItem } from "@/shared/lib/payers/details";
import { buildInitials } from "@/shared/utils/initials";
type PagadorCardUsageCardProps = {
type PayerCardUsageCardProps = {
items: PayerCardUsageItem[];
};
export function PayerCardUsageCard({ items }: PagadorCardUsageCardProps) {
export function PayerCardUsageCard({ items }: PayerCardUsageCardProps) {
if (items.length === 0) {
return (
<CardContent className="px-0">

View File

@@ -13,7 +13,7 @@ import Link from "next/link";
import { useRouter } from "next/navigation";
import { useState, useTransition } from "react";
import { toast } from "sonner";
import { sendPayerSummaryAction } from "@/features/payers/detail-actions";
import { sendPayerSummaryAction } from "@/features/payers/lib/detail-actions";
import { Badge } from "@/shared/components/ui/badge";
import { Button } from "@/shared/components/ui/button";
import {

View File

@@ -20,7 +20,7 @@ import {
ChartTooltip,
ChartTooltipContent,
} from "@/shared/components/ui/chart";
import { WidgetEmptyState } from "@/shared/components/widget-empty-state";
import { WidgetEmptyState } from "@/shared/components/widgets/widget-empty-state";
import type { PayerHistoryPoint } from "@/shared/lib/payers/details";
import { currencyFormatter } from "@/shared/utils/currency";
@@ -31,7 +31,7 @@ const chartConfig = {
},
};
type PagadorHistoryCardProps = {
type PayerHistoryCardProps = {
data: PayerHistoryPoint[];
};
@@ -57,7 +57,7 @@ const ValueLabel = (props: LabelProps) => {
);
};
export function PayerHistoryCard({ data }: PagadorHistoryCardProps) {
export function PayerHistoryCard({ data }: PayerHistoryCardProps) {
const hasData = data.length > 0;
return (

View File

@@ -17,7 +17,7 @@ type PayerInfoCardProps = {
payer: PayerInfo;
};
export function PagadorInfoCard({ payer }: PayerInfoCardProps) {
export function PayerInfoCard({ payer }: PayerInfoCardProps) {
const showSensitiveDetails = payer.canEdit;
const getStatusBadgeVariant = (status: string): "success" | "outline" => {

View File

@@ -14,7 +14,7 @@ import {
} from "@/shared/components/ui/card";
import { formatDateTime } from "@/shared/utils/date";
interface PagadorLeaveShareCardProps {
interface PayerLeaveShareCardProps {
shareId: string;
pagadorName: string;
createdAt: string;
@@ -24,7 +24,7 @@ export function PayerLeaveShareCard({
shareId,
pagadorName,
createdAt,
}: PagadorLeaveShareCardProps) {
}: PayerLeaveShareCardProps) {
const router = useRouter();
const [isPending, startTransition] = useTransition();
const [showConfirm, setShowConfirm] = useState(false);

View File

@@ -24,7 +24,7 @@ const segmentConfig = {
},
} as const;
type PagadorMonthlySummaryCardProps = {
type PayerMonthlySummaryCardProps = {
periodLabel: string;
breakdown: PayerMonthlyBreakdown;
};
@@ -32,7 +32,7 @@ type PagadorMonthlySummaryCardProps = {
export function PayerMonthlySummaryCard({
periodLabel,
breakdown,
}: PagadorMonthlySummaryCardProps) {
}: PayerMonthlySummaryCardProps) {
const splittableEntries = (
Object.keys(segmentConfig) as Array<keyof typeof segmentConfig>
).map((key) => ({

View File

@@ -10,7 +10,7 @@ import MoneyValues from "@/shared/components/money-values";
import { CardContent } from "@/shared/components/ui/card";
import { Progress } from "@/shared/components/ui/progress";
import { Separator } from "@/shared/components/ui/separator";
import { WidgetEmptyState } from "@/shared/components/widget-empty-state";
import { WidgetEmptyState } from "@/shared/components/widgets/widget-empty-state";
import type {
PayerBoletoItem,
PayerPaymentStatusData,
@@ -19,11 +19,11 @@ import { cn } from "@/shared/utils/ui";
// --- PayerBoletoCard ---
type PagadorBoletoCardProps = {
type PayerBoletoCardProps = {
items: PayerBoletoItem[];
};
export function PayerBoletoCard({ items }: PagadorBoletoCardProps) {
export function PayerBoletoCard({ items }: PayerBoletoCardProps) {
if (items.length === 0) {
return (
<CardContent className="px-0">
@@ -72,13 +72,11 @@ export function PayerBoletoCard({ items }: PagadorBoletoCardProps) {
// --- PayerPaymentStatusCard ---
type PagadorPaymentStatusCardProps = {
type PayerPaymentStatusCardProps = {
data: PayerPaymentStatusData;
};
export function PayerPaymentStatusCard({
data,
}: PagadorPaymentStatusCardProps) {
export function PayerPaymentStatusCard({ data }: PayerPaymentStatusCardProps) {
const { paidAmount, paidCount, pendingAmount, pendingCount, totalAmount } =
data;

View File

@@ -16,7 +16,7 @@ import {
CardTitle,
} from "@/shared/components/ui/card";
type PagadorShare = {
type PayerShare = {
id: string;
userId: string;
name: string;
@@ -24,17 +24,17 @@ type PagadorShare = {
createdAt: string;
};
interface PagadorSharingCardProps {
interface PayerSharingCardProps {
payerId: string;
shareCode: string;
shares: PagadorShare[];
shares: PayerShare[];
}
export function PayerSharingCard({
payerId,
shareCode,
shares,
}: PagadorSharingCardProps) {
}: PayerSharingCardProps) {
const router = useRouter();
const [currentCode, setCurrentCode] = useState(shareCode);
const [regeneratePending, startRegenerate] = useTransition();

View File

@@ -1,6 +1,6 @@
"use client";
import StatusDot from "@/shared/components/status-dot";
import StatusDot from "@/shared/components/feedback/status-dot";
export function StatusSelectContent({ label }: { label: string }) {
const isActive = label === "Ativo";

View File

@@ -5,7 +5,7 @@ import type {
TransactionFilterOption,
TransactionItem,
} from "@/features/transactions/components/types";
import type { buildOptionSets } from "@/features/transactions/page-helpers";
import type { buildOptionSets } from "@/features/transactions/lib/page-helpers";
type OptionSet = ReturnType<typeof buildOptionSets>;

View File

@@ -9,8 +9,8 @@ import { getUser } from "@/shared/lib/auth/server";
import { db } from "@/shared/lib/db";
import { getResendFromEmail } from "@/shared/lib/email/resend";
import {
fetchPagadorBoletoStats,
fetchPagadorCardUsage,
fetchPayerBoletoStats,
fetchPayerCardUsage,
fetchPayerHistory,
fetchPayerMonthlyBreakdown,
} from "@/shared/lib/payers/details";
@@ -50,7 +50,7 @@ const escapeHtml = (text: string | null | undefined): string => {
.replace(/'/g, "&#039;");
};
type LancamentoRow = {
type TransactionRow = {
id: string;
name: string | null;
paymentMethod: string | null;
@@ -80,10 +80,10 @@ type SummaryPayload = {
periodLabel: string;
monthlyBreakdown: Awaited<ReturnType<typeof fetchPayerMonthlyBreakdown>>;
historyData: Awaited<ReturnType<typeof fetchPayerHistory>>;
cardUsage: Awaited<ReturnType<typeof fetchPagadorCardUsage>>;
boletoStats: Awaited<ReturnType<typeof fetchPagadorBoletoStats>>;
cardUsage: Awaited<ReturnType<typeof fetchPayerCardUsage>>;
boletoStats: Awaited<ReturnType<typeof fetchPayerBoletoStats>>;
boletos: BoletoItem[];
transactions: LancamentoRow[];
transactions: TransactionRow[];
parcelados: ParceladoItem[];
};
@@ -445,12 +445,12 @@ export async function sendPayerSummaryAction(
payerId,
period,
}),
fetchPagadorCardUsage({
fetchPayerCardUsage({
userId: user.id,
payerId,
period,
}),
fetchPagadorBoletoStats({
fetchPayerBoletoStats({
userId: user.id,
payerId,
period,
@@ -523,7 +523,7 @@ export async function sendPayerSummaryAction(
dueDate: row.dueDate,
}));
const normalizedLancamentos: LancamentoRow[] = (
const normalizedLancamentos: TransactionRow[] = (
transactionRows as Array<{
id: string;
name: string | null;

View File

@@ -11,7 +11,7 @@ import {
} from "@/db/schema";
import { db } from "@/shared/lib/db";
export type ShareData = {
type ShareData = {
id: string;
userId: string;
name: string;
@@ -66,7 +66,7 @@ export async function fetchCurrentUserShare(
};
}
export async function fetchPagadorLancamentos(filters: SQL[]) {
export async function fetchPayerTransactions(filters: SQL[]) {
const transactionRows = await db
.select({
transaction: transactions,

View File

@@ -1,7 +1,7 @@
"use client";
import { RiPieChartLine } from "@remixicon/react";
import type { CardDetailData } from "@/features/reports/cards-report-queries";
import type { CardDetailData } from "@/features/reports/lib/cards-report-queries";
import { CategoryIconBadge } from "@/shared/components/entity-avatar";
import MoneyValues from "@/shared/components/money-values";
import {
@@ -11,7 +11,7 @@ import {
CardTitle,
} from "@/shared/components/ui/card";
import { Progress } from "@/shared/components/ui/progress";
import { WidgetEmptyState } from "@/shared/components/widget-empty-state";
import { WidgetEmptyState } from "@/shared/components/widgets/widget-empty-state";
type CardCategoryBreakdownProps = {
data: CardDetailData["categoryBreakdown"];

View File

@@ -1,7 +1,7 @@
"use client";
import { RiCalendarCheckLine } from "@remixicon/react";
import type { CardDetailData } from "@/features/reports/cards-report-queries";
import type { CardDetailData } from "@/features/reports/lib/cards-report-queries";
import {
Card,
CardContent,

View File

@@ -1,7 +1,7 @@
"use client";
import { RiShoppingBag3Line } from "@remixicon/react";
import type { CardDetailData } from "@/features/reports/cards-report-queries";
import type { CardDetailData } from "@/features/reports/lib/cards-report-queries";
import MoneyValues from "@/shared/components/money-values";
import { Badge } from "@/shared/components/ui/badge";
import {
@@ -11,7 +11,7 @@ import {
CardTitle,
} from "@/shared/components/ui/card";
import { Progress } from "@/shared/components/ui/progress";
import { WidgetEmptyState } from "@/shared/components/widget-empty-state";
import { WidgetEmptyState } from "@/shared/components/widgets/widget-empty-state";
type CardTopExpensesProps = {
data: CardDetailData["topExpenses"];

Some files were not shown because too many files have changed in this diff Show More