style(notes): polimento visual nas tarefas e modal de detalhes

Ícone de tarefa concluída em card e detalhes simplificado para
RiCheckLine verde sem caixa. Checkbox no modal de edição usa bg/border
success com texto success-foreground (claro no light, escuro no dark).
Footer do modal de detalhes reordenado: Cancelar à esquerda, Alterar
primário à direita.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Felipe Coutinho
2026-04-20 19:23:36 +00:00
parent c41fafc319
commit cbc17c8513
22 changed files with 52 additions and 66 deletions

View File

@@ -227,12 +227,12 @@ export function AccountDialog({
});
};
const title = mode === "create" ? "Nova conta" : "Editar conta";
const title = mode === "create" ? "Nova conta" : "Atualizar conta";
const description =
mode === "create"
? "Cadastre uma nova conta para organizar seus lançamentos."
: "Atualize as informações da conta selecionada.";
const submitLabel = mode === "create" ? "Salvar conta" : "Atualizar conta";
const submitLabel = mode === "create" ? "Salvar" : "Atualizar";
const handleMainDialogOpenChange = (open: boolean) => {
if (!open && logoDialogOpen) {

View File

@@ -212,7 +212,7 @@ export function AccountsPage({
onOpenChange={handleRemoveOpenChange}
title={removeTitle}
description="Ao remover esta conta, todos os dados relacionados a ela serão perdidos."
confirmLabel="Remover conta"
confirmLabel="Remover"
pendingLabel="Removendo..."
confirmVariant="destructive"
onConfirm={handleRemoveConfirm}

View File

@@ -161,13 +161,12 @@ export function BudgetDialog({
});
};
const title = mode === "create" ? "Novo orçamento" : "Editar orçamento";
const title = mode === "create" ? "Novo orçamento" : "Atualizar orçamento";
const description =
mode === "create"
? "Defina um limite de gastos para acompanhar suas despesas."
: "Atualize os detalhes do orçamento selecionado.";
const submitLabel =
mode === "create" ? "Salvar orçamento" : "Atualizar orçamento";
const submitLabel = mode === "create" ? "Salvar" : "Atualizar";
const disabled = categories.length === 0;
const parsedAmount = Number.parseFloat(formState.amount);
const sliderValue = Number.isFinite(parsedAmount)

View File

@@ -165,7 +165,7 @@ export function BudgetsPage({
onOpenChange={handleRemoveOpenChange}
title={removeTitle}
description="Esta ação remove o limite configurado para a categoria selecionada."
confirmLabel="Remover orçamento"
confirmLabel="Remover"
pendingLabel="Removendo..."
confirmVariant="destructive"
onConfirm={handleRemoveConfirm}
@@ -176,7 +176,7 @@ export function BudgetsPage({
onOpenChange={setDuplicateOpen}
title="Copiar orçamentos do último mês?"
description="Isso copiará os limites definidos no mês anterior para as categorias que ainda não possuem orçamento neste mês."
confirmLabel="Copiar orçamentos"
confirmLabel="Copiar"
pendingLabel="Copiando..."
onConfirm={handleDuplicateConfirm}
/>

View File

@@ -194,12 +194,12 @@ export function CardDialog({
});
};
const title = mode === "create" ? "Novo cartão" : "Editar cartão";
const title = mode === "create" ? "Novo cartão" : "Atualizar cartão";
const description =
mode === "create"
? "Inclua um novo cartão de crédito para acompanhar seus gastos."
: "Atualize as informações do cartão selecionado.";
const submitLabel = mode === "create" ? "Salvar cartão" : "Atualizar cartão";
const submitLabel = mode === "create" ? "Salvar" : "Atualizar";
const handleMainDialogOpenChange = (open: boolean) => {
if (!open && logoDialogOpen) {

View File

@@ -201,7 +201,7 @@ export function CardsPage({
onOpenChange={handleRemoveOpenChange}
title={removeTitle}
description="Ao remover este cartão, os registros relacionados a ele serão excluídos permanentemente."
confirmLabel="Remover cartão"
confirmLabel="Remover"
pendingLabel="Removendo..."
confirmVariant="destructive"
onConfirm={handleRemoveConfirm}

View File

@@ -11,6 +11,7 @@ import { useMemo, useState } from "react";
import { toast } from "sonner";
import { deleteCategoryAction } from "@/features/categories/actions";
import { ConfirmActionDialog } from "@/shared/components/confirm-action-dialog";
import { CategoryIconBadge } from "@/shared/components/entity-avatar";
import { Button } from "@/shared/components/ui/button";
import { Card, CardContent } from "@/shared/components/ui/card";
import {
@@ -32,7 +33,6 @@ import {
CATEGORY_TYPES,
type CategoryType,
} from "@/shared/lib/categories/constants";
import { CategoryIconBadge } from "@/shared/components/entity-avatar";
import { CategoryDialog } from "./category-dialog";
import type { Category } from "./types";
@@ -250,7 +250,7 @@ export function CategoriesPage({ categories }: CategoriesPageProps) {
onOpenChange={handleRemoveOpenChange}
title={removeTitle}
description="Ao remover esta categoria, os lançamentos associados serão desrelacionados."
confirmLabel="Remover categoria"
confirmLabel="Remover"
pendingLabel="Removendo..."
confirmVariant="destructive"
onConfirm={handleRemoveConfirm}

View File

@@ -136,13 +136,12 @@ export function CategoryDialog({
});
};
const title = mode === "create" ? "Nova categoria" : "Editar categoria";
const title = mode === "create" ? "Nova categoria" : "Atualizar categoria";
const description =
mode === "create"
? "Crie uma categoria para organizar seus lançamentos."
: "Atualize os detalhes da categoria selecionada.";
const submitLabel =
mode === "create" ? "Salvar categoria" : "Atualizar categoria";
const submitLabel = mode === "create" ? "Salvar" : "Atualizar";
return (
<Dialog open={dialogOpen} onOpenChange={setDialogOpen}>

View File

@@ -171,7 +171,7 @@ export function BillPaymentDialog({
Processando...
</>
) : (
"Confirmar pagamento"
"Confirmar"
)}
</Button>
</DialogFooter>

View File

@@ -59,7 +59,7 @@ export function GoalProgressItem({
size="icon-sm"
className="transition-opacity text-primary hover:opacity-80"
onClick={() => onEdit(item)}
aria-label={`Editar orçamento de ${item.categoryName}`}
aria-label={`Atualizar orçamento de ${item.categoryName}`}
>
<RiPencilLine className="size-3.5" />
</Button>

View File

@@ -193,7 +193,7 @@ export function InvoicePaymentDialog({
Processando...
</>
) : (
"Confirmar pagamento"
"Confirmar"
)}
</Button>
</DialogFooter>

View File

@@ -38,12 +38,12 @@ export function EditPaymentDateDialog({
<DialogTrigger asChild>{trigger}</DialogTrigger>
<DialogContent className="sm:max-w-md">
<DialogHeader>
<DialogTitle>Editar data de pagamento</DialogTitle>
<DialogTitle>Atualizar data de pagamento</DialogTitle>
<DialogDescription>
Selecione a data em que o pagamento foi realizado.
</DialogDescription>
</DialogHeader>
<div className="space-y-4 py-4">
<div className="space-y-4">
<div className="space-y-2">
<Label htmlFor="payment-date">Data de pagamento</Label>
<DatePicker

View File

@@ -97,15 +97,11 @@ export function NoteCard({
<div className="min-h-0 flex-1 space-y-2 overflow-hidden">
{sortedTasks.slice(0, 5).map((task) => (
<div key={task.id} className="flex items-start gap-2 text-sm">
<div
className={`mt-0.5 flex h-4 w-4 shrink-0 items-center justify-center rounded-sm border ${
task.completed
? "bg-success border-success"
: "border-input"
}`}
>
{task.completed && (
<RiCheckLine className="h-3 w-3 text-background" />
<div className="mt-0.5 flex h-4 w-4 shrink-0 items-center justify-center">
{task.completed ? (
<RiCheckLine className="h-4 w-4 text-success" />
) : (
<div className="h-4 w-4 rounded-sm border border-input" />
)}
</div>
<span

View File

@@ -65,15 +65,11 @@ export function NoteDetailsDialog({
key={task.id}
className="flex items-center gap-3 rounded-md px-3 py-1.5"
>
<div
className={`flex h-4 w-4 shrink-0 items-center justify-center rounded-sm border ${
task.completed
? "bg-success border-success"
: "border-input"
}`}
>
{task.completed && (
<RiCheckLine className="h-4 w-4 text-primary-foreground" />
<div className="flex h-4 w-4 shrink-0 items-center justify-center">
{task.completed ? (
<RiCheckLine className="h-4 w-4 text-success" />
) : (
<div className="h-4 w-4 rounded-sm border border-input" />
)}
</div>
<span
@@ -95,23 +91,22 @@ export function NoteDetailsDialog({
)}
<DialogFooter>
<DialogClose asChild>
<Button type="button" variant="outline">
Cancelar
</Button>
</DialogClose>
{onEdit && (
<Button
type="button"
variant="outline"
onClick={() => {
onOpenChange(false);
onEdit(note);
}}
>
Editar
Alterar
</Button>
)}
<DialogClose asChild>
<Button type="button" variant="outline">
Fechar
</Button>
</DialogClose>
</DialogFooter>
</DialogContent>
</Dialog>

View File

@@ -94,13 +94,14 @@ export function NoteDialog({
}
}, [dialogOpen, note, resetForm]);
const dialogTitle = mode === "create" ? "Nova anotação" : "Editar anotação";
const dialogTitle =
mode === "create" ? "Nova anotação" : "Atualizar anotação";
const description =
mode === "create"
? "Crie uma nota simples ou uma lista de tarefas."
: note?.type === "tarefa"
? "Editando lista de tarefas."
: "Editando nota.";
? "Atualize sua lista de tarefas"
: "Atualize sua nota";
const submitLabel = mode === "create" ? "Salvar" : "Atualizar";
const titleCount = formState.title.length;
@@ -361,7 +362,6 @@ export function NoteDialog({
className="shrink-0 gap-1.5"
>
<RiAddCircleFill className="h-4 w-4" />
Adicionar
</Button>
</div>
</div>
@@ -374,7 +374,7 @@ export function NoteDialog({
className="flex items-center gap-3 rounded-md px-3 py-1.5 hover:bg-muted/50"
>
<Checkbox
className="data-[state=checked]:bg-success data-[state=checked]:border-success"
className="data-[state=checked]:bg-success! data-[state=checked]:border-success! data-[state=checked]:text-success-foreground!"
checked={task.completed}
onCheckedChange={() => handleToggleTask(task.id)}
disabled={isPending}

View File

@@ -216,12 +216,12 @@ export function PayerDialog({
});
};
const title = mode === "create" ? "Nova pessoa" : "Editar pessoa";
const title = mode === "create" ? "Nova pessoa" : "Atualizar pessoa";
const description =
mode === "create"
? "Selecione um avatar e informe os detalhes para criar uma nova pessoa."
: "Atualize os detalhes da pessoa selecionada.";
const submitLabel = mode === "create" ? "Salvar pessoa" : "Atualizar pessoa";
const submitLabel = mode === "create" ? "Salvar" : "Atualizar";
const isUploadSelected =
uploadedAvatar !== null && formState.avatarUrl === uploadedAvatar;

View File

@@ -151,8 +151,8 @@ export function PayersPage({ payers, avatarOptions }: PayersPageProps) {
{orderedPayers.length === 0 ? (
<div className="flex min-h-[320px] items-center justify-center rounded-lg border border-dashed bg-muted/30">
<div className="max-w-sm text-center text-sm text-muted-foreground">
Cadastre seu primeira pessoa para organizar cobranças e
pagamentos recorrentes.
Cadastre seu primeira pessoa para organizar cobranças e pagamentos
recorrentes.
</div>
</div>
) : (
@@ -186,7 +186,7 @@ export function PayersPage({ payers, avatarOptions }: PayersPageProps) {
onOpenChange={handleRemoveOpenChange}
title={removeTitle}
description="Ao remover esta pessoa, os registros relacionados a ele deixarão de ser associados automaticamente."
confirmLabel="Remover pessoa"
confirmLabel="Remover"
pendingLabel="Removendo..."
confirmVariant="destructive"
onConfirm={handleRemoveConfirm}

View File

@@ -642,7 +642,7 @@ export function MassAddDialog({
</Button>
<Button onClick={handleSubmit} disabled={loading}>
{loading && <Spinner className="size-4" />}
Criar {transactions.length}{" "}
Salvar {transactions.length}{" "}
{transactions.length === 1 ? "lançamento" : "lançamentos"}
</Button>
</DialogFooter>

View File

@@ -242,7 +242,7 @@ export function TransactionDetailsDialog({
</Button>
</DialogClose>
{onEdit && !transaction.readonly && (
<Button onClick={handleEdit}>Editar</Button>
<Button onClick={handleEdit}>Alterar</Button>
)}
</DialogFooter>
</DialogContent>

View File

@@ -229,8 +229,7 @@ export function TransactionDialog({
}
if (formState.isSplit && !formState.payerId) {
const message =
"Selecione a pessoa principal para dividir o lançamento.";
const message = "Selecione a pessoa principal para dividir o lançamento.";
setErrorMessage(message);
toast.error(message);
return;
@@ -460,7 +459,7 @@ export function TransactionDialog({
? "Nova Despesa"
: "Nova Receita"
: "Novo lançamento"
: "Editar lançamento";
: "Atualizar lançamento";
const description =
mode === "create"
? isImportMode
@@ -471,7 +470,7 @@ export function TransactionDialog({
? `Informe os dados abaixo para registrar ${defaultTransactionType === "Despesa" ? "uma nova despesa" : "uma nova receita"}.`
: "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";
const submitLabel = mode === "create" ? "Salvar" : "Atualizar";
const showInstallments = formState.condition === "Parcelado";
const showRecurrence = formState.condition === "Recorrente";