fix(chat): sesión persistente entre recargas + responsive móvil/desktop
- mount(): restaura userId y convId desde sesión Laravel al recargar página - abrirChat(): guarda chat_user_id y chat_conv_id en sesión - cerrarSesion(): limpia la sesión correctamente - Desktop: chat centrado como frame (420px, bordes redondeados, sombra) - Móvil: pantalla completa sin restricción de ancho - teclado virtual: ajuste de altura solo en móvil Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 4.6
parent
4ddfdaeecc
commit
d27bd1c0d7
@@ -54,6 +54,32 @@ class PublicChat extends Component
|
|||||||
public $fotoComprobante = null;
|
public $fotoComprobante = null;
|
||||||
public bool $procesandoImagen = false;
|
public bool $procesandoImagen = false;
|
||||||
|
|
||||||
|
public function mount(): void
|
||||||
|
{
|
||||||
|
$userId = session('chat_user_id');
|
||||||
|
$convId = session('chat_conv_id');
|
||||||
|
|
||||||
|
if (! $userId || ! $convId) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$user = User::with('saldo')->find($userId);
|
||||||
|
$conv = ChatConversation::find($convId);
|
||||||
|
|
||||||
|
if (! $user || ! $conv) {
|
||||||
|
session()->forget(['chat_user_id', 'chat_conv_id']);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->userId = $user->id;
|
||||||
|
$this->nombreUsuario = $user->name;
|
||||||
|
$this->saldoUsuario = $user->saldo?->valor ?? 0;
|
||||||
|
$this->convId = $conv->id;
|
||||||
|
$this->estadoConv = $conv->estado;
|
||||||
|
$this->paso = 'chat';
|
||||||
|
$this->cargarMensajes();
|
||||||
|
}
|
||||||
|
|
||||||
protected $rules = [
|
protected $rules = [
|
||||||
'email' => 'required|email|max:100',
|
'email' => 'required|email|max:100',
|
||||||
'nombreRegistro' => 'required|max:80',
|
'nombreRegistro' => 'required|max:80',
|
||||||
@@ -139,6 +165,8 @@ class PublicChat extends Component
|
|||||||
|
|
||||||
public function cerrarSesion(): void
|
public function cerrarSesion(): void
|
||||||
{
|
{
|
||||||
|
session()->forget(['chat_user_id', 'chat_conv_id']);
|
||||||
|
|
||||||
$this->email = '';
|
$this->email = '';
|
||||||
$this->nombreRegistro = '';
|
$this->nombreRegistro = '';
|
||||||
$this->cedulaRegistro = '';
|
$this->cedulaRegistro = '';
|
||||||
@@ -257,6 +285,10 @@ class PublicChat extends Component
|
|||||||
$this->convId = $conv->id;
|
$this->convId = $conv->id;
|
||||||
$this->estadoConv = $conv->estado;
|
$this->estadoConv = $conv->estado;
|
||||||
$this->paso = 'chat';
|
$this->paso = 'chat';
|
||||||
|
|
||||||
|
session()->put('chat_user_id', $this->userId);
|
||||||
|
session()->put('chat_conv_id', $conv->id);
|
||||||
|
|
||||||
$this->cargarMensajes();
|
$this->cargarMensajes();
|
||||||
$this->mostrarMenuPrincipal($conv->id);
|
$this->mostrarMenuPrincipal($conv->id);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,11 +2,9 @@
|
|||||||
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
|
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
{{-- viewport-fit=cover expone las safe areas del notch/Dynamic Island --}}
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
|
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
|
||||||
<meta name="csrf-token" content="{{ csrf_token() }}">
|
<meta name="csrf-token" content="{{ csrf_token() }}">
|
||||||
<meta name="color-scheme" content="dark">
|
<meta name="color-scheme" content="dark">
|
||||||
{{-- Apple PWA / standalone --}}
|
|
||||||
<meta name="apple-mobile-web-app-capable" content="yes">
|
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||||
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
|
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
|
||||||
<meta name="apple-mobile-web-app-title" content="Chat">
|
<meta name="apple-mobile-web-app-title" content="Chat">
|
||||||
@@ -14,43 +12,71 @@
|
|||||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600&display=swap" rel="stylesheet">
|
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600&display=swap" rel="stylesheet">
|
||||||
<script src="https://cdn.tailwindcss.com"></script>
|
<script src="https://cdn.tailwindcss.com"></script>
|
||||||
<style>
|
<style>
|
||||||
/* ── Reset iOS/Safari ───────────────────────────────── */
|
|
||||||
*, *::before, *::after { box-sizing: border-box; }
|
*, *::before, *::after { box-sizing: border-box; }
|
||||||
|
|
||||||
html {
|
html, body {
|
||||||
/* Altura real del viewport incluyendo safe areas */
|
margin: 0; padding: 0;
|
||||||
height: -webkit-fill-available;
|
font-family: 'Inter', sans-serif;
|
||||||
|
-webkit-tap-highlight-color: transparent;
|
||||||
|
overscroll-behavior: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Móvil: pantalla completa */
|
||||||
body {
|
body {
|
||||||
font-family: 'Inter', sans-serif;
|
|
||||||
background: #111b21;
|
background: #111b21;
|
||||||
/* Evita el scroll del body — solo scrollea el área de mensajes */
|
|
||||||
overflow: hidden;
|
|
||||||
overscroll-behavior: none;
|
|
||||||
/* Altura: dvh con fallback para Safari < 15.4 */
|
|
||||||
height: 100vh;
|
height: 100vh;
|
||||||
height: 100dvh;
|
height: 100dvh;
|
||||||
height: -webkit-fill-available;
|
height: -webkit-fill-available;
|
||||||
/* Elimina el tap highlight azul en iOS */
|
overflow: hidden;
|
||||||
-webkit-tap-highlight-color: transparent;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Evita el zoom Safari en inputs < 16px */
|
/* Desktop: fondo con gradiente + chat centrado como frame */
|
||||||
input, textarea, select {
|
@media (min-width: 640px) {
|
||||||
font-size: 16px !important;
|
body {
|
||||||
|
background: #0d1117;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Scroll suave tipo nativo en iOS */
|
/* El contenedor del chat */
|
||||||
|
#chat-root {
|
||||||
|
width: 100%;
|
||||||
|
height: 100vh;
|
||||||
|
height: 100dvh;
|
||||||
|
height: -webkit-fill-available;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
background: #111b21;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 640px) {
|
||||||
|
#chat-root {
|
||||||
|
width: 420px;
|
||||||
|
height: 90vh;
|
||||||
|
height: 90dvh;
|
||||||
|
max-height: 820px;
|
||||||
|
border-radius: 20px;
|
||||||
|
box-shadow: 0 24px 64px rgba(0,0,0,.6);
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Evita zoom en inputs iOS */
|
||||||
|
input, textarea, select { font-size: 16px !important; }
|
||||||
|
|
||||||
|
/* Scroll suave nativo */
|
||||||
.ios-scroll {
|
.ios-scroll {
|
||||||
-webkit-overflow-scrolling: touch;
|
-webkit-overflow-scrolling: touch;
|
||||||
overscroll-behavior-y: contain;
|
overscroll-behavior-y: contain;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Deshabilitar appearance por defecto en iOS */
|
/* Elimina appearance por defecto iOS */
|
||||||
input[type="tel"],
|
input[type="tel"], input[type="text"],
|
||||||
input[type="text"],
|
input[type="email"], textarea {
|
||||||
textarea {
|
|
||||||
-webkit-appearance: none;
|
-webkit-appearance: none;
|
||||||
appearance: none;
|
appearance: none;
|
||||||
border-radius: 12px;
|
border-radius: 12px;
|
||||||
@@ -62,7 +88,7 @@
|
|||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Safe area — rellena el notch arriba y el home indicator abajo */
|
/* Safe areas (solo afectan en iOS con viewport-fit=cover) */
|
||||||
.safe-top { padding-top: env(safe-area-inset-top, 0px); }
|
.safe-top { padding-top: env(safe-area-inset-top, 0px); }
|
||||||
.safe-bottom { padding-bottom: env(safe-area-inset-bottom, 0px); }
|
.safe-bottom { padding-bottom: env(safe-area-inset-bottom, 0px); }
|
||||||
.safe-left { padding-left: env(safe-area-inset-left, 0px); }
|
.safe-left { padding-left: env(safe-area-inset-left, 0px); }
|
||||||
@@ -78,18 +104,16 @@
|
|||||||
@livewireScripts
|
@livewireScripts
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
/**
|
/* Ajusta altura del chat cuando aparece el teclado en móvil */
|
||||||
* visualViewport API: cuando el teclado iOS aparece, el viewport se reduce.
|
|
||||||
* Ajustamos la altura del chat dinámicamente para que el input quede visible.
|
|
||||||
*/
|
|
||||||
function initViewportFix() {
|
function initViewportFix() {
|
||||||
const root = document.getElementById('chat-root');
|
const root = document.getElementById('chat-root');
|
||||||
if (!root || !window.visualViewport) return;
|
if (!root || !window.visualViewport) return;
|
||||||
|
|
||||||
|
const isMobile = window.innerWidth < 640;
|
||||||
|
if (!isMobile) return; // En desktop no necesitamos ajustar
|
||||||
|
|
||||||
const update = () => {
|
const update = () => {
|
||||||
const h = window.visualViewport.height;
|
root.style.height = window.visualViewport.height + 'px';
|
||||||
root.style.height = h + 'px';
|
|
||||||
// Scroll al último mensaje al aparecer teclado
|
|
||||||
const msgs = document.getElementById('pub-messages');
|
const msgs = document.getElementById('pub-messages');
|
||||||
if (msgs) setTimeout(() => { msgs.scrollTop = msgs.scrollHeight; }, 50);
|
if (msgs) setTimeout(() => { msgs.scrollTop = msgs.scrollHeight; }, 50);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,6 +1,4 @@
|
|||||||
<div id="chat-root"
|
<div id="chat-root">
|
||||||
class="w-full flex flex-col bg-[#111b21]"
|
|
||||||
style="height: 100vh; height: 100dvh; height: -webkit-fill-available; max-width: 480px; margin: 0 auto;">
|
|
||||||
|
|
||||||
{{-- ══ PASO 1: Ingreso de correo ══ --}}
|
{{-- ══ PASO 1: Ingreso de correo ══ --}}
|
||||||
@if ($paso === 'email')
|
@if ($paso === 'email')
|
||||||
|
|||||||
Reference in New Issue
Block a user