"use client"; import { RiAlertLine, RiDeleteBinLine, RiSaveLine, RiSparklingLine, } from "@remixicon/react"; import { format } from "date-fns"; import { ptBR } from "date-fns/locale"; import { useEffect, useState, useTransition } from "react"; import { toast } from "sonner"; import { deleteSavedInsightsAction, generateInsightsAction, loadSavedInsightsAction, saveInsightsAction, } from "@/app/(dashboard)/insights/actions"; import { DEFAULT_MODEL } from "@/app/(dashboard)/insights/data"; import { Alert, AlertDescription } from "@/components/ui/alert"; import { Button } from "@/components/ui/button"; import { Card, CardContent, CardHeader } from "@/components/ui/card"; import { Skeleton } from "@/components/ui/skeleton"; import type { InsightsResponse } from "@/lib/schemas/insights"; import { EmptyState } from "../empty-state"; import { InsightsGrid } from "./insights-grid"; import { ModelSelector } from "./model-selector"; interface InsightsPageProps { period: string; onAnalyze?: () => void; } export function InsightsPage({ period, onAnalyze }: InsightsPageProps) { const [selectedModel, setSelectedModel] = useState(DEFAULT_MODEL); const [insights, setInsights] = useState(null); const [isPending, startTransition] = useTransition(); const [isSaving, startSaveTransition] = useTransition(); const [error, setError] = useState(null); const [isSaved, setIsSaved] = useState(false); const [savedDate, setSavedDate] = useState(null); const [isLoading, setIsLoading] = useState(true); // Carregar insights salvos ao montar o componente useEffect(() => { const loadSaved = async () => { try { const result = await loadSavedInsightsAction(period); if (result.success && result.data) { setInsights(result.data.insights); setSelectedModel(result.data.modelId); setIsSaved(true); setSavedDate(result.data.createdAt); } } catch (err) { console.error("Error loading saved insights:", err); } finally { setIsLoading(false); } }; loadSaved(); }, [period]); const handleAnalyze = () => { setError(null); setIsSaved(false); setSavedDate(null); onAnalyze?.(); startTransition(async () => { try { const result = await generateInsightsAction(period, selectedModel); if (result.success) { setInsights(result.data); toast.success("Insights gerados com sucesso!"); } else { setError(result.error); toast.error(result.error); } } catch (err) { const errorMessage = "Erro inesperado ao gerar insights."; setError(errorMessage); toast.error(errorMessage); console.error("Error generating insights:", err); } }); }; const handleSave = () => { if (!insights) return; startSaveTransition(async () => { try { const result = await saveInsightsAction( period, selectedModel, insights, ); if (result.success) { setIsSaved(true); setSavedDate(result.data.createdAt); toast.success("Análise salva com sucesso!"); } else { toast.error(result.error); } } catch (err) { toast.error("Erro ao salvar análise."); console.error("Error saving insights:", err); } }); }; const handleDelete = () => { startSaveTransition(async () => { try { const result = await deleteSavedInsightsAction(period); if (result.success) { setIsSaved(false); setSavedDate(null); toast.success("Análise removida com sucesso!"); } else { toast.error(result.error); } } catch (err) { toast.error("Erro ao remover análise."); console.error("Error deleting insights:", err); } }); }; return (
{/* Privacy Warning */} Aviso de privacidade: 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. {/* Model Selector */} {/* Analyze Button */}
{insights && !error && ( )} {isSaved && savedDate && ( Salva em{" "} {format(new Date(savedDate), "dd/MM/yyyy 'às' HH:mm", { locale: ptBR, })} )}
{/* Content Area */}
{(isPending || isLoading) && } {!isPending && !isLoading && !insights && !error && ( } title="Nenhuma análise realizada" description="Clique no botão acima para gerar insights inteligentes sobre seus dados financeiros do mês selecionado." /> )} {!isPending && !isLoading && error && ( )} {!isPending && !isLoading && insights && !error && ( )}
); } function LoadingState() { return (
{/* Intro text skeleton */}
{/* Grid de Cards */}
{Array.from({ length: 4 }).map((_, i) => (
{Array.from({ length: 4 }).map((_, j) => (
))}
))}
); } function ErrorState({ error, onRetry, }: { error: string; onRetry: () => void; }) { return (

Erro ao gerar insights

{error}

); }