"use client"; import { createFileRoute, Outlet, redirect, Link, useNavigate, useLocation } from "@tanstack/react-router"; import { useEffect, useState } from "react"; import { Bot, CreditCard, Home, LogOut, Menu, Plug, Settings, Sparkles, User, } from "lucide-react"; import { useQuery } from "@tanstack/react-query"; import { supabase } from "@/integrations/supabase/client"; import { useAuth } from "@/hooks/use-auth"; import { useProfile } from "@/hooks/use-profile"; import { useSubscriptionRealtime } from "@/hooks/use-subscription-realtime"; const PADDLE_ENV = (import.meta.env.VITE_PADDLE_ENVIRONMENT as string) === "production" ? "live" : "sandbox"; import { Logo } from "@/components/mika/Logo"; import { PaymentIssueBanner } from "@/components/mika/PaymentIssueBanner"; import { ThemeToggle } from "@/components/mika/ThemeToggle"; import { Button } from "@/components/ui/button"; import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuTrigger, } from "@/components/ui/dropdown-menu"; import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"; import { Sheet, SheetContent, SheetHeader, SheetTitle, SheetTrigger, } from "@/components/ui/sheet"; import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, } from "@/components/ui/tooltip"; import { cn } from "@/lib/utils"; export const Route = createFileRoute("/painel")({ beforeLoad: () => { // Auth real é validada client-side abaixo (Supabase usa localStorage). // Mantemos beforeLoad como hook para futuro SSR auth. }, component: PainelLayout, }); interface NavItem { to: "/painel" | "/painel/faturamento" | "/painel/configuracoes"; label: string; icon: React.ComponentType<{ className?: string }>; disabled?: boolean; } interface DisabledNavItem { to: null; label: string; icon: React.ComponentType<{ className?: string }>; disabled: true; } const NAV: (NavItem | DisabledNavItem)[] = [ { to: "/painel", label: "Dashboard", icon: Home }, { to: null, label: "Meu Agente", icon: Bot, disabled: true }, { to: null, label: "Skills", icon: Sparkles, disabled: true }, { to: null, label: "Integrações", icon: Plug, disabled: true }, { to: "/painel/faturamento", label: "Faturamento", icon: CreditCard }, { to: "/painel/configuracoes", label: "Configurações", icon: Settings }, ]; function PainelLayout() { const { user, loading } = useAuth(); const navigate = useNavigate(); const location = useLocation(); const [mobileOpen, setMobileOpen] = useState(false); // Atualiza queries quando o webhook gravar/alterar a assinatura useSubscriptionRealtime(); // Faturamento permanece acessível mesmo sem assinatura ativa // (para que o usuário possa ver o estado e assinar / gerenciar). const skipSubGuard = location.pathname.startsWith("/painel/faturamento"); const { data: hasActiveSub, isLoading: subLoading } = useQuery({ queryKey: ["has-active-subscription", user?.id, PADDLE_ENV], enabled: !!user && !skipSubGuard, queryFn: async () => { const { data, error } = await supabase.rpc("has_active_subscription", { user_uuid: user!.id, check_env: PADDLE_ENV, }); if (error) throw error; return data === true; }, }); useEffect(() => { if (!loading && !user) { navigate({ to: "/login", search: { redirect: location.pathname } }); } }, [loading, user, navigate, location.pathname]); useEffect(() => { if (!loading && user && !skipSubGuard && !subLoading && hasActiveSub === false) { window.location.href = "/#planos"; } }, [loading, user, skipSubGuard, subLoading, hasActiveSub]); const checkingSub = !skipSubGuard && (subLoading || hasActiveSub === false); if (loading || !user || checkingSub) { return (