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.
This commit is contained in:
parent
44e8569b6c
commit
54310bd204
@ -41,6 +41,12 @@ const Header = () => {
|
|||||||
localStorage.removeItem('userName');
|
localStorage.removeItem('userName');
|
||||||
localStorage.removeItem('userEmail');
|
localStorage.removeItem('userEmail');
|
||||||
|
|
||||||
|
// Dispatch a storage event to notify other components about logout
|
||||||
|
window.dispatchEvent(new StorageEvent('storage', {
|
||||||
|
key: 'autenticado',
|
||||||
|
newValue: null
|
||||||
|
}));
|
||||||
|
|
||||||
toast({
|
toast({
|
||||||
title: "Logout realizado",
|
title: "Logout realizado",
|
||||||
description: "Você foi desconectado com sucesso"
|
description: "Você foi desconectado com sucesso"
|
||||||
|
|||||||
@ -15,6 +15,7 @@ interface WhatsAppInstance {
|
|||||||
instanceName: string;
|
instanceName: string;
|
||||||
instanceId: string;
|
instanceId: string;
|
||||||
phoneNumber: string;
|
phoneNumber: string;
|
||||||
|
userId: string;
|
||||||
status?: string;
|
status?: string;
|
||||||
qrcode?: string;
|
qrcode?: string;
|
||||||
connectionState?: 'open' | 'closed' | 'connecting';
|
connectionState?: 'open' | 'closed' | 'connecting';
|
||||||
@ -36,25 +37,76 @@ const WhatsApp = () => {
|
|||||||
const [qrError, setQrError] = useState<string | null>(null);
|
const [qrError, setQrError] = useState<string | null>(null);
|
||||||
const [qrDialogOpen, setQrDialogOpen] = useState(false);
|
const [qrDialogOpen, setQrDialogOpen] = useState(false);
|
||||||
const [statusCheckInterval, setStatusCheckInterval] = useState<NodeJS.Timeout | null>(null);
|
const [statusCheckInterval, setStatusCheckInterval] = useState<NodeJS.Timeout | null>(null);
|
||||||
|
const [currentUserId, setCurrentUserId] = useState<string>('');
|
||||||
|
|
||||||
// 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(() => {
|
useEffect(() => {
|
||||||
const savedInstances = localStorage.getItem('whatsappInstances');
|
const savedInstances = localStorage.getItem('whatsappInstances');
|
||||||
if (savedInstances) {
|
if (savedInstances && currentUserId) {
|
||||||
try {
|
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) {
|
} catch (error) {
|
||||||
console.error("Error parsing saved instances:", error);
|
console.error("Error parsing saved instances:", error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, []);
|
}, [currentUserId]); // Re-run when currentUserId changes
|
||||||
|
|
||||||
// Save instances to localStorage whenever they change
|
// Save instances to localStorage whenever they change
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (instances.length > 0) {
|
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
|
// Set up periodic status checks
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@ -82,18 +134,22 @@ const WhatsApp = () => {
|
|||||||
|
|
||||||
// Function to check connection status for all instances
|
// Function to check connection status for all instances
|
||||||
const checkAllInstancesStatus = async () => {
|
const checkAllInstancesStatus = async () => {
|
||||||
const updatedInstances = await Promise.all(
|
try {
|
||||||
instances.map(async (instance) => {
|
const updatedInstances = await Promise.all(
|
||||||
try {
|
instances.map(async (instance) => {
|
||||||
const state = await fetchConnectionState(instance.instanceName);
|
try {
|
||||||
return { ...instance, connectionState: state };
|
const state = await fetchConnectionState(instance.instanceName);
|
||||||
} catch (error) {
|
return { ...instance, connectionState: state };
|
||||||
console.error(`Error checking status for ${instance.instanceName}:`, error);
|
} catch (error) {
|
||||||
return { ...instance, connectionState: 'closed' };
|
console.error(`Error checking status for ${instance.instanceName}:`, error);
|
||||||
}
|
return { ...instance, connectionState: 'closed' as const };
|
||||||
})
|
}
|
||||||
);
|
})
|
||||||
setInstances(updatedInstances);
|
);
|
||||||
|
setInstances(updatedInstances);
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error checking instances status:", error);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Function to fetch connection state for an instance
|
// Function to fetch connection state for an instance
|
||||||
@ -115,7 +171,7 @@ const WhatsApp = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const data = await response.json();
|
const data = await response.json();
|
||||||
return data.instance?.state || 'closed';
|
return data.instance?.state || 'closed' as 'open' | 'closed' | 'connecting';
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Error fetching connection state:", error);
|
console.error("Error fetching connection state:", error);
|
||||||
return 'closed';
|
return 'closed';
|
||||||
@ -142,6 +198,16 @@ const WhatsApp = () => {
|
|||||||
return;
|
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);
|
setLoading(true);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@ -169,11 +235,12 @@ const WhatsApp = () => {
|
|||||||
throw new Error(data.message || 'Erro ao criar instância');
|
throw new Error(data.message || 'Erro ao criar instância');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create new instance object
|
// Create new instance object with user ID
|
||||||
const newInstance: WhatsAppInstance = {
|
const newInstance: WhatsAppInstance = {
|
||||||
instanceName,
|
instanceName,
|
||||||
instanceId: data.instance.instanceId,
|
instanceId: data.instance.instanceId,
|
||||||
phoneNumber,
|
phoneNumber,
|
||||||
|
userId: currentUserId, // Associate with current user
|
||||||
status: data.instance.status,
|
status: data.instance.status,
|
||||||
qrcode: data.qrcode,
|
qrcode: data.qrcode,
|
||||||
connectionState: 'connecting'
|
connectionState: 'connecting'
|
||||||
@ -238,7 +305,7 @@ const WhatsApp = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Using the "code" field from the response as the QR code data
|
// 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
|
// Save the base64 image data directly - it already contains the data:image prefix
|
||||||
setQrCodeData(data.base64);
|
setQrCodeData(data.base64);
|
||||||
} else {
|
} else {
|
||||||
@ -263,9 +330,20 @@ const WhatsApp = () => {
|
|||||||
if (activeInstance?.instanceId === instanceId) {
|
if (activeInstance?.instanceId === instanceId) {
|
||||||
setQrDialogOpen(false);
|
setQrDialogOpen(false);
|
||||||
}
|
}
|
||||||
// Update localStorage
|
|
||||||
const updatedInstances = instances.filter(instance => instance.instanceId !== instanceId);
|
// Update localStorage - need to preserve other users' instances
|
||||||
localStorage.setItem('whatsappInstances', JSON.stringify(updatedInstances));
|
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({
|
toast({
|
||||||
title: "Instância removida",
|
title: "Instância removida",
|
||||||
@ -327,7 +405,7 @@ const WhatsApp = () => {
|
|||||||
</Card>
|
</Card>
|
||||||
|
|
||||||
{/* List of created instances */}
|
{/* List of created instances */}
|
||||||
{instances.length > 0 && (
|
{instances.length > 0 ? (
|
||||||
<div className="space-y-4">
|
<div className="space-y-4">
|
||||||
<h2 className="text-xl font-semibold">Instâncias Criadas</h2>
|
<h2 className="text-xl font-semibold">Instâncias Criadas</h2>
|
||||||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
|
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
|
||||||
@ -380,6 +458,15 @@ const WhatsApp = () => {
|
|||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
) : (
|
||||||
|
<Card>
|
||||||
|
<CardContent className="py-6">
|
||||||
|
<div className="text-center text-muted-foreground">
|
||||||
|
<p>Nenhuma instância criada ainda.</p>
|
||||||
|
<p className="mt-1">Crie uma instância usando o formulário acima.</p>
|
||||||
|
</div>
|
||||||
|
</CardContent>
|
||||||
|
</Card>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{/* QR Code Dialog */}
|
{/* QR Code Dialog */}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user