Fix: Address instance deletion, disappearing instances, and update errors

- Fixed instance deletion failures.
- Resolved the issue of instances appearing and disappearing in a loop.
- Addressed errors during instance updates.
- Check for missing information.
This commit is contained in:
gpt-engineer-app[bot] 2025-05-19 18:07:25 +00:00
parent f26e41707a
commit dec494083c
7 changed files with 264 additions and 69 deletions

View File

@ -56,6 +56,7 @@ const CreateInstanceForm = ({ onInstanceCreated }: CreateInstanceFormProps) => {
setLoading(true); setLoading(true);
try { try {
console.log(`Creating instance with name ${instanceName} and number ${phoneNumber}`);
const data = await createWhatsAppInstance(instanceName, phoneNumber); const data = await createWhatsAppInstance(instanceName, phoneNumber);
console.log('API response for create instance:', data); console.log('API response for create instance:', data);
@ -63,7 +64,7 @@ const CreateInstanceForm = ({ onInstanceCreated }: CreateInstanceFormProps) => {
// Create new instance object with user ID // Create new instance object with user ID
const newInstance: WhatsAppInstance = { const newInstance: WhatsAppInstance = {
instanceName, instanceName,
instanceId: data.instance?.instanceId || instanceName, // Use instanceName as fallback ID instanceId: instanceName, // Use instanceName as the ID for consistency
phoneNumber, phoneNumber,
userId: currentUserId, // Associate with current user userId: currentUserId, // Associate with current user
status: data.instance?.status || 'created', status: data.instance?.status || 'created',

View File

@ -141,6 +141,27 @@ const InstanceCard = ({
); );
}; };
// Determina o estado de conexão a ser exibido
const getConnectionStatus = () => {
// Se o status é 'disconnected', 'error', 'destroyed', ou não está definido, consideramos como desconectado
if (instance.status === 'disconnected' ||
instance.status === 'error' ||
instance.status === 'destroyed' ||
!instance.status) {
return 'closed';
}
// Se o connectionState já está definido como 'open', manter
if (instance.connectionState === 'open') {
return 'open';
}
// Em outros casos, usar o valor atual do connectionState
return instance.connectionState || 'closed';
};
const connectionStatus = getConnectionStatus();
return ( return (
<> <>
<Card className="h-full"> <Card className="h-full">
@ -154,11 +175,16 @@ const InstanceCard = ({
<span>{instance.phoneNumber}</span> <span>{instance.phoneNumber}</span>
</div> </div>
<div className="flex items-center text-sm"> <div className="flex items-center text-sm">
{instance.connectionState === 'open' ? ( {connectionStatus === 'open' ? (
<Badge variant="outline" className="flex items-center gap-1 text-green-500 border-green-300"> <Badge variant="outline" className="flex items-center gap-1 text-green-500 border-green-300">
<span className="inline-block w-2 h-2 rounded-full bg-green-500"></span> <span className="inline-block w-2 h-2 rounded-full bg-green-500"></span>
Status: Conectado Status: Conectado
</Badge> </Badge>
) : connectionStatus === 'connecting' ? (
<Badge variant="outline" className="flex items-center gap-1 text-orange-500 border-orange-300">
<span className="inline-block w-2 h-2 rounded-full bg-orange-500"></span>
Status: Conectando
</Badge>
) : ( ) : (
<Badge variant="outline" className="flex items-center gap-1 text-red-500 border-red-300"> <Badge variant="outline" className="flex items-center gap-1 text-red-500 border-red-300">
<span className="inline-block w-2 h-2 rounded-full bg-red-500"></span> <span className="inline-block w-2 h-2 rounded-full bg-red-500"></span>

View File

@ -8,7 +8,7 @@ interface InstanceStatsProps {
const InstanceStats = ({ instances }: InstanceStatsProps) => { const InstanceStats = ({ instances }: InstanceStatsProps) => {
const totalInstances = instances.length; const totalInstances = instances.length;
const connectedInstances = instances.filter(i => i.connectionState === 'open').length; const connectedInstances = instances.filter(i => i.connectionState === 'open').length;
const disconnectedInstances = instances.filter(i => i.connectionState === 'closed').length; const disconnectedInstances = instances.filter(i => i.connectionState === 'closed' || i.status === 'disconnected').length;
const connectingInstances = instances.filter(i => i.connectionState === 'connecting').length; const connectingInstances = instances.filter(i => i.connectionState === 'connecting').length;
if (totalInstances === 0) { if (totalInstances === 0) {

View File

@ -22,6 +22,7 @@ export const useWhatsAppActions = (
// Handler for quando uma instância é reiniciada // Handler for quando uma instância é reiniciada
const handleRestartInstance = async (instance: WhatsAppInstance) => { const handleRestartInstance = async (instance: WhatsAppInstance) => {
try { try {
console.log(`Attempting to restart instance ${instance.instanceName}`);
await restartInstance(instance.instanceName); await restartInstance(instance.instanceName);
// Atualiza o estado da instância para "connecting" // Atualiza o estado da instância para "connecting"
@ -29,6 +30,7 @@ export const useWhatsAppActions = (
...instance, ...instance,
connectionState: 'connecting' as const connectionState: 'connecting' as const
}; };
console.log(`Instance ${instance.instanceName} restart initiated, setting state to connecting`, updatedInstance);
updateInstance(updatedInstance); updateInstance(updatedInstance);
toast({ toast({
@ -52,13 +54,16 @@ export const useWhatsAppActions = (
// Handler for quando uma instância é desconectada // Handler for quando uma instância é desconectada
const handleLogoutInstance = async (instance: WhatsAppInstance) => { const handleLogoutInstance = async (instance: WhatsAppInstance) => {
try { try {
console.log(`Attempting to logout instance ${instance.instanceName}`);
await logoutInstance(instance.instanceName); await logoutInstance(instance.instanceName);
// Atualiza o estado da instância para "closed" // Atualiza o estado da instância para "closed"
const updatedInstance = { const updatedInstance = {
...instance, ...instance,
connectionState: 'closed' as const connectionState: 'closed' as const,
status: 'disconnected'
}; };
console.log(`Instance ${instance.instanceName} logout successful, updating instance state`, updatedInstance);
updateInstance(updatedInstance); updateInstance(updatedInstance);
toast({ toast({
@ -79,15 +84,21 @@ export const useWhatsAppActions = (
// Handler for quando a presença é alterada // Handler for quando a presença é alterada
const handleSetPresence = async (instance: WhatsAppInstance, presence: 'online' | 'offline') => { const handleSetPresence = async (instance: WhatsAppInstance, presence: 'online' | 'offline') => {
try { try {
console.log(`Setting presence to ${presence} for instance ${instance.instanceName}`);
await setInstancePresence(instance.instanceName, presence); await setInstancePresence(instance.instanceName, presence);
const updatedInstance = {
...instance,
presence: presence
};
console.log(`Updated instance with new presence status`, updatedInstance);
updateInstance(updatedInstance);
toast({ toast({
title: "Sucesso", title: "Sucesso",
description: `Instância ${instance.instanceName} agora está ${presence === 'online' ? 'Online' : 'Offline'}` description: `Instância ${instance.instanceName} agora está ${presence === 'online' ? 'Online' : 'Offline'}`
}); });
// Não precisamos alterar o estado da instância aqui, pois isso não afeta o connectionState
} catch (error) { } catch (error) {
console.error(`Error setting presence to ${presence} for instance ${instance.instanceName}:`, error); console.error(`Error setting presence to ${presence} for instance ${instance.instanceName}:`, error);
toast({ toast({
@ -100,11 +111,12 @@ export const useWhatsAppActions = (
// Handler for when an instance is deleted // Handler for when an instance is deleted
const handleDeleteInstance = async (instanceId: string, instanceName: string) => { const handleDeleteInstance = async (instanceId: string, instanceName: string) => {
console.log(`Deleting instance with ID: ${instanceId}`); console.log(`Deleting instance with ID: ${instanceId}, name: ${instanceName}`);
try { try {
// Call API to delete instance // Call API to delete instance
await deleteInstance(instanceName); const response = await deleteInstance(instanceName);
console.log(`Deletion API response for instance ${instanceName}:`, response);
// Remove from local state // Remove from local state
removeInstance(instanceId); removeInstance(instanceId);
@ -112,6 +124,7 @@ export const useWhatsAppActions = (
// If we're viewing QR code for this instance, close the dialog // If we're viewing QR code for this instance, close the dialog
if (activeInstance?.instanceId === instanceId) { if (activeInstance?.instanceId === instanceId) {
setQrDialogOpen(false); setQrDialogOpen(false);
setActiveInstance(null);
} }
toast({ toast({
@ -120,9 +133,19 @@ export const useWhatsAppActions = (
}); });
} catch (error) { } catch (error) {
console.error(`Error deleting instance with ID ${instanceId}:`, error); console.error(`Error deleting instance with ID ${instanceId}:`, error);
// Even if the API call fails, we still want to remove the instance from local storage
// This handles the case when instances are in inconsistent state with the server
removeInstance(instanceId);
if (activeInstance?.instanceId === instanceId) {
setQrDialogOpen(false);
setActiveInstance(null);
}
toast({ toast({
title: "Erro", title: "Aviso",
description: "Falha ao excluir a instância. Tente novamente.", description: "Instância removida localmente, mas pode haver falha na comunicação com o servidor.",
variant: "destructive", variant: "destructive",
}); });
} }
@ -130,6 +153,7 @@ export const useWhatsAppActions = (
// Handler for when QR code dialog is requested // Handler for when QR code dialog is requested
const handleViewQrCode = async (instance: WhatsAppInstance) => { const handleViewQrCode = async (instance: WhatsAppInstance) => {
console.log(`Opening QR code dialog for instance: ${instance.instanceName}`);
setActiveInstance(instance); setActiveInstance(instance);
setQrDialogOpen(true); setQrDialogOpen(true);

View File

@ -1,5 +1,4 @@
import { useState, useEffect, useCallback } from 'react';
import { useState, useEffect } from 'react';
import { useToast } from '@/hooks/use-toast'; import { useToast } from '@/hooks/use-toast';
import { WhatsAppInstance } from '@/types/whatsAppTypes'; import { WhatsAppInstance } from '@/types/whatsAppTypes';
import { import {
@ -37,26 +36,50 @@ export const useWhatsAppInstances = () => {
}, [instances, currentUserId]); }, [instances, currentUserId]);
// Function to check connection status for all instances // Function to check connection status for all instances
const checkAllInstancesStatus = async () => { const checkAllInstancesStatus = useCallback(async () => {
if (instances.length === 0) return; if (instances.length === 0) return;
console.log(`Checking connection status for ${instances.length} instances`);
try { try {
const updatedInstances = await Promise.all( const updatedInstances = await Promise.all(
instances.map(async (instance) => { instances.map(async (instance) => {
try { try {
console.log(`Checking status for ${instance.instanceName}`);
const state = await fetchConnectionState(instance.instanceName); const state = await fetchConnectionState(instance.instanceName);
return { ...instance, connectionState: state }; console.log(`Status for ${instance.instanceName}: ${state}`);
// Only update connectionState if it's different
if (instance.connectionState !== state) {
return { ...instance, connectionState: state };
}
return instance;
} catch (error) { } catch (error) {
console.error(`Error checking status for ${instance.instanceName}:`, error); console.error(`Error checking status for ${instance.instanceName}:`, error);
return { ...instance, connectionState: 'closed' as const };
// If the instance doesn't exist on the server, mark it as closed
if (error instanceof Error && error.message.includes("does not exist")) {
return { ...instance, connectionState: 'closed', status: 'disconnected' };
}
// Keep the current state in case of other errors
return instance;
} }
}) })
); );
setInstances(updatedInstances);
// Only update state if there are actual changes
const hasChanges = JSON.stringify(updatedInstances) !== JSON.stringify(instances);
if (hasChanges) {
console.log('Updated instances after status check:', updatedInstances);
setInstances(updatedInstances);
} else {
console.log('No changes in instance status');
}
} catch (error) { } catch (error) {
console.error("Error checking instances status:", error); console.error("Error checking instances status:", error);
} }
}; }, [instances]);
// Handler para atualizar a lista de instâncias do servidor // Handler para atualizar a lista de instâncias do servidor
const refreshInstances = async () => { const refreshInstances = async () => {
@ -71,35 +94,47 @@ export const useWhatsAppInstances = () => {
setIsRefreshing(true); setIsRefreshing(true);
try { try {
console.log("Fetching instances from server...");
const response = await fetchAllInstances(); const response = await fetchAllInstances();
console.log("Fetched instances from server:", response); console.log("Fetched instances from server:", response);
if (response.instances && Array.isArray(response.instances)) { if (response.instances && Array.isArray(response.instances)) {
// Filtra instâncias para mostrar apenas as do usuário atual // Mapeia as instâncias do servidor para o formato correto com userId
// E mapeia para o formato correto com userId
const serverInstances: WhatsAppInstance[] = response.instances const serverInstances: WhatsAppInstance[] = response.instances
.filter(serverInstance => {
// Implemente sua lógica de filtro para o usuário atual (se necessário)
// Por padrão, vamos assumir que todas as instâncias são do usuário atual
return true;
})
.map(serverInstance => ({ .map(serverInstance => ({
instanceName: serverInstance.instanceName, instanceName: serverInstance.instanceName,
instanceId: serverInstance.instanceName, instanceId: serverInstance.instanceName, // Using instanceName as the ID for consistency
phoneNumber: serverInstance.number || 'Desconhecido', phoneNumber: serverInstance.number || 'Desconhecido',
userId: currentUserId, userId: currentUserId,
connectionState: serverInstance.state || 'closed', connectionState: serverInstance.state || 'closed',
status: serverInstance.status || 'unknown' status: serverInstance.status || 'unknown'
})); }));
// Mesclando instâncias do servidor com as locais (para não perder dados locais) console.log("Mapped server instances:", serverInstances);
const localInstanceIds = new Set(instances.map(i => i.instanceId));
const newInstances = [ // Identifica instâncias novas que não existem localmente
...instances, const localInstanceIds = new Set(instances.map(i => i.instanceId));
...serverInstances.filter(i => !localInstanceIds.has(i.instanceId)) const newServerInstances = serverInstances.filter(i => !localInstanceIds.has(i.instanceId));
];
// Atualiza instâncias existentes com dados do servidor
const updatedExistingInstances = instances.map(localInstance => {
const serverMatch = serverInstances.find(si => si.instanceId === localInstance.instanceId);
if (serverMatch) {
return {
...localInstance,
connectionState: serverMatch.connectionState,
status: serverMatch.status
};
}
return localInstance;
});
// Combina tudo
const allInstances = [...updatedExistingInstances, ...newServerInstances];
console.log("Combined instances after refresh:", allInstances);
setInstances(allInstances);
setInstances(newInstances);
toast({ toast({
title: "Sucesso", title: "Sucesso",
description: `${serverInstances.length} instâncias encontradas no servidor`, description: `${serverInstances.length} instâncias encontradas no servidor`,
@ -120,18 +155,34 @@ export const useWhatsAppInstances = () => {
} finally { } finally {
setIsRefreshing(false); setIsRefreshing(false);
// Verificar status após atualizar a lista // Verificar status após atualizar a lista
checkAllInstancesStatus(); await checkAllInstancesStatus();
} }
}; };
// Add a new instance // Add a new instance
const addInstance = (newInstance: WhatsAppInstance) => { const addInstance = (newInstance: WhatsAppInstance) => {
console.log("New instance created, adding to instances list:", newInstance); console.log("New instance created, adding to instances list:", newInstance);
setInstances(prevInstances => [...prevInstances, newInstance]);
// Verifica se já existe uma instância com o mesmo ID
const existingIndex = instances.findIndex(inst => inst.instanceId === newInstance.instanceId);
if (existingIndex >= 0) {
// Atualiza a instância existente
console.log(`Instance with ID ${newInstance.instanceId} already exists, updating it`);
setInstances(prevInstances =>
prevInstances.map((instance, index) =>
index === existingIndex ? newInstance : instance
)
);
} else {
// Adiciona nova instância
setInstances(prevInstances => [...prevInstances, newInstance]);
}
}; };
// Remove an instance // Remove an instance
const removeInstance = (instanceId: string) => { const removeInstance = (instanceId: string) => {
console.log(`Removing instance with ID: ${instanceId}`);
setInstances(prevInstances => { setInstances(prevInstances => {
const filtered = prevInstances.filter(instance => instance.instanceId !== instanceId); const filtered = prevInstances.filter(instance => instance.instanceId !== instanceId);
console.log("Updated instances after deletion:", filtered); console.log("Updated instances after deletion:", filtered);
@ -141,13 +192,17 @@ export const useWhatsAppInstances = () => {
// Update an instance // Update an instance
const updateInstance = (updatedInstance: WhatsAppInstance) => { const updateInstance = (updatedInstance: WhatsAppInstance) => {
setInstances(prevInstances => console.log(`Updating instance: ${updatedInstance.instanceName}`, updatedInstance);
prevInstances.map(instance => setInstances(prevInstances => {
const newInstances = prevInstances.map(instance =>
instance.instanceId === updatedInstance.instanceId instance.instanceId === updatedInstance.instanceId
? updatedInstance ? updatedInstance
: instance : instance
) );
);
console.log("Updated instances:", newInstances);
return newInstances;
});
}; };
return { return {

View File

@ -8,8 +8,10 @@ import InstanceStats from '@/components/whatsapp/InstanceStats';
import QrCodeDialog from '@/components/whatsapp/QrCodeDialog'; import QrCodeDialog from '@/components/whatsapp/QrCodeDialog';
import { useWhatsAppInstances } from '@/hooks/useWhatsAppInstances'; import { useWhatsAppInstances } from '@/hooks/useWhatsAppInstances';
import { useWhatsAppActions } from '@/hooks/useWhatsAppActions'; import { useWhatsAppActions } from '@/hooks/useWhatsAppActions';
import { useToast } from '@/hooks/use-toast';
const WhatsApp = () => { const WhatsApp = () => {
const { toast } = useToast();
const { const {
instances, instances,
isRefreshing, isRefreshing,
@ -33,17 +35,20 @@ const WhatsApp = () => {
// Set up periodic status checks // Set up periodic status checks
useEffect(() => { useEffect(() => {
console.log("Setting up periodic status checks, current instances:", instances.length);
// Check status initially // Check status initially
if (instances.length > 0) { if (instances.length > 0) {
checkAllInstancesStatus(); checkAllInstancesStatus();
} }
// Set up interval for periodic checks (every 60 seconds) // Set up interval for periodic checks (every 30 seconds)
const interval = setInterval(() => { const interval = setInterval(() => {
if (instances.length > 0) { if (instances.length > 0) {
console.log("Running periodic status check");
checkAllInstancesStatus(); checkAllInstancesStatus();
} }
}, 60000); // 60 seconds }, 30000); // 30 seconds
// Clean up interval when component unmounts // Clean up interval when component unmounts
return () => { return () => {
@ -53,6 +58,21 @@ const WhatsApp = () => {
}; };
}, [instances.length, checkAllInstancesStatus]); }, [instances.length, checkAllInstancesStatus]);
// Run refresh instances on initial load to get server instances
useEffect(() => {
const initialLoad = async () => {
if (instances.length === 0) {
try {
await refreshInstances();
} catch (error) {
console.error("Error on initial instance refresh:", error);
}
}
};
initialLoad();
}, []);
// Handler for when a new instance is created // Handler for when a new instance is created
const handleInstanceCreated = async (newInstance: WhatsAppInstance) => { const handleInstanceCreated = async (newInstance: WhatsAppInstance) => {
console.log('New instance to be added:', newInstance); console.log('New instance to be added:', newInstance);
@ -64,14 +84,31 @@ const WhatsApp = () => {
} }
// Trigger a status check for all instances // Trigger a status check for all instances
await checkAllInstancesStatus(); try {
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",
});
}
}; };
// Handler for when an instance is deleted // Handler for when an instance is deleted
const handleDeleteInstanceWrapper = (instanceId: string) => { const handleDeleteInstanceWrapper = (instanceId: string) => {
console.log(`Instance deletion requested for ID: ${instanceId}`);
const instanceToDelete = instances.find(i => i.instanceId === instanceId); const instanceToDelete = instances.find(i => i.instanceId === instanceId);
if (instanceToDelete) { if (instanceToDelete) {
handleDeleteInstance(instanceId, instanceToDelete.instanceName); handleDeleteInstance(instanceId, instanceToDelete.instanceName);
} 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",
});
} }
}; };

View File

@ -11,6 +11,7 @@ export const createWhatsAppInstance = async (
instanceName: string, instanceName: string,
phoneNumber: string phoneNumber: string
): Promise<any> => { ): Promise<any> => {
console.log(`Creating new WhatsApp instance: ${instanceName}, ${phoneNumber}`);
const response = await fetch(`https://${SERVER_URL}/instance/create`, { const response = await fetch(`https://${SERVER_URL}/instance/create`, {
method: 'POST', method: 'POST',
headers: { headers: {
@ -27,13 +28,17 @@ export const createWhatsAppInstance = async (
if (!response.ok) { if (!response.ok) {
const errorData = await response.json(); const errorData = await response.json();
console.error('Error creating instance:', errorData);
throw new Error(errorData.message || 'Erro ao criar instância'); throw new Error(errorData.message || 'Erro ao criar instância');
} }
return response.json(); const data = await response.json();
console.log('Create instance API response:', data);
return data;
}; };
export const fetchQrCode = async (instanceName: string): Promise<any> => { export const fetchQrCode = async (instanceName: string): Promise<any> => {
console.log(`Fetching QR code for instance: ${instanceName}`);
const response = await fetch(`https://${SERVER_URL}/instance/connect/${encodeURIComponent(instanceName)}`, { const response = await fetch(`https://${SERVER_URL}/instance/connect/${encodeURIComponent(instanceName)}`, {
method: 'GET', method: 'GET',
headers: { headers: {
@ -44,14 +49,18 @@ export const fetchQrCode = async (instanceName: string): Promise<any> => {
if (!response.ok) { if (!response.ok) {
const errorData = await response.json(); const errorData = await response.json();
console.error('Error fetching QR code:', errorData);
throw new Error(errorData.message || 'Erro ao obter QR Code'); throw new Error(errorData.message || 'Erro ao obter QR Code');
} }
return response.json(); const data = await response.json();
console.log('QR code fetch response:', data);
return data;
}; };
export const fetchConnectionState = async (instanceName: string): Promise<'open' | 'closed' | 'connecting'> => { export const fetchConnectionState = async (instanceName: string): Promise<'open' | 'closed' | 'connecting'> => {
try { try {
console.log(`Fetching connection state for: ${instanceName}`);
const response = await fetch(`https://${SERVER_URL}/instance/connectionState/${encodeURIComponent(instanceName)}`, { const response = await fetch(`https://${SERVER_URL}/instance/connectionState/${encodeURIComponent(instanceName)}`, {
method: 'GET', method: 'GET',
headers: { headers: {
@ -61,13 +70,25 @@ export const fetchConnectionState = async (instanceName: string): Promise<'open'
}); });
if (!response.ok) { if (!response.ok) {
const errorData = await response.json();
console.error(`Connection state error for ${instanceName}:`, errorData);
// If instance doesn't exist, throw a specific error
if (response.status === 404) {
throw new Error(`The "${instanceName}" instance does not exist`);
}
return 'closed'; return 'closed';
} }
const data = await response.json(); const data = await response.json();
console.log(`Connection state for ${instanceName}:`, data);
return data.instance?.state || 'closed'; return data.instance?.state || 'closed';
} catch (error) { } catch (error) {
console.error("Error fetching connection state:", error); console.error(`Error fetching connection state for ${instanceName}:`, error);
if (error instanceof Error && error.message.includes("does not exist")) {
throw error; // Rethrow specific "does not exist" errors
}
return 'closed'; return 'closed';
} }
}; };
@ -75,6 +96,7 @@ export const fetchConnectionState = async (instanceName: string): Promise<'open'
// Nova função para listar todas as instâncias // Nova função para listar todas as instâncias
export const fetchAllInstances = async (): Promise<any> => { export const fetchAllInstances = async (): Promise<any> => {
try { try {
console.log('Fetching all instances');
const response = await fetch(`https://${SERVER_URL}/fetch-instances`, { const response = await fetch(`https://${SERVER_URL}/fetch-instances`, {
method: 'GET', method: 'GET',
headers: { headers: {
@ -84,10 +106,14 @@ export const fetchAllInstances = async (): Promise<any> => {
}); });
if (!response.ok) { if (!response.ok) {
throw new Error('Erro ao buscar instâncias'); const errorData = await response.json();
console.error('Error fetching instances:', errorData);
throw new Error(errorData.message || 'Erro ao buscar instâncias');
} }
return response.json(); const data = await response.json();
console.log('All instances response:', data);
return data;
} catch (error) { } catch (error) {
console.error("Error fetching all instances:", error); console.error("Error fetching all instances:", error);
throw error; throw error;
@ -97,6 +123,7 @@ export const fetchAllInstances = async (): Promise<any> => {
// Função para reiniciar uma instância // Função para reiniciar uma instância
export const restartInstance = async (instanceName: string): Promise<any> => { export const restartInstance = async (instanceName: string): Promise<any> => {
try { try {
console.log(`Restarting instance: ${instanceName}`);
const response = await fetch(`https://${SERVER_URL}/instance/restart/${encodeURIComponent(instanceName)}`, { const response = await fetch(`https://${SERVER_URL}/instance/restart/${encodeURIComponent(instanceName)}`, {
method: 'PUT', method: 'PUT',
headers: { headers: {
@ -107,10 +134,13 @@ export const restartInstance = async (instanceName: string): Promise<any> => {
if (!response.ok) { if (!response.ok) {
const errorData = await response.json(); const errorData = await response.json();
console.error(`Error restarting instance ${instanceName}:`, errorData);
throw new Error(errorData.message || 'Erro ao reiniciar instância'); throw new Error(errorData.message || 'Erro ao reiniciar instância');
} }
return response.json(); const data = await response.json();
console.log(`Restart response for ${instanceName}:`, data);
return data;
} catch (error) { } catch (error) {
console.error(`Error restarting instance ${instanceName}:`, error); console.error(`Error restarting instance ${instanceName}:`, error);
throw error; throw error;
@ -120,6 +150,7 @@ export const restartInstance = async (instanceName: string): Promise<any> => {
// Função para desconectar (logout) uma instância // Função para desconectar (logout) uma instância
export const logoutInstance = async (instanceName: string): Promise<any> => { export const logoutInstance = async (instanceName: string): Promise<any> => {
try { try {
console.log(`Logging out instance: ${instanceName}`);
const response = await fetch(`https://${SERVER_URL}/instance/logout/${encodeURIComponent(instanceName)}`, { const response = await fetch(`https://${SERVER_URL}/instance/logout/${encodeURIComponent(instanceName)}`, {
method: 'DELETE', method: 'DELETE',
headers: { headers: {
@ -130,10 +161,13 @@ export const logoutInstance = async (instanceName: string): Promise<any> => {
if (!response.ok) { if (!response.ok) {
const errorData = await response.json(); const errorData = await response.json();
console.error(`Error logging out instance ${instanceName}:`, errorData);
throw new Error(errorData.message || 'Erro ao desconectar instância'); throw new Error(errorData.message || 'Erro ao desconectar instância');
} }
return response.json(); const data = await response.json();
console.log(`Logout response for ${instanceName}:`, data);
return data;
} catch (error) { } catch (error) {
console.error(`Error logging out instance ${instanceName}:`, error); console.error(`Error logging out instance ${instanceName}:`, error);
throw error; throw error;
@ -143,6 +177,7 @@ export const logoutInstance = async (instanceName: string): Promise<any> => {
// Função para excluir uma instância // Função para excluir uma instância
export const deleteInstance = async (instanceName: string): Promise<any> => { export const deleteInstance = async (instanceName: string): Promise<any> => {
try { try {
console.log(`Deleting instance: ${instanceName}`);
const response = await fetch(`https://${SERVER_URL}/instance/${encodeURIComponent(instanceName)}`, { const response = await fetch(`https://${SERVER_URL}/instance/${encodeURIComponent(instanceName)}`, {
method: 'DELETE', method: 'DELETE',
headers: { headers: {
@ -153,10 +188,13 @@ export const deleteInstance = async (instanceName: string): Promise<any> => {
if (!response.ok) { if (!response.ok) {
const errorData = await response.json(); const errorData = await response.json();
console.error(`Error deleting instance ${instanceName}:`, errorData);
throw new Error(errorData.message || 'Erro ao excluir instância'); throw new Error(errorData.message || 'Erro ao excluir instância');
} }
return response.json(); const data = await response.json();
console.log(`Delete response for ${instanceName}:`, data);
return data;
} catch (error) { } catch (error) {
console.error(`Error deleting instance ${instanceName}:`, error); console.error(`Error deleting instance ${instanceName}:`, error);
throw error; throw error;
@ -166,6 +204,7 @@ export const deleteInstance = async (instanceName: string): Promise<any> => {
// Função para definir presença online/offline // Função para definir presença online/offline
export const setInstancePresence = async (instanceName: string, presence: 'online' | 'offline'): Promise<any> => { export const setInstancePresence = async (instanceName: string, presence: 'online' | 'offline'): Promise<any> => {
try { try {
console.log(`Setting presence to ${presence} for: ${instanceName}`);
const response = await fetch(`https://${SERVER_URL}/instance/setPresence/${encodeURIComponent(instanceName)}`, { const response = await fetch(`https://${SERVER_URL}/instance/setPresence/${encodeURIComponent(instanceName)}`, {
method: 'POST', method: 'POST',
headers: { headers: {
@ -177,10 +216,13 @@ export const setInstancePresence = async (instanceName: string, presence: 'onlin
if (!response.ok) { if (!response.ok) {
const errorData = await response.json(); const errorData = await response.json();
console.error(`Error setting presence for ${instanceName}:`, errorData);
throw new Error(errorData.message || `Erro ao definir presença para ${presence}`); throw new Error(errorData.message || `Erro ao definir presença para ${presence}`);
} }
return response.json(); const data = await response.json();
console.log(`Set presence response for ${instanceName}:`, data);
return data;
} catch (error) { } catch (error) {
console.error(`Error setting presence to ${presence} for instance ${instanceName}:`, error); console.error(`Error setting presence to ${presence} for instance ${instanceName}:`, error);
throw error; throw error;
@ -192,19 +234,24 @@ export const saveInstancesToLocalStorage = (
currentUserId: string currentUserId: string
): void => { ): void => {
try { try {
console.log(`Saving ${instances.length} instances for user ${currentUserId}`);
// Get existing instances from localStorage // Get existing instances from localStorage
const savedInstancesStr = localStorage.getItem(STORAGE_KEY); const savedInstancesStr = localStorage.getItem(STORAGE_KEY);
let allInstances: WhatsAppInstance[] = []; let allInstances: WhatsAppInstance[] = [];
if (savedInstancesStr) { if (savedInstancesStr) {
// Parse saved instances try {
const savedInstances = JSON.parse(savedInstancesStr); // Parse saved instances
const savedInstances = JSON.parse(savedInstancesStr);
// If it's an array, filter out current user's old instances
if (Array.isArray(savedInstances)) { // If it's an array, filter out current user's old instances
allInstances = savedInstances.filter( if (Array.isArray(savedInstances)) {
(instance: WhatsAppInstance) => instance.userId !== currentUserId allInstances = savedInstances.filter(
); (instance: WhatsAppInstance) => instance.userId !== currentUserId
);
}
} catch (parseError) {
console.error('Error parsing stored instances, resetting:', parseError);
} }
} }
@ -223,21 +270,26 @@ export const loadInstancesFromLocalStorage = (
userId: string userId: string
): WhatsAppInstance[] => { ): WhatsAppInstance[] => {
try { try {
console.log(`Loading instances for user: ${userId}`);
const savedInstancesStr = localStorage.getItem(STORAGE_KEY); const savedInstancesStr = localStorage.getItem(STORAGE_KEY);
console.log('Raw saved instances from localStorage:', savedInstancesStr); console.log('Raw saved instances from localStorage:', savedInstancesStr);
if (savedInstancesStr && userId) { if (savedInstancesStr && userId) {
// Parse saved instances try {
const allInstances = JSON.parse(savedInstancesStr); // Parse saved instances
const allInstances = JSON.parse(savedInstancesStr);
// If it's an array, filter by user ID
if (Array.isArray(allInstances)) { // If it's an array, filter by user ID
// Filter instances to only show those belonging to the current user if (Array.isArray(allInstances)) {
const userInstances = allInstances.filter( // Filter instances to only show those belonging to the current user
(instance: WhatsAppInstance) => instance.userId === userId const userInstances = allInstances.filter(
); (instance: WhatsAppInstance) => instance.userId === userId
console.log(`Found ${userInstances.length} instances for user ${userId}:`, userInstances); );
return userInstances; console.log(`Found ${userInstances.length} instances for user ${userId}:`, userInstances);
return userInstances;
}
} catch (parseError) {
console.error('Error parsing stored instances:', parseError);
} }
} }
console.log(`No instances found for user ${userId}`); console.log(`No instances found for user ${userId}`);