"use client"; import { createFileRoute, Link } from "@tanstack/react-router"; import { useEffect, useRef, useState } from "react"; import { ArrowRight, CheckCircle2, Loader2, MessageCircle, Sparkles } from "lucide-react"; import { useSubscription } from "@/hooks/use-profile"; import { useProfile } from "@/hooks/use-profile"; import { useAgentInstance } from "@/hooks/use-agent-instance"; import { Button } from "@/components/ui/button"; import { Skeleton } from "@/components/ui/skeleton"; import { SubscriptionBanner } from "@/components/mika/SubscriptionBanner"; import { SkillsDashboardWidget } from "@/components/mika/SkillsDashboardWidget"; import { CronjobsDashboardWidget } from "@/components/mika/cronjobs/CronjobsDashboardWidget"; import { IntegrationsDashboardWidget } from "@/components/mika/integrations/IntegrationsDashboardWidget"; import { AutoPausedBanner } from "@/components/mika/cronjobs/AutoPausedBanner"; import { TelegramOnboardingWizard } from "@/components/mika/telegram/TelegramOnboardingWizard"; import { toast } from "sonner"; import { cn } from "@/lib/utils"; type DashboardSearch = { status?: string }; export const Route = createFileRoute("/painel/")({ validateSearch: (search: Record): DashboardSearch => ({ status: typeof search.status === "string" ? search.status : undefined, }), component: DashboardPage, }); function DashboardPage() { const { data: subscription, isLoading } = useSubscription(); const { data: profile } = useProfile(); const { data: agent } = useAgentInstance(); const search = Route.useSearch(); const navigate = Route.useNavigate(); const [wizardOpen, setWizardOpen] = useState(false); const previousStatusRef = useRef(null); // Redireciona para /bem-vindo se cliente acabou de pagar e ainda não completou onboarding // OU se ainda não conectou o Telegram (para usar o novo fluxo de Managed Bot) useEffect(() => { if (search.status !== "success" || !agent) return; if (agent.status === "suspended" || agent.status === "error") { navigate({ search: { status: undefined }, replace: true }); return; } if (!agent.onboarding_completed || !agent.telegram_bot_token_vault_id) { navigate({ to: "/bem-vindo", replace: true }); return; } navigate({ search: { status: undefined }, replace: true }); }, [search.status, agent, navigate]); useEffect(() => { if (search.status === "success" && !agent && !isLoading) { toast.info("Seu agente ainda não está pronto. Aguarde o provisionamento."); } }, [search.status, agent, isLoading]); // Toast quando agente sair de provisioning → active (uma única vez) useEffect(() => { if (!agent) return; const prev = previousStatusRef.current; if (prev === "provisioning" && agent.status === "active") { toast.success("Sua Mika está pronta! 🎉", { description: "Abra o Telegram e mande uma mensagem para começar.", }); } previousStatusRef.current = agent.status; }, [agent]); if (isLoading) { return (
); } const firstName = (profile?.full_name || "").split(" ")[0] || "por aqui"; const agentName = agent?.agent_name?.trim() || "Mika"; const statusLabel = agent?.status === "active" ? "ativo" : agent?.status === "provisioning" ? "sendo preparado" : agent?.status === "suspended" ? "pausado" : agent?.status === "error" ? "com erro" : "aguardando configuração"; return (

Olá, {firstName} 👋

{subscription ? agent ? <>Seu agente {agentName} está {statusLabel}. : "Acompanhe abaixo o status do seu agente." : "Vamos colocar seu agente Mika no ar."}

{!subscription && } {subscription && (subscription.status === "incomplete" || subscription.status === "active") && agent?.status === "provisioning" && ( )} {subscription && subscription.status === "active" && agent?.status === "active" && ( <> {agent.telegram_bot_username && }
)}
); } function NoSubscriptionCard() { return (

Escolha um plano para começar

Em poucos minutos seu agente Mika estará disponível no Telegram, com memória persistente e skills personalizadas.

); } type StepState = "done" | "active" | "pending"; function ProvisioningCard({ telegramConnected, railwayServiceCreated: _railwayServiceCreated, }: { telegramConnected: boolean; railwayServiceCreated?: boolean; }) { // Etapas dinâmicas — sabemos: pagamento confirmado (sempre done aqui), // Telegram conectado (vem do agent.telegram_bot_username), e o resto // está em andamento até o railway-webhook chegar como SUCCESS. const steps: { label: string; state: StepState }[] = [ { label: "Pagamento confirmado", state: "done" }, { label: telegramConnected ? "Telegram conectado" : "Conecte seu Telegram", state: telegramConnected ? "done" : "active", }, { label: "Provisionando container", state: telegramConnected ? "active" : "pending", }, { label: "Mika quase pronta!", state: "pending", }, ]; return (

Estamos preparando seu agente Mika

Geralmente leva de 3 a 5 minutos. Esta página atualiza sozinha quando ficar pronta.

    {steps.map((step, i) => (
  1. {step.state === "done" ? ( ) : step.state === "active" ? ( ) : ( i + 1 )}

    {step.label}

  2. ))}
); } function ActiveSuccessCard({ botUsername }: { botUsername: string }) { return (

Seu Assistente Pessoal - IA está no ar 🎉

Abra o Telegram e converse com{" "} @{botUsername} para começar.

); }