Files
sirpremiumv2/resources/views/livewire/chat/show-conversaciones.blade.php
T
2026-04-30 21:32:32 -05:00

202 lines
13 KiB
PHP

<div class="flex overflow-hidden bg-[#111b21]" style="height: calc(100vh - 4.5rem)">
{{-- ══ Panel izquierdo: lista de conversaciones ══ --}}
<div class="w-80 flex flex-col border-r border-[#2a3942] flex-shrink-0 bg-[#111b21]">
{{-- Header --}}
<div class="bg-[#202c33] px-4 py-3 flex items-center gap-2 flex-shrink-0">
<svg class="w-5 h-5 text-[#00a884]" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" d="M8.625 9.75a.375.375 0 1 1-.75 0 .375.375 0 0 1 .75 0Zm0 0H8.25m4.125 0a.375.375 0 1 1-.75 0 .375.375 0 0 1 .75 0Zm0 0H12m4.125 0a.375.375 0 1 1-.75 0 .375.375 0 0 1 .75 0Zm0 0h-.375M21 12c0 4.556-4.03 8.25-9 8.25a9.764 9.764 0 0 1-2.555-.337A5.972 5.972 0 0 1 5.41 20.97a5.969 5.969 0 0 1-.474-.065 4.48 4.48 0 0 0 .978-2.025c.09-.457-.133-.901-.467-1.226C3.93 16.178 3 14.189 3 12c0-4.556 4.03-8.25 9-8.25s9 3.694 9 8.25Z" />
</svg>
<span class="text-white font-semibold text-sm">Conversaciones</span>
</div>
{{-- Búsqueda + filtros --}}
<div class="bg-[#111b21] px-3 py-2 space-y-2 flex-shrink-0">
<input wire:model.debounce.300ms="busqueda" type="text" placeholder="Buscar contacto..."
class="w-full bg-[#2a3942] text-white text-sm rounded-full px-4 py-2 outline-none placeholder-[#8696a0]">
<div class="flex flex-wrap gap-1">
<button wire:click="$set('filtroEstado','')"
class="text-xs px-2 py-1 rounded-full transition {{ $filtroEstado === '' ? 'bg-[#00a884] text-white' : 'bg-[#2a3942] text-[#8696a0] hover:text-white' }}">
Todas
</button>
<button wire:click="$set('filtroEstado','bot')"
class="text-xs px-2 py-1 rounded-full transition {{ $filtroEstado === 'bot' ? 'bg-[#00a884] text-white' : 'bg-[#2a3942] text-[#8696a0] hover:text-white' }}">
Bot
</button>
<button wire:click="$set('filtroEstado','agente')"
class="text-xs px-2 py-1 rounded-full transition {{ $filtroEstado === 'agente' ? 'bg-amber-600 text-white' : 'bg-[#2a3942] text-[#8696a0] hover:text-white' }}">
Agente
</button>
<button wire:click="$set('filtroEstado','cerrada')"
class="text-xs px-2 py-1 rounded-full transition {{ $filtroEstado === 'cerrada' ? 'bg-gray-600 text-white' : 'bg-[#2a3942] text-[#8696a0] hover:text-white' }}">
Cerradas
</button>
</div>
</div>
{{-- Lista conversaciones --}}
<div class="flex-1 overflow-y-auto" wire:poll.5000ms>
@forelse($conversaciones as $conv)
<button wire:click="selectConv({{ $conv->id }})"
class="w-full flex items-start gap-3 px-4 py-3 border-b border-[#2a3942] text-left transition
{{ $convSelecId === $conv->id ? 'bg-[#2a3942]' : 'hover:bg-[#182229]' }}">
{{-- Avatar canal --}}
<div class="w-11 h-11 rounded-full flex items-center justify-center flex-shrink-0
{{ $conv->canal === 'telegram' ? 'bg-blue-600' : 'bg-[#00a884]' }}">
<span class="text-white text-sm font-semibold">
{{ strtoupper(substr($conv->contact?->nombre ?? '?', 0, 1)) }}
</span>
</div>
{{-- Info --}}
<div class="flex-1 min-w-0">
<div class="flex items-center justify-between gap-1">
<span class="text-white text-sm font-medium truncate">{{ $conv->contact?->nombre ?? 'Sin nombre' }}</span>
@if($conv->mensajes_no_leidos > 0)
<span class="bg-[#00a884] text-white text-[10px] rounded-full px-1.5 py-0.5 flex-shrink-0 font-semibold">
{{ $conv->mensajes_no_leidos }}
</span>
@endif
</div>
<div class="flex items-center gap-1.5 mt-0.5">
{{-- badge canal --}}
<span class="text-[9px] px-1.5 py-0.5 rounded-full flex-shrink-0 font-semibold
{{ $conv->canal === 'telegram' ? 'bg-blue-900 text-blue-300' : 'bg-emerald-900 text-emerald-300' }}">
{{ $conv->canal === 'telegram' ? 'TG' : 'WEB' }}
</span>
{{-- badge estado --}}
<span class="text-[9px] px-1.5 py-0.5 rounded-full flex-shrink-0
{{ $conv->estado === 'bot' ? 'bg-gray-700 text-gray-300' : ($conv->estado === 'agente' ? 'bg-amber-700 text-amber-200' : 'bg-gray-800 text-gray-500') }}">
{{ $conv->estado }}
</span>
<span class="text-[#8696a0] text-[10px] truncate flex-1">
{{ $conv->contact?->telefono ?? $conv->contact?->canal_id }}
</span>
</div>
@if($conv->ultimo_mensaje_at)
<p class="text-[#8696a0] text-[10px] mt-0.5">{{ $conv->ultimo_mensaje_at->diffForHumans() }}</p>
@endif
</div>
</button>
@empty
<div class="p-6 text-center text-[#8696a0] text-sm">Sin conversaciones</div>
@endforelse
</div>
</div>
{{-- ══ Panel derecho: mensajes ══ --}}
@if($convSelec)
<div class="flex-1 flex flex-col min-w-0 bg-[#0b141a]"
x-data
x-on:scroll-admin.window="$nextTick(() => { let el = document.getElementById('admin-msgs'); if(el) el.scrollTop = el.scrollHeight; })">
{{-- Header conv seleccionada --}}
<div class="bg-[#202c33] px-4 py-3 flex items-center gap-3 flex-shrink-0 border-b border-[#2a3942]">
<div class="w-10 h-10 rounded-full flex items-center justify-center flex-shrink-0
{{ $convSelec->canal === 'telegram' ? 'bg-blue-600' : 'bg-[#00a884]' }}">
<span class="text-white text-sm font-semibold">
{{ strtoupper(substr($convSelec->contact?->nombre ?? '?', 0, 1)) }}
</span>
</div>
<div class="flex-1 min-w-0">
<p class="text-white text-sm font-semibold truncate">{{ $convSelec->contact?->nombre ?? 'Sin nombre' }}</p>
<p class="text-[#8696a0] text-xs">
{{ $convSelec->canal === 'telegram' ? 'Telegram' : 'Web' }} ·
{{ $convSelec->contact?->telefono ?? $convSelec->contact?->canal_id }}
</p>
</div>
{{-- Acciones --}}
<div class="flex items-center gap-2">
@if($convSelec->estado === 'bot')
<button wire:click="tomarControl"
class="text-xs px-3 py-1.5 bg-amber-700 hover:bg-amber-600 text-white rounded-lg transition">
Tomar control
</button>
@elseif($convSelec->estado === 'agente')
<button wire:click="devolverAlBot"
class="text-xs px-3 py-1.5 bg-gray-700 hover:bg-gray-600 text-white rounded-lg transition">
Al bot
</button>
@endif
@if($convSelec->estado !== 'cerrada')
<button wire:click="cerrarConv" onclick="return confirm('¿Cerrar esta conversación?')"
class="text-xs px-3 py-1.5 bg-red-800 hover:bg-red-700 text-white rounded-lg transition">
Cerrar
</button>
@endif
</div>
</div>
{{-- Mensajes --}}
<div class="flex-1 overflow-y-auto px-4 py-4 space-y-2" id="admin-msgs">
@forelse($mensajes as $msg)
@if ($msg['tipo'] === 'usuario')
<div class="flex justify-start">
<div class="max-w-[70%] bg-[#202c33] text-white rounded-xl rounded-tl-sm px-4 py-2 shadow text-sm">
<p class="whitespace-pre-line break-words">{{ $msg['contenido'] }}</p>
<span class="text-[#8696a0] text-[10px] float-right mt-1 ml-2">{{ $msg['created_at'] }}</span>
</div>
</div>
@elseif ($msg['tipo'] === 'bot')
<div class="flex justify-end">
<div class="max-w-[70%] bg-[#1a3a2a] text-white rounded-xl rounded-tr-sm px-4 py-2 shadow text-sm border border-[#00a884]/20">
<span class="text-[#00a884] text-[10px] font-semibold block mb-0.5">Bot</span>
<p class="whitespace-pre-line break-words">{{ $msg['contenido'] }}</p>
<span class="text-[#8696a0] text-[10px] float-right mt-1 ml-2">{{ $msg['created_at'] }}</span>
</div>
</div>
@else
<div class="flex justify-end">
<div class="max-w-[70%] bg-[#005c4b] text-white rounded-xl rounded-tr-sm px-4 py-2 shadow text-sm">
<span class="text-amber-300 text-[10px] font-semibold block mb-0.5">Agente</span>
<p class="whitespace-pre-line break-words">{{ $msg['contenido'] }}</p>
<span class="text-[#8696a0] text-[10px] float-right mt-1 ml-2">{{ $msg['created_at'] }}</span>
</div>
</div>
@endif
@empty
<div class="text-center text-[#8696a0] text-sm py-10">Sin mensajes</div>
@endforelse
</div>
{{-- Input respuesta (solo en estado agente) --}}
@if($convSelec->estado === 'agente')
<div class="bg-[#202c33] px-3 py-3 flex items-end gap-2 flex-shrink-0">
<textarea wire:model.defer="replyText" rows="2"
placeholder="Escribe tu respuesta como agente..."
class="flex-1 bg-[#2a3942] text-white text-sm rounded-xl px-4 py-3 resize-none outline-none placeholder-[#8696a0] max-h-28"></textarea>
<button wire:click="sendReply"
class="w-11 h-11 bg-[#00a884] hover:bg-[#06cf9c] rounded-full flex items-center justify-center transition flex-shrink-0">
<svg class="w-5 h-5 text-white" viewBox="0 0 24 24" fill="currentColor">
<path d="M2.01 21L23 12 2.01 3 2 10l15 2-15 2z"/>
</svg>
</button>
</div>
@elseif($convSelec->estado === 'bot')
<div class="bg-[#202c33] px-4 py-3 text-center text-[#8696a0] text-xs flex-shrink-0 border-t border-[#2a3942]">
El bot está respondiendo. Usa <strong class="text-white">Tomar control</strong> para responder manualmente.
</div>
@else
<div class="bg-[#202c33] px-4 py-3 text-center text-[#8696a0] text-xs flex-shrink-0 border-t border-[#2a3942]">
Conversación cerrada.
</div>
@endif
</div>
@else
<div class="flex-1 flex items-center justify-center bg-[#0b141a]">
<div class="text-center">
<div class="w-20 h-20 bg-[#202c33] rounded-full flex items-center justify-center mx-auto mb-4">
<svg class="w-10 h-10 text-[#8696a0]" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" d="M8.625 9.75a.375.375 0 1 1-.75 0 .375.375 0 0 1 .75 0Zm0 0H8.25m4.125 0a.375.375 0 1 1-.75 0 .375.375 0 0 1 .75 0Zm0 0H12m4.125 0a.375.375 0 1 1-.75 0 .375.375 0 0 1 .75 0Zm0 0h-.375M21 12c0 4.556-4.03 8.25-9 8.25a9.764 9.764 0 0 1-2.555-.337A5.972 5.972 0 0 1 5.41 20.97a5.969 5.969 0 0 1-.474-.065 4.48 4.48 0 0 0 .978-2.025c.09-.457-.133-.901-.467-1.226C3.93 16.178 3 14.189 3 12c0-4.556 4.03-8.25 9-8.25s9 3.694 9 8.25Z" />
</svg>
</div>
<p class="text-[#8696a0] text-sm">Selecciona una conversación para ver los mensajes</p>
</div>
</div>
@endif
</div>