From 54310bd2042c6330f04ce318ace4e20f938c225a Mon Sep 17 00:00:00 2001 From: "gpt-engineer-app[bot]" <159125892+gpt-engineer-app[bot]@users.noreply.github.com> Date: Mon, 19 May 2025 14:41:04 +0000 Subject: [PATCH] feat: Implement user-specific WhatsApp instances - Associate WhatsApp instances with logged-in users. - Store user ID/email with instance data. - Filter instance cards to show only the user's instances. - Clear instances on logout/login. --- src/components/layout/Header.tsx | 6 ++ src/pages/WhatsApp.tsx | 137 +++++++++++++++++++++++++------ 2 files changed, 118 insertions(+), 25 deletions(-) diff --git a/src/components/layout/Header.tsx b/src/components/layout/Header.tsx index 6ddcd5c..e7d5a2a 100644 --- a/src/components/layout/Header.tsx +++ b/src/components/layout/Header.tsx @@ -41,6 +41,12 @@ const Header = () => { localStorage.removeItem('userName'); localStorage.removeItem('userEmail'); + // Dispatch a storage event to notify other components about logout + window.dispatchEvent(new StorageEvent('storage', { + key: 'autenticado', + newValue: null + })); + toast({ title: "Logout realizado", description: "Você foi desconectado com sucesso" diff --git a/src/pages/WhatsApp.tsx b/src/pages/WhatsApp.tsx index 2d51425..386159a 100644 --- a/src/pages/WhatsApp.tsx +++ b/src/pages/WhatsApp.tsx @@ -15,6 +15,7 @@ interface WhatsAppInstance { instanceName: string; instanceId: string; phoneNumber: string; + userId: string; status?: string; qrcode?: string; connectionState?: 'open' | 'closed' | 'connecting'; @@ -36,25 +37,76 @@ const WhatsApp = () => { const [qrError, setQrError] = useState(null); const [qrDialogOpen, setQrDialogOpen] = useState(false); const [statusCheckInterval, setStatusCheckInterval] = useState(null); + const [currentUserId, setCurrentUserId] = useState(''); - // Load saved instances from localStorage on component mount + // Get current user ID on component mount + useEffect(() => { + const userId = localStorage.getItem('userId') || ''; + setCurrentUserId(userId); + }, []); + + // Load saved instances from localStorage on component mount and filter by current user useEffect(() => { const savedInstances = localStorage.getItem('whatsappInstances'); - if (savedInstances) { + if (savedInstances && currentUserId) { try { - setInstances(JSON.parse(savedInstances)); + const allInstances = JSON.parse(savedInstances); + // Filter instances to only show those belonging to the current user + const userInstances = allInstances.filter( + (instance: WhatsAppInstance) => instance.userId === currentUserId + ); + setInstances(userInstances); } catch (error) { console.error("Error parsing saved instances:", error); } } - }, []); + }, [currentUserId]); // Re-run when currentUserId changes // Save instances to localStorage whenever they change useEffect(() => { if (instances.length > 0) { - localStorage.setItem('whatsappInstances', JSON.stringify(instances)); + // We need to save ALL instances (not just current user's) to maintain everyone's data + const savedInstances = localStorage.getItem('whatsappInstances'); + let allInstances: WhatsAppInstance[] = []; + + if (savedInstances) { + try { + const parsedInstances = JSON.parse(savedInstances); + // Filter out current user's instances from saved data (we'll add updated ones) + allInstances = parsedInstances.filter( + (instance: WhatsAppInstance) => instance.userId !== currentUserId + ); + } catch (error) { + console.error("Error parsing saved instances:", error); + } + } + + // Add current user's instances to the array + const updatedInstances = [...allInstances, ...instances]; + localStorage.setItem('whatsappInstances', JSON.stringify(updatedInstances)); } - }, [instances]); + }, [instances, currentUserId]); + + // Handle user logout event to clear instances display + useEffect(() => { + const handleStorageChange = (e: StorageEvent) => { + if (e.key === 'autenticado' && e.newValue === null) { + // User logged out, clear instances from display + setInstances([]); + setCurrentUserId(''); + } else if (e.key === 'userId') { + // User ID changed (new login) + const newUserId = localStorage.getItem('userId') || ''; + setCurrentUserId(newUserId); + } + }; + + window.addEventListener('storage', handleStorageChange); + + return () => { + window.removeEventListener('storage', handleStorageChange); + }; + }, []); // Set up periodic status checks useEffect(() => { @@ -82,18 +134,22 @@ const WhatsApp = () => { // Function to check connection status for all instances const checkAllInstancesStatus = async () => { - const updatedInstances = await Promise.all( - instances.map(async (instance) => { - try { - const state = await fetchConnectionState(instance.instanceName); - return { ...instance, connectionState: state }; - } catch (error) { - console.error(`Error checking status for ${instance.instanceName}:`, error); - return { ...instance, connectionState: 'closed' }; - } - }) - ); - setInstances(updatedInstances); + try { + const updatedInstances = await Promise.all( + instances.map(async (instance) => { + try { + const state = await fetchConnectionState(instance.instanceName); + return { ...instance, connectionState: state }; + } catch (error) { + console.error(`Error checking status for ${instance.instanceName}:`, error); + return { ...instance, connectionState: 'closed' as const }; + } + }) + ); + setInstances(updatedInstances); + } catch (error) { + console.error("Error checking instances status:", error); + } }; // Function to fetch connection state for an instance @@ -115,7 +171,7 @@ const WhatsApp = () => { } const data = await response.json(); - return data.instance?.state || 'closed'; + return data.instance?.state || 'closed' as 'open' | 'closed' | 'connecting'; } catch (error) { console.error("Error fetching connection state:", error); return 'closed'; @@ -142,6 +198,16 @@ const WhatsApp = () => { return; } + // Ensure user is logged in + if (!currentUserId) { + toast({ + title: "Erro de autenticação", + description: "Você precisa estar logado para criar uma instância", + variant: "destructive", + }); + return; + } + setLoading(true); try { @@ -169,11 +235,12 @@ const WhatsApp = () => { throw new Error(data.message || 'Erro ao criar instância'); } - // Create new instance object + // Create new instance object with user ID const newInstance: WhatsAppInstance = { instanceName, instanceId: data.instance.instanceId, phoneNumber, + userId: currentUserId, // Associate with current user status: data.instance.status, qrcode: data.qrcode, connectionState: 'connecting' @@ -238,7 +305,7 @@ const WhatsApp = () => { } // Using the "code" field from the response as the QR code data - if (data && data.code) { + if (data && data.base64) { // Save the base64 image data directly - it already contains the data:image prefix setQrCodeData(data.base64); } else { @@ -263,9 +330,20 @@ const WhatsApp = () => { if (activeInstance?.instanceId === instanceId) { setQrDialogOpen(false); } - // Update localStorage - const updatedInstances = instances.filter(instance => instance.instanceId !== instanceId); - localStorage.setItem('whatsappInstances', JSON.stringify(updatedInstances)); + + // Update localStorage - need to preserve other users' instances + const savedInstances = localStorage.getItem('whatsappInstances'); + if (savedInstances) { + try { + const allInstances = JSON.parse(savedInstances); + const updatedInstances = allInstances.filter( + (instance: WhatsAppInstance) => !(instance.instanceId === instanceId && instance.userId === currentUserId) + ); + localStorage.setItem('whatsappInstances', JSON.stringify(updatedInstances)); + } catch (error) { + console.error("Error updating instances in localStorage:", error); + } + } toast({ title: "Instância removida", @@ -327,7 +405,7 @@ const WhatsApp = () => { {/* List of created instances */} - {instances.length > 0 && ( + {instances.length > 0 ? (

Instâncias Criadas

@@ -380,6 +458,15 @@ const WhatsApp = () => { ))}
+ ) : ( + + +
+

Nenhuma instância criada ainda.

+

Crie uma instância usando o formulário acima.

+
+
+
)} {/* QR Code Dialog */}