Refactor: Split GruposWhatsApp.tsx into smaller components
Split the large GruposWhatsApp.tsx file into smaller, more manageable components to improve readability and maintainability. This refactoring aims to improve code organization without altering existing functionality.
This commit is contained in:
parent
c5f3a3d161
commit
6d6734c17d
171
src/components/whatsappGroups/CreateGroupForm.tsx
Normal file
171
src/components/whatsappGroups/CreateGroupForm.tsx
Normal file
@ -0,0 +1,171 @@
|
||||
|
||||
import { useState } from 'react';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { Card, CardContent, CardHeader, CardTitle, CardDescription } from '@/components/ui/card';
|
||||
import { Input } from '@/components/ui/input';
|
||||
import { Label } from '@/components/ui/label';
|
||||
import { Loader2, Plus } from 'lucide-react';
|
||||
import { cadastrarGrupoWhatsApp } from '@/services/gruposWhatsAppService';
|
||||
import { useToast } from '@/hooks/use-toast';
|
||||
|
||||
interface CreateGroupFormProps {
|
||||
userEmail: string;
|
||||
onSuccess: () => void;
|
||||
}
|
||||
|
||||
const CreateGroupForm = ({ userEmail, onSuccess }: CreateGroupFormProps) => {
|
||||
const { toast } = useToast();
|
||||
const [cadastrando, setCadastrando] = useState<boolean>(false);
|
||||
const [nomeGrupo, setNomeGrupo] = useState<string>('');
|
||||
const [errorMessage, setErrorMessage] = useState<string | null>(null);
|
||||
const [debugInfo, setDebugInfo] = useState<string | null>(null);
|
||||
|
||||
// Cadastrar novo grupo ou atualizar workflow se necessário
|
||||
const handleCadastrarGrupo = async () => {
|
||||
setErrorMessage(null);
|
||||
setDebugInfo(null);
|
||||
|
||||
if (!userEmail) {
|
||||
toast({
|
||||
title: 'Erro',
|
||||
description: 'Você precisa estar logado para cadastrar um grupo',
|
||||
variant: 'destructive',
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
if (!nomeGrupo.trim()) {
|
||||
toast({
|
||||
title: 'Atenção',
|
||||
description: 'Digite um nome para o grupo',
|
||||
variant: 'destructive',
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
setCadastrando(true);
|
||||
try {
|
||||
console.log("Iniciando processo de cadastro de grupo...");
|
||||
const grupo = await cadastrarGrupoWhatsApp(nomeGrupo.trim());
|
||||
|
||||
if (grupo) {
|
||||
let successMessage = 'Grupo registrado com sucesso';
|
||||
let variant: 'default' | 'destructive' = 'default';
|
||||
|
||||
if (grupo.workflow_id) {
|
||||
successMessage = 'Grupo cadastrado e workflow criado com sucesso!';
|
||||
} else {
|
||||
successMessage = 'Grupo cadastrado, mas falha ao criar workflow de automação.';
|
||||
setDebugInfo('O grupo foi criado no Supabase, mas houve um problema ao criar o workflow no n8n. Verifique os logs do console para mais detalhes.');
|
||||
variant = 'destructive';
|
||||
}
|
||||
|
||||
toast({
|
||||
title: grupo.workflow_id ? 'Sucesso' : 'Atenção',
|
||||
description: successMessage,
|
||||
variant: variant,
|
||||
});
|
||||
|
||||
// Resetar o campo de nome
|
||||
setNomeGrupo('');
|
||||
|
||||
// Atualizar a lista de grupos
|
||||
onSuccess();
|
||||
} else {
|
||||
setErrorMessage('Não foi possível registrar o grupo. Verifique a conexão com o Supabase.');
|
||||
toast({
|
||||
title: 'Erro',
|
||||
description: 'Não foi possível registrar o grupo',
|
||||
variant: 'destructive',
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Erro ao cadastrar grupo:', error);
|
||||
let errorMsg = 'Erro desconhecido';
|
||||
if (error instanceof Error) {
|
||||
errorMsg = error.message;
|
||||
|
||||
// Tentar extrair detalhes específicos do erro se existirem
|
||||
if (errorMsg.includes('Status')) {
|
||||
const statusMatch = errorMsg.match(/Status (\d+)/);
|
||||
if (statusMatch && statusMatch[1]) {
|
||||
setDebugInfo(`Código de status HTTP da API: ${statusMatch[1]}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
setErrorMessage('Erro ao cadastrar grupo: ' + errorMsg);
|
||||
toast({
|
||||
title: 'Erro',
|
||||
description: 'Não foi possível registrar o grupo',
|
||||
variant: 'destructive',
|
||||
});
|
||||
} finally {
|
||||
setCadastrando(false);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle>Cadastrar novo grupo</CardTitle>
|
||||
<CardDescription>
|
||||
Preencha as informações abaixo para cadastrar um novo grupo do WhatsApp
|
||||
</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent className="space-y-4">
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="nomeGrupo">Nome do grupo</Label>
|
||||
<Input
|
||||
id="nomeGrupo"
|
||||
placeholder="Ex: Controle de Gastos da Família"
|
||||
value={nomeGrupo}
|
||||
onChange={(e) => setNomeGrupo(e.target.value)}
|
||||
/>
|
||||
<p className="text-sm text-muted-foreground">
|
||||
Digite um nome descritivo para o grupo que você irá criar
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<Button
|
||||
onClick={handleCadastrarGrupo}
|
||||
disabled={cadastrando || !userEmail || !nomeGrupo.trim()}
|
||||
className="w-full"
|
||||
>
|
||||
{cadastrando ? (
|
||||
<>
|
||||
<Loader2 className="h-4 w-4 mr-2 animate-spin" />
|
||||
Cadastrando...
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<Plus className="h-4 w-4 mr-2" />
|
||||
Cadastrar Grupo
|
||||
</>
|
||||
)}
|
||||
</Button>
|
||||
|
||||
<div className="mt-4 border-t pt-4">
|
||||
<h3 className="font-medium mb-2">Após cadastrar:</h3>
|
||||
<ol className="list-decimal list-inside space-y-2">
|
||||
<li>Adicione o número (61)99244-4275 ao grupo do WhatsApp que deseja automatizar</li>
|
||||
<li>Envie uma mensagem neste grupo com o seguinte texto:</li>
|
||||
</ol>
|
||||
|
||||
<div className="bg-muted p-3 rounded-md font-mono mt-2">
|
||||
{userEmail}
|
||||
</div>
|
||||
|
||||
<p className="text-sm text-muted-foreground mt-2">
|
||||
Copie e cole o email exatamente como aparece acima
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{errorMessage && <p className="text-destructive text-sm mt-4">{errorMessage}</p>}
|
||||
{debugInfo && <p className="text-amber-800 text-sm mt-2 bg-amber-50 p-3 rounded-md">{debugInfo}</p>}
|
||||
</CardContent>
|
||||
</Card>
|
||||
);
|
||||
};
|
||||
|
||||
export default CreateGroupForm;
|
||||
35
src/components/whatsappGroups/DebugInfo.tsx
Normal file
35
src/components/whatsappGroups/DebugInfo.tsx
Normal file
@ -0,0 +1,35 @@
|
||||
|
||||
import { Alert, AlertDescription, AlertTitle } from '@/components/ui/alert';
|
||||
|
||||
interface DebugInfoProps {
|
||||
errorMessage: string | null;
|
||||
debugInfo: string | null;
|
||||
}
|
||||
|
||||
const DebugInfo = ({ errorMessage, debugInfo }: DebugInfoProps) => {
|
||||
if (!errorMessage && !debugInfo) return null;
|
||||
|
||||
return (
|
||||
<>
|
||||
{errorMessage && (
|
||||
<Alert variant="destructive">
|
||||
<AlertTitle>Erro ao cadastrar grupo</AlertTitle>
|
||||
<AlertDescription>
|
||||
{errorMessage}
|
||||
</AlertDescription>
|
||||
</Alert>
|
||||
)}
|
||||
|
||||
{debugInfo && (
|
||||
<Alert variant="default" className="bg-amber-50 border-amber-200">
|
||||
<AlertTitle>Informações de depuração</AlertTitle>
|
||||
<AlertDescription className="text-amber-800">
|
||||
{debugInfo}
|
||||
</AlertDescription>
|
||||
</Alert>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default DebugInfo;
|
||||
81
src/components/whatsappGroups/GroupsList.tsx
Normal file
81
src/components/whatsappGroups/GroupsList.tsx
Normal file
@ -0,0 +1,81 @@
|
||||
|
||||
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table';
|
||||
import { Card, CardContent, CardHeader, CardTitle, CardDescription } from '@/components/ui/card';
|
||||
import { Badge } from '@/components/ui/badge';
|
||||
import { Loader2, MessageSquare } from 'lucide-react';
|
||||
import { WhatsAppGroup } from '@/types/financialTypes';
|
||||
|
||||
interface GroupsListProps {
|
||||
grupos: WhatsAppGroup[];
|
||||
carregando: boolean;
|
||||
}
|
||||
|
||||
const GroupsList = ({ grupos, carregando }: GroupsListProps) => {
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle>Seus grupos cadastrados</CardTitle>
|
||||
<CardDescription>
|
||||
Lista de grupos do WhatsApp que você cadastrou
|
||||
</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
{carregando ? (
|
||||
<div className="flex justify-center py-8">
|
||||
<Loader2 className="h-8 w-8 animate-spin text-primary" />
|
||||
</div>
|
||||
) : grupos.length > 0 ? (
|
||||
<Table>
|
||||
<TableHeader>
|
||||
<TableRow>
|
||||
<TableHead>ID</TableHead>
|
||||
<TableHead>Nome do grupo</TableHead>
|
||||
<TableHead>Status</TableHead>
|
||||
<TableHead>Workflow</TableHead>
|
||||
<TableHead>Cadastro</TableHead>
|
||||
</TableRow>
|
||||
</TableHeader>
|
||||
<TableBody>
|
||||
{grupos.map((grupo) => (
|
||||
<TableRow key={grupo.id}>
|
||||
<TableCell className="font-medium">{grupo.id}</TableCell>
|
||||
<TableCell>
|
||||
{grupo.nome_grupo || (
|
||||
<span className="text-muted-foreground italic">
|
||||
{grupo.remote_jid ? 'Sem nome definido' : 'Aguardando vínculo...'}
|
||||
</span>
|
||||
)}
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<Badge variant={grupo.remote_jid ? "success" : "outline"}>
|
||||
{grupo.remote_jid ? 'Ativo' : 'Pendente'}
|
||||
</Badge>
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
{grupo.workflow_id ? (
|
||||
<Badge variant="secondary" className="bg-green-100 text-green-800">
|
||||
Configurado
|
||||
</Badge>
|
||||
) : (
|
||||
<Badge variant="outline" className="text-gray-500">
|
||||
Não configurado
|
||||
</Badge>
|
||||
)}
|
||||
</TableCell>
|
||||
<TableCell>{new Date(grupo.created_at).toLocaleDateString()}</TableCell>
|
||||
</TableRow>
|
||||
))}
|
||||
</TableBody>
|
||||
</Table>
|
||||
) : (
|
||||
<div className="text-center py-8">
|
||||
<MessageSquare className="h-12 w-12 text-muted-foreground opacity-20 mx-auto mb-4" />
|
||||
<p className="text-muted-foreground">Você ainda não cadastrou nenhum grupo</p>
|
||||
</div>
|
||||
)}
|
||||
</CardContent>
|
||||
</Card>
|
||||
);
|
||||
};
|
||||
|
||||
export default GroupsList;
|
||||
@ -2,26 +2,21 @@
|
||||
import { useState, useEffect } from 'react';
|
||||
import Layout from '@/components/layout/Layout';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { Card, CardContent, CardHeader, CardTitle, CardDescription } from '@/components/ui/card';
|
||||
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table';
|
||||
import { Badge } from '@/components/ui/badge';
|
||||
import { Loader2, Plus, RefreshCw, MessageSquare, Edit } from 'lucide-react';
|
||||
import { cadastrarGrupoWhatsApp, listarGruposWhatsApp } from '@/services/gruposWhatsAppService';
|
||||
import { RefreshCw } from 'lucide-react';
|
||||
import { listarGruposWhatsApp } from '@/services/gruposWhatsAppService';
|
||||
import { WhatsAppGroup } from '@/types/financialTypes';
|
||||
import { useToast } from '@/hooks/use-toast';
|
||||
import { Alert, AlertDescription, AlertTitle } from '@/components/ui/alert';
|
||||
import { Input } from '@/components/ui/input';
|
||||
import { Label } from '@/components/ui/label';
|
||||
import CreateGroupForm from '@/components/whatsappGroups/CreateGroupForm';
|
||||
import GroupsList from '@/components/whatsappGroups/GroupsList';
|
||||
import DebugInfo from '@/components/whatsappGroups/DebugInfo';
|
||||
|
||||
const GruposWhatsApp = () => {
|
||||
const { toast } = useToast();
|
||||
const [grupos, setGrupos] = useState<WhatsAppGroup[]>([]);
|
||||
const [carregando, setCarregando] = useState<boolean>(true);
|
||||
const [cadastrando, setCadastrando] = useState<boolean>(false);
|
||||
const [userEmail, setUserEmail] = useState<string>('');
|
||||
const [errorMessage, setErrorMessage] = useState<string | null>(null);
|
||||
const [debugInfo, setDebugInfo] = useState<string | null>(null);
|
||||
const [nomeGrupo, setNomeGrupo] = useState<string>('');
|
||||
|
||||
// Buscar os grupos do usuário ao carregar a página
|
||||
const buscarGrupos = async () => {
|
||||
@ -53,91 +48,6 @@ const GruposWhatsApp = () => {
|
||||
buscarGrupos();
|
||||
}, []);
|
||||
|
||||
// Cadastrar novo grupo ou atualizar workflow se necessário
|
||||
const handleCadastrarGrupo = async () => {
|
||||
setErrorMessage(null);
|
||||
setDebugInfo(null);
|
||||
|
||||
if (!userEmail) {
|
||||
toast({
|
||||
title: 'Erro',
|
||||
description: 'Você precisa estar logado para cadastrar um grupo',
|
||||
variant: 'destructive',
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
if (!nomeGrupo.trim()) {
|
||||
toast({
|
||||
title: 'Atenção',
|
||||
description: 'Digite um nome para o grupo',
|
||||
variant: 'destructive',
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
setCadastrando(true);
|
||||
try {
|
||||
console.log("Iniciando processo de cadastro de grupo...");
|
||||
const grupo = await cadastrarGrupoWhatsApp(nomeGrupo.trim());
|
||||
|
||||
if (grupo) {
|
||||
let successMessage = 'Grupo registrado com sucesso';
|
||||
let variant: 'default' | 'destructive' = 'default';
|
||||
|
||||
if (grupo.workflow_id) {
|
||||
successMessage = 'Grupo cadastrado e workflow criado com sucesso!';
|
||||
} else {
|
||||
successMessage = 'Grupo cadastrado, mas falha ao criar workflow de automação.';
|
||||
setDebugInfo('O grupo foi criado no Supabase, mas houve um problema ao criar o workflow no n8n. Verifique os logs do console para mais detalhes.');
|
||||
variant = 'destructive';
|
||||
}
|
||||
|
||||
toast({
|
||||
title: grupo.workflow_id ? 'Sucesso' : 'Atenção',
|
||||
description: successMessage,
|
||||
variant: variant,
|
||||
});
|
||||
|
||||
// Resetar o campo de nome
|
||||
setNomeGrupo('');
|
||||
|
||||
// Atualizar a lista de grupos
|
||||
buscarGrupos();
|
||||
} else {
|
||||
setErrorMessage('Não foi possível registrar o grupo. Verifique a conexão com o Supabase.');
|
||||
toast({
|
||||
title: 'Erro',
|
||||
description: 'Não foi possível registrar o grupo',
|
||||
variant: 'destructive',
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Erro ao cadastrar grupo:', error);
|
||||
let errorMsg = 'Erro desconhecido';
|
||||
if (error instanceof Error) {
|
||||
errorMsg = error.message;
|
||||
|
||||
// Tentar extrair detalhes específicos do erro se existirem
|
||||
if (errorMsg.includes('Status')) {
|
||||
const statusMatch = errorMsg.match(/Status (\d+)/);
|
||||
if (statusMatch && statusMatch[1]) {
|
||||
setDebugInfo(`Código de status HTTP da API: ${statusMatch[1]}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
setErrorMessage('Erro ao cadastrar grupo: ' + errorMsg);
|
||||
toast({
|
||||
title: 'Erro',
|
||||
description: 'Não foi possível registrar o grupo',
|
||||
variant: 'destructive',
|
||||
});
|
||||
} finally {
|
||||
setCadastrando(false);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<Layout>
|
||||
<div className="space-y-6">
|
||||
@ -156,144 +66,9 @@ const GruposWhatsApp = () => {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{errorMessage && (
|
||||
<Alert variant="destructive">
|
||||
<AlertTitle>Erro ao cadastrar grupo</AlertTitle>
|
||||
<AlertDescription>
|
||||
{errorMessage}
|
||||
</AlertDescription>
|
||||
</Alert>
|
||||
)}
|
||||
|
||||
{debugInfo && (
|
||||
<Alert variant="default" className="bg-amber-50 border-amber-200">
|
||||
<AlertTitle>Informações de depuração</AlertTitle>
|
||||
<AlertDescription className="text-amber-800">
|
||||
{debugInfo}
|
||||
</AlertDescription>
|
||||
</Alert>
|
||||
)}
|
||||
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle>Cadastrar novo grupo</CardTitle>
|
||||
<CardDescription>
|
||||
Preencha as informações abaixo para cadastrar um novo grupo do WhatsApp
|
||||
</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent className="space-y-4">
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="nomeGrupo">Nome do grupo</Label>
|
||||
<Input
|
||||
id="nomeGrupo"
|
||||
placeholder="Ex: Controle de Gastos da Família"
|
||||
value={nomeGrupo}
|
||||
onChange={(e) => setNomeGrupo(e.target.value)}
|
||||
/>
|
||||
<p className="text-sm text-muted-foreground">
|
||||
Digite um nome descritivo para o grupo que você irá criar
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<Button
|
||||
onClick={handleCadastrarGrupo}
|
||||
disabled={cadastrando || !userEmail || !nomeGrupo.trim()}
|
||||
className="w-full"
|
||||
>
|
||||
{cadastrando ? (
|
||||
<>
|
||||
<Loader2 className="h-4 w-4 mr-2 animate-spin" />
|
||||
Cadastrando...
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<Plus className="h-4 w-4 mr-2" />
|
||||
Cadastrar Grupo
|
||||
</>
|
||||
)}
|
||||
</Button>
|
||||
|
||||
<div className="mt-4 border-t pt-4">
|
||||
<h3 className="font-medium mb-2">Após cadastrar:</h3>
|
||||
<ol className="list-decimal list-inside space-y-2">
|
||||
<li>Adicione o número (61)99244-4275 ao grupo do WhatsApp que deseja automatizar</li>
|
||||
<li>Envie uma mensagem neste grupo com o seguinte texto:</li>
|
||||
</ol>
|
||||
|
||||
<div className="bg-muted p-3 rounded-md font-mono mt-2">
|
||||
{userEmail}
|
||||
</div>
|
||||
|
||||
<p className="text-sm text-muted-foreground mt-2">
|
||||
Copie e cole o email exatamente como aparece acima
|
||||
</p>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle>Seus grupos cadastrados</CardTitle>
|
||||
<CardDescription>
|
||||
Lista de grupos do WhatsApp que você cadastrou
|
||||
</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
{carregando ? (
|
||||
<div className="flex justify-center py-8">
|
||||
<Loader2 className="h-8 w-8 animate-spin text-primary" />
|
||||
</div>
|
||||
) : grupos.length > 0 ? (
|
||||
<Table>
|
||||
<TableHeader>
|
||||
<TableRow>
|
||||
<TableHead>ID</TableHead>
|
||||
<TableHead>Nome do grupo</TableHead>
|
||||
<TableHead>Status</TableHead>
|
||||
<TableHead>Workflow</TableHead>
|
||||
<TableHead>Cadastro</TableHead>
|
||||
</TableRow>
|
||||
</TableHeader>
|
||||
<TableBody>
|
||||
{grupos.map((grupo) => (
|
||||
<TableRow key={grupo.id}>
|
||||
<TableCell className="font-medium">{grupo.id}</TableCell>
|
||||
<TableCell>
|
||||
{grupo.nome_grupo || (
|
||||
<span className="text-muted-foreground italic">
|
||||
{grupo.remote_jid ? 'Sem nome definido' : 'Aguardando vínculo...'}
|
||||
</span>
|
||||
)}
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<Badge variant={grupo.remote_jid ? "success" : "outline"}>
|
||||
{grupo.remote_jid ? 'Ativo' : 'Pendente'}
|
||||
</Badge>
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
{grupo.workflow_id ? (
|
||||
<Badge variant="secondary" className="bg-green-100 text-green-800">
|
||||
Configurado
|
||||
</Badge>
|
||||
) : (
|
||||
<Badge variant="outline" className="text-gray-500">
|
||||
Não configurado
|
||||
</Badge>
|
||||
)}
|
||||
</TableCell>
|
||||
<TableCell>{new Date(grupo.created_at).toLocaleDateString()}</TableCell>
|
||||
</TableRow>
|
||||
))}
|
||||
</TableBody>
|
||||
</Table>
|
||||
) : (
|
||||
<div className="text-center py-8">
|
||||
<MessageSquare className="h-12 w-12 text-muted-foreground opacity-20 mx-auto mb-4" />
|
||||
<p className="text-muted-foreground">Você ainda não cadastrou nenhum grupo</p>
|
||||
</div>
|
||||
)}
|
||||
</CardContent>
|
||||
</Card>
|
||||
<DebugInfo errorMessage={errorMessage} debugInfo={debugInfo} />
|
||||
<CreateGroupForm userEmail={userEmail} onSuccess={buscarGrupos} />
|
||||
<GroupsList grupos={grupos} carregando={carregando} />
|
||||
</div>
|
||||
</Layout>
|
||||
);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user