feat: preview de imagen y doble indicador de carga al subir comprobante
- Muestra thumbnail de la imagen seleccionada inmediatamente (FileReader) con spinner superpuesto mientras Livewire sube el archivo - wire:loading wire:target="fotoComprobante" muestra "Analizando con IA..." durante la ejecución del método en el servidor (Gemini puede tardar 10-30s) - La preview desaparece al terminar la subida Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 4.6
parent
7408a413ff
commit
c7c52df743
@@ -161,10 +161,10 @@
|
||||
{{-- ══ PASO 3: Interfaz de chat ══ --}}
|
||||
@else
|
||||
<div class="flex-1 flex flex-col min-h-0 bg-[#0b141a] relative"
|
||||
x-data="{ uploading: false }"
|
||||
x-data="{ uploading: false, previewUrl: null }"
|
||||
@livewire-upload-start.window="uploading = true"
|
||||
@livewire-upload-finish.window="uploading = false"
|
||||
@livewire-upload-error.window="uploading = false">
|
||||
@livewire-upload-finish.window="uploading = false; previewUrl = null"
|
||||
@livewire-upload-error.window="uploading = false; previewUrl = null"
|
||||
|
||||
{{-- Header --}}
|
||||
<div class="bg-[#202c33] shadow-md flex-shrink-0 safe-top safe-left safe-right">
|
||||
@@ -617,8 +617,23 @@
|
||||
{{-- Input + upload --}}
|
||||
@if ($estadoConv !== 'cerrada')
|
||||
<div class="bg-[#202c33] flex-shrink-0 safe-bottom safe-left safe-right" style="flex-shrink:0;">
|
||||
{{-- Indicador subiendo / analizando imagen --}}
|
||||
<div x-show="uploading" x-cloak class="px-4 pt-2 pb-1">
|
||||
{{-- Preview local de la imagen seleccionada --}}
|
||||
<template x-if="previewUrl">
|
||||
<div class="px-3 pt-2 pb-1 flex items-center gap-3">
|
||||
<div class="relative">
|
||||
<img :src="previewUrl" class="h-16 w-16 object-cover rounded-xl border-2 border-[#00a884]">
|
||||
<div class="absolute inset-0 bg-black/50 rounded-xl flex items-center justify-center">
|
||||
<svg class="w-5 h-5 animate-spin text-white" fill="none" viewBox="0 0 24 24">
|
||||
<circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>
|
||||
<path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8v8z"></path>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
<span class="text-[#8696a0] text-xs">Subiendo comprobante...</span>
|
||||
</div>
|
||||
</template>
|
||||
{{-- Indicador: subiendo archivo (fase Alpine) --}}
|
||||
<div x-show="uploading && !previewUrl" x-cloak class="px-4 pt-2 pb-1">
|
||||
<div class="flex items-center gap-2 text-[#8696a0] text-xs">
|
||||
<svg class="w-4 h-4 animate-spin text-[#00a884]" fill="none" viewBox="0 0 24 24">
|
||||
<circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>
|
||||
@@ -627,10 +642,22 @@
|
||||
Subiendo imagen...
|
||||
</div>
|
||||
</div>
|
||||
{{-- Indicador: analizando con IA (fase Livewire server) --}}
|
||||
<div wire:loading wire:target="fotoComprobante" class="px-4 pt-2 pb-1">
|
||||
<div class="flex items-center gap-2 text-[#8696a0] text-xs">
|
||||
<svg class="w-4 h-4 animate-spin text-[#00a884]" fill="none" viewBox="0 0 24 24">
|
||||
<circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>
|
||||
<path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8v8z"></path>
|
||||
</svg>
|
||||
Analizando comprobante con IA...
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex items-end gap-2 px-3 py-2.5">
|
||||
{{-- Botón adjuntar foto --}}
|
||||
<label class="flex-shrink-0 cursor-pointer text-[#8696a0] active:text-[#00a884] transition" style="min-width:44px; min-height:44px; display:flex; align-items:center; justify-content:center;">
|
||||
<input type="file" wire:model="fotoComprobante" accept="image/*" class="hidden">
|
||||
<input type="file" wire:model="fotoComprobante" accept="image/*" class="hidden"
|
||||
@change="if($event.target.files[0]){ let r=new FileReader(); r.onload=e=>previewUrl=e.target.result; r.readAsDataURL($event.target.files[0]); }"
|
||||
>
|
||||
<svg class="w-6 h-6" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="m2.25 15.75 5.159-5.159a2.25 2.25 0 0 1 3.182 0l5.159 5.159m-1.5-1.5 1.409-1.409a2.25 2.25 0 0 1 3.182 0l2.909 2.909m-18 3.75h16.5a1.5 1.5 0 0 0 1.5-1.5V6a1.5 1.5 0 0 0-1.5-1.5H3.75A1.5 1.5 0 0 0 2.25 6v12a1.5 1.5 0 0 0 1.5 1.5Zm10.5-11.25h.008v.008h-.008V8.25Zm.375 0a.375.375 0 1 1-.75 0 .375.375 0 0 1 .75 0Z" />
|
||||
</svg>
|
||||
|
||||
Reference in New Issue
Block a user