modulo de agente pessoal de IA
This commit is contained in:
@@ -0,0 +1,312 @@
|
||||
import { useState, useEffect } from "react";
|
||||
import { toast } from "sonner";
|
||||
import { GoogleCalendarCard } from "@/modules/intelligence-ia/components/integrations/GoogleCalendarCard";
|
||||
import { GoogleSheetsCard } from "@/modules/intelligence-ia/components/integrations/GoogleSheetsCard";
|
||||
import { AsanaCard } from "@/modules/intelligence-ia/components/integrations/AsanaCard";
|
||||
import { asanaService } from "@/services/asana";
|
||||
import { userProfileService } from "@/services/userProfile";
|
||||
import { GlobalFunctions, TransferAreaProperties } from "@/GlobalFunctions";
|
||||
|
||||
interface Workspace {
|
||||
id: string;
|
||||
name: string;
|
||||
}
|
||||
|
||||
interface User {
|
||||
id: string;
|
||||
name: string;
|
||||
}
|
||||
|
||||
|
||||
export default function Integrations() {
|
||||
const [asanaWorkspaces, setAsanaWorkspaces] = useState<Workspace[]>([]);
|
||||
const [asanaUsers, setAsanaUsers] = useState<User[]>([]);
|
||||
const [loadingAsanaWorkspaces, setLoadingAsanaWorkspaces] = useState(false);
|
||||
const [loadingAsanaUsers, setLoadingAsanaUsers] = useState(false);
|
||||
const [asanaToken, setAsanaToken] = useState<string>("");
|
||||
const [asanaApiKey, setAsanaApiKey] = useState<string>("");
|
||||
const [selectedWorkspaceId, setSelectedWorkspaceId] = useState<string>("");
|
||||
const [selectedUserId, setSelectedUserId] = useState<string>("");
|
||||
const [loadingIntegration, setLoadingIntegration] = useState(true);
|
||||
const [hasIntegration, setHasIntegration] = useState(false);
|
||||
const [integrationId, setIntegrationId] = useState<string>("");
|
||||
const [userId, setUserId] = useState<string>("");
|
||||
const [saving, setSaving] = useState(false);
|
||||
|
||||
const handleAsanaSave = async (apiKey: string, workspaceId: string, usuarioAsanaId: string) => {
|
||||
if (!apiKey || !workspaceId || !usuarioAsanaId) {
|
||||
toast.error("Preencha todos os campos obrigatórios");
|
||||
return;
|
||||
}
|
||||
|
||||
// Encontra o nome do workspace e do usuário selecionado
|
||||
const workspace = asanaWorkspaces.find(w => w.id === workspaceId);
|
||||
const user = asanaUsers.find(u => u.id === usuarioAsanaId);
|
||||
|
||||
if (!workspace || !user) {
|
||||
toast.error("Workspace ou usuário não encontrado");
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
setSaving(true);
|
||||
|
||||
if (hasIntegration && integrationId) {
|
||||
// Atualiza integração existente
|
||||
await asanaService.updateIntegration(integrationId, {
|
||||
api_key: apiKey,
|
||||
workspace_gid: workspaceId,
|
||||
workspace_nome: workspace.name,
|
||||
usuario_asana_gid: usuarioAsanaId,
|
||||
usuario_asana_nome: user.name,
|
||||
});
|
||||
toast.success("Integração do Asana atualizada com sucesso!");
|
||||
} else {
|
||||
// Cria nova integração
|
||||
if (!userId) {
|
||||
toast.error("ID do usuário não encontrado");
|
||||
return;
|
||||
}
|
||||
|
||||
const response = await asanaService.createIntegration({
|
||||
user_id: userId,
|
||||
api_key: apiKey,
|
||||
workspace_gid: workspaceId,
|
||||
workspace_nome: workspace.name,
|
||||
usuario_asana_gid: usuarioAsanaId,
|
||||
usuario_asana_nome: user.name,
|
||||
});
|
||||
|
||||
if (response.success && response.integracao_id) {
|
||||
setIntegrationId(response.integracao_id);
|
||||
setHasIntegration(true);
|
||||
}
|
||||
toast.success("Integração do Asana criada com sucesso!");
|
||||
}
|
||||
} catch (error: unknown) {
|
||||
console.error("Erro ao salvar integração do Asana:", error);
|
||||
const errorMessage = error && typeof error === 'object' && 'message' in error
|
||||
? (error as { message: string }).message
|
||||
: "Erro ao salvar integração do Asana";
|
||||
toast.error(errorMessage);
|
||||
} finally {
|
||||
setSaving(false);
|
||||
}
|
||||
};
|
||||
|
||||
const handleAsanaApiKeyConfirm = async (apiKey: string) => {
|
||||
if (!apiKey || apiKey.trim().length === 0) {
|
||||
toast.error("Insira um token válido do Asana");
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
setLoadingAsanaWorkspaces(true);
|
||||
|
||||
// Busca workspaces da API do Asana
|
||||
const workspaces = await asanaService.getWorkspaces(apiKey);
|
||||
|
||||
if (workspaces && workspaces.length > 0) {
|
||||
setAsanaWorkspaces(workspaces);
|
||||
setAsanaUsers([]);
|
||||
setAsanaToken(apiKey); // Armazena o token para usar na busca de usuários
|
||||
toast.success(`${workspaces.length} workspace(s) encontrado(s)`);
|
||||
} else {
|
||||
setAsanaWorkspaces([]);
|
||||
setAsanaUsers([]);
|
||||
setAsanaToken("");
|
||||
toast.warning("Nenhum workspace encontrado para este token");
|
||||
}
|
||||
} catch (error: unknown) {
|
||||
console.error("Erro ao buscar workspaces do Asana:", error);
|
||||
const errorMessage = error && typeof error === 'object' && 'message' in error
|
||||
? (error as { message: string }).message
|
||||
: "Erro ao buscar workspaces do Asana. Verifique se o token está correto.";
|
||||
|
||||
toast.error(errorMessage);
|
||||
setAsanaWorkspaces([]);
|
||||
setAsanaUsers([]);
|
||||
setAsanaToken(""); // Limpa o token em caso de erro
|
||||
} finally {
|
||||
setLoadingAsanaWorkspaces(false);
|
||||
}
|
||||
};
|
||||
|
||||
const handleAsanaWorkspaceChange = async (workspaceId: string) => {
|
||||
setSelectedWorkspaceId(workspaceId);
|
||||
|
||||
if (!workspaceId || !asanaToken) {
|
||||
setAsanaUsers([]);
|
||||
setSelectedUserId("");
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
setLoadingAsanaUsers(true);
|
||||
|
||||
// Busca usuários do workspace da API do Asana
|
||||
const users = await asanaService.getUsers(asanaToken, workspaceId);
|
||||
|
||||
if (users && users.length > 0) {
|
||||
setAsanaUsers(users);
|
||||
// Não mostra toast ao selecionar workspace (só quando confirmar token)
|
||||
} else {
|
||||
setAsanaUsers([]);
|
||||
setSelectedUserId("");
|
||||
}
|
||||
} catch (error: unknown) {
|
||||
console.error("Erro ao buscar usuários do Asana:", error);
|
||||
const errorMessage = error && typeof error === 'object' && 'message' in error
|
||||
? (error as { message: string }).message
|
||||
: "Erro ao buscar usuários do Asana. Verifique se o token está correto.";
|
||||
|
||||
toast.error(errorMessage);
|
||||
setAsanaUsers([]);
|
||||
setSelectedUserId("");
|
||||
} finally {
|
||||
setLoadingAsanaUsers(false);
|
||||
}
|
||||
};
|
||||
|
||||
// Carrega a integração do Asana ao montar o componente
|
||||
useEffect(() => {
|
||||
const loadAsanaIntegration = async () => {
|
||||
try {
|
||||
setLoadingIntegration(true);
|
||||
|
||||
// Obtém o ID do usuário do perfil
|
||||
let userEmail = GlobalFunctions.getUsuarioLogado().email;
|
||||
|
||||
// Se não tem email, tenta obter do Transfer Area como fallback
|
||||
if (!userEmail) {
|
||||
const transferEmail = GlobalFunctions.getTransferProperty(
|
||||
TransferAreaProperties.UsuarioEmail
|
||||
);
|
||||
if (transferEmail) {
|
||||
userEmail = transferEmail as string;
|
||||
}
|
||||
}
|
||||
|
||||
// Se ainda não tem email, tenta obter do token novamente após refresh
|
||||
if (!userEmail) {
|
||||
try {
|
||||
await GlobalFunctions.getToken();
|
||||
await new Promise(resolve => setTimeout(resolve, 500));
|
||||
userEmail = GlobalFunctions.getUsuarioLogado().email;
|
||||
} catch (error) {
|
||||
console.error("Erro ao fazer refresh do token:", error);
|
||||
}
|
||||
}
|
||||
|
||||
if (!userEmail) {
|
||||
console.log("Integrations: Não foi possível obter email do usuário");
|
||||
setLoadingIntegration(false);
|
||||
return;
|
||||
}
|
||||
|
||||
// Busca o perfil do usuário para obter o ID
|
||||
const userProfile = await userProfileService.getUserProfile(userEmail);
|
||||
|
||||
if (!userProfile.success || !userProfile.id) {
|
||||
console.log("Integrations: Usuário não encontrado ou sem ID");
|
||||
setLoadingIntegration(false);
|
||||
return;
|
||||
}
|
||||
|
||||
// Armazena o ID do usuário para usar ao criar integração
|
||||
setUserId(userProfile.id);
|
||||
|
||||
// Busca a integração do Asana
|
||||
const integration = await asanaService.getIntegration(userProfile.id);
|
||||
|
||||
if (integration && integration.success) {
|
||||
// Marca que há integração existente
|
||||
setHasIntegration(true);
|
||||
|
||||
// Armazena o ID da integração (pode vir como integracao_id ou id)
|
||||
if (integration.integracao_id) {
|
||||
setIntegrationId(integration.integracao_id);
|
||||
} else if (integration.id) {
|
||||
setIntegrationId(integration.id);
|
||||
}
|
||||
|
||||
// Preenche os dados da integração
|
||||
if (integration.api_key) {
|
||||
setAsanaApiKey(integration.api_key);
|
||||
setAsanaToken(integration.api_key);
|
||||
|
||||
// Busca workspaces com o token
|
||||
try {
|
||||
const workspaces = await asanaService.getWorkspaces(integration.api_key);
|
||||
setAsanaWorkspaces(workspaces);
|
||||
|
||||
// Se tem workspace_gid, seleciona e busca usuários
|
||||
if (integration.workspace_gid) {
|
||||
setSelectedWorkspaceId(integration.workspace_gid);
|
||||
|
||||
// Busca usuários do workspace
|
||||
const users = await asanaService.getUsers(integration.api_key, integration.workspace_gid);
|
||||
setAsanaUsers(users);
|
||||
|
||||
// Se tem usuario_asana_gid, seleciona
|
||||
if (integration.usuario_asana_gid) {
|
||||
setSelectedUserId(integration.usuario_asana_gid);
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Erro ao carregar workspaces/usuários:", error);
|
||||
// Continua mesmo se não conseguir carregar workspaces
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Não há integração, marca como false
|
||||
setHasIntegration(false);
|
||||
}
|
||||
} catch (error: unknown) {
|
||||
console.error("Erro ao carregar integração do Asana:", error);
|
||||
// Não mostra erro para o usuário, apenas deixa os campos vazios
|
||||
} finally {
|
||||
setLoadingIntegration(false);
|
||||
}
|
||||
};
|
||||
|
||||
loadAsanaIntegration();
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div className="space-y-8">
|
||||
{/* Header */}
|
||||
<div>
|
||||
<h1 className="text-2xl font-semibold text-foreground mb-1">
|
||||
Integrações
|
||||
</h1>
|
||||
<p className="text-muted-foreground">
|
||||
Configure as conexões do seu agente com serviços externos
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{/* Integrations Grid */}
|
||||
<div className="grid grid-cols-1 lg:grid-cols-2 gap-4">
|
||||
<GoogleCalendarCard />
|
||||
|
||||
<GoogleSheetsCard />
|
||||
|
||||
<AsanaCard
|
||||
apiKey={asanaApiKey}
|
||||
workspaces={asanaWorkspaces}
|
||||
users={asanaUsers}
|
||||
selectedWorkspaceId={selectedWorkspaceId}
|
||||
selectedUserId={selectedUserId}
|
||||
onSave={handleAsanaSave}
|
||||
onConfirmApiKey={handleAsanaApiKeyConfirm}
|
||||
onWorkspaceChange={handleAsanaWorkspaceChange}
|
||||
loadingWorkspaces={loadingAsanaWorkspaces}
|
||||
loadingUsers={loadingAsanaUsers}
|
||||
loadingIntegration={loadingIntegration}
|
||||
hasIntegration={hasIntegration}
|
||||
saving={saving}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user