diff --git a/CHANGELOG.md b/CHANGELOG.md index 53aa065..82b3145 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,28 @@ Todas as mudanças notáveis deste projeto serão documentadas neste arquivo. O formato é baseado em [Keep a Changelog](https://keepachangelog.com/pt-BR/1.1.0/), e este projeto adere ao [Versionamento Semântico](https://semver.org/lang/pt-BR/). +## [2.7.7] - 2026-06-20 + +Esta versão faz ajustes pontuais de leitura nos resumos financeiros e no dashboard, reforçando a identidade visual de cartões e contas e deixando as listas dos widgets mais consistentes sem alterar a estrutura de navegação das páginas. + +### Alterado +- Cartões e contas: os cabeçalhos dos resumos agora destacam melhor o logo, o nome da entidade e o período exibido. +- Dashboard: as listas dos widgets agora compartilham padrões de altura, espaçamento, alinhamento e truncamento para melhorar a leitura de valores, status e metadados. + +## [2.7.6] - 2026-06-20 + +Esta versão melhora dois fluxos importantes: a importação de planilhas fica mais esperta ao reconhecer categorias já informadas no arquivo, e lançamentos avulsos podem ser reorganizados como parcelamentos ou recorrências sem precisar recriá-los manualmente. + +As funcionalidades desta versão foram desenvolvidas originalmente por Yuri Argolo (`yurnasg`) e adaptadas para integração ao projeto principal. + +### Adicionado +- Importação: planilhas XLS/XLSX agora aceitam a coluna `Categoria` no template e tentam mapear automaticamente o valor para uma categoria existente compatível com o tipo do lançamento. +- Lançamentos: lançamentos à vista agora podem ser convertidos em recorrentes diretamente pelo menu de ações. +- Lançamentos: lançamentos à vista de cartão de crédito agora podem ser convertidos em uma série parcelada informando o total de parcelas. + +### Alterado +- Lançamentos: conversões para séries respeitam faturas pagas e limite disponível do cartão antes de criar novos movimentos. + ## [2.7.5] - 2026-06-13 Esta versão faz um polimento pontual no dashboard, deixando os widgets mais explicativos, consistentes e confiáveis quando há listas maiores ou informações complementares para revisar. diff --git a/README.md b/README.md index 916d56f..cd37c22 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ > **Não há versão online hospedada.** Você precisa clonar o repositório e rodar localmente ou no seu próprio servidor. -[![Version](https://img.shields.io/badge/version-2.7.5-blue?style=flat-square)](CHANGELOG.md) +[![Version](https://img.shields.io/badge/version-2.7.7-blue?style=flat-square)](CHANGELOG.md) [![Next.js](https://img.shields.io/badge/Next.js-black?style=flat-square&logo=next.js)](https://nextjs.org/) [![TypeScript](https://img.shields.io/badge/TypeScript-blue?style=flat-square&logo=typescript)](https://www.typescriptlang.org/) [![PostgreSQL](https://img.shields.io/badge/PostgreSQL-blue?style=flat-square&logo=postgresql)](https://www.postgresql.org/) @@ -65,11 +65,11 @@ A ideia é simples: ter um lugar onde consigo ver todas as minhas contas, cartõ ### Funcionalidades -💰 **Contas e transações** — Contas bancárias, cartões, dinheiro. Receitas, despesas, rendimentos e transferências. Categorização, divisão de lançamentos entre várias pessoas, filtros combináveis com intervalo de datas, extratos detalhados e importação de extratos OFX e XLS/XLSX com detecção automática de categoria. +💰 **Contas e transações** — Contas bancárias, cartões, dinheiro. Receitas, despesas, rendimentos e transferências. Categorização, divisão de lançamentos entre várias pessoas, filtros combináveis com intervalo de datas, extratos detalhados com identificação visual clara da conta e importação de extratos OFX e XLS/XLSX com detecção automática de categoria. -📊 **Dashboard e relatórios** — Widgets personalizáveis, métricas com atalhos para lançamentos, gráficos de evolução, comparativos por categoria, tendências, uso de cartões, top estabelecimentos e navegação direta entre meses pelo seletor de período. Exportação em PDF e Excel. +📊 **Dashboard e relatórios** — Widgets personalizáveis com listas consistentes, métricas com atalhos para lançamentos, gráficos de evolução, comparativos por categoria, tendências, uso de cartões, top estabelecimentos e navegação direta entre meses pelo seletor de período. Exportação em PDF e Excel. -💳 **Faturas de cartão** — Acompanhe faturas por período, controle limites e vencimentos. +💳 **Faturas de cartão** — Acompanhe faturas por período, controle limites e vencimentos com identificação visual mais clara do cartão. 🎯 **Orçamentos** — Defina limites por categoria e acompanhe o progresso. diff --git a/package.json b/package.json index 9c9274b..b70785b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "openmonetis", - "version": "2.7.5", + "version": "2.7.7", "private": true, "packageManager": "pnpm@11.1.3", "scripts": { diff --git a/src/features/accounts/components/account-statement-card.tsx b/src/features/accounts/components/account-statement-card.tsx index f333e80..acff7cf 100644 --- a/src/features/accounts/components/account-statement-card.tsx +++ b/src/features/accounts/components/account-statement-card.tsx @@ -1,6 +1,6 @@ "use client"; -import { RiInformationLine } from "@remixicon/react"; +import { RiBankLine, RiInformationLine } from "@remixicon/react"; import Image from "next/image"; import type { ReactNode } from "react"; import MoneyValues from "@/shared/components/money-values"; @@ -52,28 +52,32 @@ export function AccountStatementCard({ const resultado = totalIncomes - totalExpenses; return ( - +
{/* Linha 1 — identidade */} -
-
+
+
{logoPath ? (
{`Logo
- ) : null} -
-

+ ) : ( + + + + )} +
+

{accountName}

-

+

Extrato de {periodLabel}

diff --git a/src/features/dashboard/components/bills/bill-list-item.tsx b/src/features/dashboard/components/bills/bill-list-item.tsx index c1aea55..cd12154 100644 --- a/src/features/dashboard/components/bills/bill-list-item.tsx +++ b/src/features/dashboard/components/bills/bill-list-item.tsx @@ -8,6 +8,7 @@ import { isIncomeBill, } from "@/features/dashboard/bills/bills-helpers"; import type { DashboardBill } from "@/features/dashboard/bills/bills-queries"; +import { dashboardWidgetListStyles as styles } from "@/features/dashboard/components/dashboard-widget-list-styles"; import { EstablishmentLogo } from "@/shared/components/entity-avatar"; import MoneyValues from "@/shared/components/money-values"; import { Button } from "@/shared/components/ui/button"; @@ -47,18 +48,15 @@ export function BillListItem({ bill, period, onPay }: BillListItemProps) { const href = buildTransactionsHref(bill.name, period); return ( -
  • -
    +
  • +
    -
    - +
    + {bill.name} -
    +
    {statusLabel ? ( statusTooltipLabel ? ( @@ -92,10 +90,10 @@ export function BillListItem({ bill, period, onPay }: BillListItemProps) {
    -
    - +
    + {bill.isSettled ? ( - + {" "} {income ? "Recebido" : "Pago"} @@ -104,7 +102,7 @@ export function BillListItem({ bill, period, onPay }: BillListItemProps) { type="button" size="sm" variant="link" - className="-mr-1.5 h-7 px-1.5 py-0" + className={styles.actionButton} onClick={() => onPay(bill.id)} > {overdue ? ( diff --git a/src/features/dashboard/components/category-breakdown/category-breakdown-list-item.tsx b/src/features/dashboard/components/category-breakdown/category-breakdown-list-item.tsx index 4c72ebd..9ca9229 100644 --- a/src/features/dashboard/components/category-breakdown/category-breakdown-list-item.tsx +++ b/src/features/dashboard/components/category-breakdown/category-breakdown-list-item.tsx @@ -1,5 +1,6 @@ import Link from "next/link"; import type { DashboardCategoryBreakdownItem } from "@/features/dashboard/categories/category-breakdown-helpers"; +import { dashboardWidgetListStyles as styles } from "@/features/dashboard/components/dashboard-widget-list-styles"; import { PercentageChangeIndicator } from "@/features/dashboard/components/percentage-change-indicator"; import { CategoryIconBadge } from "@/shared/components/entity-avatar"; import MoneyValues from "@/shared/components/money-values"; @@ -45,25 +46,23 @@ export function CategoryBreakdownListItem({ return (
    -
    - - {position} - -
    +
    + {position} +
    -
    +
    {category.categoryName}
    -
    +
    {formatPercentage( category.percentageOfTotal, @@ -97,13 +96,13 @@ export function CategoryBreakdownListItem({
    -
    +
    {category.percentageChange !== null ? ( - + +
  • {item.categoryName} ) : ( -

    - {item.categoryName} -

    +

    {item.categoryName}

    )} -

    +

    {" "} de{" "} diff --git a/src/features/dashboard/components/invoices/invoice-list-item.tsx b/src/features/dashboard/components/invoices/invoice-list-item.tsx index 393e04a..cbb1d3b 100644 --- a/src/features/dashboard/components/invoices/invoice-list-item.tsx +++ b/src/features/dashboard/components/invoices/invoice-list-item.tsx @@ -1,5 +1,6 @@ import { RiCheckboxCircleFill, RiGroupLine } from "@remixicon/react"; import Link from "next/link"; +import { dashboardWidgetListStyles as styles } from "@/features/dashboard/components/dashboard-widget-list-styles"; import { PercentageChangeIndicator } from "@/features/dashboard/components/percentage-change-indicator"; import { buildInvoiceDetailsHref, @@ -62,18 +63,14 @@ export function InvoiceListItem({ invoice, onPay }: InvoiceListItemProps) { : null; const linkNode = ( - + {invoice.cardName} ); return ( -

  • -
    +
  • +
    -
    +
    {hasBreakdown ? ( @@ -155,7 +152,7 @@ export function InvoiceListItem({ invoice, onPay }: InvoiceListItemProps) { ) : null}
    -
    +
    {!isPaid ? ( dueTooltipLabel ? ( @@ -204,13 +201,13 @@ export function InvoiceListItem({ invoice, onPay }: InvoiceListItemProps) {
    -
    +
    {isPaid ? ( - + Pago ) : ( @@ -218,7 +215,7 @@ export function InvoiceListItem({ invoice, onPay }: InvoiceListItemProps) { type="button" size="sm" variant="link" - className="-mr-1.5 h-7 px-1.5 py-0" + className={styles.actionButton} onClick={() => onPay(invoice.id)} > {isOverdue ? ( diff --git a/src/features/dashboard/components/notes/note-list-item.tsx b/src/features/dashboard/components/notes/note-list-item.tsx index e2f954f..d7ec4d5 100644 --- a/src/features/dashboard/components/notes/note-list-item.tsx +++ b/src/features/dashboard/components/notes/note-list-item.tsx @@ -3,6 +3,7 @@ import { RiFileList2Line, RiPencilLine, } from "@remixicon/react"; +import { dashboardWidgetListStyles as styles } from "@/features/dashboard/components/dashboard-widget-list-styles"; import type { Note } from "@/features/notes/components/types"; import { buildNoteDisplayTitle, @@ -33,18 +34,16 @@ export function NoteListItem({ const isTask = note.type === "tarefa"; return ( -
  • -
    -

    - {displayTitle} -

    -
    +
  • +
    +

    {displayTitle}

    +
    {isTask ? ( {getNoteTasksSummary(note)} ) : null} -

    +

    {createdAtLabel} @@ -53,7 +52,7 @@ export function NoteListItem({

    -
    +
    + + + + Use o total de meses da série, incluindo este lançamento.

    + {recurringSummary ? ( +

    + Resumo: este lançamento vira a primeira recorrência e{" "} + {recurringSummary.createdCount}{" "} + {pluralize( + recurringSummary.createdCount, + "novo lançamento mensal será criado", + "novos lançamentos mensais serão criados", + )}{" "} + com valor de {recurringSummary.amount}. +

    + ) : null}
    diff --git a/src/features/transactions/components/table/transaction-actions-menu.tsx b/src/features/transactions/components/table/transaction-actions-menu.tsx index 2e14f0b..5a05b4e 100644 --- a/src/features/transactions/components/table/transaction-actions-menu.tsx +++ b/src/features/transactions/components/table/transaction-actions-menu.tsx @@ -11,6 +11,7 @@ import { RiRefundLine, RiTimeLine, } from "@remixicon/react"; +import { CREDIT_CARD_PAYMENT_METHOD } from "@/features/transactions/lib/constants"; import { Button } from "@/shared/components/ui/button"; import { DropdownMenu, @@ -20,8 +21,6 @@ import { DropdownMenuTrigger, } from "@/shared/components/ui/dropdown-menu"; import { REFUND_NOTE_PREFIX } from "@/shared/lib/accounts/constants"; -import { CREDIT_CARD_PAYMENT_METHOD } from "@/features/transactions/lib/constants"; -import { detectInstallmentFromName } from "@/features/transactions/lib/installment-detection"; import { getConditionIcon } from "@/shared/utils/icons"; import type { TransactionItem } from "../types"; @@ -66,7 +65,6 @@ export function TransactionActionsMenu({ const showInstallmentActions = isOwnData && item.condition === "Parcelado" && item.seriesId; - const detectedInstallment = detectInstallmentFromName(item.name); const canConvertToInstallment = isOwnData && item.paymentMethod === CREDIT_CARD_PAYMENT_METHOD && @@ -74,7 +72,6 @@ export function TransactionActionsMenu({ !item.splitGroupId && !item.isDivided && !item.readonly && - Boolean(detectedInstallment) && Boolean(onConvertToInstallment); const canConvertToRecurring = @@ -140,18 +137,14 @@ export function TransactionActionsMenu({ ) : null} {canConvertToInstallment ? ( - onConvertToInstallment?.(item)} - > + onConvertToInstallment?.(item)}> {getConditionIcon("Parcelado")} Converter em Parcelamento ) : null} {canConvertToRecurring ? ( - onConvertToRecurring?.(item)} - > + onConvertToRecurring?.(item)}> {getConditionIcon("Recorrente")} Converter em Recorrente diff --git a/src/features/transactions/components/table/transactions-columns.tsx b/src/features/transactions/components/table/transactions-columns.tsx index 917c463..ac8a633 100644 --- a/src/features/transactions/components/table/transactions-columns.tsx +++ b/src/features/transactions/components/table/transactions-columns.tsx @@ -551,8 +551,12 @@ function buildColumns({ onRefund={handleRefund} onAnticipate={handleAnticipate} onViewAnticipationHistory={handleViewAnticipationHistory} - onConvertToInstallment={onConvertToInstallment ? handleConvertToInstallment : undefined} - onConvertToRecurring={onConvertToRecurring ? handleConvertToRecurring : undefined} + onConvertToInstallment={ + onConvertToInstallment ? handleConvertToInstallment : undefined + } + onConvertToRecurring={ + onConvertToRecurring ? handleConvertToRecurring : undefined + } />
    ),