update codigo referido funcionamiento login, register y dashboard

This commit is contained in:
Juan Felipe Duarte
2025-10-15 16:43:43 -05:00
parent 6d49224d44
commit 5c04a95792
10 changed files with 490 additions and 239 deletions
@@ -24,7 +24,7 @@
<div class="flex justify-between my-2 items-center mb-8 scroll">
<div class="flex items-center gap-4">
<div class="flex text-sm">
<x-icon-arrow-right/>
<x-icon-arrow-right />
Promociones
</div>
@if (auth()->user()->rol->nombre == 'super' || auth()->user()->rol->nombre == 'administrador')
@@ -66,67 +66,32 @@
</div> --}}
</div>
<div
class="x-auto bg-white grid grid-cols-1 lg:grid-cols-1text-center rounded-xl py-4 px-2 ms:px-8 shadow-md xl:mx-10 mb-8 ">
<div class="mb-2">
<h2>Seleccione una categoria:</h2>
<div class="swiper-container overflow-hidden py-4 px-3" wire:ignore>
<div class="swiper-wrapper">
@foreach ($categorias as $i => $categoria1)
<div wire:key="banner-{{ $categoria1->id }}" class="swiper-slide cursor-pointer transition hover:scale-105 rounded-lg overflow-hidden shadow bg-white" x-on:click="categorian='{{ $categoria1->nombre }}'">
<img src="{{ asset($categoria1->imagen) }}" class="w-full h-12 md:h-32 object-cover object-center text-xs" alt="imagen de {{ $categoria1->nombre }}">
</div>
@endforeach
</div>
</div>
<div class="relative">
<div class="slider2 scroll-smooth py-2 px-4 overflow-x-scroll w-full gap-4 " id="content">
<table>
@foreach ($categorias as $categoria1)
<td>
<div class="cursor-pointer transition hover:scale-[1.05] w-[250px] h-[250px] sm:w-[350px] sm:h-[350px] mx-4" x-on:click="categorian='{{ $categoria1->nombre }}'">
<img src="{{ asset($categoria1->imagen) }}" class="w-full m-auto rounded-lg object-cover h-full object-center shadow" alt="imagen de {{ $categoria1->nombre }}">
</div>
</td>
@endforeach
</table>
</div>
<button class="prev2 p-2 md:p-3 absolute left-0 top-1/3 rounded-full bg-[#B221FD]"><svg
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:svgjs="http://svgjs.com/svgjs" version="1.1" class="w-4 md:w-7" x="0"
y="0" viewBox="0 0 24 24" style="enable-background:new 0 0 512 512"
xml:space="preserve">
<g>
<path
d="M17.921,1.505a1.5,1.5,0,0,1-.44,1.06L9.809,10.237a2.5,2.5,0,0,0,0,3.536l7.662,7.662a1.5,1.5,0,0,1-2.121,2.121L7.688,15.9a5.506,5.506,0,0,1,0-7.779L15.36.444a1.5,1.5,0,0,1,2.561,1.061Z"
fill="#ffffff" data-original="#000000" />
</g>
</svg></button>
<button class="next2 p-2 md:p-3 absolute right-0 top-1/3 rounded-full bg-[#B221FD]"><svg
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:svgjs="http://svgjs.com/svgjs" version="1.1" class="w-4 md:w-7" x="0"
y="0" viewBox="0 0 24 24" style="enable-background:new 0 0 512 512"
xml:space="preserve">
<g>
<path
d="M6.079,22.5a1.5,1.5,0,0,1,.44-1.06l7.672-7.672a2.5,2.5,0,0,0,0-3.536L6.529,2.565A1.5,1.5,0,0,1,8.65.444l7.662,7.661a5.506,5.506,0,0,1,0,7.779L8.64,23.556A1.5,1.5,0,0,1,6.079,22.5Z"
fill="#ffffff" data-original="#000000" />
</g>
</svg></button>
</div>
<button x-on:click="verPro=true"
class="my-2 mx max-w-sm ml-auto rounded-lg border border-transparent px-4 py-2 sm:mb-[0] mb-2 text-white bg-[#B221FD] hover:bg-[#7a02b8] focus:shadow-outline-green sm-text-sm sm-leading-5">Ver
todos</button>
<div class="flex items-center justify-center mt-2 mb-4">
<button x-on:click="verPro=true" class="max-w-md rounded-lg text-sm md:text-base px-4 py-2 text-white bg-[#B221FD] hover:bg-[#7a02b8] focus:shadow-outline-green sm-text-sm sm-leading-5">
Ver todas las promociones
</button>
</div>
<div>
@if ($categorian)
<div class="bg-[#f8f8f8] shadow-md rounded-[1.2rem] mb-4 px-4 py-4 ">
<div class="mb-2">
<h2>Seleccione una promocion:</h2>
</div>
<div id="promo" class="grid sm:grid-cols-2 md:grid-cols-2 lg:grid-cols-4 gap-4 py-2 px-4">
<div class="mb-4 px-4 py-4">
<div id="promo" class="grid grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-4 py-2 px-4">
@foreach ($categorias->where('nombre', $categorian)->first()->promociones as $promocion)
@if ($promocion->visible == 'true')
@if (empty(($usuario = $promocion->usuario_promos->where('usuario_id', Auth::user()->id)->first())))
<div class="select-none bg-white shadow-md transition hover:scale-[1.05] hover:shadow-xl cursor-pointer rounded-lg text-center relative object-cover "
<div class="select-none bg-white shadow-md transition hover:scale-105 hover:shadow-xl cursor-pointer rounded-lg text-center relative object-cover "
x-data="{ openOption: false }">
<svg x-on:click="openOption=!openOption" xmlns="http://www.w3.org/2000/svg"
fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"
@@ -215,8 +180,7 @@
<div x-cloak x-show="newPromocion" x-transition:enter="transition duration-350"
x-transition:enter-start="opacity-0 scale-100" x-transition:enter-end="opacity-100 scale-100"
x-transition:leave="transition duration-350" x-transition:leave-start="opacity-100 scale-100"
x-transition:leave-end="opacity-0 scale-100"
class="fixed inset-0 z-50 backdrop-blur-sm bg-black/20">
x-transition:leave-end="opacity-0 scale-100" class="fixed inset-0 z-50 backdrop-blur-sm bg-black/20">
<div class="grid h-full place-items-center overflow-y-auto">
<div class="bg-white px-4 pt-5 pb-4 sm:p-6 sm:pb-4 rounded-[1rem] shadow-md">
<div class="mb-4 grid grid-cols-2 items-center justify-items-center">
@@ -291,11 +255,10 @@
</div>
<div class="mb-4">
<label for="utilidad"
class="block text-gray-700 text-sm font-bold mb-2">Valor de compra:</label>
<input name="utilidad" wire:model="utilidad" type="number" min="0"
placeholder="$0"
class="w-full border-2 border-neutral-200 shadow rounded-[0.8rem] px-4 py-2 text-gray-900 sm:text-sm focus:border-neutral-300 focus:outline-none focus:shadow-outline focus:ring-0 block datepicker-input">
<label for="utilidad" class="block text-gray-700 text-sm font-bold mb-2">Valor de
compra:</label>
<input name="utilidad" wire:model="utilidad" type="number" min="0" placeholder="$0"
class="w-full border-2 border-neutral-200 shadow rounded-[0.8rem] px-4 py-2 text-gray-900 sm:text-sm focus:border-neutral-300 focus:outline-none focus:shadow-outline focus:ring-0 block datepicker-input">
</div>
@@ -327,8 +290,7 @@
class="w-10 h-10 float-right bg-[#B221FD] hover:bg-[#7a02b8] rounded-full active:shadow-lg mouse shadow ease-in focus:outline-none">
<svg viewBox="0 0 20 20" enable-background="new 0 0 20 20"
class="w-6 h-6 inline-block">
<path fill="#FFFFFF"
d="M16,10c0,0.553-0.048,1-0.601,1H11v4.399C11,15.951,10.553,16,10,16c-0.553,0-1-0.049-1-0.601V11H4.601
<path fill="#FFFFFF" d="M16,10c0,0.553-0.048,1-0.601,1H11v4.399C11,15.951,10.553,16,10,16c-0.553,0-1-0.049-1-0.601V11H4.601
C4.049,11,4,10.553,4,10c0-0.553,0.049-1,0.601-1H9V4.601C9,4.048,9.447,4,10,4c0.553,0,1,0.048,1,0.601V9h4.399
C15.952,9,16,9.447,16,10z" />
</svg>
@@ -345,21 +307,20 @@
<option value="" selected>Tarifas</option>
@foreach ($tarifas as $tarifa)
@if($tarifa->servicio?->estado == 'activo')
<option value="{{ $tarifa->id }}">{{ $tarifa->servicio->nombre ?? '' }}
:
@if (!empty($tarifa->servicio->por_tiempo))
{{ $tarifa->dias ?? '' }}
{{ $tarifa->dias == 1 ? 'día' : 'días' }}
@else
{{ $tarifa->pantallas ?? '' }}
{{ $tarifa->pantallas == 1 ? 'pantalla' : 'pantallas' }} -
{{ $tarifa->dias ?? '' }}
{{ $tarifa->dias == 1 ? 'día' : 'días' }}
@if ($tarifa->servicio?->estado == 'activo')
<option value="{{ $tarifa->id }}">{{ $tarifa->servicio->nombre ?? '' }}
:
@if (!empty($tarifa->servicio->por_tiempo))
{{ $tarifa->dias ?? '' }}
{{ $tarifa->dias == 1 ? 'día' : 'días' }}
@else
{{ $tarifa->pantallas ?? '' }}
{{ $tarifa->pantallas == 1 ? 'pantalla' : 'pantallas' }} -
{{ $tarifa->dias ?? '' }}
{{ $tarifa->dias == 1 ? 'día' : 'días' }}
@endif
</option>
@endif
</option>
@endif
@endforeach
</select>
@@ -523,7 +484,9 @@
<div
class="bg-white px-4 py-3 sm:px-6 sm:flex sm:flex-row-reverse sm:justify-evenly gap-5 mt-2 mb-3">
<span>
<button x-on:click="modalComprarPromo=true,verPromo=false" wire:loading.attr="disabled" type="button" class="inline-flex justify-center w-full rounded-md border border-transparent px-4 py-2 sm:mb-[0] mb-2 text-white bg-[#B221FD] hover:bg-[#7a02b8] focus:shadow-outline-green sm-text-sm sm-leading-5">Comprar</button>
<button x-on:click="modalComprarPromo=true,verPromo=false"
wire:loading.attr="disabled" type="button"
class="inline-flex justify-center w-full rounded-md border border-transparent px-4 py-2 sm:mb-[0] mb-2 text-white bg-[#B221FD] hover:bg-[#7a02b8] focus:shadow-outline-green sm-text-sm sm-leading-5">Comprar</button>
</span>
<span>
<button x-on:click="verPromo=false" type="button"
@@ -635,8 +598,7 @@
class="w-10 h-10 float-right bg-[#B221FD] hover:bg-[#7a02b8] rounded-full active:shadow-lg mouse shadow ease-in focus:outline-none">
<svg viewBox="0 0 20 20" enable-background="new 0 0 20 20"
class="w-6 h-6 inline-block">
<path fill="#FFFFFF"
d="M16,10c0,0.553-0.048,1-0.601,1H11v4.399C11,15.951,10.553,16,10,16c-0.553,0-1-0.049-1-0.601V11H4.601
<path fill="#FFFFFF" d="M16,10c0,0.553-0.048,1-0.601,1H11v4.399C11,15.951,10.553,16,10,16c-0.553,0-1-0.049-1-0.601V11H4.601
C4.049,11,4,10.553,4,10c0-0.553,0.049-1,0.601-1H9V4.601C9,4.048,9.447,4,10,4c0.553,0,1,0.048,1,0.601V9h4.399
C15.952,9,16,9.447,16,10z" />
</svg>
@@ -818,73 +780,82 @@
</p>
</div>
<div class="mb-4">
<div class="border-2 flex text-gray-400 text-xs text-center justify-center gap-2 py-3 rounded-lg md:mx-3 2xl:mx-6">
El valor de ${{ number_format($total = (int) $precioAhora * (int) $cantidad_comprarPromo) }} será descontado de su saldo.
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:svgjs="http://svgjs.com/svgjs" class="w-4" x="0" y="0" viewBox="0 0 24 24" style="enable-background:new 0 0 512 512" xml:space="preserve">
<div
class="border-2 flex text-gray-400 text-xs text-center justify-center gap-2 py-3 rounded-lg md:mx-3 2xl:mx-6">
El valor de
${{ number_format($total = (int) $precioAhora * (int) $cantidad_comprarPromo) }} será
descontado de su saldo.
<svg xmlns="http://www.w3.org/2000/svg" version="1.1"
xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:svgjs="http://svgjs.com/svgjs"
class="w-4" x="0" y="0" viewBox="0 0 24 24"
style="enable-background:new 0 0 512 512" xml:space="preserve">
<g>
<path d="M12,0A12,12,0,1,0,24,12,12.013,12.013,0,0,0,12,0Zm0,22A10,10,0,1,1,22,12,10.011,10.011,0,0,1,12,22Z" fill="#9f9f9f" data-original="#000000"></path>
<path d="M12,5a1,1,0,0,0-1,1v8a1,1,0,0,0,2,0V6A1,1,0,0,0,12,5Z" fill="#9f9f9f" data-original="#000000"></path>
<rect x="11" y="17" width="2" height="2" rx="1" fill="#9f9f9f" data-original="#000000"></rect>
<path
d="M12,0A12,12,0,1,0,24,12,12.013,12.013,0,0,0,12,0Zm0,22A10,10,0,1,1,22,12,10.011,10.011,0,0,1,12,22Z"
fill="#9f9f9f" data-original="#000000"></path>
<path d="M12,5a1,1,0,0,0-1,1v8a1,1,0,0,0,2,0V6A1,1,0,0,0,12,5Z" fill="#9f9f9f"
data-original="#000000"></path>
<rect x="11" y="17" width="2" height="2" rx="1"
fill="#9f9f9f" data-original="#000000"></rect>
</g>
</svg>
</div>
@if ($total > auth()->user()->saldo->valor)
<div class=" flex text-red-400 text-xs text-center justify-center gap-2 py-2 rounded-lg md:mx-2 2xl:mx-6">
<div
class=" flex text-red-400 text-xs text-center justify-center gap-2 py-2 rounded-lg md:mx-2 2xl:mx-6">
<p>No tiene fondo suficientes para esta compra, recargue su cuenta.</p>
@if (auth()->user()->rol->nombre != 'editor' && auth()->user()->rol->nombre != 'administrador')
<a href="{{ route('recarga') }}"><button class="bg-green-600 text-white rounded px-2 py-1">Recargar</button></a>
<a href="{{ route('recarga') }}"><button
class="bg-green-600 text-white rounded px-2 py-1">Recargar</button></a>
@endif
</div>
@endif
</div>
<div class="bg-white px-4 py-3 sm:px-6 sm:flex sm:flex-row-reverse sm:justify-evenly gap-5 mt-4">
<div
class="bg-white px-4 py-3 sm:px-6 sm:flex sm:flex-row-reverse sm:justify-evenly gap-5 mt-4">
<span>
<!-- Botón de Comprar con protección de múltiples clics y mensaje de procesando -->
<button id="comprarButton"
wire:click="pagar"
wire:loading.attr="disabled"
type="button"
@if ($total <= auth()->user()->saldo->valor)
class="inline-flex justify-center w-full rounded-md border border-transparent px-4 py-2 sm:mb-[0] mb-2 text-white bg-[#B221FD] hover:bg-[#7a02b8] focus:shadow-outline-green sm-text-sm sm-leading-5"
@else
disabled
class="cursor-no-drop inline-flex justify-center w-full rounded-md border border-transparent px-4 py-2 sm:mb-[0] mb-2 text-white bg-gray-200 hover:bg-gray-200 focus:shadow-outline-green sm-text-sm sm-leading-5"
@endif
onclick="enviarInfoCompra()">
<button id="comprarButton" wire:click="pagar" wire:loading.attr="disabled"
type="button"
@if ($total <= auth()->user()->saldo->valor) class="inline-flex justify-center w-full rounded-md border border-transparent px-4 py-2 sm:mb-[0] mb-2 text-white bg-[#B221FD] hover:bg-[#7a02b8] focus:shadow-outline-green sm-text-sm sm-leading-5"
@else
disabled
class="cursor-no-drop inline-flex justify-center w-full rounded-md border border-transparent px-4 py-2 sm:mb-[0] mb-2 text-white bg-gray-200 hover:bg-gray-200 focus:shadow-outline-green sm-text-sm sm-leading-5" @endif
onclick="enviarInfoCompra()">
Comprar
</button>
</span>
<span>
<!-- Botón Cerrar -->
<button x-on:click="modalComprarPromo=false" type="button"
class="inline-flex justify-center w-full rounded-md border border-transparent px-4 py-2 text-white bg-[#585858] hover:bg-[#3a3a3a] focus:shadow-outline-green sm-text-sm sm-leading-5">
class="inline-flex justify-center w-full rounded-md border border-transparent px-4 py-2 text-white bg-[#585858] hover:bg-[#3a3a3a] focus:shadow-outline-green sm-text-sm sm-leading-5">
Cerrar
</button>
</span>
<!-- Mensaje de Procesando -->
<div id="procesandoMensaje" class="hidden mt-2 text-sm text-gray-500">
Procesando... por favor espera.
</div>
</div>
<script>
let botonBloqueado = false; // Controla si el botón está bloqueado
let botonBloqueado = false; // Controla si el botón está bloqueado
// Función para manejar el proceso de compra
function enviarInfoCompra() {
if (botonBloqueado) return; // Si el botón está bloqueado, no hacer nada
botonBloqueado = true; // Bloquea el botón
if (botonBloqueado) return; // Si el botón está bloqueado, no hacer nada
botonBloqueado = true; // Bloquea el botón
const boton = document.getElementById('comprarButton');
const mensaje = document.getElementById('procesandoMensaje'); // Referencia al mensaje de procesamiento
boton.setAttribute('disabled', 'true'); // Deshabilita el botón
boton.classList.add('cursor-not-allowed', 'bg-gray-300'); // Cambia el estilo visual
mensaje.classList.remove('hidden'); // Muestra el mensaje
const mensaje = document.getElementById('procesandoMensaje'); // Referencia al mensaje de procesamiento
boton.setAttribute('disabled', 'true'); // Deshabilita el botón
boton.classList.add('cursor-not-allowed', 'bg-gray-300'); // Cambia el estilo visual
mensaje.classList.remove('hidden'); // Muestra el mensaje
// Realiza la petición al servidor
fetch('/registrar-accion-compra', {
method: 'POST',
@@ -892,7 +863,9 @@
'Content-Type': 'application/json',
'X-CSRF-TOKEN': '{{ csrf_token() }}'
},
body: JSON.stringify({ /* puedes enviar datos si es necesario */ })
body: JSON.stringify({
/* puedes enviar datos si es necesario */
})
})
.then(response => response.json())
.then(data => {
@@ -905,11 +878,11 @@
botonBloqueado = false;
boton.removeAttribute('disabled');
boton.classList.remove('cursor-not-allowed', 'bg-gray-300');
mensaje.classList.add('hidden'); // Oculta el mensaje
mensaje.classList.add('hidden'); // Oculta el mensaje
});
}
</script>
</div>
</div>
@@ -1053,7 +1026,6 @@
@if (!empty($cuenta->servicio->ver_url))
*URL:* {{ $cuenta->servicio->url }}
@else
*Servicio:* {{ $cuenta->servicio->nombre }} @foreach ($cuenta->perfil as $perfil)
@if ($cuentas->id == $perfil->historial_id && $cuenta->estado == 'activo')
- Perfil {{ $perfil->perfil }} @if (!empty($cuenta->servicio->perfiles))
@@ -1119,12 +1091,9 @@
</div>
<div
class="bg-white px-4 py-3 sm:px-6 sm:flex sm:flex-row-reverse sm:justify-evenly gap-5 mt-4">
<div class="bg-white px-4 py-3 sm:px-6 sm:flex sm:flex-row-reverse sm:justify-evenly gap-5 mt-4">
<span>
<button x-on:click="credenciales=false" type="button"
class="inline-flex justify-center w-full rounded-md border border-transparent px-4 py-2 text-white bg-[#585858] hover:bg-[#3a3a3a] focus:shadow-outline-green sm-text-sm sm-leading-5">Cerrar</button>
<button x-on:click="credenciales=false" type="button" class="inline-flex justify-center w-full rounded-md border border-transparent px-4 py-2 text-white bg-[#585858] hover:bg-[#3a3a3a] focus:shadow-outline-green sm-text-sm sm-leading-5">Cerrar</button>
</span>
</div>
@@ -1165,38 +1134,50 @@
</div>
</div>
<script>
function copiarAlPortapapeles2(id_elemento) {
var aux = document.createElement("input");
aux.setAttribute("value", document.getElementById(id_elemento).innerHTML);
document.body.appendChild(aux);
aux.select();
document.execCommand("copy");
document.body.removeChild(aux);
}
const prev2 = document.querySelector('.prev2')
const next2 = document.querySelector('.next2')
const slider2 = document.querySelector('.slider2')
prev2.addEventListener('click', () => {
slider2.scrollLeft -= 600
})
next2.addEventListener('click', () => {
slider2.scrollLeft += 600
})
function copyToClipboard2() {
var copyText = document.getElementById("d").value;
navigator.clipboard.writeText(copyText).then(() => {
// Alert the user that the action took place.
// Nobody likes hidden stuff being done under the hood!
//alert("Copied to clipboard");
});
}
</script>
</div>
<script>
document.addEventListener('livewire:load', () => {
const swiper = new Swiper('.swiper-container', {
slidesPerView: 3,
spaceBetween: 10,
loop: true,
centeredSlides: true,
autoplay: {
delay: 5000,
disableOnInteraction: false,
pauseOnMouseEnter: true,
},
breakpoints: {
640: { slidesPerView: 2, spaceBetween: 20 },
1024: { slidesPerView: 3, spaceBetween: 30 },
1440: { slidesPerView: 4, spaceBetween: 40 },
}
});
Livewire.on('refreshCarousel', () => {
swiper.update();
});
});
function copiarAlPortapapeles2(id_elemento) {
var aux = document.createElement("input");
aux.setAttribute("value", document.getElementById(id_elemento).innerHTML);
document.body.appendChild(aux);
aux.select();
document.execCommand("copy");
document.body.removeChild(aux);
}
function copyToClipboard2() {
var copyText = document.getElementById("d").value;
navigator.clipboard.writeText(copyText).then(() => {
// Alert the user that the action took place.
// Nobody likes hidden stuff being done under the hood!
//alert("Copied to clipboard");
});
}
</script>