feat(dashboard): adicionar alerta de privacidade e ajustar estilos

- Adicionar alerta de privacidade na página de insights
- Ajustar classes de estilo para widgets de despesas e renda
- Atualizar .gitignore para incluir QWEN.md
- Modificar estilos de fundo e sombra no componente DashboardWelcome
This commit is contained in:
Felipe Coutinho
2025-12-09 17:23:45 +00:00
parent ed2b7070eb
commit 0c445ee4a5
6 changed files with 40 additions and 29 deletions

1
.gitignore vendored
View File

@@ -106,6 +106,7 @@ docker-compose.override.yml
.cursor/ .cursor/
CLAUDE.md CLAUDE.md
AGENTS.md AGENTS.md
QWEN.md
claude.md claude.md
agents.md agents.md

View File

@@ -88,35 +88,35 @@
.dark { .dark {
/* Base surfaces - true dark with minimal saturation */ /* Base surfaces - true dark with minimal saturation */
--background: oklch(14% 0.004 285); --background: oklch(18.674% 0.00002 271.152);
--foreground: oklch(95% 0.003 285); --foreground: oklch(85.505% 0.02038 100.68);
--card: oklch(18% 0.005 285); --card: oklch(24.039% 0.00151 16.27);
--card-foreground: oklch(95% 0.003 285); --card-foreground: oklch(85.505% 0.02038 100.68);
--popover: oklch(20% 0.006 285); --popover: oklch(24.039% 0.00151 16.27);
--popover-foreground: oklch(95% 0.003 285); --popover-foreground: oklch(85.196% 0.0204 100.682);
/* Primary - vibrant terracotta stands out on dark */ /* Primary - vibrant terracotta stands out on dark */
--primary: oklch(69.18% 0.18855 38.353); --primary: oklch(69.18% 0.18855 38.353);
--primary-foreground: oklch(12% 0.008 285); --primary-foreground: oklch(20.019% 0.00002 271.152);
/* Secondary - elevated surface */ /* Secondary - elevated surface */
--secondary: oklch(22% 0.004 285); --secondary: oklch(22% 0.004 285);
--secondary-foreground: oklch(93% 0.003 285); --secondary-foreground: oklch(85.196% 0.0204 100.682);
/* Muted - subtle surface variant */ /* Muted - subtle surface variant */
--muted: oklch(20% 0.004 285); --muted: oklch(33.674% 0.00531 91.552);
--muted-foreground: oklch(72.285% 0.00436 286.016); --muted-foreground: oklch(72.285% 0.00436 286.016);
/* Accent - subtle highlight */ /* Accent - subtle highlight */
--accent: oklch(26% 0.006 285); --accent: oklch(26.893% 0.00391 84.539);
--accent-foreground: oklch(95% 0.003 285); --accent-foreground: oklch(85.196% 0.0204 100.682);
/* Destructive - accessible red for dark */ /* Destructive - accessible red for dark */
--destructive: oklch(62% 0.2 28); --destructive: oklch(62% 0.2 28);
--destructive-foreground: oklch(98% 0.005 30); --destructive-foreground: oklch(98% 0.005 30);
/* Borders and inputs - visible but subtle */ /* Borders and inputs - visible but subtle */
--border: oklch(28% 0.004 285); --border: oklch(37.332% 0.01493 101.928);
--input: oklch(32% 0.005 285); --input: oklch(32% 0.005 285);
--ring: oklch(69.18% 0.18855 38.353); --ring: oklch(69.18% 0.18855 38.353);
@@ -128,12 +128,12 @@
--chart-5: oklch(74% 0.15 88); --chart-5: oklch(74% 0.15 88);
/* Sidebar - slight separation from main */ /* Sidebar - slight separation from main */
--sidebar: oklch(16% 0.004 285); --sidebar: oklch(24.039% 0.00151 16.27);
--sidebar-foreground: oklch(95% 0.003 285); --sidebar-foreground: oklch(85.196% 0.0204 100.682);
--sidebar-primary: oklch(69.18% 0.18855 38.353); --sidebar-primary: oklch(69.18% 0.18855 38.353);
--sidebar-primary-foreground: oklch(12% 0.008 285); --sidebar-primary-foreground: oklch(12.897% 0.00619 87.19);
--sidebar-accent: oklch(24% 0.005 285); --sidebar-accent: oklch(32.242% 0.00447 67.486);
--sidebar-accent-foreground: oklch(95% 0.003 285); --sidebar-accent-foreground: oklch(85.196% 0.0204 100.682);
--sidebar-border: oklch(26% 0.004 285); --sidebar-border: oklch(26% 0.004 285);
--sidebar-ring: oklch(69.18% 0.18855 38.353); --sidebar-ring: oklch(69.18% 0.18855 38.353);
@@ -159,12 +159,12 @@
--spacing: 0.25rem; --spacing: 0.25rem;
/* Special components */ /* Special components */
--month-picker: oklch(22% 0.006 285); --month-picker: oklch(24.039% 0.00151 16.27);
--month-picker-foreground: oklch(85% 0.02 315); --month-picker-foreground: oklch(85.196% 0.0204 100.682);
--dark: oklch(93% 0.003 285); --dark: oklch(85.196% 0.0204 100.682);
--dark-foreground: oklch(18% 0.005 285); --dark-foreground: oklch(18.711% 0.00427 84.566);
--welcome-banner: oklch(22% 0.006 285); --welcome-banner: oklch(24.039% 0.00151 16.27);
--welcome-banner-foreground: oklch(95% 0.003 285); --welcome-banner-foreground: oklch(85.196% 0.0204 100.682);
} }
@theme inline { @theme inline {

View File

@@ -51,7 +51,7 @@ export function DashboardWelcome({ name }: DashboardWelcomeProps) {
return ( return (
<Card <Card
className={`${main_font.className} relative px-6 py-12 bg-welcome-banner border-none shadow-lg overflow-hidden`} className={`${main_font.className} relative px-6 py-12 bg-welcome-banner border-none shadow-none overflow-hidden`}
> >
<div className="absolute inset-0 flex items-center justify-center opacity-20 pointer-events-none"> <div className="absolute inset-0 flex items-center justify-center opacity-20 pointer-events-none">
<MagnetLines <MagnetLines

View File

@@ -127,9 +127,9 @@ export function ExpensesByCategoryWidget({
<span <span
className={`flex items-center gap-0.5 text-xs ${ className={`flex items-center gap-0.5 text-xs ${
hasIncrease hasIncrease
? "text-red-600" ? "text-red-600 dark:text-red-500"
: hasDecrease : hasDecrease
? "text-green-600" ? "text-green-600 dark:text-green-500"
: "text-muted-foreground" : "text-muted-foreground"
}`} }`}
> >

View File

@@ -127,9 +127,9 @@ export function IncomeByCategoryWidget({
<span <span
className={`flex items-center gap-0.5 text-xs ${ className={`flex items-center gap-0.5 text-xs ${
hasIncrease hasIncrease
? "text-green-600" ? "text-green-600 dark:text-green-500"
: hasDecrease : hasDecrease
? "text-red-600" ? "text-red-600 dark:text-red-500"
: "text-muted-foreground" : "text-muted-foreground"
}`} }`}
> >

View File

@@ -10,8 +10,9 @@ import { DEFAULT_MODEL } from "@/app/(dashboard)/insights/data";
import { Button } from "@/components/ui/button"; import { Button } from "@/components/ui/button";
import { Card, CardContent, CardHeader } from "@/components/ui/card"; import { Card, CardContent, CardHeader } from "@/components/ui/card";
import { Skeleton } from "@/components/ui/skeleton"; import { Skeleton } from "@/components/ui/skeleton";
import { Alert, AlertDescription } from "@/components/ui/alert";
import type { InsightsResponse } from "@/lib/schemas/insights"; import type { InsightsResponse } from "@/lib/schemas/insights";
import { RiDeleteBinLine, RiSaveLine, RiSparklingLine } from "@remixicon/react"; import { RiDeleteBinLine, RiSaveLine, RiSparklingLine, RiAlertLine } from "@remixicon/react";
import { useEffect, useState, useTransition } from "react"; import { useEffect, useState, useTransition } from "react";
import { toast } from "sonner"; import { toast } from "sonner";
import { EmptyState } from "../empty-state"; import { EmptyState } from "../empty-state";
@@ -127,6 +128,15 @@ export function InsightsPage({ period, onAnalyze }: InsightsPageProps) {
return ( return (
<div className="flex flex-col gap-6"> <div className="flex flex-col gap-6">
{/* Privacy Warning */}
<Alert>
<RiAlertLine className="size-4" />
<AlertDescription className="text-sm">
<strong>Aviso de privacidade:</strong> Ao gerar insights, seus dados financeiros serão enviados para o provedor de IA selecionado
(Anthropic, OpenAI, Google ou OpenRouter) para processamento. Certifique-se de que você confia no provedor escolhido antes de prosseguir.
</AlertDescription>
</Alert>
{/* Model Selector */} {/* Model Selector */}
<ModelSelector <ModelSelector
value={selectedModel} value={selectedModel}