mirror of
https://github.com/felipegcoutinho/openmonetis.git
synced 2026-05-09 11:01:45 +00:00
Padroniza copias e badges da interface
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
"use client";
|
||||
|
||||
import { RiAddCircleLine, RiBankLine } from "@remixicon/react";
|
||||
import { RiAddCircleFill, RiBankLine } from "@remixicon/react";
|
||||
import Image from "next/image";
|
||||
import { useRouter } from "next/navigation";
|
||||
import { useState } from "react";
|
||||
@@ -176,7 +176,7 @@ export function AccountsPage({
|
||||
logoOptions={logoOptions}
|
||||
trigger={
|
||||
<Button className="w-full sm:w-auto">
|
||||
<RiAddCircleLine className="size-4" />
|
||||
<RiAddCircleFill className="size-4" />
|
||||
Nova conta
|
||||
</Button>
|
||||
}
|
||||
|
||||
@@ -207,7 +207,7 @@ export function BudgetDialog({
|
||||
) : (
|
||||
<form className="space-y-4" onSubmit={handleSubmit}>
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="budget-category">Category</Label>
|
||||
<Label htmlFor="budget-category">Categoria</Label>
|
||||
<Select
|
||||
value={formState.categoryId}
|
||||
onValueChange={(value) => updateField("categoryId", value)}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
"use client";
|
||||
|
||||
import { RiAddCircleLine, RiFileCopyLine, RiFundsLine } from "@remixicon/react";
|
||||
import { RiAddCircleFill, RiFileCopyLine, RiFundsLine } from "@remixicon/react";
|
||||
import { useState } from "react";
|
||||
import { toast } from "sonner";
|
||||
import {
|
||||
@@ -115,7 +115,7 @@ export function BudgetsPage({
|
||||
disabled={categories.length === 0}
|
||||
className="w-full sm:w-auto"
|
||||
>
|
||||
<RiAddCircleLine className="size-4" />
|
||||
<RiAddCircleFill className="size-4" />
|
||||
Novo orçamento
|
||||
</Button>
|
||||
}
|
||||
|
||||
@@ -1,11 +1,5 @@
|
||||
import { and, asc, eq, inArray, isNull, or, sql, sum } from "drizzle-orm";
|
||||
import {
|
||||
type Budget,
|
||||
budgets,
|
||||
categories,
|
||||
payers,
|
||||
transactions,
|
||||
} from "@/db/schema";
|
||||
import { budgets, categories, payers, transactions } from "@/db/schema";
|
||||
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";
|
||||
|
||||
@@ -162,7 +162,7 @@ export function DayCell({ day, onSelect, onCreate }: DayCellProps) {
|
||||
<button
|
||||
type="button"
|
||||
onClick={handleCreateClick}
|
||||
className="flex size-6 items-center justify-center rounded-full border bg-muted text-muted-foreground transition-colors hover:bg-primary/20 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary focus-visible:ring-offset-1"
|
||||
className="flex size-6 items-center justify-center rounded-full bg-muted text-muted-foreground transition-colors hover:bg-primary/20 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary focus-visible:ring-offset-1"
|
||||
aria-label={`Criar lançamento em ${day.date}`}
|
||||
>
|
||||
<RiAddLine className="size-3.5" />
|
||||
|
||||
@@ -160,7 +160,7 @@ export function CardFormFields({
|
||||
</div>
|
||||
|
||||
<div className="flex flex-col gap-2 sm:col-span-2">
|
||||
<Label htmlFor="card-account">FinancialAccount vinculada</Label>
|
||||
<Label htmlFor="card-account">Conta vinculada</Label>
|
||||
<Select
|
||||
value={values.accountId}
|
||||
onValueChange={(value) => onChange("accountId", value)}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
"use client";
|
||||
|
||||
import { RiAddCircleLine, RiBankCard2Line } from "@remixicon/react";
|
||||
import { RiAddCircleFill, RiBankCard2Line } from "@remixicon/react";
|
||||
import { useRouter } from "next/navigation";
|
||||
import { useMemo, useState } from "react";
|
||||
import { toast } from "sonner";
|
||||
@@ -164,7 +164,7 @@ export function CardsPage({
|
||||
logoOptions={logoOptions}
|
||||
trigger={
|
||||
<Button className="w-full sm:w-auto">
|
||||
<RiAddCircleLine className="size-4" />
|
||||
<RiAddCircleFill className="size-4" />
|
||||
Novo cartão
|
||||
</Button>
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
"use client";
|
||||
|
||||
import {
|
||||
RiAddCircleLine,
|
||||
RiAddCircleFill,
|
||||
RiDeleteBin5Line,
|
||||
RiExternalLinkLine,
|
||||
RiPencilLine,
|
||||
@@ -127,7 +127,7 @@ export function CategoriesPage({ categories }: CategoriesPageProps) {
|
||||
defaultType={activeType}
|
||||
trigger={
|
||||
<Button className="w-full sm:w-auto">
|
||||
<RiAddCircleLine className="size-4" />
|
||||
<RiAddCircleFill className="size-4" />
|
||||
Nova categoria
|
||||
</Button>
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { RiArrowDownSFill, RiArrowUpSFill } from "@remixicon/react";
|
||||
import { TypeBadge } from "@/shared/components/type-badge";
|
||||
import { TransactionTypeBadge } from "@/shared/components/transaction-type-badge";
|
||||
import { Card } from "@/shared/components/ui/card";
|
||||
import type { CategoryType } from "@/shared/lib/categories/constants";
|
||||
import { currencyFormatter } from "@/shared/utils/currency";
|
||||
@@ -85,7 +85,7 @@ export function CategoryDetailHeader({
|
||||
{category.name}
|
||||
</h1>
|
||||
<div className="flex flex-wrap items-center gap-2 text-sm text-muted-foreground">
|
||||
<TypeBadge type={category.type} />
|
||||
<TransactionTypeBadge kind={category.type} />
|
||||
<span>
|
||||
{transactionCount}{" "}
|
||||
{transactionCount === 1 ? "lançamento" : "lançamentos"} no{" "}
|
||||
|
||||
@@ -16,7 +16,7 @@ import {
|
||||
sortableKeyboardCoordinates,
|
||||
} from "@dnd-kit/sortable";
|
||||
import {
|
||||
RiAddCircleLine,
|
||||
RiAddCircleFill,
|
||||
RiCheckLine,
|
||||
RiCloseLine,
|
||||
RiDragMove2Line,
|
||||
@@ -198,10 +198,7 @@ export function DashboardGridEditable({
|
||||
{/* Toolbar */}
|
||||
<div className="flex flex-wrap items-center justify-between gap-2">
|
||||
{!isEditing ? (
|
||||
<div className="flex w-full min-w-0 flex-col gap-1 px-1 sm:w-auto sm:flex-row sm:items-center sm:gap-2">
|
||||
<span className="text-[11px] font-semibold uppercase tracking-wide text-muted-foreground">
|
||||
Ações rápidas
|
||||
</span>
|
||||
<div className="flex w-full min-w-0 flex-col gap-1 sm:w-auto sm:flex-row sm:items-center sm:gap-2">
|
||||
<div className="-mb-1 grid w-full grid-cols-3 gap-1 pb-1 sm:mb-0 sm:flex sm:w-auto sm:items-center sm:gap-2 sm:overflow-visible sm:pb-0">
|
||||
<TransactionDialog
|
||||
mode="create"
|
||||
@@ -221,7 +218,7 @@ export function DashboardGridEditable({
|
||||
className="h-12 w-full min-w-0 flex-col justify-center gap-0.5 px-1.5 text-sm whitespace-normal sm:h-8 sm:w-auto sm:flex-row sm:gap-2 sm:px-3 sm:whitespace-nowrap"
|
||||
>
|
||||
<span className="flex items-center gap-0.5">
|
||||
<RiAddCircleLine className="size-3.5 shrink-0 text-success/80" />
|
||||
<RiAddCircleFill className="size-3.5 shrink-0 text-success/80" />
|
||||
</span>
|
||||
<span className="sm:hidden">Receita</span>
|
||||
<span className="hidden sm:inline">Nova receita</span>
|
||||
@@ -246,7 +243,7 @@ export function DashboardGridEditable({
|
||||
className="h-12 w-full min-w-0 flex-col justify-center gap-0.5 px-1.5 text-sm whitespace-normal sm:h-8 sm:w-auto sm:flex-row sm:gap-2 sm:px-3 sm:whitespace-nowrap"
|
||||
>
|
||||
<span className="flex items-center gap-0.5">
|
||||
<RiAddCircleLine className="size-3.5 shrink-0 text-destructive/80" />
|
||||
<RiAddCircleFill className="size-3.5 shrink-0 text-destructive/80" />
|
||||
</span>
|
||||
<span className="sm:hidden">Despesa</span>
|
||||
<span className="hidden sm:inline">Nova despesa</span>
|
||||
|
||||
@@ -113,10 +113,7 @@ export async function fetchDashboardPayers(
|
||||
}))
|
||||
.sort((a, b) => b.totalExpenses - a.totalExpenses);
|
||||
|
||||
const totalExpenses = payerList.reduce(
|
||||
(sum, p) => sum + p.totalExpenses,
|
||||
0,
|
||||
);
|
||||
const totalExpenses = payerList.reduce((sum, p) => sum + p.totalExpenses, 0);
|
||||
|
||||
return {
|
||||
payers: payerList,
|
||||
|
||||
@@ -134,7 +134,7 @@ export function InsightsPage({ period, onAnalyze }: InsightsPageProps) {
|
||||
return (
|
||||
<div className="flex flex-col gap-6">
|
||||
{/* Privacy Warning */}
|
||||
<Alert className="border-none">
|
||||
<Alert className="border-none bg-primary/15">
|
||||
<RiAlertLine className="size-4" color="red" />
|
||||
<AlertDescription className="text-sm text-card-foreground">
|
||||
<strong>Aviso de privacidade:</strong> Ao gerar insights, seus dados
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
"use client";
|
||||
|
||||
import { RiAddLine, RiDeleteBinLine } from "@remixicon/react";
|
||||
import { RiAddCircleFill, RiDeleteBinLine } from "@remixicon/react";
|
||||
import {
|
||||
type ReactNode,
|
||||
useEffect,
|
||||
@@ -329,7 +329,7 @@ export function NoteDialog({
|
||||
disabled={isPending || !normalize(newTaskText)}
|
||||
className="shrink-0"
|
||||
>
|
||||
<RiAddLine className="h-4 w-4" />
|
||||
<RiAddCircleFill className="h-4 w-4" />
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
"use client";
|
||||
|
||||
import { RiAddCircleLine, RiTodoLine } from "@remixicon/react";
|
||||
import { RiAddCircleFill, RiTodoLine } from "@remixicon/react";
|
||||
import { useMemo, useState } from "react";
|
||||
import { toast } from "sonner";
|
||||
import { archiveNoteAction, deleteNoteAction } from "@/features/notes/actions";
|
||||
@@ -208,7 +208,7 @@ export function NotesPage({ notes, archivedNotes }: NotesPageProps) {
|
||||
onOpenChange={handleCreateOpenChange}
|
||||
trigger={
|
||||
<Button className="w-full sm:w-auto">
|
||||
<RiAddCircleLine className="size-4" />
|
||||
<RiAddCircleFill className="size-4" />
|
||||
Nova anotação
|
||||
</Button>
|
||||
}
|
||||
|
||||
@@ -201,7 +201,7 @@ export function PayerHeaderCard({
|
||||
{summary.periodLabel}
|
||||
</span>{" "}
|
||||
para{" "}
|
||||
<span className="font-medium text-foreground">
|
||||
<span className="font-semibold text-foreground">
|
||||
{payer.email}
|
||||
</span>
|
||||
</DialogDescription>
|
||||
|
||||
@@ -32,7 +32,7 @@ export function PagadorInfoCard({ payer }: PayerInfoCardProps) {
|
||||
<Card className="border gap-4">
|
||||
<CardHeader className="gap-1.5">
|
||||
<CardTitle className="text-lg font-semibold">
|
||||
Detalhes do payer
|
||||
Detalhes do pagador
|
||||
</CardTitle>
|
||||
<CardDescription>
|
||||
{showSensitiveDetails
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
"use client";
|
||||
|
||||
import { RiAddCircleLine } from "@remixicon/react";
|
||||
import { RiAddCircleFill } from "@remixicon/react";
|
||||
import { useRouter } from "next/navigation";
|
||||
import { useMemo, useState, useTransition } from "react";
|
||||
import { toast } from "sonner";
|
||||
@@ -126,7 +126,7 @@ export function PayersPage({ payers, avatarOptions }: PayersPageProps) {
|
||||
avatarOptions={avatarOptions}
|
||||
trigger={
|
||||
<Button className="w-full sm:w-auto">
|
||||
<RiAddCircleLine className="size-4" />
|
||||
<RiAddCircleFill className="size-4" />
|
||||
Novo pagador
|
||||
</Button>
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import type { payers } from "@/db/schema";
|
||||
import type {
|
||||
AccountCardFilterOption,
|
||||
TransactionFilterOption,
|
||||
SelectOption,
|
||||
TransactionFilterOption,
|
||||
TransactionItem,
|
||||
} from "@/features/transactions/components/types";
|
||||
import type { buildOptionSets } from "@/features/transactions/page-helpers";
|
||||
@@ -35,10 +35,7 @@ export function buildReadOnlyOptionSets(
|
||||
if (item.accountId && !contaOptionsMap.has(item.accountId)) {
|
||||
contaOptionsMap.set(item.accountId, {
|
||||
value: item.accountId,
|
||||
label: normalizeOptionLabel(
|
||||
item.contaName,
|
||||
"FinancialAccount sem nome",
|
||||
),
|
||||
label: normalizeOptionLabel(item.contaName, "Conta sem nome"),
|
||||
slug: item.accountId,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@ export function CardCategoryBreakdown({ data }: CardCategoryBreakdownProps) {
|
||||
<CardHeader className="pb-3">
|
||||
<CardTitle className="flex items-center gap-1.5 text-base">
|
||||
<RiPieChartLine className="size-4 text-primary" />
|
||||
Gastos por Category
|
||||
Gastos por Categoria
|
||||
</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
@@ -45,7 +45,7 @@ export function CardCategoryBreakdown({ data }: CardCategoryBreakdownProps) {
|
||||
<CardHeader className="pb-3">
|
||||
<CardTitle className="flex items-center gap-1.5 text-base">
|
||||
<RiPieChartLine className="size-4 text-primary" />
|
||||
Gastos por Category
|
||||
Gastos por Categoria
|
||||
</CardTitle>
|
||||
</CardHeader>
|
||||
|
||||
|
||||
@@ -150,7 +150,7 @@ export function CategoryReportChart({ data }: CategoryReportChartProps) {
|
||||
<Card className="pt-0">
|
||||
<CardHeader className="flex items-center gap-2 space-y-0 border-b py-5 sm:flex-row">
|
||||
<div className="grid flex-1 gap-1">
|
||||
<CardTitle>Evolução por Category</CardTitle>
|
||||
<CardTitle>Evolução por Categoria</CardTitle>
|
||||
<CardDescription>{periodLabel}</CardDescription>
|
||||
</div>
|
||||
<Select value={limit} onValueChange={setLimit}>
|
||||
|
||||
@@ -54,7 +54,7 @@ export function CategoryReportExport({
|
||||
|
||||
// Build CSV content
|
||||
const headers = [
|
||||
"Category",
|
||||
"Categoria",
|
||||
...data.periods.map(formatPeriodLabel),
|
||||
"Total",
|
||||
];
|
||||
@@ -129,7 +129,7 @@ export function CategoryReportExport({
|
||||
|
||||
// Build data array
|
||||
const headers = [
|
||||
"Category",
|
||||
"Categoria",
|
||||
...data.periods.map(formatPeriodLabel),
|
||||
"Total",
|
||||
];
|
||||
@@ -249,7 +249,7 @@ export function CategoryReportExport({
|
||||
|
||||
// Build table data
|
||||
const headers = [
|
||||
["Category", ...data.periods.map(formatPeriodLabel), "Total"],
|
||||
["Categoria", ...data.periods.map(formatPeriodLabel), "Total"],
|
||||
];
|
||||
const body: string[][] = [];
|
||||
|
||||
|
||||
@@ -129,7 +129,7 @@ export function CategoryReportFilters({
|
||||
|
||||
const selectedText =
|
||||
selectedCategories.length === 0
|
||||
? "Category"
|
||||
? "Categoria"
|
||||
: selectedCategories.length === categories.length
|
||||
? "Todas"
|
||||
: selectedCategories.length === 1
|
||||
|
||||
@@ -65,7 +65,7 @@ export function CategoryTable({
|
||||
<TableHeader>
|
||||
<TableRow>
|
||||
<TableHead className="w-[240px] min-w-[240px] font-bold">
|
||||
Category
|
||||
Categoria
|
||||
</TableHead>
|
||||
{periods.map((period) => (
|
||||
<TableHead
|
||||
|
||||
@@ -92,7 +92,7 @@ export function EstablishmentsList({
|
||||
.map((cat, catIndex) => (
|
||||
<Badge
|
||||
key={catIndex}
|
||||
variant="secondary"
|
||||
variant="outline"
|
||||
className="text-xs px-1.5 py-0 h-5"
|
||||
>
|
||||
{cat.name}
|
||||
|
||||
@@ -11,17 +11,15 @@ type HighlightsCardsProps = {
|
||||
export function HighlightsCards({ summary }: HighlightsCardsProps) {
|
||||
return (
|
||||
<div className="grid gap-3 sm:grid-cols-2">
|
||||
<Card className="bg-linear-to-br from-violet-50 to-violet-50/50 dark:from-violet-950/20 dark:to-violet-950/10">
|
||||
<Card className="">
|
||||
<CardContent className="p-4">
|
||||
<div className="flex items-center gap-3">
|
||||
<div className="flex items-center justify-center size-10 rounded-xl bg-violet-100 dark:bg-violet-900/40">
|
||||
<RiTrophyLine className="size-5 text-violet-600 dark:text-violet-400" />
|
||||
<div className="flex items-center justify-center size-10 rounded-md bg-primary">
|
||||
<RiTrophyLine className="size-5" />
|
||||
</div>
|
||||
<div className="min-w-0 flex-1">
|
||||
<p className="text-xs text-violet-700/80 dark:text-violet-400/80 font-medium">
|
||||
Mais Frequente
|
||||
</p>
|
||||
<p className="font-bold text-xl text-violet-900 dark:text-violet-100 truncate">
|
||||
<p className="text-xs font-bold">Mais Frequente</p>
|
||||
<p className="font-bold text-2xl truncate">
|
||||
{summary.mostFrequent || "—"}
|
||||
</p>
|
||||
</div>
|
||||
@@ -29,17 +27,15 @@ export function HighlightsCards({ summary }: HighlightsCardsProps) {
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
<Card className="bg-linear-to-br from-red-50 to-rose-50/50 dark:from-red-950/20 dark:to-rose-950/10">
|
||||
<Card className="">
|
||||
<CardContent className="p-4">
|
||||
<div className="flex items-center gap-3">
|
||||
<div className="flex items-center justify-center size-10 rounded-xl bg-red-100 dark:bg-red-900/40">
|
||||
<RiFireLine className="size-5 text-red-600 dark:text-red-400" />
|
||||
<div className="flex items-center justify-center size-10 rounded-md bg-primary">
|
||||
<RiFireLine className="size-5" />
|
||||
</div>
|
||||
<div className="min-w-0 flex-1">
|
||||
<p className="text-xs text-red-700/80 dark:text-red-400/80 font-medium">
|
||||
Maior Gasto Total
|
||||
</p>
|
||||
<p className="font-bold text-xl text-red-900 dark:text-red-100 truncate">
|
||||
<p className="text-xs font-bold">Maior Gasto Total</p>
|
||||
<p className="font-bold text-2xl truncate">
|
||||
{summary.highestSpending || "—"}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
"use client";
|
||||
|
||||
import {
|
||||
RiAddLine,
|
||||
RiAddCircleFill,
|
||||
RiAlertLine,
|
||||
RiCheckLine,
|
||||
RiDeleteBinLine,
|
||||
@@ -154,7 +154,7 @@ export function ApiTokensForm({ tokens }: ApiTokensFormProps) {
|
||||
>
|
||||
<DialogTrigger asChild>
|
||||
<Button size="sm">
|
||||
<RiAddLine className="h-4 w-4 mr-1" />
|
||||
<RiAddCircleFill className="h-4 w-4 mr-1" />
|
||||
Novo Token
|
||||
</Button>
|
||||
</DialogTrigger>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
"use client";
|
||||
|
||||
import {
|
||||
RiAddLine,
|
||||
RiAddCircleFill,
|
||||
RiAlertLine,
|
||||
RiDeleteBinLine,
|
||||
RiFingerprintLine,
|
||||
@@ -210,7 +210,7 @@ export function PasskeysForm() {
|
||||
>
|
||||
<DialogTrigger asChild>
|
||||
<Button size="sm" disabled={isMutating || !passkeySupported}>
|
||||
<RiAddLine className="h-4 w-4 mr-1" />
|
||||
<RiAddCircleFill className="h-4 w-4 mr-1" />
|
||||
Adicionar
|
||||
</Button>
|
||||
</DialogTrigger>
|
||||
|
||||
@@ -269,7 +269,7 @@ export function AnticipateInstallmentsDialog({
|
||||
</Field>
|
||||
|
||||
<Field className="gap-1">
|
||||
<FieldLabel htmlFor="anticipation-pagador">Payer</FieldLabel>
|
||||
<FieldLabel htmlFor="anticipation-pagador">Pagador</FieldLabel>
|
||||
<FieldContent>
|
||||
<Select
|
||||
value={formState.payerId}
|
||||
|
||||
@@ -24,8 +24,8 @@ import {
|
||||
SelectValue,
|
||||
} from "@/shared/components/ui/select";
|
||||
import {
|
||||
CategorySelectContent,
|
||||
AccountCardSelectContent,
|
||||
CategorySelectContent,
|
||||
PayerSelectContent,
|
||||
} from "../select-items";
|
||||
import type { SelectOption, TransactionItem } from "../types";
|
||||
@@ -203,7 +203,7 @@ export function BulkImportDialog({
|
||||
|
||||
<form className="space-y-4" onSubmit={handleSubmit}>
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="pagador">Payer *</Label>
|
||||
<Label htmlFor="pagador">Pagador *</Label>
|
||||
<Select value={payerId} onValueChange={setPagadorId}>
|
||||
<SelectTrigger id="pagador" className="w-full">
|
||||
<SelectValue placeholder="Selecione o pagador">
|
||||
@@ -235,7 +235,7 @@ export function BulkImportDialog({
|
||||
</div>
|
||||
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="categoria">Category *</Label>
|
||||
<Label htmlFor="categoria">Categoria *</Label>
|
||||
<Select value={categoryId} onValueChange={setCategoriaId}>
|
||||
<SelectTrigger id="categoria" className="w-full">
|
||||
<SelectValue placeholder="Selecione a categoria">
|
||||
@@ -274,7 +274,7 @@ export function BulkImportDialog({
|
||||
{hasNonCredit && (
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="conta">
|
||||
FinancialAccount {hasCredit ? "(para não cartão)" : "*"}
|
||||
Conta {hasCredit ? "(para não cartão)" : "*"}
|
||||
</Label>
|
||||
<Select value={accountId} onValueChange={setContaId}>
|
||||
<SelectTrigger id="conta" className="w-full">
|
||||
|
||||
@@ -44,8 +44,8 @@ import {
|
||||
periodToDate,
|
||||
} from "@/shared/utils/period";
|
||||
import {
|
||||
CategorySelectContent,
|
||||
AccountCardSelectContent,
|
||||
CategorySelectContent,
|
||||
PayerSelectContent,
|
||||
PaymentMethodSelectContent,
|
||||
TransactionTypeSelectContent,
|
||||
@@ -413,7 +413,7 @@ export function MassAddDialog({
|
||||
{/* FinancialAccount (for non-credit-card methods) */}
|
||||
{!isCartaoSelected ? (
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="conta">FinancialAccount</Label>
|
||||
<Label htmlFor="conta">Conta</Label>
|
||||
<Select value={accountId} onValueChange={setContaId}>
|
||||
<SelectTrigger id="conta" className="w-full">
|
||||
<SelectValue placeholder="Selecione">
|
||||
@@ -534,7 +534,7 @@ export function MassAddDialog({
|
||||
htmlFor={`pagador-${transaction.id}`}
|
||||
className="sr-only"
|
||||
>
|
||||
Payer {index + 1}
|
||||
Pagador {index + 1}
|
||||
</Label>
|
||||
<Select
|
||||
value={transaction.payerId}
|
||||
@@ -546,7 +546,7 @@ export function MassAddDialog({
|
||||
id={`pagador-${transaction.id}`}
|
||||
className="w-32 truncate"
|
||||
>
|
||||
<SelectValue placeholder="Payer">
|
||||
<SelectValue placeholder="Pagador">
|
||||
{transaction.payerId &&
|
||||
(() => {
|
||||
const selectedOption = payerOptions.find(
|
||||
@@ -579,7 +579,7 @@ export function MassAddDialog({
|
||||
htmlFor={`categoria-${transaction.id}`}
|
||||
className="sr-only"
|
||||
>
|
||||
Category {index + 1}
|
||||
Categoria {index + 1}
|
||||
</Label>
|
||||
<Select
|
||||
value={transaction.categoryId}
|
||||
@@ -591,7 +591,7 @@ export function MassAddDialog({
|
||||
id={`categoria-${transaction.id}`}
|
||||
className="w-32 truncate"
|
||||
>
|
||||
<SelectValue placeholder="Category" />
|
||||
<SelectValue placeholder="Categoria" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
{groupedCategorias.map((group) => (
|
||||
|
||||
@@ -5,9 +5,8 @@ import {
|
||||
formatCondition,
|
||||
formatDate,
|
||||
formatPeriod,
|
||||
getTransactionBadgeVariant,
|
||||
} from "@/features/transactions/formatting-helpers";
|
||||
import { Badge } from "@/shared/components/ui/badge";
|
||||
import { TransactionTypeBadge } from "@/shared/components/transaction-type-badge";
|
||||
import { Button } from "@/shared/components/ui/button";
|
||||
import {
|
||||
CardContent,
|
||||
@@ -93,12 +92,12 @@ export function TransactionDetailsDialog({
|
||||
</li>
|
||||
|
||||
<DetailRow
|
||||
label={transaction.cartaoName ? "Cartão" : "FinancialAccount"}
|
||||
label={transaction.cartaoName ? "Cartão" : "Conta"}
|
||||
value={transaction.cartaoName ?? transaction.contaName ?? "—"}
|
||||
/>
|
||||
|
||||
<DetailRow
|
||||
label="Category"
|
||||
label="Categoria"
|
||||
value={transaction.categoriaName ?? "—"}
|
||||
/>
|
||||
|
||||
@@ -106,19 +105,13 @@ export function TransactionDetailsDialog({
|
||||
<span className="text-muted-foreground">
|
||||
Tipo de Transação
|
||||
</span>
|
||||
<span className="capitalize">
|
||||
<Badge
|
||||
variant={getTransactionBadgeVariant(
|
||||
transaction.categoriaName === "Saldo inicial"
|
||||
? "Saldo inicial"
|
||||
: transaction.transactionType,
|
||||
)}
|
||||
>
|
||||
{transaction.categoriaName === "Saldo inicial"
|
||||
? "Saldo Inicial"
|
||||
: transaction.transactionType}
|
||||
</Badge>
|
||||
</span>
|
||||
<TransactionTypeBadge
|
||||
kind={
|
||||
transaction.categoriaName === "Saldo inicial"
|
||||
? "Saldo inicial"
|
||||
: transaction.transactionType
|
||||
}
|
||||
/>
|
||||
</li>
|
||||
|
||||
<DetailRow
|
||||
|
||||
@@ -65,7 +65,7 @@ export function CategorySection({
|
||||
showTransactionTypeField ? "md:w-1/2" : "md:w-full",
|
||||
)}
|
||||
>
|
||||
<Label htmlFor="categoria">Category</Label>
|
||||
<Label htmlFor="categoria">Categoria</Label>
|
||||
<Select
|
||||
value={formState.categoryId}
|
||||
onValueChange={(value) => onFieldChange("categoryId", value)}
|
||||
|
||||
@@ -36,7 +36,7 @@ export function PayerSection({
|
||||
return (
|
||||
<div className="flex w-full flex-col gap-2 md:flex-row">
|
||||
<div className="w-full space-y-1">
|
||||
<Label htmlFor="payer">Payer</Label>
|
||||
<Label htmlFor="payer">Pagador</Label>
|
||||
<div className="flex gap-2">
|
||||
<Select
|
||||
value={formState.payerId}
|
||||
|
||||
@@ -194,7 +194,7 @@ export function PaymentMethodSection({
|
||||
!isUpdateMode ? "md:w-1/2" : "md:w-full",
|
||||
)}
|
||||
>
|
||||
<Label htmlFor="conta">FinancialAccount</Label>
|
||||
<Label htmlFor="conta">Conta</Label>
|
||||
<Select
|
||||
value={formState.accountId}
|
||||
onValueChange={(value) => onFieldChange("accountId", value)}
|
||||
@@ -308,7 +308,7 @@ export function PaymentMethodSection({
|
||||
!isUpdateMode ? "md:w-1/2" : "md:w-full",
|
||||
)}
|
||||
>
|
||||
<Label htmlFor="contaUpdate">FinancialAccount</Label>
|
||||
<Label htmlFor="contaUpdate">Conta</Label>
|
||||
<Select
|
||||
value={formState.accountId}
|
||||
onValueChange={(value) => onFieldChange("accountId", value)}
|
||||
|
||||
@@ -134,14 +134,14 @@ export function AnticipationCard({
|
||||
|
||||
{anticipation.payer && (
|
||||
<div>
|
||||
<dt className="text-muted-foreground">Payer</dt>
|
||||
<dt className="text-muted-foreground">Pagador</dt>
|
||||
<dd className="mt-1 font-medium">{anticipation.payer.name}</dd>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{anticipation.category && (
|
||||
<div>
|
||||
<dt className="text-muted-foreground">Category</dt>
|
||||
<dt className="text-muted-foreground">Categoria</dt>
|
||||
<dd className="mt-1 font-medium">{anticipation.category.name}</dd>
|
||||
</div>
|
||||
)}
|
||||
|
||||
@@ -368,7 +368,7 @@ export function TransactionsFilters({
|
||||
</div>
|
||||
|
||||
<div className="space-y-2">
|
||||
<label className="text-sm font-medium">Payer</label>
|
||||
<label className="text-sm font-medium">Pagador</label>
|
||||
<Select
|
||||
value={getParamValue("payer")}
|
||||
onValueChange={(value) =>
|
||||
@@ -409,7 +409,7 @@ export function TransactionsFilters({
|
||||
</div>
|
||||
|
||||
<div className="space-y-2">
|
||||
<label className="text-sm font-medium">Category</label>
|
||||
<label className="text-sm font-medium">Categoria</label>
|
||||
<Popover
|
||||
open={categoryOpen}
|
||||
onOpenChange={setCategoryOpen}
|
||||
|
||||
@@ -34,7 +34,7 @@ import { CategoryIcon } from "@/features/categories/components/category-icon";
|
||||
import { DEFAULT_LANCAMENTOS_COLUMN_ORDER } from "@/features/transactions/column-order";
|
||||
import { EmptyState } from "@/shared/components/empty-state";
|
||||
import MoneyValues from "@/shared/components/money-values";
|
||||
import { TypeBadge } from "@/shared/components/type-badge";
|
||||
import { TransactionTypeBadge } from "@/shared/components/transaction-type-badge";
|
||||
import {
|
||||
Avatar,
|
||||
AvatarFallback,
|
||||
@@ -302,8 +302,8 @@ const buildColumns = ({
|
||||
: row.original.transactionType;
|
||||
|
||||
return (
|
||||
<TypeBadge
|
||||
type={
|
||||
<TransactionTypeBadge
|
||||
kind={
|
||||
type as "Despesa" | "Receita" | "Transferência" | "Saldo inicial"
|
||||
}
|
||||
/>
|
||||
@@ -458,7 +458,7 @@ const buildColumns = ({
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>{content}</TooltipTrigger>
|
||||
<TooltipContent side="top">
|
||||
{isCartao ? "Cartão" : "FinancialAccount"}: {label}
|
||||
{isCartao ? "Cartão" : "Conta"}: {label}
|
||||
</TooltipContent>
|
||||
</Tooltip>
|
||||
);
|
||||
@@ -484,7 +484,7 @@ const buildColumns = ({
|
||||
</Link>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent side="top">
|
||||
{isCartao ? "Cartão" : "FinancialAccount"}: {label}
|
||||
{isCartao ? "Cartão" : "Conta"}: {label}
|
||||
</TooltipContent>
|
||||
</Tooltip>
|
||||
);
|
||||
@@ -607,7 +607,7 @@ const buildColumns = ({
|
||||
row.original.userId !== currentUserId && (
|
||||
<DropdownMenuItem onSelect={() => handleImport(row.original)}>
|
||||
<RiFileCopyLine className="size-4" />
|
||||
Importar para Minha FinancialAccount
|
||||
Importar para Minha Conta
|
||||
</DropdownMenuItem>
|
||||
)}
|
||||
{row.original.userId === currentUserId && (
|
||||
@@ -866,14 +866,14 @@ export function TransactionsTable({
|
||||
onClick={() => onCreate("Receita")}
|
||||
className="w-full sm:w-auto"
|
||||
>
|
||||
<RiAddCircleLine className="size-4" />
|
||||
<RiAddCircleFill className="size-4" />
|
||||
Nova Receita
|
||||
</Button>
|
||||
<Button
|
||||
onClick={() => onCreate("Despesa")}
|
||||
className="w-full sm:w-auto"
|
||||
>
|
||||
<RiAddCircleLine className="size-4" />
|
||||
<RiAddCircleFill className="size-4" />
|
||||
Nova Despesa
|
||||
</Button>
|
||||
</>
|
||||
@@ -887,7 +887,7 @@ export function TransactionsTable({
|
||||
size="icon"
|
||||
className="hidden size-9 sm:inline-flex"
|
||||
>
|
||||
<RiAddCircleFill className="size-4" />
|
||||
<RiAddCircleLine className="size-4" />
|
||||
<span className="sr-only">
|
||||
Adicionar múltiplos lançamentos
|
||||
</span>
|
||||
|
||||
@@ -72,21 +72,6 @@ export function formatCondition(value?: string | null): string {
|
||||
return capitalize(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the badge variant for a transaction type
|
||||
* @param type - Transaction type (Receita/Despesa)
|
||||
* @returns Badge variant
|
||||
*/
|
||||
export function getTransactionBadgeVariant(
|
||||
type?: string | null,
|
||||
): "default" | "destructive" | "secondary" {
|
||||
if (!type) return "secondary";
|
||||
const normalized = type.toLowerCase();
|
||||
return normalized === "receita" || normalized === "saldo inicial"
|
||||
? "default"
|
||||
: "destructive";
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats currency value
|
||||
* @param value - Numeric value
|
||||
|
||||
Reference in New Issue
Block a user