Refactor: Break down WhatsApp.tsx into smaller components
Refactors WhatsApp.tsx into smaller, more manageable components and hooks to improve readability and maintainability. This reduces the overall complexity of the file.
This commit is contained in:
parent
62e2acbf4e
commit
d9a804c36a
17
src/components/whatsapp/LoadingState.tsx
Normal file
17
src/components/whatsapp/LoadingState.tsx
Normal file
@ -0,0 +1,17 @@
|
||||
|
||||
import React from 'react';
|
||||
|
||||
interface LoadingStateProps {
|
||||
message?: string;
|
||||
}
|
||||
|
||||
const LoadingState = ({ message = "Buscando instância..." }: LoadingStateProps) => {
|
||||
return (
|
||||
<div className="flex justify-center items-center p-10">
|
||||
<div className="animate-spin rounded-full h-12 w-12 border-b-2 border-primary"></div>
|
||||
<p className="ml-3">{message}</p>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default LoadingState;
|
||||
37
src/hooks/whatsApp/usePeriodicStatusCheck.ts
Normal file
37
src/hooks/whatsApp/usePeriodicStatusCheck.ts
Normal file
@ -0,0 +1,37 @@
|
||||
|
||||
import { useEffect } from 'react';
|
||||
|
||||
export const usePeriodicStatusCheck = (
|
||||
instancesCount: number,
|
||||
checkAllInstancesStatus: () => Promise<void>
|
||||
) => {
|
||||
// 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]);
|
||||
};
|
||||
115
src/hooks/whatsApp/useWhatsAppInstance.ts
Normal file
115
src/hooks/whatsApp/useWhatsAppInstance.ts
Normal file
@ -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
|
||||
};
|
||||
};
|
||||
@ -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 = () => {
|
||||
</div>
|
||||
|
||||
{isLoading ? (
|
||||
<div className="flex justify-center items-center p-10">
|
||||
<div className="animate-spin rounded-full h-12 w-12 border-b-2 border-primary"></div>
|
||||
<p className="ml-3">Buscando instância...</p>
|
||||
</div>
|
||||
<LoadingState />
|
||||
) : !instanceFound ? (
|
||||
// Show create form if no instance found
|
||||
<CreateInstanceForm
|
||||
|
||||
Loading…
Reference in New Issue
Block a user