feat(ui): padroniza avatares e paleta visual da interface

This commit is contained in:
Felipe Coutinho
2026-03-17 17:08:54 +00:00
parent 7064c0b0bc
commit 272e90aef9
32 changed files with 316 additions and 314 deletions

View File

@@ -1,70 +1,2 @@
import { cn } from "@/shared/utils/ui";
interface EstabelecimentoLogoProps {
name: string;
size?: number;
className?: string;
}
const COLOR_PALETTE = [
"bg-purple-400 dark:bg-purple-600",
"bg-pink-400 dark:bg-pink-600",
"bg-red-400 dark:bg-red-600",
"bg-orange-400 dark:bg-orange-600",
"bg-indigo-400 dark:bg-indigo-600",
"bg-violet-400 dark:bg-violet-600",
"bg-fuchsia-400 dark:bg-fuchsia-600",
"bg-rose-400 dark:bg-rose-600",
"bg-amber-400 dark:bg-amber-600",
"bg-emerald-400 dark:bg-emerald-600",
];
function getInitials(name: string): string {
if (!name || !name.trim()) return "?";
const words = name.trim().split(/\s+/);
if (words.length === 1) {
return words[0]?.[0]?.toUpperCase() || "?";
}
const firstInitial = words[0]?.[0]?.toUpperCase() || "";
const secondInitial = words[1]?.[0]?.toUpperCase() || "";
return `${firstInitial}${secondInitial}`;
}
function generateColorFromName(name: string): string {
let hash = 0;
for (let i = 0; i < name.length; i++) {
hash = name.charCodeAt(i) + ((hash << 5) - hash);
}
const index = Math.abs(hash) % COLOR_PALETTE.length;
return COLOR_PALETTE[index] || "bg-gray-400";
}
export function EstabelecimentoLogo({
name,
size = 32,
className,
}: EstabelecimentoLogoProps) {
const initials = getInitials(name);
const colorClass = generateColorFromName(name);
return (
<div
className={cn(
"flex items-center justify-center rounded-full text-white font-bold shrink-0",
colorClass,
className,
)}
style={{
width: size,
height: size,
fontSize: (size ?? 32) * 0.4,
}}
>
{initials}
</div>
);
}
// Re-export from shared — componente movido para src/shared/components/entity-avatar/
export { EstablishmentLogo as EstabelecimentoLogo } from "@/shared/components/entity-avatar";

View File

@@ -1,6 +1,5 @@
"use client";
import {
RiAddCircleFill,
RiAddFill,
RiArrowLeftDoubleLine,
RiArrowLeftRightLine,
@@ -15,6 +14,7 @@ import {
RiDeleteBin5Line,
RiFileCopyLine,
RiFileList2Line,
RiFlashlightFill,
RiGroupLine,
RiHistoryLine,
RiMoreFill,
@@ -35,9 +35,12 @@ import {
import Image from "next/image";
import Link from "next/link";
import { useMemo, useState } from "react";
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 {
CategoryIconBadge,
EstablishmentLogo,
} from "@/shared/components/entity-avatar";
import MoneyValues from "@/shared/components/money-values";
import { TransactionTypeBadge } from "@/shared/components/transaction-type-badge";
import {
@@ -83,7 +86,6 @@ import { getAvatarSrc } from "@/shared/lib/payers/utils";
import { formatDate } from "@/shared/utils/date";
import { getConditionIcon, getPaymentMethodIcon } from "@/shared/utils/icons";
import { cn } from "@/shared/utils/ui";
import { EstabelecimentoLogo } from "../shared/establishment-logo";
import { TransactionsExport } from "../transactions-export";
import type {
AccountCardFilterOption,
@@ -192,7 +194,7 @@ const buildColumns = ({
return (
<span className="flex items-center gap-2">
<EstabelecimentoLogo name={name} size={28} />
<EstablishmentLogo name={name} size={28} />
<span className="flex flex-col">
<span className="text-[11px] text-muted-foreground">
{formatDate(purchaseDate)}
@@ -375,7 +377,11 @@ const buildColumns = ({
return (
<span className="flex items-center gap-2">
<CategoryIcon name={categoriaIcon} className="size-4" />
<CategoryIconBadge
icon={categoriaIcon}
name={categoriaName}
size="sm"
/>
<span>{categoriaName}</span>
</span>
);
@@ -909,7 +915,7 @@ export function TransactionsTable({
size="icon"
className="hidden size-9 sm:inline-flex"
>
<RiAddCircleFill className="size-4" />
<RiFlashlightFill className="size-4" />
<span className="sr-only">
Adicionar múltiplos lançamentos
</span>
@@ -1043,7 +1049,7 @@ export function TransactionsTable({
row.original.dueDate &&
!row.original.isSettled &&
new Date(row.original.dueDate) < new Date()
? "bg-destructive/[0.03] hover:bg-destructive/[0.05]"
? "bg-destructive/3 hover:bg-destructive/5"
: undefined,
)}
>