FEAT: Atualizado abertura de atendimento com agenda e etiqueta
This commit is contained in:
parent
7a7179bb5d
commit
dcad70b708
@ -6,7 +6,6 @@ import { API_BASE_URL } from '../../../shared/services/apiConfig';
|
|||||||
import { getCurrentUser } from '../../auth/services/sessionService';
|
import { getCurrentUser } from '../../auth/services/sessionService';
|
||||||
import { listContactProfiles, saveContactProfile } from '../../chat/services/contactProfileService';
|
import { listContactProfiles, saveContactProfile } from '../../chat/services/contactProfileService';
|
||||||
import { getAccessOptions } from '../../management/services/adminAccessService';
|
import { getAccessOptions } from '../../management/services/adminAccessService';
|
||||||
import { RecentContactsList } from '../components/RecentContactsList';
|
|
||||||
import { attendanceChannels } from '../services/attendanceMocks';
|
import { attendanceChannels } from '../services/attendanceMocks';
|
||||||
|
|
||||||
const countryOptions = [
|
const countryOptions = [
|
||||||
@ -253,7 +252,7 @@ export function NewAttendancePage({ embedded = false }) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return contacts.filter((contact) => {
|
return contacts.filter((contact) => {
|
||||||
const haystack = `${contact.name} ${contact.phone} ${contact.rawPhone}`.toLowerCase();
|
const haystack = `${contact.name} ${contact.phone} ${contact.rawPhone} ${contact.company} ${contact.note}`.toLowerCase();
|
||||||
return haystack.includes(search);
|
return haystack.includes(search);
|
||||||
});
|
});
|
||||||
}, [contacts, search]);
|
}, [contacts, search]);
|
||||||
@ -269,9 +268,9 @@ export function NewAttendancePage({ embedded = false }) {
|
|||||||
const gridTemplateColumns = isMobile
|
const gridTemplateColumns = isMobile
|
||||||
? '1fr'
|
? '1fr'
|
||||||
: isWideDesktop
|
: isWideDesktop
|
||||||
? 'minmax(300px, 360px) minmax(0, 1fr)'
|
? 'minmax(0, 1fr) minmax(340px, 0.8fr)'
|
||||||
: isDesktop || isTablet
|
: isDesktop || isTablet
|
||||||
? 'minmax(280px, 340px) minmax(0, 1fr)'
|
? 'minmax(0, 1fr) minmax(320px, 0.85fr)'
|
||||||
: '1fr';
|
: '1fr';
|
||||||
|
|
||||||
function selectContact(contactId) {
|
function selectContact(contactId) {
|
||||||
@ -406,12 +405,6 @@ export function NewAttendancePage({ embedded = false }) {
|
|||||||
alignItems: 'start',
|
alignItems: 'start',
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<RecentContactsList
|
|
||||||
contacts={filteredContacts}
|
|
||||||
activeContactId={selectedContactId}
|
|
||||||
onSelectContact={selectContact}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<section
|
<section
|
||||||
style={{
|
style={{
|
||||||
background: '#fff',
|
background: '#fff',
|
||||||
@ -430,20 +423,6 @@ export function NewAttendancePage({ embedded = false }) {
|
|||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<input
|
|
||||||
type="search"
|
|
||||||
value={searchValue}
|
|
||||||
onChange={(event) => setSearchValue(event.target.value)}
|
|
||||||
placeholder="Buscar contato salvo por nome ou número"
|
|
||||||
style={{
|
|
||||||
border: '1px solid var(--color-border)',
|
|
||||||
borderRadius: '18px',
|
|
||||||
padding: '0.95rem 1rem',
|
|
||||||
background: '#fff',
|
|
||||||
outline: 'none',
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<div
|
<div
|
||||||
style={{
|
style={{
|
||||||
display: 'grid',
|
display: 'grid',
|
||||||
@ -565,12 +544,12 @@ export function NewAttendancePage({ embedded = false }) {
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<label style={{ display: 'grid', gap: '0.45rem' }}>
|
<label style={{ display: 'grid', gap: '0.45rem' }}>
|
||||||
<span style={{ fontWeight: 600 }}>Tag</span>
|
<span style={{ fontWeight: 600 }}>Etiqueta de identificação</span>
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
value={form.company}
|
value={form.company}
|
||||||
onChange={(event) => setForm((current) => ({ ...current, company: event.target.value }))}
|
onChange={(event) => setForm((current) => ({ ...current, company: event.target.value }))}
|
||||||
placeholder="Tag ou conta vinculada"
|
placeholder="Ex: Departamento, vaga ou conta vinculada"
|
||||||
style={{
|
style={{
|
||||||
border: '1px solid var(--color-border)',
|
border: '1px solid var(--color-border)',
|
||||||
borderRadius: '18px',
|
borderRadius: '18px',
|
||||||
@ -768,7 +747,7 @@ export function NewAttendancePage({ embedded = false }) {
|
|||||||
Número: {buildInternationalPhone(form.phone, selectedCountryId) ? `+${buildInternationalPhone(form.phone, selectedCountryId)}` : 'Não informado'}
|
Número: {buildInternationalPhone(form.phone, selectedCountryId) ? `+${buildInternationalPhone(form.phone, selectedCountryId)}` : 'Não informado'}
|
||||||
</span>
|
</span>
|
||||||
<span style={{ color: 'rgba(255, 255, 255, 0.74)' }}>
|
<span style={{ color: 'rgba(255, 255, 255, 0.74)' }}>
|
||||||
Tag: {form.company || 'Não informada'}
|
Etiqueta de identificação: {form.company || 'Não informada'}
|
||||||
</span>
|
</span>
|
||||||
<span style={{ color: 'rgba(255, 255, 255, 0.74)' }}>
|
<span style={{ color: 'rgba(255, 255, 255, 0.74)' }}>
|
||||||
Origem: {selectedContactId ? 'Agenda' : 'Novo contato'}
|
Origem: {selectedContactId ? 'Agenda' : 'Novo contato'}
|
||||||
@ -826,6 +805,127 @@ export function NewAttendancePage({ embedded = false }) {
|
|||||||
</article>
|
</article>
|
||||||
</section>
|
</section>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
<aside style={{ display: 'grid', gap: '0.85rem', alignContent: 'start' }}>
|
||||||
|
<article
|
||||||
|
style={{
|
||||||
|
border: '1px solid var(--color-border)',
|
||||||
|
borderRadius: 24,
|
||||||
|
padding: '1rem',
|
||||||
|
background: '#fff',
|
||||||
|
display: 'grid',
|
||||||
|
gap: '0.75rem',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div>
|
||||||
|
<strong style={{ display: 'block' }}>Agenda de contatos</strong>
|
||||||
|
<span style={{ color: 'var(--color-text-soft)', fontSize: '0.9rem' }}>
|
||||||
|
Selecione um contato salvo para preencher o atendimento.
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<input
|
||||||
|
type="search"
|
||||||
|
value={searchValue}
|
||||||
|
onChange={(event) => setSearchValue(event.target.value)}
|
||||||
|
placeholder="Buscar por nome, telefone ou etiqueta"
|
||||||
|
style={{
|
||||||
|
border: '1px solid var(--color-border)',
|
||||||
|
borderRadius: '16px',
|
||||||
|
padding: '0.85rem 0.9rem',
|
||||||
|
background: '#fff',
|
||||||
|
outline: 'none',
|
||||||
|
fontWeight: 600,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<div style={{ display: 'grid', gap: '0.45rem', maxHeight: 460, overflowY: 'auto', paddingRight: '0.2rem' }}>
|
||||||
|
{filteredContacts.map((contact) => {
|
||||||
|
const isSelected = selectedContactId === contact.id;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<button
|
||||||
|
key={contact.id}
|
||||||
|
type="button"
|
||||||
|
onClick={() => selectContact(contact.id)}
|
||||||
|
style={{
|
||||||
|
border: '1px solid',
|
||||||
|
borderColor: isSelected ? 'rgba(0, 164, 183, 0.36)' : 'var(--color-border)',
|
||||||
|
borderRadius: 16,
|
||||||
|
padding: '0.78rem',
|
||||||
|
background: isSelected ? 'rgba(0, 164, 183, 0.08)' : '#fff',
|
||||||
|
textAlign: 'left',
|
||||||
|
display: 'grid',
|
||||||
|
gap: '0.25rem',
|
||||||
|
cursor: 'pointer',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<strong style={{ overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>
|
||||||
|
{contact.name}
|
||||||
|
</strong>
|
||||||
|
<span style={{ color: 'var(--color-text-soft)', fontSize: '0.88rem' }}>
|
||||||
|
+{contact.rawPhone || normalizePhone(contact.phone)}
|
||||||
|
</span>
|
||||||
|
{contact.company ? (
|
||||||
|
<span
|
||||||
|
style={{
|
||||||
|
width: 'fit-content',
|
||||||
|
borderRadius: 999,
|
||||||
|
padding: '0.16rem 0.48rem',
|
||||||
|
background: 'rgba(0,49,80,0.06)',
|
||||||
|
color: 'var(--color-text-soft)',
|
||||||
|
fontSize: '0.76rem',
|
||||||
|
fontWeight: 800,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{contact.company}
|
||||||
|
</span>
|
||||||
|
) : null}
|
||||||
|
</button>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
|
||||||
|
{!filteredContacts.length ? (
|
||||||
|
<span style={{ color: 'var(--color-text-soft)', fontWeight: 700 }}>
|
||||||
|
Nenhum contato encontrado na agenda.
|
||||||
|
</span>
|
||||||
|
) : null}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{selectedContactId ? (
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
onClick={clearSelection}
|
||||||
|
style={{
|
||||||
|
border: '1px solid var(--color-border)',
|
||||||
|
borderRadius: 14,
|
||||||
|
padding: '0.75rem',
|
||||||
|
background: '#fff',
|
||||||
|
color: 'var(--color-primary)',
|
||||||
|
fontWeight: 800,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Limpar contato selecionado
|
||||||
|
</button>
|
||||||
|
) : null}
|
||||||
|
</article>
|
||||||
|
|
||||||
|
<article
|
||||||
|
style={{
|
||||||
|
border: '1px solid rgba(0, 164, 183, 0.24)',
|
||||||
|
borderRadius: 24,
|
||||||
|
padding: '1rem',
|
||||||
|
background: 'rgba(0, 164, 183, 0.06)',
|
||||||
|
color: 'var(--color-text-soft)',
|
||||||
|
lineHeight: 1.45,
|
||||||
|
fontWeight: 700,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{selectedContactId
|
||||||
|
? 'Contato carregado da agenda. Você ainda pode ajustar nome, etiqueta e observação antes de iniciar.'
|
||||||
|
: 'Você também pode digitar um novo número manualmente no formulário.'}
|
||||||
|
</article>
|
||||||
|
</aside>
|
||||||
</section>
|
</section>
|
||||||
</section>
|
</section>
|
||||||
);
|
);
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user