diff --git a/src/app/globals.css b/src/app/globals.css index 6cc8389..8b2e518 100644 --- a/src/app/globals.css +++ b/src/app/globals.css @@ -16,7 +16,7 @@ --popover-foreground: var(--foreground); --primary: oklch(72.069% 0.18335 44.069); - --primary-foreground: oklch(98% 0.008 80); + --primary-foreground: oklch(16% 0.004 60); --secondary: oklch(96.2% 0.005 70); --secondary-foreground: oklch(30% 0.01 45); @@ -51,6 +51,18 @@ --chart-9: var(--color-cyan-500); --chart-10: var(--color-lime-500); + /* Data palette — análoga quente (hue 0–120), família do primary */ + --data-1: oklch(58% 0.22 18); /* vermelho-tijolo */ + --data-2: oklch(64% 0.22 30); /* vermelho-laranja */ + --data-3: oklch(69% 0.21 42); /* laranja (≈ primary) */ + --data-4: oklch(74% 0.18 55); /* âmbar */ + --data-5: oklch(78% 0.16 68); /* âmbar-dourado */ + --data-6: oklch(76% 0.15 82); /* amarelo-quente */ + --data-7: oklch(70% 0.17 95); /* amarelo-lima */ + --data-8: oklch(65% 0.18 108); /* lima-verde */ + --data-9: oklch(62% 0.17 120); /* verde-oliva claro */ + --data-10: oklch(56% 0.15 10); /* terracota escuro */ + --sidebar: oklch(99.3% 0.0015 75); --sidebar-foreground: var(--foreground); --sidebar-primary: var(--primary); @@ -88,7 +100,7 @@ --popover: oklch(28% 0.004 55); --popover-foreground: var(--foreground); - --primary: oklch(66% 0.15 45.139); + --primary: oklch(72.069% 0.18335 44.069); --primary-foreground: oklch(16% 0.004 60); --secondary: oklch(29% 0.004 55); @@ -124,6 +136,19 @@ --chart-9: var(--color-cyan-500); --chart-10: var(--color-lime-500); + /* Data palette — dark mode (ligeiramente mais vivos) */ + /* Data palette dark — ligeiramente mais vivos para contrastar no fundo escuro */ + --data-1: oklch(66% 0.22 18); + --data-2: oklch(72% 0.22 30); + --data-3: oklch(76% 0.21 42); + --data-4: oklch(81% 0.18 55); + --data-5: oklch(84% 0.16 68); + --data-6: oklch(82% 0.15 82); + --data-7: oklch(77% 0.17 95); + --data-8: oklch(72% 0.18 108); + --data-9: oklch(69% 0.17 120); + --data-10: oklch(63% 0.15 10); + --sidebar: oklch(19.5% 0.004 55); --sidebar-foreground: var(--foreground); --sidebar-primary: var(--primary); diff --git a/src/features/budgets/components/budget-card.tsx b/src/features/budgets/components/budget-card.tsx index 261d41f..be51b42 100644 --- a/src/features/budgets/components/budget-card.tsx +++ b/src/features/budgets/components/budget-card.tsx @@ -6,7 +6,7 @@ import { RiPencilLine, } from "@remixicon/react"; import Link from "next/link"; -import { CategoryIconBadge } from "@/features/categories/components/category-icon-badge"; +import { CategoryIconBadge } from "@/shared/components/entity-avatar"; import MoneyValues from "@/shared/components/money-values"; import { Card, CardContent, CardFooter } from "@/shared/components/ui/card"; import { Progress } from "@/shared/components/ui/progress"; @@ -15,7 +15,6 @@ import type { Budget } from "./types"; interface BudgetCardProps { budget: Budget; - colorIndex: number; periodLabel: string; onEdit: (budget: Budget) => void; onRemove: (budget: Budget) => void; @@ -34,7 +33,6 @@ const formatCategoryName = (budget: Budget) => export function BudgetCard({ budget, - colorIndex, periodLabel, onEdit, onRemove, @@ -51,7 +49,6 @@ export function BudgetCard({
diff --git a/src/features/budgets/components/budgets-page.tsx b/src/features/budgets/components/budgets-page.tsx index 0c5eaea..e5d45fd 100644 --- a/src/features/budgets/components/budgets-page.tsx +++ b/src/features/budgets/components/budgets-page.tsx @@ -137,7 +137,6 @@ export function BudgetsPage({ diff --git a/src/features/categories/components/category-detail-header.tsx b/src/features/categories/components/category-detail-header.tsx index 5689c1d..5d0e575 100644 --- a/src/features/categories/components/category-detail-header.tsx +++ b/src/features/categories/components/category-detail-header.tsx @@ -77,7 +77,6 @@ export function CategoryDetailHeader({
diff --git a/src/features/categories/components/category-icon-badge.tsx b/src/features/categories/components/category-icon-badge.tsx index ba96a63..eb48c79 100644 --- a/src/features/categories/components/category-icon-badge.tsx +++ b/src/features/categories/components/category-icon-badge.tsx @@ -1,76 +1,6 @@ -"use client"; - -import { - buildCategoryInitials, - getCategoryBgColor, - getCategoryColor, -} from "@/shared/utils/category-colors"; -import { getIconComponent } from "@/shared/utils/icons"; -import { cn } from "@/shared/utils/ui"; - -const sizeVariants = { - sm: { - container: "size-8", - icon: "size-4", - text: "text-[10px]", - }, - md: { - container: "size-9", - icon: "size-5", - text: "text-xs", - }, - lg: { - container: "size-12", - icon: "size-6", - text: "text-sm", - }, -} as const; - -export type CategoryIconBadgeSize = keyof typeof sizeVariants; - -export interface CategoryIconBadgeProps { - /** Nome do ícone Remix (ex: "RiShoppingBag3Line") */ - icon?: string | null; - /** Nome da categoria (usado para gerar iniciais como fallback) */ - name: string; - /** Índice para determinar a cor (cicla entre as cores disponíveis) */ - colorIndex: number; - /** Tamanho do badge: sm (32px), md (36px), lg (48px) */ - size?: CategoryIconBadgeSize; - /** Classes adicionais para o container */ - className?: string; -} - -export function CategoryIconBadge({ - icon, - name, - colorIndex, - size = "md", - className, -}: CategoryIconBadgeProps) { - const IconComponent = icon ? getIconComponent(icon) : null; - const initials = buildCategoryInitials(name); - const color = getCategoryColor(colorIndex); - const bgColor = getCategoryBgColor(colorIndex); - const variant = sizeVariants[size]; - - return ( -
- {IconComponent ? ( - // @ts-expect-error icon accepts style but type is too narrow - - ) : ( - - {initials} - - )} -
- ); -} +// Re-export from shared — componente movido para src/shared/components/entity-avatar/ +export { + CategoryIconBadge, + type CategoryIconBadgeProps, + type CategoryIconBadgeSize, +} from "@/shared/components/entity-avatar"; diff --git a/src/features/dashboard/components/bills/bill-list-item.tsx b/src/features/dashboard/components/bills/bill-list-item.tsx index 98e77ba..f376d55 100644 --- a/src/features/dashboard/components/bills/bill-list-item.tsx +++ b/src/features/dashboard/components/bills/bill-list-item.tsx @@ -4,7 +4,7 @@ import { isBillOverdue, } from "@/features/dashboard/bills-helpers"; import type { DashboardBill } from "@/features/dashboard/bills-queries"; -import { EstabelecimentoLogo } from "@/features/transactions/components/shared/establishment-logo"; +import { EstablishmentLogo } from "@/shared/components/entity-avatar"; import MoneyValues from "@/shared/components/money-values"; import { Button } from "@/shared/components/ui/button"; import { cn } from "@/shared/utils/ui"; @@ -21,7 +21,7 @@ export function BillListItem({ bill, onPay }: BillListItemProps) { return (
  • - +
    diff --git a/src/features/dashboard/components/category-breakdown/category-breakdown-widget-view.tsx b/src/features/dashboard/components/category-breakdown/category-breakdown-widget-view.tsx index 5b0519f..4887e0e 100644 --- a/src/features/dashboard/components/category-breakdown/category-breakdown-widget-view.tsx +++ b/src/features/dashboard/components/category-breakdown/category-breakdown-widget-view.tsx @@ -12,8 +12,8 @@ import { import Link from "next/link"; import { useMemo, useState } from "react"; import { Pie, PieChart, Tooltip } from "recharts"; -import { CategoryIconBadge } from "@/features/categories/components/category-icon-badge"; import type { DashboardCategoryBreakdownData } from "@/features/dashboard/categories/category-breakdown"; +import { CategoryIconBadge } from "@/shared/components/entity-avatar"; import MoneyValues from "@/shared/components/money-values"; import { type ChartConfig, ChartContainer } from "@/shared/components/ui/chart"; import { @@ -220,7 +220,6 @@ export function CategoryBreakdownWidgetView({
    diff --git a/src/features/dashboard/components/goals-progress/goal-progress-item.tsx b/src/features/dashboard/components/goals-progress/goal-progress-item.tsx index 218ef2d..4ea14bc 100644 --- a/src/features/dashboard/components/goals-progress/goal-progress-item.tsx +++ b/src/features/dashboard/components/goals-progress/goal-progress-item.tsx @@ -1,11 +1,10 @@ import { RiPencilLine } from "@remixicon/react"; -import { CategoryIconBadge } from "@/features/categories/components/category-icon-badge"; import { clampGoalProgress, formatGoalProgressPercentage, - getGoalProgressStatusColorClass, } from "@/features/dashboard/goals-progress-helpers"; import type { GoalProgressItem as GoalProgressItemData } from "@/features/dashboard/goals-progress-queries"; +import { CategoryIconBadge } from "@/shared/components/entity-avatar"; import MoneyValues from "@/shared/components/money-values"; import { Button } from "@/shared/components/ui/button"; import { Progress } from "@/shared/components/ui/progress"; @@ -21,10 +20,14 @@ export function GoalProgressItem({ index, onEdit, }: GoalProgressItemProps) { - const statusColor = getGoalProgressStatusColorClass(item.status); const progressValue = clampGoalProgress(item.usedPercentage, 0, 100); const percentageDelta = item.usedPercentage - 100; - + const deltaColor = + percentageDelta > 0 + ? "text-destructive" + : percentageDelta < 0 + ? "text-success" + : "text-muted-foreground"; const isExceeded = item.status === "exceeded"; return ( @@ -34,7 +37,6 @@ export function GoalProgressItem({
    @@ -44,19 +46,19 @@ export function GoalProgressItem({

    de{" "} + + {formatGoalProgressPercentage(percentageDelta, true)} +

    - - {formatGoalProgressPercentage(percentageDelta, true)} -