update codigo referido funcionamiento login, register y dashboard
This commit is contained in:
@@ -3,6 +3,8 @@
|
||||
namespace App\Http\Controllers\Auth;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Role;
|
||||
use App\Models\Saldo;
|
||||
use App\Models\User;
|
||||
use App\Providers\RouteServiceProvider;
|
||||
use Illuminate\Auth\Events\Registered;
|
||||
@@ -13,36 +15,69 @@ use Illuminate\Validation\Rules;
|
||||
|
||||
class RegisteredUserController extends Controller
|
||||
{
|
||||
/**
|
||||
* Display the registration view.
|
||||
*
|
||||
* @return \Illuminate\View\View
|
||||
*/
|
||||
public function create()
|
||||
public function create(Request $request)
|
||||
{
|
||||
return view('auth.register');
|
||||
$referralCode = $request->query('ref');
|
||||
|
||||
return view('auth.register', [
|
||||
'referralCode' => $referralCode,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle an incoming registration request.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*
|
||||
* @throws \Illuminate\Validation\ValidationException
|
||||
*/
|
||||
public function store(Request $request)
|
||||
{
|
||||
$request->validate([
|
||||
'name' => ['required', 'string', 'max:255'],
|
||||
'email' => ['required', 'string', 'email', 'max:255', 'unique:users'],
|
||||
'password' => ['required', 'confirmed', Rules\Password::defaults()],
|
||||
'referral_code' => ['required', 'string'],
|
||||
],[
|
||||
'email.unique' => 'El correo electrónico ya está en uso.',
|
||||
'email.email' => 'El correo electrónico no es válido.',
|
||||
'email.required' => 'El correo electrónico es obligatorio.',
|
||||
'name.required' => 'El nombre es obligatorio.',
|
||||
'name.string' => 'El nombre debe ser una cadena de texto.',
|
||||
'name.max' => 'El nombre no debe exceder los 255 caracteres.',
|
||||
'password.required' => 'La contraseña es obligatoria.',
|
||||
'password.confirmed' => 'La confirmación de la contraseña no coincide.',
|
||||
'password.min' => 'La contraseña debe tener al menos 8 caracteres.',
|
||||
'referral_code.required' => 'El código de referido es obligatorio.',
|
||||
|
||||
'password.confirmed' => 'Las contraseñas no coinciden.',
|
||||
]);
|
||||
|
||||
$referralUser = null;
|
||||
if ($request->filled('referral_code')) {
|
||||
$referralUser = User::where('referral_code', $request->referral_code)->first();
|
||||
}
|
||||
|
||||
// Determinar el rol del nuevo usuario
|
||||
if ($referralUser) {
|
||||
if ($referralUser->rol->nombre === 'super') {
|
||||
// Si el referido es "super", asignar "cliente"
|
||||
$rolCliente = Role::where('nombre', 'cliente')->first();
|
||||
$rol_id = $rolCliente ? $rolCliente->id : null;
|
||||
} else {
|
||||
// Si no es super, tomar el mismo rol del referido
|
||||
$rol_id = $referralUser->rol_id;
|
||||
}
|
||||
} else {
|
||||
// Si no tiene referral_code, asignar rol por defecto (cliente)
|
||||
$rolCliente = Role::where('nombre', 'cliente')->first();
|
||||
$rol_id = $rolCliente ? $rolCliente->id : null;
|
||||
}
|
||||
|
||||
$user = User::create([
|
||||
'name' => $request->name,
|
||||
'email' => $request->email,
|
||||
'password' => Hash::make($request->password),
|
||||
'rol_id' => $rol_id,
|
||||
'parent_id' => $referralUser ? $referralUser->id : null,
|
||||
]);
|
||||
|
||||
Saldo::create([
|
||||
'usuario_id' => $user->id,
|
||||
'valor' => 0,
|
||||
]);
|
||||
|
||||
event(new Registered($user));
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Livewire;
|
||||
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Livewire\Component;
|
||||
|
||||
class ShareCodeComponent extends Component
|
||||
{
|
||||
public function render()
|
||||
{
|
||||
$referrals = Auth::user()->children()
|
||||
->select('*')
|
||||
->selectRaw('(SELECT COUNT(*) FROM users u WHERE u.parent_id = users.id::text) as children_count')
|
||||
->orderBy('created_at', 'desc')
|
||||
->get();
|
||||
|
||||
return view('livewire.share-code-component', compact('referrals'));
|
||||
}
|
||||
}
|
||||
@@ -7,6 +7,7 @@ use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Foundation\Auth\User as Authenticatable;
|
||||
use Illuminate\Notifications\Notifiable;
|
||||
use Laravel\Sanctum\HasApiTokens;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class User extends Authenticatable
|
||||
{
|
||||
@@ -22,6 +23,12 @@ class User extends Authenticatable
|
||||
'rol_id',
|
||||
'subvendedor_id',
|
||||
'subvendedor',
|
||||
|
||||
'referral_code',
|
||||
'parent_id',
|
||||
|
||||
|
||||
'rank_id',
|
||||
];
|
||||
|
||||
protected $hidden = [
|
||||
@@ -107,4 +114,36 @@ class User extends Authenticatable
|
||||
{
|
||||
return $this->hasMany(User::class, 'subvendedor_id');
|
||||
}
|
||||
|
||||
// Referral relationships
|
||||
public function parent()
|
||||
{
|
||||
return $this->belongsTo(User::class, 'parent_id');
|
||||
}
|
||||
|
||||
public function children()
|
||||
{
|
||||
return $this->hasMany(User::class, 'parent_id')->orderBy('created_at', 'desc');
|
||||
}
|
||||
|
||||
// public function rank()
|
||||
// {
|
||||
// return $this->belongsTo(Rank::class);
|
||||
// }
|
||||
|
||||
protected static function boot()
|
||||
{
|
||||
parent::boot();
|
||||
|
||||
static::creating(function ($user) {
|
||||
if (empty($user->referral_code)) {
|
||||
do {
|
||||
$code = strtoupper(Str::random(8));
|
||||
} while (self::where('referral_code', $code)->exists());
|
||||
|
||||
$user->referral_code = $code;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up()
|
||||
{
|
||||
Schema::table('users', function (Blueprint $table) {
|
||||
$table->string('referral_code')->unique()->nullable();
|
||||
$table->string('parent_id')->nullable();
|
||||
$table->string('rank_id')->nullable();
|
||||
});
|
||||
}
|
||||
|
||||
public function down()
|
||||
{
|
||||
Schema::table('users', function (Blueprint $table) {
|
||||
$table->dropColumn([
|
||||
'referral_code',
|
||||
'parent_id',
|
||||
'rank_id',
|
||||
]);
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -1,5 +1,5 @@
|
||||
<x-guest-layout>
|
||||
|
||||
|
||||
<!-- Session Status -->
|
||||
<x-auth-session-status class="mb-4" :status="session('status')" />
|
||||
|
||||
@@ -10,37 +10,37 @@
|
||||
<a href="#" >@ {{App\Models\Configuracione::Orderby('id','desc')->first()->nombre}}</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="mx-auto mt-[-1.5rem] mb-[3.5rem] md:mb-0 flex justify-center w-[17rem] md:max-w-sm md:w-full bg-[#F2F4FF] md:ml-28 px-6 py-5 md:py-10 rounded-lg select-none">
|
||||
<form method="POST" action="{{ route('login') }}" class="w-full px-4">
|
||||
@csrf
|
||||
|
||||
|
||||
<div>
|
||||
<!-- Email Address -->
|
||||
<div class="mt-4">
|
||||
{{-- <x-input-label for="email" :value="__('Email')" /> --}}
|
||||
<x-text-input id="email" class="block mt-1 w-full md:text-lg border-none drop-shadow-lg " type="email" name="email" :value="old('email')"
|
||||
required
|
||||
<x-text-input id="email" class="block mt-1 w-full md:text-lg border-none drop-shadow-lg " type="email" name="email" :value="old('email')"
|
||||
required
|
||||
placeholder="Correo electronico"
|
||||
autofocus />
|
||||
|
||||
|
||||
<x-input-error :messages="$errors->get('email')" class="mt-2" />
|
||||
</div>
|
||||
|
||||
|
||||
<!-- Password -->
|
||||
<div class="mt-4 relative" x-data="{ver : true , btnOjo : true , btnOjoSlash : false}">
|
||||
{{-- <x-input-label for="password" :value="__('Password')" /> --}}
|
||||
<x-text-input id="password" class=" block mt-1 w-full md:text-lg border-none drop-shadow-lg pr-10"
|
||||
x-bind:type="ver ? 'password' : 'text'"
|
||||
name="password"
|
||||
required
|
||||
required
|
||||
placeholder="Contraseña"
|
||||
autocomplete="current-password" />
|
||||
<svg x-show="btnOjo" x-on:click="ver=false,btnOjoSlash=true,btnOjo=false" xmlns="http://www.w3.org/2000/svg" id="Layer_1" data-name="Layer 1" viewBox="0 0 24 24" class="w-4 absolute right-4 top-1/3 fill-slate-600 cursor-pointer"><path d="M23.821,11.181v0C22.943,9.261,19.5,3,12,3S1.057,9.261.179,11.181a1.969,1.969,0,0,0,0,1.64C1.057,14.739,4.5,21,12,21s10.943-6.261,11.821-8.181A1.968,1.968,0,0,0,23.821,11.181ZM12,18a6,6,0,1,1,6-6A6.006,6.006,0,0,1,12,18Z"/><circle cx="12" cy="12" r="4"/></svg>
|
||||
<svg x-show="btnOjoSlash" x-on:click="ver=true,btnOjoSlash=false,btnOjo=true" xmlns="http://www.w3.org/2000/svg" id="Layer_1" data-name="Layer 1" viewBox="0 0 24 24" class="w-4 absolute right-4 top-1/3 fill-slate-600 cursor-pointer"><path d="M23.821,11.181v0a15.736,15.736,0,0,0-4.145-5.44l3.032-3.032L21.293,1.293,18,4.583A11.783,11.783,0,0,0,12,3C4.5,3,1.057,9.261.179,11.181a1.969,1.969,0,0,0,0,1.64,15.736,15.736,0,0,0,4.145,5.44L1.293,21.293l1.414,1.414L6,19.417A11.783,11.783,0,0,0,12,21c7.5,0,10.943-6.261,11.821-8.181A1.968,1.968,0,0,0,23.821,11.181ZM6,12a5.99,5.99,0,0,1,9.471-4.885L14.019,8.567A3.947,3.947,0,0,0,12,8a4,4,0,0,0-4,4,3.947,3.947,0,0,0,.567,2.019L7.115,15.471A5.961,5.961,0,0,1,6,12Zm6,6a5.961,5.961,0,0,1-3.471-1.115l1.452-1.452A3.947,3.947,0,0,0,12,16a4,4,0,0,0,4-4,3.947,3.947,0,0,0-.567-2.019l1.452-1.452A5.99,5.99,0,0,1,12,18Z"/></svg> <x-input-error :messages="$errors->get('password')" class="mt-2" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- Remember Me -->
|
||||
<div class="block mt-4 mb-2 text-left">
|
||||
<label for="remember_me" class="inline-flex items-center ">
|
||||
@@ -48,13 +48,13 @@
|
||||
<span class="ml-2 text-sm text-gray-600 md:text-base">{{ __('Recordarme') }}</span>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
|
||||
<div>
|
||||
<x-primary-button class="w-full justify-center text-center text-base md:text-lg ">
|
||||
{{ __('Iniciar Sesión') }}
|
||||
</x-primary-button>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="mt-2 text-center md:text-lg ">
|
||||
@if (Route::has('password.request'))
|
||||
<a class="underline-none text-sm md:text-base text-[#B221FD] hover:text-[#7a02b8]" href="{{ route('password.request') }}">
|
||||
@@ -62,10 +62,20 @@
|
||||
</a>
|
||||
@endif
|
||||
</div>
|
||||
|
||||
<div class="mt-4 text-center">
|
||||
<span class="text-sm text-gray-600 md:text-base">
|
||||
¿No tienes una cuenta?
|
||||
</span>
|
||||
<a href="{{ route('register') }}"
|
||||
class="inline-block ml-2 px-4 py-2 bg-[#B221FD] hover:bg-[#7a02b8] text-white text-sm md:text-base font-semibold rounded-md shadow-md transition-all duration-200">
|
||||
Crear cuenta
|
||||
</a>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
</x-guest-layout>
|
||||
|
||||
@@ -1,64 +1,91 @@
|
||||
<x-guest-layout>
|
||||
<x-auth-card>
|
||||
<x-slot name="logo">
|
||||
<a href="/">
|
||||
<x-application-logo class="w-20 h-20 fill-current text-gray-500" />
|
||||
</a>
|
||||
</x-slot>
|
||||
<x-auth-session-status class="mb-4" :status="session('status')" />
|
||||
|
||||
<form method="POST" action="{{ route('register') }}">
|
||||
@csrf
|
||||
|
||||
<!-- Name -->
|
||||
<div>
|
||||
<x-input-label for="name" :value="__('Name')" />
|
||||
|
||||
<x-text-input id="name" class="block mt-1 w-full" type="text" name="name" :value="old('name')" required autofocus />
|
||||
|
||||
<x-input-error :messages="$errors->get('name')" class="mt-2" />
|
||||
<div
|
||||
class="h-full bg-[#000029] overflow-y-auto md:grid md:grid-cols-2 text-center content-center items-center w-full md:flex md:px-5">
|
||||
<div
|
||||
class="border mt-2 mb-0 md:mb-8 md:mt-0 mx-auto md:mr-14 border-gray-600/20 rounded-full w-[15rem] md:w-full md:max-w-xl overflow-hidden relative ">
|
||||
<img src="{{ App\Models\Configuracione::Orderby('id', 'desc')->first()->url_logo }}" alt=""
|
||||
class="">
|
||||
<div class="text-lg text-[#d37bff] w-full absolute bottom-6 md:bottom-10 text-center">
|
||||
<a href="#">@ {{ App\Models\Configuracione::Orderby('id', 'desc')->first()->nombre }}</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Email Address -->
|
||||
<div class="mt-4">
|
||||
<x-input-label for="email" :value="__('Email')" />
|
||||
<div
|
||||
class="mx-auto mt-[-1.5rem] mb-[3.5rem] md:mb-0 flex justify-center w-[17rem] md:max-w-sm md:w-full bg-[#F2F4FF] md:ml-28 px-6 py-5 md:py-10 rounded-lg select-none">
|
||||
<form method="POST" action="{{ route('register') }}" class="w-full px-4">
|
||||
@csrf
|
||||
|
||||
<x-text-input id="email" class="block mt-1 w-full" type="email" name="email" :value="old('email')" required />
|
||||
<!-- Name -->
|
||||
<div>
|
||||
{{-- <x-input-label for="name" :value="__('Name')" /> --}}
|
||||
|
||||
<x-input-error :messages="$errors->get('email')" class="mt-2" />
|
||||
</div>
|
||||
<x-text-input id="name" class="block mt-1 w-full" type="text" name="name"
|
||||
placeholder="Ingresa tu nombre"
|
||||
:value="old('name')" required autofocus />
|
||||
|
||||
<!-- Password -->
|
||||
<div class="mt-4">
|
||||
<x-input-label for="password" :value="__('Password')" />
|
||||
<x-input-error :messages="$errors->get('name')" class="mt-2" />
|
||||
</div>
|
||||
|
||||
<x-text-input id="password" class="block mt-1 w-full"
|
||||
type="password"
|
||||
name="password"
|
||||
required autocomplete="new-password" />
|
||||
<!-- Email Address -->
|
||||
<div class="mt-4">
|
||||
{{-- <x-input-label for="email" :value="__('Email')" /> --}}
|
||||
|
||||
<x-input-error :messages="$errors->get('password')" class="mt-2" />
|
||||
</div>
|
||||
<x-text-input id="email" class="block mt-1 w-full" type="email" name="email" placeholder="ejemplo@correo.com"
|
||||
:value="old('email')" required />
|
||||
|
||||
<!-- Confirm Password -->
|
||||
<div class="mt-4">
|
||||
<x-input-label for="password_confirmation" :value="__('Confirm Password')" />
|
||||
<x-input-error :messages="$errors->get('email')" class="mt-2" />
|
||||
</div>
|
||||
|
||||
<x-text-input id="password_confirmation" class="block mt-1 w-full"
|
||||
type="password"
|
||||
name="password_confirmation" required />
|
||||
<!-- Password -->
|
||||
<div class="mt-4">
|
||||
{{-- <x-input-label for="password" :value="__('Password')" /> --}}
|
||||
|
||||
<x-input-error :messages="$errors->get('password_confirmation')" class="mt-2" />
|
||||
</div>
|
||||
<x-text-input id="password" class="block mt-1 w-full" type="password" name="password" required placeholder="Crea una contraseña segura"
|
||||
autocomplete="new-password" />
|
||||
|
||||
<div class="flex items-center justify-end mt-4">
|
||||
<a class="underline text-sm text-gray-600 hover:text-gray-900" href="{{ route('login') }}">
|
||||
{{ __('Already registered?') }}
|
||||
</a>
|
||||
<x-input-error :messages="$errors->get('password')" class="mt-2" />
|
||||
</div>
|
||||
|
||||
<x-primary-button class="ml-4">
|
||||
{{ __('Register') }}
|
||||
</x-primary-button>
|
||||
</div>
|
||||
</form>
|
||||
</x-auth-card>
|
||||
<!-- Confirm Password -->
|
||||
<div class="mt-4">
|
||||
{{-- <x-input-label for="password_confirmation" :value="__('Confirm Password')" /> --}}
|
||||
|
||||
<x-text-input id="password_confirmation" class="block mt-1 w-full" type="password" placeholder="Repite tu contraseña"
|
||||
name="password_confirmation" required />
|
||||
|
||||
<x-input-error :messages="$errors->get('password_confirmation')" class="mt-2" />
|
||||
</div>
|
||||
|
||||
<div class="mt-4">
|
||||
{{-- <x-input-label for="referral_code" :value="__('Referral Code')" /> --}}
|
||||
|
||||
@if (!empty($referralCode))
|
||||
<x-text-input id="referral_code" class="block mt-1 w-full" type="text" name="referral_code"
|
||||
value="{{ old('referral_code', $referralCode) }}" required autocomplete="referral_code" placeholder="Código de referido"
|
||||
readonly />
|
||||
@else
|
||||
<x-text-input id="referral_code" class="block mt-1 w-full" type="text" name="referral_code" placeholder="Código de referido"
|
||||
value="{{ old('referral_code') }}" autocomplete="referral_code" />
|
||||
@endif
|
||||
|
||||
<x-input-error :messages="$errors->get('referral_code')" class="mt-2" />
|
||||
</div>
|
||||
|
||||
|
||||
<div class="flex flex-col md:flex-row items-center justify-between mt-6 space-y-3 md:space-y-0">
|
||||
<a href="{{ route('login') }}"
|
||||
class="w-full md:w-auto text-center px-4 py-2 bg-gray-200 hover:bg-gray-300 text-gray-700 text-sm md:text-base font-semibold rounded-md shadow-sm transition-all duration-200">
|
||||
{{ __('Iniciar Sesión') }}
|
||||
</a>
|
||||
|
||||
<x-primary-button class="w-full md:w-auto justify-center text-sm md:text-base">
|
||||
{{ __('Registrarse') }}
|
||||
</x-primary-button>
|
||||
</div>
|
||||
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</x-guest-layout>
|
||||
|
||||
@@ -1,8 +1,12 @@
|
||||
<x-app-layout>
|
||||
|
||||
<livewire:show-inicio />
|
||||
|
||||
|
||||
<livewire:show-inicio />
|
||||
|
||||
<br>
|
||||
|
||||
<livewire:show-clientes />
|
||||
|
||||
@if (!in_array(auth()->user()->rol?->nombre, ['administrador', 'Roger','editor']))
|
||||
<livewire:share-code-component />
|
||||
@endif
|
||||
<br>
|
||||
|
||||
</x-app-layout>
|
||||
|
||||
@@ -0,0 +1,107 @@
|
||||
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 my-12">
|
||||
<div>
|
||||
<div class="bg-white shadow overflow-hidden sm:rounded-lg">
|
||||
<div class="px-4 py-5 sm:px-6">
|
||||
<h3 class="text-lg leading-6 font-medium text-gray-900">Compartir Código</h3>
|
||||
<p class="mt-1 max-w-2xl text-sm text-gray-500">
|
||||
Comparte tu código de referido.
|
||||
</p>
|
||||
<div class="mt-4 p-4 bg-gray-100 rounded">
|
||||
<span class="text-sm text-gray-700">Tu código:</span>
|
||||
<div class="flex items-center mt-2">
|
||||
<input type="text" id="referralLink" value="{{ route('register', ['ref' => Auth::user()->referral_code]) }}" class="flex-1 px-3 py-2 border border-gray-300 rounded-l-md text-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500" readonly >
|
||||
<button onclick="copyToClipboard()" class="bg-blue-600 hover:bg-blue-700 text-white px-4 py-2 rounded-r-md text-sm font-medium focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500" >
|
||||
Copiar
|
||||
</button>
|
||||
</div>
|
||||
<p id="copyFeedback" class="hidden text-green-600 text-xs mt-1"></p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 mb-12">
|
||||
<div class="bg-white">
|
||||
<div class="flex items-center justify-between mb-4">
|
||||
<div class="px-4 py-5 sm:px-6">
|
||||
<h3 class="text-lg leading-6 font-medium text-gray-900">Mis Referidos</h3>
|
||||
<p class="mt-1 text-sm text-gray-500">
|
||||
Aquí puedes ver la lista de tus referidos.
|
||||
</p>
|
||||
</div>
|
||||
<div class="flex items-center space-x-2 bg-purple-50 px-4 py-2 rounded-lg shadow-sm">
|
||||
<svg class="w-6 h-6 text-purple-600" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M18 18.72a9.094 9.094 0 0 0 3.741-.479 3 3 0 0 0-4.682-2.72m.94 3.198.001.031c0 .225-.012.447-.037.666A11.944 11.944 0 0 1 12 21c-2.17 0-4.207-.576-5.963-1.584A6.062 6.062 0 0 1 6 18.719m12 0a5.971 5.971 0 0 0-.941-3.197m0 0A5.995 5.995 0 0 0 12 12.75a5.995 5.995 0 0 0-5.058 2.772m0 0a3 3 0 0 0-4.681 2.72 8.986 8.986 0 0 0 3.74.477m.94-3.197a5.971 5.971 0 0 0-.94 3.197M15 6.75a3 3 0 1 1-6 0 3 3 0 0 1 6 0Zm6 3a2.25 2.25 0 1 1-4.5 0 2.25 2.25 0 0 1 4.5 0Zm-13.5 0a2.25 2.25 0 1 1-4.5 0 2.25 2.25 0 0 1 4.5 0Z" />
|
||||
</svg>
|
||||
|
||||
<span class="text-purple-700 font-semibold text-lg">
|
||||
{{ $referrals->count() }}
|
||||
</span>
|
||||
<span class="text-gray-600 text-sm">Total de referidos</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="shadow overflow-hidden sm:rounded-lg">
|
||||
<div class="overflow-x-auto">
|
||||
<table class="min-w-full divide-y divide-gray-200">
|
||||
<thead class="bg-gray-50">
|
||||
<tr>
|
||||
<th class="px-6 py-3 text-left text-xs font-semibold text-gray-600 uppercase tracking-wider">
|
||||
Fecha
|
||||
</th>
|
||||
<th class="px-6 py-3 text-left text-xs font-semibold text-gray-600 uppercase tracking-wider">
|
||||
Usuario
|
||||
</th>
|
||||
<th class="px-6 py-3 text-center text-xs font-semibold text-gray-600 uppercase tracking-wider">
|
||||
Referidos del usuario
|
||||
</th>
|
||||
<th class="px-6 py-3 text-center text-xs font-semibold text-gray-600 uppercase tracking-wider">
|
||||
Estado
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="bg-white divide-y divide-gray-100">
|
||||
@forelse ($referrals as $item)
|
||||
<tr class="hover:bg-gray-50 transition duration-150">
|
||||
<td class="px-6 py-4 text-sm text-gray-700">{{ $item->created_at->format('Y-m-d') }}</td>
|
||||
<td class="px-6 py-4 text-sm font-medium text-gray-900">{{ $item->email }}</td>
|
||||
<td class="px-6 py-4 text-center text-sm text-gray-700">{{ $item->children_count }}</td>
|
||||
<td class="px-6 py-4 text-center select-none">
|
||||
<span class="px-3 py-1 text-xs font-semibold rounded-full bg-red-100 text-red-700">
|
||||
Inactivo
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
@empty
|
||||
<tr>
|
||||
<td colspan="4" class="px-6 py-4 text-center text-sm text-gray-500">
|
||||
No tienes referidos aún.
|
||||
</td>
|
||||
</tr>
|
||||
@endforelse
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<script>
|
||||
function copyToClipboard() {
|
||||
const copyText = document.getElementById("referralLink");
|
||||
|
||||
copyText.select();
|
||||
copyText.setSelectionRange(0, 99999);
|
||||
|
||||
document.execCommand("copy");
|
||||
|
||||
const feedback = document.getElementById("copyFeedback");
|
||||
feedback.classList.remove("hidden");
|
||||
|
||||
setTimeout(() => {
|
||||
feedback.classList.add("hidden");
|
||||
}, 2000);
|
||||
}
|
||||
</script>
|
||||
@@ -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>
|
||||
|
||||
@@ -488,10 +488,10 @@
|
||||
|
||||
<!-- Rol -->
|
||||
<div class="mb-4">
|
||||
<label for="estado_promocion" class="block text-gray-700 text-sm font-bold mb-2">Selecciona rol:</label>
|
||||
<select id="estado_promocion" wire:model="rol"
|
||||
<label for="rol" class="block text-gray-700 text-sm font-bold mb-2">Selecciona rol:</label>
|
||||
<select id="rol" wire:model="rol"
|
||||
class="w-full border-2 border-neutral-200 rounded-[0.8rem] shadow appearance-none ring-0 focus:ring-0 focus:border-neutral-300 py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline">
|
||||
<option selected>Rol</option>
|
||||
<option value="" selected>Rol</option>
|
||||
@foreach ($roles as $rol)
|
||||
<option value="{{ $rol->id }}">{{ $rol->nombre }}</option>
|
||||
@endforeach
|
||||
|
||||
Reference in New Issue
Block a user