diff --git a/src/components/whatsapp/LoadingState.tsx b/src/components/whatsapp/LoadingState.tsx new file mode 100644 index 0000000..024e498 --- /dev/null +++ b/src/components/whatsapp/LoadingState.tsx @@ -0,0 +1,17 @@ + +import React from 'react'; + +interface LoadingStateProps { + message?: string; +} + +const LoadingState = ({ message = "Buscando instância..." }: LoadingStateProps) => { + return ( +
+
+

{message}

+
+ ); +}; + +export default LoadingState; diff --git a/src/hooks/whatsApp/usePeriodicStatusCheck.ts b/src/hooks/whatsApp/usePeriodicStatusCheck.ts new file mode 100644 index 0000000..db9fc61 --- /dev/null +++ b/src/hooks/whatsApp/usePeriodicStatusCheck.ts @@ -0,0 +1,37 @@ + +import { useEffect } from 'react'; + +export const usePeriodicStatusCheck = ( + instancesCount: number, + checkAllInstancesStatus: () => Promise +) => { + // Set up periodic status checks + useEffect(() => { + console.log("Setting up periodic status checks, current instances:", instancesCount); + + // Check status initially after a short delay to prevent immediate execution + let initialCheck: NodeJS.Timeout; + if (instancesCount > 0) { + initialCheck = setTimeout(() => { + console.log("Running initial status check"); + checkAllInstancesStatus(); + }, 1000); + } + + // Set up interval for periodic checks (every 30 seconds) + const interval = setInterval(() => { + if (instancesCount > 0) { + console.log("Running periodic status check"); + checkAllInstancesStatus(); + } + }, 30000); // 30 seconds + + // Clean up interval and timeout when component unmounts + return () => { + clearInterval(interval); + if (initialCheck) { + clearTimeout(initialCheck); + } + }; + }, [instancesCount, checkAllInstancesStatus]); +}; diff --git a/src/hooks/whatsApp/useWhatsAppInstance.ts b/src/hooks/whatsApp/useWhatsAppInstance.ts new file mode 100644 index 0000000..501ef55 --- /dev/null +++ b/src/hooks/whatsApp/useWhatsAppInstance.ts @@ -0,0 +1,115 @@ + +import { useState, useEffect } from 'react'; +import { useToast } from '@/hooks/use-toast'; +import { WhatsAppInstance } from '@/types/whatsAppTypes'; +import { fetchSpecificInstance } from '@/services/whatsApp/instanceManagement'; + +// Key used for storing instance name in localStorage +export const WHATSAPP_INSTANCE_KEY = 'whatsapp_instance_name'; + +export const useWhatsAppInstance = ( + currentUserId: string, + addInstance: (instance: WhatsAppInstance) => void +) => { + const { toast } = useToast(); + // Get instance name from localStorage + const [instanceName, setInstanceName] = useState(() => { + if (currentUserId) { + return localStorage.getItem(`${WHATSAPP_INSTANCE_KEY}_${currentUserId}`) || ''; + } + return ''; + }); + + const [isLoading, setIsLoading] = useState(false); + const [instanceFound, setInstanceFound] = useState(false); + + // Function to fetch specific instance by name + const fetchInstanceByName = async () => { + // Skip if user not logged in or no instance name + if (!currentUserId || !instanceName.trim()) { + return; + } + + setIsLoading(true); + + try { + console.log(`Fetching specific instance: ${instanceName}`); + const data = await fetchSpecificInstance(instanceName); + console.log('Fetch specific instance response:', data); + + if (data && data.instance) { + // Instance found, create or update instance object + const foundInstance: WhatsAppInstance = { + instanceName, + instanceId: instanceName, + phoneNumber: data.instance.number || '', + userId: currentUserId, + status: data.instance.status || 'unknown', + connectionState: data.instance.state || 'closed', + qrcode: data.qrcode?.base64 || null + }; + + console.log('Found instance:', foundInstance); + addInstance(foundInstance); + setInstanceFound(true); + toast({ + title: "Instância encontrada", + description: `A instância ${instanceName} foi localizada no servidor.` + }); + } else { + setInstanceFound(false); + console.log(`Instance ${instanceName} not found`); + } + } catch (error) { + console.error('Error fetching specific instance:', error); + setInstanceFound(false); + toast({ + title: "Instância não encontrada", + description: "Não foi possível encontrar a instância com este nome.", + variant: "destructive" + }); + } finally { + setIsLoading(false); + } + }; + + // Save instance name to localStorage + const saveInstanceName = (name: string) => { + if (currentUserId) { + localStorage.setItem(`${WHATSAPP_INSTANCE_KEY}_${currentUserId}`, name); + setInstanceName(name); + } + }; + + // Clear instance name from localStorage + const clearInstanceName = () => { + if (currentUserId) { + localStorage.removeItem(`${WHATSAPP_INSTANCE_KEY}_${currentUserId}`); + setInstanceName(''); + setInstanceFound(false); + } + }; + + // Run once when component mounts + useEffect(() => { + if (currentUserId) { + fetchInstanceByName(); + } else { + toast({ + title: "Login necessário", + description: "Você precisa estar logado para ver suas instâncias do WhatsApp.", + variant: "destructive" + }); + } + }, [currentUserId]); // Only depend on userId, not instanceName + + return { + instanceName, + isLoading, + instanceFound, + setInstanceFound, + fetchInstanceByName, + saveInstanceName, + clearInstanceName + }; +}; diff --git a/src/pages/WhatsApp.tsx b/src/pages/WhatsApp.tsx index c6e8c11..bfc2346 100644 --- a/src/pages/WhatsApp.tsx +++ b/src/pages/WhatsApp.tsx @@ -1,20 +1,17 @@ -import { useEffect, useState } from 'react'; -import Layout from '@/components/layout/Layout'; import { WhatsAppInstance } from '@/types/whatsAppTypes'; +import Layout from '@/components/layout/Layout'; import CreateInstanceForm from '@/components/whatsapp/CreateInstanceForm'; import InstanceList from '@/components/whatsapp/InstanceList'; import InstanceStats from '@/components/whatsapp/InstanceStats'; import QrCodeDialog from '@/components/whatsapp/QrCodeDialog'; +import LoadingState from '@/components/whatsapp/LoadingState'; import { useWhatsAppInstances } from '@/hooks/useWhatsAppInstances'; import { useWhatsAppActions } from '@/hooks/useWhatsAppActions'; -import { useToast } from '@/hooks/use-toast'; -import { fetchSpecificInstance } from '@/services/whatsApp/instanceManagement'; - -const WHATSAPP_INSTANCE_KEY = 'whatsapp_instance_name'; +import { useWhatsAppInstance, WHATSAPP_INSTANCE_KEY } from '@/hooks/whatsApp/useWhatsAppInstance'; +import { usePeriodicStatusCheck } from '@/hooks/whatsApp/usePeriodicStatusCheck'; const WhatsApp = () => { - const { toast } = useToast(); const { instances, isRefreshing, @@ -22,7 +19,8 @@ const WhatsApp = () => { removeInstance, updateInstance, refreshInstances, - checkAllInstancesStatus + checkAllInstancesStatus, + currentUserId } = useWhatsAppInstances(); const { @@ -36,111 +34,18 @@ const WhatsApp = () => { handleViewQrCode } = useWhatsAppActions(updateInstance, removeInstance, checkAllInstancesStatus); - // Obter o nome da instância salvo no localStorage - const [instanceName, setInstanceName] = useState(() => { - const userId = localStorage.getItem('userId'); - if (userId) { - return localStorage.getItem(`${WHATSAPP_INSTANCE_KEY}_${userId}`) || ''; - } - return ''; - }); - - const [isLoading, setIsLoading] = useState(false); - const [instanceFound, setInstanceFound] = useState(false); - const currentUserId = localStorage.getItem('userId') || ''; - - // Function to fetch specific instance by name - const fetchInstanceByName = async () => { - // Skip if user not logged in or no instance name - if (!currentUserId || !instanceName.trim()) { - return; - } - - setIsLoading(true); - - try { - console.log(`Fetching specific instance: ${instanceName}`); - const data = await fetchSpecificInstance(instanceName); - console.log('Fetch specific instance response:', data); - - if (data && data.instance) { - // Instance found, create or update instance object - const foundInstance: WhatsAppInstance = { - instanceName, - instanceId: instanceName, - phoneNumber: data.instance.number || '', - userId: currentUserId, - status: data.instance.status || 'unknown', - connectionState: data.instance.state || 'closed', - qrcode: data.qrcode?.base64 || null - }; - - console.log('Found instance:', foundInstance); - addInstance(foundInstance); - setInstanceFound(true); - toast({ - title: "Instância encontrada", - description: `A instância ${instanceName} foi localizada no servidor.` - }); - } else { - setInstanceFound(false); - console.log(`Instance ${instanceName} not found`); - } - } catch (error) { - console.error('Error fetching specific instance:', error); - setInstanceFound(false); - toast({ - title: "Instância não encontrada", - description: "Não foi possível encontrar a instância com este nome.", - variant: "destructive" - }); - } finally { - setIsLoading(false); - } - }; - - // Set up periodic status checks - useEffect(() => { - console.log("Setting up periodic status checks, current instances:", instances.length); - - // Check status initially after a short delay to prevent immediate execution - let initialCheck: NodeJS.Timeout; - if (instances.length > 0) { - initialCheck = setTimeout(() => { - console.log("Running initial status check"); - checkAllInstancesStatus(); - }, 1000); - } - - // Set up interval for periodic checks (every 30 seconds) - const interval = setInterval(() => { - if (instances.length > 0) { - console.log("Running periodic status check"); - checkAllInstancesStatus(); - } - }, 30000); // 30 seconds - - // Clean up interval and timeout when component unmounts - return () => { - clearInterval(interval); - if (initialCheck) { - clearTimeout(initialCheck); - } - }; - }, [instances.length, checkAllInstancesStatus]); - - // Fetch the specific instance when the component mounts (não a cada digitação) - useEffect(() => { - if (currentUserId) { - fetchInstanceByName(); - } else { - toast({ - title: "Login necessário", - description: "Você precisa estar logado para ver suas instâncias do WhatsApp.", - variant: "destructive" - }); - } - }, [currentUserId]); + // Custom hook for instance fetching and management + const { + instanceName, + isLoading, + instanceFound, + setInstanceFound, + saveInstanceName, + clearInstanceName + } = useWhatsAppInstance(currentUserId, addInstance); + + // Set up periodic status checking + usePeriodicStatusCheck(instances.length, checkAllInstancesStatus); // Handler para quando o usuário cria uma nova instância const handleInstanceCreated = (newInstance: WhatsAppInstance) => { @@ -149,10 +54,7 @@ const WhatsApp = () => { setInstanceFound(true); // Salvar o nome da instância no localStorage para uso futuro - if (currentUserId) { - localStorage.setItem(`${WHATSAPP_INSTANCE_KEY}_${currentUserId}`, newInstance.instanceName); - setInstanceName(newInstance.instanceName); - } + saveInstanceName(newInstance.instanceName); // If there's a QR code in the response, show it if (newInstance.qrcode) { @@ -165,11 +67,6 @@ const WhatsApp = () => { await checkAllInstancesStatus(); } catch (error) { console.error("Error checking status after instance creation:", error); - toast({ - title: "Aviso", - description: "Instância criada, mas não foi possível verificar o status. Tente atualizar a lista manualmente.", - variant: "default", - }); } }, 2000); }; @@ -182,18 +79,11 @@ const WhatsApp = () => { handleDeleteInstance(instanceId, instanceToDelete.instanceName); // Se a instância excluída for a atual, limpar o nome salvo - if (instanceToDelete.instanceName === instanceName && currentUserId) { - localStorage.removeItem(`${WHATSAPP_INSTANCE_KEY}_${currentUserId}`); - setInstanceName(''); - setInstanceFound(false); + if (instanceToDelete.instanceName === instanceName) { + clearInstanceName(); } } else { console.error(`Instance with ID ${instanceId} not found for deletion`); - toast({ - title: "Erro", - description: "Instância não encontrada para exclusão", - variant: "destructive", - }); } }; @@ -208,10 +98,7 @@ const WhatsApp = () => { {isLoading ? ( -
-
-

Buscando instância...

-
+ ) : !instanceFound ? ( // Show create form if no instance found