@@ -434,7 +434,7 @@ export function NoteDialog({
className="h-8 w-8 p-0 shrink-0 text-muted-foreground hover:text-destructive"
aria-label={`Remover tarefa "${task.text}"`}
>
-
@@ -169,17 +169,17 @@ export function InstallmentExpensesWidget({
- Restantes {remainingInstallments} - {endDate && ` - Termina em ${endDate}`} - {" - Restante "} +
+ {endDate && `Termina em ${endDate}`}
+ {` - Restante (${remainingInstallments}) `}
diff --git a/components/dashboard/recent-transactions-widget.tsx b/components/dashboard/recent-transactions-widget.tsx index fdcc193..f251b74 100644 --- a/components/dashboard/recent-transactions-widget.tsx +++ b/components/dashboard/recent-transactions-widget.tsx @@ -1,37 +1,13 @@ +import { EstabelecimentoLogo } from "@/components/lancamentos/shared/estabelecimento-logo"; import MoneyValues from "@/components/money-values"; import type { RecentTransactionsData } from "@/lib/dashboard/recent-transactions"; import { RiExchangeLine } from "@remixicon/react"; -import Image from "next/image"; import { WidgetEmptyState } from "../widget-empty-state"; type RecentTransactionsWidgetProps = { data: RecentTransactionsData; }; -const resolveLogoPath = (logo: string | null) => { - if (!logo) { - return null; - } - if (/^(https?:\/\/|data:)/.test(logo)) { - return logo; - } - return logo.startsWith("/") ? logo : `/logos/${logo}`; -}; - -const buildInitials = (value: string) => { - const parts = value.trim().split(/\s+/).filter(Boolean); - if (parts.length === 0) { - return "LC"; - } - if (parts.length === 1) { - const firstPart = parts[0]; - return firstPart ? firstPart.slice(0, 2).toUpperCase() : "LC"; - } - const firstChar = parts[0]?.[0] ?? ""; - const secondChar = parts[1]?.[0] ?? ""; - return `${firstChar}${secondChar}`.toUpperCase() || "LC"; -}; - const formatTransactionDate = (date: Date) => { const formatter = new Intl.DateTimeFormat("pt-BR", { weekday: "short", @@ -59,32 +35,13 @@ export function RecentTransactionsWidget({ ) : (
diff --git a/components/dashboard/recurring-expenses-widget.tsx b/components/dashboard/recurring-expenses-widget.tsx index 6b2b66a..5fb3218 100644 --- a/components/dashboard/recurring-expenses-widget.tsx +++ b/components/dashboard/recurring-expenses-widget.tsx @@ -1,3 +1,4 @@ +import { EstabelecimentoLogo } from "@/components/lancamentos/shared/estabelecimento-logo"; import MoneyValues from "@/components/money-values"; import { CardContent } from "@/components/ui/card"; import type { RecurringExpensesData } from "@/lib/dashboard/expenses/recurring-expenses"; @@ -38,9 +39,7 @@ export function RecurringExpensesWidget({ key={expense.id} className="flex items-start gap-3 border-b border-dashed pb-2 last:border-b-0 last:pb-0" > -
diff --git a/components/dashboard/top-expenses-widget.tsx b/components/dashboard/top-expenses-widget.tsx index 1d8f4f6..0d9b603 100644 --- a/components/dashboard/top-expenses-widget.tsx +++ b/components/dashboard/top-expenses-widget.tsx @@ -1,10 +1,13 @@ "use client"; +import { EstabelecimentoLogo } from "@/components/lancamentos/shared/estabelecimento-logo"; import MoneyValues from "@/components/money-values"; import { Switch } from "@/components/ui/switch"; -import type { TopExpense, TopExpensesData } from "@/lib/dashboard/expenses/top-expenses"; +import type { + TopExpense, + TopExpensesData, +} from "@/lib/dashboard/expenses/top-expenses"; import { RiArrowUpDoubleLine } from "@remixicon/react"; -import Image from "next/image"; import { useMemo, useState } from "react"; import { WidgetEmptyState } from "../widget-empty-state"; @@ -13,30 +16,6 @@ type TopExpensesWidgetProps = { cardOnlyExpenses: TopExpensesData; }; -const resolveLogoPath = (logo: string | null) => { - if (!logo) { - return null; - } - if (/^(https?:\/\/|data:)/.test(logo)) { - return logo; - } - return logo.startsWith("/") ? logo : `/logos/${logo}`; -}; - -const buildInitials = (value: string) => { - const parts = value.trim().split(/\s+/).filter(Boolean); - if (parts.length === 0) { - return "LC"; - } - if (parts.length === 1) { - const firstPart = parts[0]; - return firstPart ? firstPart.slice(0, 2).toUpperCase() : "LC"; - } - const firstChar = parts[0]?.[0] ?? ""; - const secondChar = parts[1]?.[0] ?? ""; - return `${firstChar}${secondChar}`.toUpperCase() || "LC"; -}; - const formatTransactionDate = (date: Date) => { const formatter = new Intl.DateTimeFormat("pt-BR", { weekday: "short", @@ -129,30 +108,13 @@ export function TopExpensesWidget({ ) : (
diff --git a/components/lancamentos/dialogs/lancamento-dialog/lancamento-dialog.tsx b/components/lancamentos/dialogs/lancamento-dialog/lancamento-dialog.tsx
index 9d4ef79..b7e008d 100644
--- a/components/lancamentos/dialogs/lancamento-dialog/lancamento-dialog.tsx
+++ b/components/lancamentos/dialogs/lancamento-dialog/lancamento-dialog.tsx
@@ -306,10 +306,17 @@ export function LancamentoDialog({
]
);
- const title = mode === "create" ? "Novo lançamento" : "Editar lançamento";
+ const isCopyMode = mode === "create" && Boolean(lancamento);
+ const title = mode === "create"
+ ? isCopyMode
+ ? "Copiar lançamento"
+ : "Novo lançamento"
+ : "Editar lançamento";
const description =
mode === "create"
- ? "Informe os dados abaixo para registrar um novo lançamento."
+ ? isCopyMode
+ ? "Os dados do lançamento foram copiados. Revise e ajuste conforme necessário antes de salvar."
+ : "Informe os dados abaixo para registrar um novo lançamento."
: "Atualize as informações do lançamento selecionado.";
const submitLabel = mode === "create" ? "Salvar lançamento" : "Atualizar";
diff --git a/components/lancamentos/page/lancamentos-page.tsx b/components/lancamentos/page/lancamentos-page.tsx
index 81781bc..2b9b7ab 100644
--- a/components/lancamentos/page/lancamentos-page.tsx
+++ b/components/lancamentos/page/lancamentos-page.tsx
@@ -69,6 +69,9 @@ export function LancamentosPage({
useState
- {formatCurrency(summary.totalExpenses)} em despesas - registradas -
-- Cartões: {formatCurrency(summary.paymentSplits.card)} - - Boletos: {formatCurrency(summary.paymentSplits.boleto)} - - Pix/Débito/Dinheiro:{" "} - {formatCurrency(summary.paymentSplits.instant)} -
++ Total de Despesas +
++ {formatCurrency(summary.totalExpenses)} +
++ {summary.lancamentoCount} lançamentos +
+- {summary.cardUsage.length - ? summary.cardUsage - .map( - (item) => - `${item.name}: ${formatCurrency(item.amount)}` - ) - .join(" - ") - : "Sem lançamentos com cartão no período."} -
-- Pagos: {formatCurrency(summary.boletoStats.paidAmount)} ( - {summary.boletoStats.paidCount}) + {/* Grid de Formas de Pagamento */} +
+ {formatCurrency(summary.paymentSplits.card)}
-- Pendentes:{" "} - {formatCurrency(summary.boletoStats.pendingAmount)} ( - {summary.boletoStats.pendingCount}) +
+ {formatCurrency(summary.paymentSplits.boleto)} +
++ {formatCurrency(summary.paymentSplits.instant)}
Pagos
++ {formatCurrency(summary.boletoStats.paidAmount)}{" "} + + ({summary.boletoStats.paidCount}) + +
++ Pendentes +
++ {formatCurrency(summary.boletoStats.pendingAmount)}{" "} + + ({summary.boletoStats.pendingCount}) + +
+