FEAT: Adicionado configuração para canal de atendimento Whatsapp
This commit is contained in:
parent
072cd1cb75
commit
c4b846a079
@ -1,4 +1,5 @@
|
||||
import { useEffect, useMemo, useState } from 'react';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import { DataPanel } from '../components/DataPanel';
|
||||
import { ManagementLayout } from '../components/ManagementLayout';
|
||||
import { ManagementTable } from '../components/ManagementTable';
|
||||
@ -65,6 +66,7 @@ const integrationCards = [
|
||||
name: 'WhatsApp',
|
||||
icon: 'WA',
|
||||
color: '#20a45b',
|
||||
configured: true,
|
||||
description: 'Canal principal para atendimento, abertura ativa e continuidade das conversas no chat.',
|
||||
},
|
||||
{
|
||||
@ -73,6 +75,7 @@ const integrationCards = [
|
||||
name: 'SMS',
|
||||
icon: 'SM',
|
||||
color: '#00a4b7',
|
||||
configured: false,
|
||||
description: 'Envio de comunicados curtos, confirmações e mensagens transacionais para contatos sem WhatsApp.',
|
||||
},
|
||||
{
|
||||
@ -81,6 +84,7 @@ const integrationCards = [
|
||||
name: 'Email',
|
||||
icon: 'EM',
|
||||
color: '#d8891c',
|
||||
configured: false,
|
||||
description: 'Recebimento e resposta de demandas por email dentro da fila omnichannel.',
|
||||
},
|
||||
{
|
||||
@ -89,6 +93,7 @@ const integrationCards = [
|
||||
name: 'SharePoint',
|
||||
icon: 'SP',
|
||||
color: '#036c70',
|
||||
configured: false,
|
||||
description: 'Permite que a IA visualize documentos autorizados para alimentar e manter a base de conhecimento.',
|
||||
},
|
||||
{
|
||||
@ -97,6 +102,7 @@ const integrationCards = [
|
||||
name: 'Gupy',
|
||||
icon: 'GP',
|
||||
color: '#7b4cc2',
|
||||
configured: false,
|
||||
description: 'Conecta vagas abertas e processos dos candidatos para enriquecer a base de conhecimento.',
|
||||
},
|
||||
];
|
||||
@ -180,6 +186,7 @@ export function AdminAttendanceWorkspace({ isWideDesktop, isDesktop, isTablet, i
|
||||
}
|
||||
|
||||
export function AdminPage() {
|
||||
const navigate = useNavigate();
|
||||
const { isWideDesktop, isDesktop, isTablet, isMobile } = useViewport();
|
||||
const userDisplay = getCurrentUserDisplay();
|
||||
const [activeAdminSection, setActiveAdminSection] = useState('home');
|
||||
@ -213,6 +220,8 @@ export function AdminPage() {
|
||||
sharepoint: false,
|
||||
gupy: false,
|
||||
});
|
||||
const [integrationNotice, setIntegrationNotice] = useState('');
|
||||
const [configurationModal, setConfigurationModal] = useState(null);
|
||||
|
||||
useEffect(() => {
|
||||
let isMounted = true;
|
||||
@ -1271,6 +1280,21 @@ export function AdminPage() {
|
||||
const channelCount = integrationCards.filter((item) => item.group === 'Canal' && integrationStates[item.id]).length;
|
||||
const integrationCount = integrationCards.filter((item) => item.group === 'Integração' && integrationStates[item.id]).length;
|
||||
|
||||
function toggleIntegration(item) {
|
||||
const isEnabled = Boolean(integrationStates[item.id]);
|
||||
|
||||
if (!isEnabled && !item.configured) {
|
||||
setIntegrationNotice(`${item.name} ainda não pode ser habilitado porque precisa ser configurado primeiro.`);
|
||||
return;
|
||||
}
|
||||
|
||||
setIntegrationNotice('');
|
||||
setIntegrationStates((current) => ({
|
||||
...current,
|
||||
[item.id]: !current[item.id],
|
||||
}));
|
||||
}
|
||||
|
||||
return (
|
||||
<section style={{ display: 'grid', gap: '1rem' }}>
|
||||
<DataPanel
|
||||
@ -1305,6 +1329,22 @@ export function AdminPage() {
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
{integrationNotice ? (
|
||||
<div
|
||||
role="alert"
|
||||
style={{
|
||||
border: '1px solid rgba(216, 137, 28, 0.32)',
|
||||
borderRadius: 16,
|
||||
padding: '0.85rem 1rem',
|
||||
background: 'rgba(216, 137, 28, 0.08)',
|
||||
color: '#7a4a08',
|
||||
fontWeight: 800,
|
||||
}}
|
||||
>
|
||||
{integrationNotice}
|
||||
</div>
|
||||
) : null}
|
||||
</DataPanel>
|
||||
|
||||
<div
|
||||
@ -1371,12 +1411,7 @@ export function AdminPage() {
|
||||
<button
|
||||
type="button"
|
||||
aria-pressed={isEnabled}
|
||||
onClick={() => {
|
||||
setIntegrationStates((current) => ({
|
||||
...current,
|
||||
[item.id]: !current[item.id],
|
||||
}));
|
||||
}}
|
||||
onClick={() => toggleIntegration(item)}
|
||||
style={{
|
||||
border: 'none',
|
||||
borderRadius: 999,
|
||||
@ -1422,10 +1457,18 @@ export function AdminPage() {
|
||||
}}
|
||||
>
|
||||
<span style={{ color: isEnabled ? item.color : 'var(--color-text-soft)', fontWeight: 800 }}>
|
||||
{isEnabled ? 'Habilitado' : 'Desabilitado'}
|
||||
{isEnabled ? 'Habilitado' : item.configured ? 'Desabilitado' : 'Pendente de configuração'}
|
||||
</span>
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => {
|
||||
if (item.id === 'whatsapp') {
|
||||
navigate('/admin/whatsapp');
|
||||
return;
|
||||
}
|
||||
|
||||
setConfigurationModal(item);
|
||||
}}
|
||||
style={{
|
||||
border: `1px solid ${item.color}44`,
|
||||
borderRadius: 14,
|
||||
@ -1442,6 +1485,85 @@ export function AdminPage() {
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
|
||||
{configurationModal ? (
|
||||
<div
|
||||
role="dialog"
|
||||
aria-modal="true"
|
||||
aria-labelledby="integration-config-title"
|
||||
style={{
|
||||
position: 'fixed',
|
||||
inset: 0,
|
||||
background: 'rgba(0, 20, 32, 0.42)',
|
||||
display: 'grid',
|
||||
placeItems: 'center',
|
||||
padding: '1rem',
|
||||
zIndex: 50,
|
||||
}}
|
||||
onClick={() => setConfigurationModal(null)}
|
||||
>
|
||||
<div
|
||||
onClick={(event) => event.stopPropagation()}
|
||||
style={{
|
||||
width: 'min(460px, 100%)',
|
||||
borderRadius: 22,
|
||||
border: '1px solid var(--color-border)',
|
||||
background: '#fff',
|
||||
padding: '1.25rem',
|
||||
display: 'grid',
|
||||
gap: '0.9rem',
|
||||
boxShadow: 'var(--shadow-lg)',
|
||||
}}
|
||||
>
|
||||
<div style={{ display: 'flex', alignItems: 'center', gap: '0.8rem' }}>
|
||||
<div
|
||||
aria-hidden="true"
|
||||
style={{
|
||||
width: 44,
|
||||
height: 44,
|
||||
borderRadius: 14,
|
||||
display: 'grid',
|
||||
placeItems: 'center',
|
||||
background: configurationModal.color,
|
||||
color: '#fff',
|
||||
fontWeight: 900,
|
||||
}}
|
||||
>
|
||||
{configurationModal.icon}
|
||||
</div>
|
||||
<div>
|
||||
<strong id="integration-config-title" style={{ display: 'block', fontSize: '1.08rem' }}>
|
||||
Configurar {configurationModal.name}
|
||||
</strong>
|
||||
<span style={{ color: 'var(--color-text-soft)', fontWeight: 700 }}>
|
||||
{configurationModal.group}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<p style={{ margin: 0, color: 'var(--color-text-soft)', lineHeight: 1.5, fontWeight: 700 }}>
|
||||
Esta configuração ainda está em construção. Assim que a integração estiver disponível, este espaço vai reunir credenciais, permissões e parâmetros de sincronização.
|
||||
</p>
|
||||
|
||||
<div style={{ display: 'flex', justifyContent: 'flex-end' }}>
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => setConfigurationModal(null)}
|
||||
style={{
|
||||
border: 'none',
|
||||
borderRadius: 14,
|
||||
padding: '0.75rem 0.95rem',
|
||||
background: 'var(--color-primary)',
|
||||
color: '#fff',
|
||||
fontWeight: 800,
|
||||
}}
|
||||
>
|
||||
Entendi
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
) : null}
|
||||
</section>
|
||||
);
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user