From 12e6cda1df782d9c7ccce5ca5d47bb79dcc525fc Mon Sep 17 00:00:00 2001 From: "gpt-engineer-app[bot]" <159125892+gpt-engineer-app[bot]@users.noreply.github.com> Date: Tue, 20 May 2025 16:01:08 +0000 Subject: [PATCH] Feat: Fetch WhatsApp instance on mount Adds functionality to fetch a WhatsApp instance from the Evolution API when the "Conectar WhatsApp" menu is accessed. The request uses the instance name entered in the form, includes the necessary headers, and displays the instance information. It also handles cases where the user is not logged in and when the instance is not found. --- .../whatsapp/CreateInstanceForm.tsx | 32 +++- src/pages/WhatsApp.tsx | 143 +++++++++++++----- src/services/whatsApp/instanceManagement.ts | 21 +++ 3 files changed, 155 insertions(+), 41 deletions(-) diff --git a/src/components/whatsapp/CreateInstanceForm.tsx b/src/components/whatsapp/CreateInstanceForm.tsx index 1ba7af9..c9a78da 100644 --- a/src/components/whatsapp/CreateInstanceForm.tsx +++ b/src/components/whatsapp/CreateInstanceForm.tsx @@ -1,5 +1,5 @@ -import { useState } from 'react'; +import { useState, useEffect } from 'react'; import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'; import { Input } from '@/components/ui/input'; import { Button } from '@/components/ui/button'; @@ -11,17 +11,35 @@ import { WhatsAppInstance } from '@/types/whatsAppTypes'; interface CreateInstanceFormProps { onInstanceCreated: (instance: WhatsAppInstance) => void; + initialInstanceName?: string; + onInstanceNameChange?: (name: string) => void; } -const CreateInstanceForm = ({ onInstanceCreated }: CreateInstanceFormProps) => { +const CreateInstanceForm = ({ + onInstanceCreated, + initialInstanceName = '', + onInstanceNameChange +}: CreateInstanceFormProps) => { const { toast } = useToast(); const [loading, setLoading] = useState(false); - const [instanceName, setInstanceName] = useState(() => { - // Get user's name from localStorage as default value - return localStorage.getItem('userName') || ''; - }); + const [instanceName, setInstanceName] = useState(initialInstanceName || ''); const [phoneNumber, setPhoneNumber] = useState(''); const currentUserId = localStorage.getItem('userId') || ''; + + // Update instance name if initial value changes + useEffect(() => { + if (initialInstanceName) { + setInstanceName(initialInstanceName); + } + }, [initialInstanceName]); + + const handleInstanceNameChange = (e: React.ChangeEvent) => { + const newName = e.target.value; + setInstanceName(newName); + if (onInstanceNameChange) { + onInstanceNameChange(newName); + } + }; const handleCreateInstance = async () => { // Validate form fields @@ -115,7 +133,7 @@ const CreateInstanceForm = ({ onInstanceCreated }: CreateInstanceFormProps) => { setInstanceName(e.target.value)} + onChange={handleInstanceNameChange} placeholder="Digite um nome para a instância" required /> diff --git a/src/pages/WhatsApp.tsx b/src/pages/WhatsApp.tsx index 80c0500..3ba06fd 100644 --- a/src/pages/WhatsApp.tsx +++ b/src/pages/WhatsApp.tsx @@ -1,5 +1,5 @@ -import { useEffect } from 'react'; +import { useEffect, useState } from 'react'; import Layout from '@/components/layout/Layout'; import { WhatsAppInstance } from '@/types/whatsAppTypes'; import CreateInstanceForm from '@/components/whatsapp/CreateInstanceForm'; @@ -9,6 +9,7 @@ import QrCodeDialog from '@/components/whatsapp/QrCodeDialog'; import { useWhatsAppInstances } from '@/hooks/useWhatsAppInstances'; import { useWhatsAppActions } from '@/hooks/useWhatsAppActions'; import { useToast } from '@/hooks/use-toast'; +import { fetchSpecificInstance } from '@/services/whatsApp/instanceManagement'; const WhatsApp = () => { const { toast } = useToast(); @@ -32,6 +33,64 @@ const WhatsApp = () => { handleDeleteInstance, handleViewQrCode } = useWhatsAppActions(updateInstance, removeInstance, checkAllInstancesStatus); + + const [instanceName, setInstanceName] = useState(() => { + // Get user's name from localStorage as default instance name + return localStorage.getItem('userName') || ''; + }); + 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(() => { @@ -63,28 +122,29 @@ const WhatsApp = () => { }; }, [instances.length, checkAllInstancesStatus]); - // Run refresh instances on initial load to get server instances + // Fetch the specific instance when the component mounts useEffect(() => { - // Only run on first render - const initialLoad = async () => { - if (instances.length === 0) { - try { - await refreshInstances(); - } catch (error) { - console.error("Error on initial instance refresh:", error); - } - } - }; - - initialLoad(); - // This effect should only run once when the component mounts - // eslint-disable-next-line react-hooks/exhaustive-deps - }, []); + if (currentUserId) { + fetchInstanceByName(); + } else { + toast({ + title: "Login necessário", + description: "Você precisa estar logado para ver suas instâncias do WhatsApp.", + variant: "destructive" + }); + } + }, [currentUserId, instanceName]); + + // Handler for when the user changes the instance name + const handleInstanceNameChange = (name: string) => { + setInstanceName(name); + }; // Handler for when a new instance is created const handleInstanceCreated = async (newInstance: WhatsAppInstance) => { console.log('New instance to be added:', newInstance); addInstance(newInstance); + setInstanceFound(true); // If there's a QR code in the response, show it if (newInstance.qrcode) { @@ -123,6 +183,7 @@ const WhatsApp = () => { }; console.log('Current instances in WhatsApp component:', instances); + console.log('Instance found status:', instanceFound); return ( @@ -131,23 +192,37 @@ const WhatsApp = () => {

Conectar WhatsApp

- {/* Form to create a new instance */} - - - {/* Stats component */} - - - {/* List of created instances */} - + {isLoading ? ( +
+
+

Buscando instância...

+
+ ) : !instanceFound ? ( + // Show create form if no instance found + + ) : ( + // Only show stats and instance list if instance found + <> + {/* Stats component */} + + + {/* List of created instances */} + + + )} {/* QR Code Dialog */} => { throw error; } }; + +/** + * Fetches a specific WhatsApp instance by name + */ +export const fetchSpecificInstance = async (instanceName: string): Promise => { + try { + console.log(`Fetching specific instance: ${instanceName}`); + + if (!instanceName) { + throw new Error("Instance name cannot be empty"); + } + + const data = await makeRequest(`/instance/fetchInstances/${encodeURIComponent(instanceName)}`, 'GET'); + + console.log(`Specific instance response for ${instanceName}:`, data); + return data; + } catch (error) { + console.error(`Error fetching specific instance ${instanceName}:`, error); + throw error; + } +};