Drawer WhatsApp: banner persistente em erros de envio
friendlySendError (string única) virou classifySendError, que devolve
{ code, status, message, hint, action, secondaryAction }. UI passa a
renderizar banner persistente no chat (não só toast efêmero) com título
+ dica explicativa + CTA contextual.
Casos cobertos:
- 502/503/504 -> "Servidor de WhatsApp fora do ar" + CTA Configurar +
CTA Comprar créditos (caso ainda não tenha contratado)
- insufficient_credits -> CTA Comprar créditos
- canal nao configurado / inativo -> CTA Configurar agora
- credenciais evolution incompletas -> CTA Configuracoes WhatsApp
- twilio credenciais incompletas -> sem CTA (fala pra contatar suporte)
- evolution retornou ... -> CTA Ver status
- twilio_send_failed... -> CTA Configuracoes WhatsApp
- auth -> "sessao expirou", sem CTA
- forbidden -> sem CTA
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1103,6 +1103,45 @@ function insertEmoji(emoji) {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Banner de erro de envio (persistente até user enviar com sucesso ou dispensar) -->
|
||||
<div
|
||||
v-if="store.lastSendError"
|
||||
class="flex items-start gap-2.5 mt-2 px-3 py-2.5 rounded-lg border border-amber-300/60 bg-amber-50 text-amber-900 dark:border-amber-500/40 dark:bg-amber-500/10 dark:text-amber-100"
|
||||
>
|
||||
<i class="pi pi-exclamation-triangle text-amber-600 dark:text-amber-300 mt-0.5 shrink-0" />
|
||||
<div class="flex-1 min-w-0">
|
||||
<div class="text-sm font-medium leading-snug">{{ store.lastSendError.message }}</div>
|
||||
<div v-if="store.lastSendError.hint" class="text-xs opacity-85 mt-0.5 leading-snug">
|
||||
{{ store.lastSendError.hint }}
|
||||
</div>
|
||||
<div v-if="store.lastSendError.action || store.lastSendError.secondaryAction" class="flex flex-wrap gap-3 mt-1.5">
|
||||
<RouterLink
|
||||
v-if="store.lastSendError.action"
|
||||
:to="store.lastSendError.action.url"
|
||||
class="inline-flex items-center gap-1 text-xs font-semibold underline hover:no-underline"
|
||||
@click="store.dismissSendError()"
|
||||
>
|
||||
{{ store.lastSendError.action.label }} <i class="pi pi-arrow-right text-[0.6rem]" />
|
||||
</RouterLink>
|
||||
<RouterLink
|
||||
v-if="store.lastSendError.secondaryAction"
|
||||
:to="store.lastSendError.secondaryAction.url"
|
||||
class="inline-flex items-center gap-1 text-xs font-medium underline hover:no-underline opacity-90"
|
||||
@click="store.dismissSendError()"
|
||||
>
|
||||
{{ store.lastSendError.secondaryAction.label }} <i class="pi pi-arrow-right text-[0.6rem]" />
|
||||
</RouterLink>
|
||||
</div>
|
||||
</div>
|
||||
<button
|
||||
class="shrink-0 w-6 h-6 grid place-items-center rounded hover:bg-amber-100 dark:hover:bg-amber-500/20 transition-colors"
|
||||
title="Dispensar"
|
||||
@click="store.dismissSendError()"
|
||||
>
|
||||
<i class="pi pi-times text-[0.7rem]" />
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- Compose -->
|
||||
<div v-if="store.thread.channel === 'whatsapp' && store.thread.contact_number" class="border-t border-[var(--surface-border)] pt-2 flex flex-col gap-2">
|
||||
<div class="flex items-end gap-2">
|
||||
|
||||
Reference in New Issue
Block a user