From d9a804c36a097dcb4e920b1f668ee471d1d77457 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 17:01:02 +0000
Subject: [PATCH] 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.
---
src/components/whatsapp/LoadingState.tsx | 17 ++
src/hooks/whatsApp/usePeriodicStatusCheck.ts | 37 +++++
src/hooks/whatsApp/useWhatsAppInstance.ts | 115 ++++++++++++++
src/pages/WhatsApp.tsx | 157 +++----------------
4 files changed, 191 insertions(+), 135 deletions(-)
create mode 100644 src/components/whatsapp/LoadingState.tsx
create mode 100644 src/hooks/whatsApp/usePeriodicStatusCheck.ts
create mode 100644 src/hooks/whatsApp/useWhatsAppInstance.ts
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 (
+
+ );
+};
+
+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