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:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -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
|
||||||
|
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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"
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -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"
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -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}
|
||||||
|
|||||||
Reference in New Issue
Block a user