"use client"; import { useCallback, useEffect, useState } from "react"; import ConfirmModal from "@/components/ConfirmModal"; import GoogleCalendarCard from "@/components/GoogleCalendarCard"; import QRCodeModal from "@/components/QRCodeModal"; import Toast from "@/components/Toast"; import WhatsAppInstanceCard from "@/components/WhatsAppInstanceCard"; import type { InstanceStatus } from "@/lib/evolutionapi"; import { supabase } from "@/lib/supabase"; export default function DashboardPage() { const [userName, setUserName] = useState("Usuário"); const [instances, setInstances] = useState([]); const [loading, setLoading] = useState(true); // QR Code Modal State const [qrModalOpen, setQrModalOpen] = useState(false); const [qrCode, setQrCode] = useState(null); const [qrInstanceName, setQrInstanceName] = useState(""); const [qrLoading, setQrLoading] = useState(false); const [qrError, setQrError] = useState(null); // Disconnect Confirmation State const [confirmModalOpen, setConfirmModalOpen] = useState(false); const [disconnectInstanceName, setDisconnectInstanceName] = useState(""); const [disconnectLoading, setDisconnectLoading] = useState(false); // Toast State const [toastVisible, setToastVisible] = useState(false); const [toastMessage, setToastMessage] = useState(""); const [toastType, setToastType] = useState<"success" | "error">("success"); // Google Calendar State const [calendarConnected, setCalendarConnected] = useState(false); const [calendarEmail, setCalendarEmail] = useState(null); const [calendarCredentialId, setCalendarCredentialId] = useState< string | null >(null); const [calendarCredentialName, setCalendarCredentialName] = useState< string | null >(null); const [calendarLoading, setCalendarLoading] = useState(true); const [calendarConnecting, _setCalendarConnecting] = useState(false); const loadInstances = useCallback(async () => { setLoading(true); try { const response = await fetch("/api/instances"); if (!response.ok) { throw new Error("Failed to fetch instances"); } const data: InstanceStatus[] = await response.json(); setInstances(data); } catch (error) { console.error("Error loading instances:", error); } finally { setLoading(false); } }, []); const loadGoogleCalendarStatus = useCallback(async () => { setCalendarLoading(true); try { const { data: { user }, } = await supabase.auth.getUser(); if (user) { const { data, error } = await supabase .schema("portal") .from("integrations") .select( "status, connected_at, n8n_credential_id, n8n_credential_name, connected_email", ) .eq("user_id", user.id) .eq("provider", "google_calendar") .maybeSingle(); if (error && error.code !== "PGRST116") { // PGRST116 = no rows returned throw error; } if (data && data.status === "connected") { setCalendarConnected(true); setCalendarCredentialId(data.n8n_credential_id || null); setCalendarCredentialName(data.n8n_credential_name || null); // Usar email da conta Google conectada (não o email de login do Supabase) setCalendarEmail(data.connected_email || null); } else { setCalendarConnected(false); setCalendarEmail(null); setCalendarCredentialId(null); setCalendarCredentialName(null); } } } catch (error) { console.error("Error loading Google Calendar status:", error); setCalendarConnected(false); } finally { setCalendarLoading(false); } }, []); useEffect(() => { const getUser = async () => { const { data: { user }, } = await supabase.auth.getUser(); if (user?.email) { const name = user.email.split("@")[0]; setUserName(name); } }; const init = async () => { await getUser(); await Promise.all([loadInstances(), loadGoogleCalendarStatus()]); }; init(); // Check for OAuth callback const urlParams = new URLSearchParams(window.location.search); const oauthSuccess = urlParams.get("oauth_success"); const oauthError = urlParams.get("oauth_error"); if (oauthSuccess === "true") { setToastMessage("Google Calendar conectado com sucesso!"); setToastType("success"); setToastVisible(true); window.history.replaceState({}, "", "/dashboard"); loadGoogleCalendarStatus(); // Reload status } else if (oauthError) { setToastMessage("Erro ao conectar Google Calendar. Tente novamente."); setToastType("error"); setToastVisible(true); window.history.replaceState({}, "", "/dashboard"); } }, [loadInstances, loadGoogleCalendarStatus]); const handleGenerateQR = async (instanceName: string) => { setQrInstanceName(instanceName); setQrModalOpen(true); setQrCode(null); setQrError(null); setQrLoading(true); try { const response = await fetch(`/api/instances/${instanceName}/qr`); if (!response.ok) { throw new Error("Failed to generate QR code"); } const data = await response.json(); setQrCode(data.qrcode || data.base64 || data.code); } catch (error: unknown) { setQrError("Falha ao gerar QR code. Tente novamente."); console.error("QR Code generation error:", error); } finally { setQrLoading(false); } }; const handleCloseQrModal = () => { setQrModalOpen(false); setQrCode(null); setQrError(null); setQrInstanceName(""); // Reload instances to check if connected loadInstances(); }; const handleDisconnectClick = (instanceName: string) => { setDisconnectInstanceName(instanceName); setConfirmModalOpen(true); }; const handleDisconnectConfirm = async () => { setDisconnectLoading(true); try { const response = await fetch(`/api/instances/${disconnectInstanceName}`, { method: "DELETE", }); if (!response.ok) { throw new Error("Failed to disconnect instance"); } // Success! setToastMessage("Instância desconectada com sucesso"); setToastType("success"); setToastVisible(true); // Close modal and reload setConfirmModalOpen(false); await loadInstances(); } catch (error: unknown) { // Error setToastMessage("Falha ao desconectar. Tente novamente."); setToastType("error"); setToastVisible(true); console.error("Disconnect error:", error); } finally { setDisconnectLoading(false); setDisconnectInstanceName(""); } }; const handleConnectGoogleCalendar = async () => { try { setCalendarLoading(true); const { data: { user }, } = await supabase.auth.getUser(); if (!user) { throw new Error("User not authenticated"); } // Chamar API route que gera oauth_url via n8n const response = await fetch("/api/google-calendar/auth"); if (!response.ok) { throw new Error("Failed to get OAuth URL"); } const data = await response.json(); if (!data.oauthUrl) { throw new Error("No OAuth URL returned"); } // Redirecionar para Google OAuth (URL gerada pelo n8n com state correto) window.location.href = data.oauthUrl; } catch (error) { console.error("Error connecting Google Calendar:", error); setToastMessage("Erro ao conectar Google Calendar. Tente novamente."); setToastType("error"); setToastVisible(true); } finally { setCalendarLoading(false); } }; return (
{/* Welcome Section */}

Bem-vindo ao Portal AutomatizaSE, {userName}!

Gerencie suas integrações de WhatsApp e Google Calendar.

{/* WhatsApp Instances Section */}

Instâncias WhatsApp

{loading ? (
Carregando instâncias...
) : instances.length === 0 ? (
Nenhuma instância configurada
) : (
{instances.map((instance) => ( handleGenerateQR(instance.instance)} onDisconnect={() => handleDisconnectClick(instance.instance)} /> ))}
)}
{/* Google Calendar Section */}

Integrações

{calendarLoading ? (
Carregando status do Google Calendar...
) : ( )}
{/* QR Code Modal */} {/* Disconnect Confirmation Modal */} setConfirmModalOpen(false)} onConfirm={handleDisconnectConfirm} title="Desconectar Instância" message={`Tem certeza que deseja desconectar a instância "${disconnectInstanceName}"?`} confirmText="Desconectar" cancelText="Cancelar" loading={disconnectLoading} /> {/* Toast Notification */} setToastVisible(false)} />
); }