feat(studio): rediseño de la pantalla del agente — estado arriba, tres zonas, probar al lado
La pantalla estaba organizada por tabla de base de datos: siete pestañas que eran nuestras siete entidades —documentos, herramientas, canales, conexiones, eventos— y que se desbordaban a lo ancho. Un dueño de negocio nunca piensa "voy a Conexiones": piensa "¿por qué contestó mal?" o "quiero que sepa mis precios nuevos". Tres cambios. Un estado arriba que responde "¿está bien mi asistente?" sin un clic: "Atendiendo en WhatsApp · Sabe de 2 cosas · 1 conversación", y en ámbar cuando algo falta — "No está atendiendo en ningún lado", "Todavía no sabe nada de tu negocio". Antes eso había que deducirlo entrando pestaña por pestaña. Cada señal es un botón que lleva a donde se arregla, y si el destino está en Avanzado, lo despliega. Tres zonas en lugar de siete pestañas: Conversaciones, Lo que sabe, Dónde atiende. Herramientas, Cuentas conectadas y Problemas pasan a "Avanzado", plegado. No se sacan —hacen falta— pero dejan de competir todos los días con lo que se mira todos los días. Y el conocimiento con la prueba lado a lado. El bucle real es leer lo que sabe → probar → corregir → probar de nuevo; en dos pestañas separadas eso eran seis clics por corrección. Desde 1024px van en dos columnas, con el chat fijo al hacer scroll; abajo de eso se apilan, que es el orden en que igual se trabaja. El vocabulario deja de ser el nuestro: "Base de conocimiento" es "Lo que sabe", "Auditoría" es "Problemas", "Conexiones" es "Cuentas conectadas". Y la site_key sale del encabezado: se usa una vez, al instalar el widget, y vive donde se instala. No se tocó ni el color ni la tipografía ni Umi. Esto es estructura, no pintura: cambiando las dos cosas a la vez no se sabría cuál mejoró qué. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
c78fcce89b
commit
22158a10a7
@@ -0,0 +1,104 @@
|
||||
<script setup>
|
||||
import { computed } from 'vue'
|
||||
import UiIcono from '../../components/ui/UiIcono.vue'
|
||||
|
||||
// Responde "¿está bien mi asistente?" sin hacer un solo clic.
|
||||
//
|
||||
// Antes había que entrar pestaña por pestaña para saberlo: si estaba atendiendo
|
||||
// en algún lado, si sabía algo, si alguien le había escrito. Tres datos que el
|
||||
// dueño quiere de un vistazo y que estaban repartidos en tres pantallas.
|
||||
const props = defineProps({
|
||||
canales: { type: Array, default: () => [] },
|
||||
documentos: { type: Array, default: () => [] },
|
||||
sesiones: { type: Array, default: () => [] },
|
||||
eventos: { type: Array, default: () => [] },
|
||||
})
|
||||
|
||||
const emit = defineEmits(['ir'])
|
||||
|
||||
const canalesActivos = computed(() => props.canales.filter((c) => c.activo))
|
||||
|
||||
// Los tipos vienen en minúscula del backend; "Atendiendo en whatsapp" se lee
|
||||
// como un error de tipeo.
|
||||
const NOMBRES_CANAL = { whatsapp: 'WhatsApp', telegram: 'Telegram', web: 'tu web' }
|
||||
const nombreCanal = (t) => NOMBRES_CANAL[t] || t
|
||||
|
||||
const fuentesListas = computed(() => props.documentos.filter((d) => d.estado === 'listo'))
|
||||
|
||||
// Dos meses es cuando una fuente empieza a ser sospechosa de estar vieja: es el
|
||||
// mismo corte que usa la lista de conocimiento, para que no digan cosas
|
||||
// distintas.
|
||||
const fuentesViejas = computed(() =>
|
||||
fuentesListas.value.filter(
|
||||
(d) => d.procesado_at && Date.now() - new Date(d.procesado_at) > 60 * 86400000,
|
||||
),
|
||||
)
|
||||
|
||||
const problemas = computed(() => props.eventos.filter((e) => e.nivel === 'error').length)
|
||||
|
||||
// Cada señal dice qué pasa y, cuando algo anda mal, a dónde ir a arreglarlo.
|
||||
const señales = computed(() => [
|
||||
{
|
||||
clave: 'canales',
|
||||
icono: 'mensaje',
|
||||
bien: canalesActivos.value.length > 0,
|
||||
texto: canalesActivos.value.length
|
||||
? `Atendiendo en ${canalesActivos.value.map((c) => nombreCanal(c.tipo)).join(' y ')}`
|
||||
: 'No está atendiendo en ningún lado',
|
||||
destino: 'canales',
|
||||
},
|
||||
{
|
||||
clave: 'conocimiento',
|
||||
icono: 'escribir',
|
||||
bien: fuentesListas.value.length > 0 && fuentesViejas.value.length === 0,
|
||||
texto: !fuentesListas.value.length
|
||||
? 'Todavía no sabe nada de tu negocio'
|
||||
: fuentesViejas.value.length
|
||||
? `${fuentesViejas.value.length} de ${fuentesListas.value.length} fuentes están viejas`
|
||||
: `Sabe de ${fuentesListas.value.length} ${fuentesListas.value.length === 1 ? 'cosa' : 'cosas'}`,
|
||||
destino: 'conocimiento',
|
||||
},
|
||||
{
|
||||
clave: 'conversaciones',
|
||||
icono: 'grafico',
|
||||
// Que nadie haya escrito todavía no es un problema: es un dato.
|
||||
bien: true,
|
||||
neutro: props.sesiones.length === 0,
|
||||
texto: props.sesiones.length
|
||||
? `${props.sesiones.length} ${props.sesiones.length === 1 ? 'conversación' : 'conversaciones'}`
|
||||
: 'Nadie escribió todavía',
|
||||
destino: 'conversaciones',
|
||||
},
|
||||
])
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="card p-1 mb-6 flex flex-wrap">
|
||||
<button
|
||||
v-for="s in señales"
|
||||
:key="s.clave"
|
||||
class="flex items-center gap-2 px-3 py-2 rounded-lg text-sm hover:bg-elevado transition-colors text-left"
|
||||
@click="emit('ir', s.destino)"
|
||||
>
|
||||
<UiIcono
|
||||
:nombre="s.bien ? s.icono : 'alerta'"
|
||||
:tam="16"
|
||||
:class="s.neutro ? 'text-tenue' : s.bien ? 'text-brand' : 'text-amber-600 dark:text-amber-400'"
|
||||
/>
|
||||
<span :class="s.neutro ? 'text-tenue' : s.bien ? 'text-texto' : 'text-amber-700 dark:text-amber-400 font-medium'">
|
||||
{{ s.texto }}
|
||||
</span>
|
||||
</button>
|
||||
|
||||
<button
|
||||
v-if="problemas"
|
||||
class="flex items-center gap-2 px-3 py-2 rounded-lg text-sm hover:bg-elevado transition-colors ml-auto"
|
||||
@click="emit('ir', 'auditoria')"
|
||||
>
|
||||
<UiIcono nombre="alerta" :tam="16" class="text-red-600 dark:text-red-400" />
|
||||
<span class="text-red-700 dark:text-red-400 font-medium">
|
||||
{{ problemas }} {{ problemas === 1 ? 'problema' : 'problemas' }}
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
</template>
|
||||
Reference in New Issue
Block a user