Introduces a new rank management system including the Rank model, migrations for the ranks table and user IP address, Livewire components for managing and displaying ranks, and related Blade views. Updates navigation and routes to include the new 'Gestión Rangos' section, and enhances the ShareCodeComponent with user data. Also adds a reusable input field component for forms.
131 lines
7.8 KiB
PHP
131 lines
7.8 KiB
PHP
<div
|
|
x-data="{
|
|
modal : @entangle('modal'),
|
|
}"
|
|
class="p-6 bg-gray-50 min-h-screen">
|
|
<div class="grid grid-cols-1 text-center sm:flex justify-between my-2 items-center text-sm">
|
|
<div class="grid grid-cols-1 sm:flex items-center gap-4">
|
|
<div class="flex text-sm">
|
|
<x-icon-arrow-right />
|
|
<h1>Rangos</h1>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="flex gap-4">
|
|
<button wire:click="crear" class="justify-center gap-2 flex px-4 py-2 rounded-lg cursor-pointer text-white bg-indigo-600 hover:bg-indigo-700 mb-3 md:mb-0">
|
|
Nuevo Rango
|
|
<svg class="w-3" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" id="Capa_1" x="0px" y="0px" viewBox="0 0 512 512" style="enable-background:new 0 0 512 512;" xml:space="preserve">
|
|
<path d="M480,224H288V32c0-17.673-14.327-32-32-32s-32,14.327-32,32v192H32c-17.673,0-32,14.327-32,32s14.327,32,32,32h192v192 c0,17.673,14.327,32,32,32s32-14.327,32-32V288h192c17.673,0,32-14.327,32-32S497.673,224,480,224z" fill="#ffffff" />
|
|
</svg>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
|
|
<x-primary-table>
|
|
<x-slot name="thead">
|
|
<tr class="text-left">
|
|
<th class="px-4 py-3">Logo</th>
|
|
<th class="px-4 py-3">Nombre</th>
|
|
<th class="px-4 py-3">Cashback</th>
|
|
<th class="px-4 py-3">Bono Equipo</th>
|
|
<th class="px-4 py-3">Tope</th>
|
|
<th class="px-4 py-3">Compra Mínima</th>
|
|
<th class="px-4 py-3">Directos</th>
|
|
<th class="px-4 py-3">Niveles</th>
|
|
<th class="px-4 py-3">Volumen</th>
|
|
<th class="px-4 py-3">Por Nivel</th>
|
|
<th></th>
|
|
</tr>
|
|
</x-slot>
|
|
<x-slot name="tbody">
|
|
@forelse ($ranks as $rank)
|
|
<tr class="border-b hover:bg-gray-50 transition text-left" x-data="{ openOption: false }">
|
|
<td class="px-4 py-3">
|
|
@if($rank->logo)
|
|
<img src="{{ asset('storage/' . $rank->logo) }}" alt="{{ $rank->nombre }}" class="h-10 w-10 rounded-full object-cover">
|
|
@endif
|
|
</td>
|
|
<td class="px-4 py-3">{{ $rank->cashback }}%</td>
|
|
<td class="px-4 py-3">{{ $rank->cashback }}%</td>
|
|
<td class="px-4 py-3">{{ $rank->bono_equipo }}%</td>
|
|
<td class="px-4 py-3">${{ number_format($rank->tope_bono_equipo) }}</td>
|
|
<td class="px-4 py-3">${{ number_format($rank->compra_personal_min) }}</td>
|
|
<td class="px-4 py-3">{{ $rank->directos_activos_min }}</td>
|
|
<td class="px-4 py-3">{{ $rank->niveles_min }}</td>
|
|
<td class="px-4 py-3">${{ number_format($rank->volumen_equipo_min) }}</td>
|
|
<td class="px-4 py-3">${{ number_format($rank->volumen_por_nivel_min) }}</td>
|
|
<td>
|
|
<button x-on:click="openOption=!openOption">
|
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6 cursor-pointer">
|
|
<path stroke-linecap="round" stroke-linejoin="round" d="M6.75 12a.75.75 0 11-1.5 0 .75.75 0 011.5 0zM12.75 12a.75.75 0 11-1.5 0 .75.75 0 011.5 0zM18.75 12a.75.75 0 11-1.5 0 .75.75 0 011.5 0z" />
|
|
</svg>
|
|
</button>
|
|
|
|
<div x-cloak x-show="openOption" @click.away="openOption = false" class="sm:absolute bg-white text-center w-[8rem] rounded-[1rem] border-b border-gray-200 shadow-lg right-10">
|
|
<button x-on:click="openOption=false" wire:click="editar({{ $rank->id }})" class="text-gray-500 w-full py-1 hover:bg-gray-200 border-b border-gray-300 hover:rounded-t-[1rem]">Editar</button>
|
|
<button x-on:click="openOption=false" wire:click="eliminar({{ $rank->id }})" class="text-white w-full py-1 bg-red-400 rounded-b-[1rem] hover:bg-red-600 hover:rounded-b-[1rem]">Eliminar</button>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
@empty
|
|
<tr>
|
|
<td colspan="10" class="text-center py-6 text-gray-500">No hay rangos registrados aún.</td>
|
|
</tr>
|
|
@endforelse
|
|
</x-slot>
|
|
<x-slot name="tlink">
|
|
</x-slot>
|
|
</x-primary-table>
|
|
|
|
{{-- Modal --}}
|
|
<div x-cloak x-show="modal" 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">
|
|
<div class="grid h-full place-items-center overflow-y-auto ">
|
|
|
|
<div class="p-6 bg-white rounded-xl">
|
|
<h2 class="text-lg font-bold mb-4">{{ $rank_id ? 'Editar Rango' : 'Nuevo Rango' }}</h2>
|
|
|
|
<form wire:submit.prevent="guardar" class="grid grid-cols-2 gap-4">
|
|
<div class="col-span-2">
|
|
<label class="block text-sm font-medium text-gray-700 mb-1">Logo del Rango</label>
|
|
<input type="file" wire:model="logo"
|
|
class="block w-full text-sm text-gray-700 border border-gray-300 rounded-lg cursor-pointer focus:ring-indigo-500 focus:border-indigo-500" />
|
|
@error('logo') <span class="text-xs text-red-500">{{ $message }}</span> @enderror
|
|
|
|
{{-- Preview --}}
|
|
@if ($logo)
|
|
<div class="mt-3">
|
|
<img src="{{ $logo->temporaryUrl() }}" class="h-20 rounded-lg shadow-md" accept="image/*">
|
|
</div>
|
|
@elseif ($logo_url)
|
|
<div class="mt-3">
|
|
<img src="{{ asset('storage/' . $logo_url) }}" class="h-20 rounded-lg shadow-md" accept="image/*">
|
|
</div>
|
|
@endif
|
|
</div>
|
|
<x-input-field label="Nombre" model="nombre" />
|
|
<x-input-field label="Cashback (%)" model="cashback" type="number" step="0.01" />
|
|
<x-input-field label="Bono de Equipo (%)" model="bono_equipo" type="number" step="0.01" />
|
|
<x-input-field label="Tope del Bono" model="tope_bono_equipo" type="number" />
|
|
<x-input-field label="Compra Personal Mínima" model="compra_personal_min" type="number" />
|
|
<x-input-field label="Directos Activos Mínimos" model="directos_activos_min" type="number" />
|
|
<x-input-field label="Niveles Mínimos" model="niveles_min" type="number" />
|
|
<x-input-field label="Volumen de Equipo Mínimo" model="volumen_equipo_min" type="number" />
|
|
<x-input-field label="Volumen por Nivel" model="volumen_por_nivel_min" type="number" />
|
|
</form>
|
|
|
|
<div class="flex justify-end mt-6 space-x-3">
|
|
<button wire:click="$set('modal', false)" type="button" class="bg-gray-200 hover:bg-gray-300 text-gray-800 px-4 py-2 rounded-lg">
|
|
Cancelar
|
|
</button>
|
|
<button wire:click="guardar" class="bg-indigo-600 hover:bg-indigo-700 text-white px-4 py-2 rounded-lg">
|
|
Guardar
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|