Files
sirpremiumv2/resources/views/livewire/whatsapp/show-conversaciones.blade.php
T
2026-04-24 21:40:10 -05:00

167 lines
12 KiB
PHP

<div class="flex h-[calc(100vh-72px)] overflow-hidden bg-gray-100">
{{-- Panel izquierdo: lista de contactos --}}
<div class="w-80 flex-shrink-0 bg-white border-r border-gray-200 flex flex-col">
{{-- Header --}}
<div class="p-4 border-b border-gray-200">
<h2 class="text-lg font-bold text-gray-800 flex items-center gap-2">
<svg class="w-6 h-6 text-green-500" fill="currentColor" viewBox="0 0 24 24">
<path d="M17.472 14.382c-.297-.149-1.758-.867-2.03-.967-.273-.099-.471-.148-.67.15-.197.297-.767.966-.94 1.164-.173.199-.347.223-.644.075-.297-.15-1.255-.463-2.39-1.475-.883-.788-1.48-1.761-1.653-2.059-.173-.297-.018-.458.13-.606.134-.133.298-.347.446-.52.149-.174.198-.298.298-.497.099-.198.05-.371-.025-.52-.075-.149-.669-1.612-.916-2.207-.242-.579-.487-.5-.669-.51-.173-.008-.371-.01-.57-.01-.198 0-.52.074-.792.372-.272.297-1.04 1.016-1.04 2.479 0 1.462 1.065 2.875 1.213 3.074.149.198 2.096 3.2 5.077 4.487.709.306 1.262.489 1.694.625.712.227 1.36.195 1.871.118.571-.085 1.758-.719 2.006-1.413.248-.694.248-1.289.173-1.413-.074-.124-.272-.198-.57-.347z"/>
<path d="M12 0C5.373 0 0 5.373 0 12c0 2.127.558 4.122 1.532 5.857L.057 23.786a.5.5 0 0 0 .629.628l5.963-1.467A11.944 11.944 0 0 0 12 24c6.627 0 12-5.373 12-12S18.627 0 12 0zm0 22c-1.88 0-3.638-.52-5.145-1.42l-.369-.22-3.818.94.974-3.782-.239-.381A9.944 9.944 0 0 1 2 12c0-5.523 4.477-10 10-10s10 4.477 10 10-4.477 10-10 10z"/>
</svg>
WhatsApp
</h2>
<div class="mt-2">
<input wire:model.live.debounce.300ms="search"
type="text"
placeholder="Buscar contacto..."
class="w-full text-sm border border-gray-300 rounded-lg px-3 py-2 focus:outline-none focus:ring-2 focus:ring-green-400">
</div>
</div>
{{-- Lista de usuarios --}}
<div class="flex-1 overflow-y-auto">
@forelse($users as $user)
<button wire:click="selectUser({{ $user->id }})"
class="w-full text-left px-4 py-3 border-b border-gray-100 hover:bg-gray-50 flex items-center gap-3 transition
{{ $selectedUserId === $user->id ? 'bg-green-50 border-l-4 border-l-green-500' : '' }}">
<div class="relative flex-shrink-0">
<img src="https://ui-avatars.com/api/?name={{ urlencode($user->name ?? $user->phone_number) }}&size=40&background=22c55e&color=fff"
class="w-10 h-10 rounded-full" alt="">
<span class="absolute bottom-0 right-0 w-3 h-3 rounded-full border-2 border-white
{{ $user->status === 'active' ? 'bg-green-400' : ($user->status === 'blocked' ? 'bg-red-400' : 'bg-gray-400') }}">
</span>
</div>
<div class="flex-1 min-w-0">
<div class="flex justify-between items-center">
<span class="text-sm font-semibold text-gray-800 truncate">{{ $user->name ?? $user->phone_number }}</span>
@if($user->unread_count > 0)
<span class="bg-green-500 text-white text-xs rounded-full px-2 py-0.5 ml-1">{{ $user->unread_count }}</span>
@endif
</div>
<p class="text-xs text-gray-500 truncate">
{{ $user->phone_number }}
</p>
@if($user->lastMessage)
<p class="text-xs text-gray-400 truncate">
{{ Str::limit($user->lastMessage->content, 40) }}
</p>
@endif
</div>
</button>
@empty
<div class="p-6 text-center text-gray-400 text-sm">No hay contactos</div>
@endforelse
</div>
{{-- Paginación --}}
<div class="p-2 border-t border-gray-200 text-xs">
{{ $users->links() }}
</div>
</div>
{{-- Panel derecho: chat --}}
<div class="flex-1 flex flex-col">
@if($selectedUser)
{{-- Chat header --}}
<div class="bg-white px-4 py-3 border-b border-gray-200 flex items-center justify-between shadow-sm">
<div class="flex items-center gap-3">
<img src="https://ui-avatars.com/api/?name={{ urlencode($selectedUser->name ?? $selectedUser->phone_number) }}&size=40&background=22c55e&color=fff"
class="w-10 h-10 rounded-full" alt="">
<div>
<div class="font-semibold text-gray-800">{{ $selectedUser->name ?? 'Sin nombre' }}</div>
<div class="text-xs text-gray-500">{{ $selectedUser->phone_number }}</div>
</div>
</div>
<div class="flex items-center gap-2">
@if($selectedUser->in_service)
<span class="text-xs bg-blue-100 text-blue-700 px-2 py-1 rounded-full">En atención</span>
@endif
@if($selectedUser->on_hold)
<span class="text-xs bg-yellow-100 text-yellow-700 px-2 py-1 rounded-full">En espera</span>
@endif
<button wire:click="toggleBlockUser"
class="text-xs px-3 py-1 rounded-full border transition
{{ $selectedUser->status === 'blocked'
? 'bg-red-100 text-red-700 border-red-200 hover:bg-red-200'
: 'bg-gray-100 text-gray-600 border-gray-200 hover:bg-gray-200' }}">
{{ $selectedUser->status === 'blocked' ? 'Desbloquear' : 'Bloquear' }}
</button>
</div>
</div>
{{-- Mensajes --}}
<div id="chat-messages" class="flex-1 overflow-y-auto p-4 space-y-2 bg-[#e5ddd5]"
x-data x-init="$nextTick(() => { let el = document.getElementById('chat-messages'); el.scrollTop = el.scrollHeight; })"
@scroll-to-bottom.window="$nextTick(() => { $el.scrollTop = $el.scrollHeight })">
@forelse($messages as $msg)
<div class="flex {{ $msg->direction === 'outgoing' ? 'justify-end' : 'justify-start' }}">
<div class="max-w-xs lg:max-w-md xl:max-w-lg {{ $msg->direction === 'outgoing' ? 'bg-[#dcf8c6]' : 'bg-white' }} rounded-lg px-3 py-2 shadow-sm">
@if($msg->message_type === 'text')
<p class="text-sm text-gray-800 whitespace-pre-wrap">{{ $msg->content }}</p>
@elseif(in_array($msg->message_type, ['image', 'video', 'document', 'audio']))
@if($msg->media_url)
@if($msg->message_type === 'image')
<img src="{{ $msg->media_url }}" class="rounded max-w-full" alt="Imagen">
@elseif($msg->message_type === 'document')
<a href="{{ $msg->media_url }}" target="_blank" class="text-blue-600 text-sm underline flex items-center gap-1">
<svg class="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 10v6m0 0-3-3m3 3 3-3M3 17V7a2 2 0 012-2h6l2 2h6a2 2 0 012 2v8a2 2 0 01-2 2H5a2 2 0 01-2-2z"/></svg>
{{ $msg->filename ?? 'Documento' }}
</a>
@else
<span class="text-xs text-gray-500 italic">[{{ strtoupper($msg->message_type) }}]</span>
@endif
@else
<span class="text-xs text-gray-400 italic">[{{ strtoupper($msg->message_type) }} sin URL]</span>
@endif
@else
<p class="text-sm text-gray-600 italic">{{ $msg->content }}</p>
@endif
<div class="text-right mt-1">
<span class="text-[10px] text-gray-400">{{ $msg->created_at->format('H:i') }}</span>
@if($msg->direction === 'outgoing')
<span class="text-[10px] ml-1 {{ $msg->status === 'read' ? 'text-blue-500' : 'text-gray-400' }}">✓✓</span>
@endif
</div>
</div>
</div>
@empty
<div class="text-center text-gray-400 text-sm py-10">No hay mensajes</div>
@endforelse
</div>
{{-- Input de respuesta --}}
<div class="bg-white border-t border-gray-200 p-3">
@if($selectedUser->status === 'blocked')
<div class="text-center text-red-500 text-sm py-2">Usuario bloqueado desbloquea para responder</div>
@else
<form wire:submit.prevent="sendReply" class="flex items-end gap-2">
<textarea wire:model="replyText"
placeholder="Escribe un mensaje..."
rows="2"
class="flex-1 border border-gray-300 rounded-lg px-3 py-2 text-sm resize-none focus:outline-none focus:ring-2 focus:ring-green-400"
x-on:keydown.ctrl.enter="$wire.sendReply()"></textarea>
<button type="submit"
class="bg-green-500 hover:bg-green-600 text-white p-3 rounded-lg transition">
<svg class="w-5 h-5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 19l9 2-9-18-9 18 9-2zm0 0v-8"/>
</svg>
</button>
</form>
@error('replyText') <p class="text-red-500 text-xs mt-1">{{ $message }}</p> @enderror
@if(session('error')) <p class="text-red-500 text-xs mt-1">{{ session('error') }}</p> @endif
@endif
</div>
@else
<div class="flex-1 flex flex-col items-center justify-center text-gray-400 bg-[#e5ddd5]">
<svg class="w-20 h-20 mb-4 opacity-30" fill="currentColor" viewBox="0 0 24 24">
<path d="M17.472 14.382c-.297-.149-1.758-.867-2.03-.967-.273-.099-.471-.148-.67.15-.197.297-.767.966-.94 1.164-.173.199-.347.223-.644.075-.297-.15-1.255-.463-2.39-1.475-.883-.788-1.48-1.761-1.653-2.059-.173-.297-.018-.458.13-.606.134-.133.298-.347.446-.52.149-.174.198-.298.298-.497.099-.198.05-.371-.025-.52-.075-.149-.669-1.612-.916-2.207-.242-.579-.487-.5-.669-.51-.173-.008-.371-.01-.57-.01-.198 0-.52.074-.792.372-.272.297-1.04 1.016-1.04 2.479 0 1.462 1.065 2.875 1.213 3.074.149.198 2.096 3.2 5.077 4.487.709.306 1.262.489 1.694.625.712.227 1.36.195 1.871.118.571-.085 1.758-.719 2.006-1.413.248-.694.248-1.289.173-1.413-.074-.124-.272-.198-.57-.347z"/>
</svg>
<p class="text-lg font-medium">Selecciona una conversación</p>
<p class="text-sm">Elige un contacto de la lista para ver el chat</p>
</div>
@endif
</div>
</div>