diff --git a/src/components/whatsapp/CreateInstanceForm.tsx b/src/components/whatsapp/CreateInstanceForm.tsx index 4626e6b..16f4ad8 100644 --- a/src/components/whatsapp/CreateInstanceForm.tsx +++ b/src/components/whatsapp/CreateInstanceForm.tsx @@ -4,11 +4,12 @@ import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/com import { Input } from '@/components/ui/input'; import { Button } from '@/components/ui/button'; import { Label } from '@/components/ui/label'; -import { MessageCircle } from 'lucide-react'; +import { MessageCircle, AlertCircle } from 'lucide-react'; import { useToast } from '@/hooks/use-toast'; import { createWhatsAppInstance } from '@/services/whatsAppService'; -import { updateUserWhatsAppInstance } from '@/services/whatsAppInstanceService'; +import { updateUserWhatsAppInstance, getUserWhatsAppInstance } from '@/services/whatsAppInstanceService'; import { WhatsAppInstance } from '@/types/whatsAppTypes'; +import { Alert, AlertDescription } from '@/components/ui/alert'; interface CreateInstanceFormProps { onInstanceCreated: (instance: WhatsAppInstance) => void; @@ -22,12 +23,44 @@ const CreateInstanceForm = ({ const { toast } = useToast(); const [loading, setLoading] = useState(false); const [phoneNumber, setPhoneNumber] = useState(''); + const [hasExistingInstance, setHasExistingInstance] = useState(false); + const [checkingExistingInstance, setCheckingExistingInstance] = useState(true); const currentUserId = localStorage.getItem('userId') || ''; const userEmail = localStorage.getItem('userEmail') || ''; // Nome da instância será sempre o email do usuário const instanceName = userEmail; + // Verificar se o usuário já tem uma instância + useEffect(() => { + const checkExistingInstance = async () => { + if (!userEmail) { + setCheckingExistingInstance(false); + return; + } + + try { + console.log('Verificando se usuário já tem instância:', userEmail); + const existingInstance = await getUserWhatsAppInstance(userEmail); + + if (existingInstance && existingInstance.instancia_zap) { + console.log('Usuário já possui instância:', existingInstance.instancia_zap); + setHasExistingInstance(true); + } else { + console.log('Usuário não possui instância'); + setHasExistingInstance(false); + } + } catch (error) { + console.error('Erro ao verificar instância existente:', error); + setHasExistingInstance(false); + } finally { + setCheckingExistingInstance(false); + } + }; + + checkExistingInstance(); + }, [userEmail]); + const handleCreateInstance = async () => { // Validate form fields if (!userEmail) { @@ -58,37 +91,46 @@ const CreateInstanceForm = ({ return; } + // Verificar novamente se já existe instância antes de criar + if (hasExistingInstance) { + toast({ + title: "Erro", + description: "Você já possui uma instância WhatsApp. Apenas uma instância por usuário é permitida.", + variant: "destructive", + }); + return; + } + setLoading(true); try { - console.log(`Creating instance with name ${instanceName} and number ${phoneNumber}`); - const data = await createWhatsAppInstance(instanceName, phoneNumber); + console.log(`Criando instância com nome ${instanceName} e número ${phoneNumber}`); - console.log('API response for create instance:', data); + // 1. Primeiro atualizar o banco de dados com a instância + await updateUserWhatsAppInstance(userEmail, instanceName, 'desconectado'); + console.log('Instância registrada no banco de dados'); - // Create new instance object with user ID + // 2. Criar instância na API + const data = await createWhatsAppInstance(instanceName, phoneNumber); + console.log('Resposta da API de criação de instância:', data); + + // 3. Criar objeto da instância const newInstance: WhatsAppInstance = { instanceName, - instanceId: instanceName, // Use instanceName as the ID for consistency + instanceId: instanceName, phoneNumber, - userId: currentUserId, // Associate with current user + userId: currentUserId, status: data.instance?.status || 'created', qrcode: data.qrcode?.base64 || null, - connectionState: 'closed' // Default to closed/disconnected + connectionState: 'closed' }; - console.log('New instance created:', newInstance); + console.log('Nova instância criada:', newInstance); - // Atualizar o banco de dados com a instância - try { - await updateUserWhatsAppInstance(userEmail, instanceName, 'desconectado'); - console.log('Instância salva no banco de dados'); - } catch (dbError) { - console.error('Erro ao salvar instância no banco:', dbError); - // Não bloquear o processo se falhar ao salvar no banco - } + // 4. Atualizar estado para evitar nova criação + setHasExistingInstance(true); - // Notify parent component about the new instance + // 5. Notificar componente pai onInstanceCreated(newInstance); toast({ @@ -100,7 +142,16 @@ const CreateInstanceForm = ({ setPhoneNumber(''); } catch (error) { - console.error("Error creating WhatsApp instance:", error); + console.error("Erro ao criar instância WhatsApp:", error); + + // Se houve erro na API, remover do banco de dados + try { + await updateUserWhatsAppInstance(userEmail, '', 'desconectado'); + console.log('Instância removida do banco devido ao erro na API'); + } catch (dbError) { + console.error('Erro ao remover instância do banco:', dbError); + } + toast({ title: "Erro na criação da instância", description: "Ocorreu um erro ao conectar com a API. Tente novamente mais tarde.", @@ -111,6 +162,53 @@ const CreateInstanceForm = ({ } }; + if (checkingExistingInstance) { + return ( + + +
+
+

Verificando instâncias existentes...

+
+
+
+ ); + } + + if (hasExistingInstance) { + return ( + + +
+ + WhatsApp já Conectado +
+ + Você já possui uma instância WhatsApp vinculada ao seu email + +
+ + + + + Apenas uma instância WhatsApp por usuário é permitida. + Sua instância atual: {instanceName} + + + +
+

+ ✓ Instância ativa: {instanceName} +

+

+ Para gerenciar sua instância, utilize os botões na lista de instâncias acima. +

+
+
+
+ ); + } + return ( @@ -155,6 +253,15 @@ const CreateInstanceForm = ({ > {loading ? "Criando..." : "Criar Instância"} + +
+

Importante:

+
    +
  • • Apenas uma instância por usuário é permitida
  • +
  • • O nome da instância será seu email de login
  • +
  • • Após criar, você precisará escanear o QR Code para conectar
  • +
+
); diff --git a/src/hooks/whatsApp/useWhatsAppInstance.ts b/src/hooks/whatsApp/useWhatsAppInstance.ts index d76e3cc..b2fe254 100644 --- a/src/hooks/whatsApp/useWhatsAppInstance.ts +++ b/src/hooks/whatsApp/useWhatsAppInstance.ts @@ -3,6 +3,7 @@ import { useState, useEffect } from 'react'; import { useToast } from '@/hooks/use-toast'; import { WhatsAppInstance } from '@/types/whatsAppTypes'; import { fetchSpecificInstance } from '@/services/whatsApp/instanceManagement'; +import { getUserWhatsAppInstance } from '@/services/whatsAppInstanceService'; // Key used for storing instance name in localStorage export const WHATSAPP_INSTANCE_KEY = 'whatsapp_instance_name'; @@ -12,19 +13,47 @@ export const useWhatsAppInstance = ( 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 userEmail = localStorage.getItem('userEmail') || ''; + // Get instance name from database/localStorage + const [instanceName, setInstanceName] = useState(''); const [isLoading, setIsLoading] = useState(false); const [instanceFound, setInstanceFound] = useState(false); const [shouldShowToast, setShouldShowToast] = useState(false); const [toastMessage, setToastMessage] = useState({ title: '', description: '', variant: '' as any }); + // Load instance name from database on component mount + useEffect(() => { + const loadInstanceFromDatabase = async () => { + if (!userEmail || !currentUserId) return; + + try { + console.log('Carregando instância do banco de dados para:', userEmail); + const instanceData = await getUserWhatsAppInstance(userEmail); + + if (instanceData && instanceData.instancia_zap) { + console.log('Instância encontrada no banco:', instanceData.instancia_zap); + setInstanceName(instanceData.instancia_zap); + setInstanceFound(true); + + // Also save to localStorage for consistency + localStorage.setItem(`${WHATSAPP_INSTANCE_KEY}_${currentUserId}`, instanceData.instancia_zap); + } else { + console.log('Nenhuma instância encontrada no banco'); + setInstanceFound(false); + + // Clear localStorage if no instance in database + localStorage.removeItem(`${WHATSAPP_INSTANCE_KEY}_${currentUserId}`); + } + } catch (error) { + console.error('Erro ao carregar instância do banco:', error); + setInstanceFound(false); + } + }; + + loadInstanceFromDatabase(); + }, [userEmail, currentUserId]); + // Function to fetch specific instance by name const fetchInstanceByName = async () => { // Skip if no instance name @@ -41,9 +70,9 @@ export const useWhatsAppInstance = ( setIsLoading(true); try { - console.log(`Fetching specific instance: ${instanceName}`); + console.log(`Buscando instância específica: ${instanceName}`); const data = await fetchSpecificInstance(instanceName); - console.log('Fetch specific instance response:', data); + console.log('Resposta da busca de instância específica:', data); if (data && data.instance) { // Instance found, create or update instance object @@ -57,7 +86,7 @@ export const useWhatsAppInstance = ( qrcode: data.qrcode?.base64 || null }; - console.log('Found instance:', foundInstance); + console.log('Instância encontrada:', foundInstance); addInstance(foundInstance); setInstanceFound(true); @@ -70,10 +99,10 @@ export const useWhatsAppInstance = ( setShouldShowToast(true); } else { setInstanceFound(false); - console.log(`Instance ${instanceName} not found`); + console.log(`Instância ${instanceName} não encontrada`); } } catch (error) { - console.error('Error fetching specific instance:', error); + console.error('Erro ao buscar instância específica:', error); setInstanceFound(false); // Set toast data instead of calling toast directly @@ -100,7 +129,7 @@ export const useWhatsAppInstance = ( } }, [shouldShowToast, toastMessage, toast]); - // Save instance name to localStorage + // Save instance name to localStorage and database const saveInstanceName = (name: string) => { if (currentUserId) { localStorage.setItem(`${WHATSAPP_INSTANCE_KEY}_${currentUserId}`, name); @@ -108,7 +137,7 @@ export const useWhatsAppInstance = ( } }; - // Clear instance name from localStorage + // Clear instance name from localStorage and database const clearInstanceName = () => { if (currentUserId) { localStorage.removeItem(`${WHATSAPP_INSTANCE_KEY}_${currentUserId}`); @@ -117,8 +146,6 @@ export const useWhatsAppInstance = ( } }; - // Don't automatically load the instance - removed the useEffect that called fetchInstanceByName - return { instanceName, isLoading, diff --git a/src/services/whatsAppInstanceService.ts b/src/services/whatsAppInstanceService.ts index 16060db..758d75a 100644 --- a/src/services/whatsAppInstanceService.ts +++ b/src/services/whatsAppInstanceService.ts @@ -10,6 +10,8 @@ export async function updateUserWhatsAppInstance( status: 'conectado' | 'desconectado' ): Promise { try { + console.log(`Atualizando instância no banco: ${userEmail} -> ${instanceName} (${status})`); + const { error } = await supabase .from('usuarios') .update({ @@ -23,7 +25,7 @@ export async function updateUserWhatsAppInstance( throw error; } - console.log(`Instância WhatsApp atualizada: ${instanceName} - ${status}`); + console.log(`Instância WhatsApp atualizada com sucesso: ${instanceName} - ${status}`); } catch (error) { console.error('Erro ao atualizar instância WhatsApp no banco:', error); throw error; @@ -45,7 +47,7 @@ export async function getUserWhatsAppInstance(userEmail: string): Promise<{ .from('usuarios') .select('instancia_zap, status_instancia, whatsapp') .eq('email', userEmail.trim().toLowerCase()) - .maybeSingle(); // Use maybeSingle em vez de single para evitar erro quando não encontrar + .maybeSingle(); if (error) { console.error('Erro ao buscar instância WhatsApp:', error); @@ -59,3 +61,43 @@ export async function getUserWhatsAppInstance(userEmail: string): Promise<{ return null; } } + +/** + * Verifica se o usuário já possui uma instância ativa + */ +export async function checkUserHasInstance(userEmail: string): Promise { + try { + const instanceData = await getUserWhatsAppInstance(userEmail); + return !!(instanceData && instanceData.instancia_zap && instanceData.instancia_zap.trim() !== ''); + } catch (error) { + console.error('Erro ao verificar se usuário tem instância:', error); + return false; + } +} + +/** + * Remove a instância WhatsApp do usuário + */ +export async function removeUserWhatsAppInstance(userEmail: string): Promise { + try { + console.log(`Removendo instância do usuário: ${userEmail}`); + + const { error } = await supabase + .from('usuarios') + .update({ + instancia_zap: null, + status_instancia: 'desconectado' + }) + .eq('email', userEmail.trim().toLowerCase()); + + if (error) { + console.error('Erro ao remover instância WhatsApp:', error); + throw error; + } + + console.log('Instância WhatsApp removida com sucesso'); + } catch (error) { + console.error('Erro ao remover instância WhatsApp do banco:', error); + throw error; + } +}