se cargan modulos de chat en tiempo real

This commit is contained in:
2026-02-28 16:10:19 -06:00
parent 68d32dbd88
commit aeb24f2874
28 changed files with 1830 additions and 33 deletions
+8
View File
@@ -2,3 +2,11 @@ import axios from 'axios';
window.axios = axios;
window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
/**
* Echo exposes an expressive API for subscribing to channels and listening
* for events that are broadcast by Laravel. Echo and event broadcasting
* allow your team to quickly build robust real-time web applications.
*/
import './echo';
+14
View File
@@ -0,0 +1,14 @@
import Echo from 'laravel-echo';
import Pusher from 'pusher-js';
window.Pusher = Pusher;
window.Echo = new Echo({
broadcaster: 'reverb',
key: import.meta.env.VITE_REVERB_APP_KEY,
wsHost: import.meta.env.VITE_REVERB_HOST,
wsPort: import.meta.env.VITE_REVERB_PORT ?? 80,
wssPort: import.meta.env.VITE_REVERB_PORT ?? 443,
forceTLS: false,
enabledTransports: ['ws', 'wss'],
});
-23
View File
@@ -1,23 +0,0 @@
@extends('layouts.landing')
@section('title',"show")
@section('content')
<div class="container-fluid">
<div class="card shadow mb-4">
<div class="card-header py-3">
<div class="d-sm-flex align-items-center justify-content-between">
<h6 class="m-0 font-weight-bold text-primary">Datos carrera</h6>
<a href="{{route('carrera.index')}}" class="d-sm-inline-block btn btn-sm btn-primary shadow-sm"><i class="fas fa-download fa-sm text-white-50"></i> Regresar</a>
</div>
</div>
<div class="card-body">
<h1>{{$carrera->name}}</h1>
</div>
</div>
</div>
@endsection
+160
View File
@@ -0,0 +1,160 @@
@extends('layouts.landing')
@section('title',"Chat")
@section('content')
<div class="container-fluid">
<div class="card shadow mb-4">
<div class="card-header py-3">
<h6 class="m-0 font-weight-bold text-primary">
Mensajes
</h6>
</div>
<div class="card-body">
{{-- CONTENEDOR CHAT --}}
<div id="chat-app"
data-conversation-id="{{ $conversation->id }}">
{{-- MENSAJES --}}
<div id="messages"
style="height:400px;overflow-y:auto;padding:10px;background:#f5f5f5;border-radius:10px;">
@foreach($conversation->messages as $message)
<div class="message {{ $message->user_id == auth()->id() ? 'mine' : 'theirs' }}">
<div class="bubble">
<strong>{{ $message->user->name }}</strong><br>
{{ $message->message }}
</div>
</div>
@endforeach
</div>
{{-- INPUT --}}
<div style="margin-top:10px;display:flex;gap:10px;">
<input id="messageInput"
class="form-control"
placeholder="Escribe mensaje...">
<button onclick="sendMessage()"
class="btn btn-primary">
Enviar
</button>
</div>
</div>
</div>
</div>
</div>
@endsection
@push('scripts')
<script>
window.USER_ID = {{ auth()->id() }};
</script>
<script>
document.addEventListener('DOMContentLoaded', function () {
const chatApp = document.getElementById('chat-app');
const messagesDiv = document.getElementById('messages');
if (!chatApp || !messagesDiv) {
console.error('Chat DOM no encontrado');
return;
}
const conversationId =
chatApp.dataset.conversationId;
console.log('Chat conectado a:', conversationId);
/*
|--------------------------------------------------------------------------
| ESCUCHAR MENSAJES REALTIME
|--------------------------------------------------------------------------
*/
window.Echo.private(`chat.${conversationId}`)
.listen('.ChatMessageSent', (e) => {
console.log('Nuevo mensaje:', e);
let mine =
e.message.user_id == window.USER_ID;
let div = document.createElement('div');
div.className =
'message ' + (mine ? 'mine' : 'theirs');
div.innerHTML = `
<div class="bubble">
<strong>${e.message.user.name}</strong><br>
${e.message.message}
</div>
`;
messagesDiv.appendChild(div);
scrollChat();
});
scrollChat();
});
/*
|--------------------------------------------------------------------------
| ENVIAR MENSAJE
|--------------------------------------------------------------------------
*/
function sendMessage() {
let input = document.getElementById('messageInput');
if (!input.value.trim()) return;
axios.post('/chat/send', {
conversation_id:
document
.getElementById('chat-app')
.dataset.conversationId,
message: input.value
});
input.value = '';
}
/*
|--------------------------------------------------------------------------
| AUTO SCROLL
|--------------------------------------------------------------------------
*/
function scrollChat() {
const container =
document.getElementById('messages');
container.scrollTop =
container.scrollHeight;
}
</script>
@endpush
@@ -3,6 +3,8 @@
<!DOCTYPE html>
<html lang="es">
<head>
@vite(['resources/css/app.css', 'resources/js/app.js'])
@include('layouts._partials.head')
{{-- Livewire styles --}}