Initial commit: Lash Vanshy - Complete project with admin panel, gallery, products, and contact

This commit is contained in:
2026-04-08 00:23:16 -06:00
commit e07e065791
111 changed files with 17939 additions and 0 deletions

View File

@@ -0,0 +1,64 @@
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class AdminUserRequest extends FormRequest
{
public function authorize(): bool
{
return true;
}
public function rules(): array
{
$rules = [
'name' => ['required', 'string', 'max:255'],
'email' => ['required', 'string', 'email', 'max:255', 'unique:admin_users,email'],
'password' => ['required', 'string', 'min:8', 'max:255'],
'rol' => ['required', 'in:super_admin,admin'],
'avatar' => ['nullable', 'image', 'mimes:jpeg,png,gif,webp', 'max:5120'],
];
// En actualización, password no es obligatorio (puede mantener el actual)
if ($this->isMethod('PATCH') || $this->isMethod('PUT')) {
$rules['password'] = ['nullable', 'string', 'min:8', 'max:255'];
$rules['email'] = ['required', 'string', 'email', 'max:255', 'unique:admin_users,email,'.$this->route('admin_user')];
$rules['avatar'] = ['nullable', 'image', 'mimes:jpeg,png,gif,webp', 'max:5120'];
}
return $rules;
}
public function messages(): array
{
return [
'name.required' => 'El nombre es obligatorio.',
'name.max' => 'El nombre no puede exceder 255 caracteres.',
'email.required' => 'El email es obligatorio.',
'email.email' => 'El email debe ser una dirección válida.',
'email.max' => 'El email no puede exceder 255 caracteres.',
'email.unique' => 'El email ya está en uso.',
'password.required' => 'La contraseña es obligatoria.',
'password.min' => 'La contraseña debe tener al menos 6 caracteres.',
'password.max' => 'La contraseña no puede exceder 255 caracteres.',
'rol.required' => 'El rol es obligatorio.',
'rol.in' => 'El rol debe ser super_admin o admin.',
'avatar.image' => 'El avatar debe ser una imagen.',
'avatar.mimes' => 'El formato del avatar no es válido.',
'avatar.max' => 'El avatar no puede exceder 5MB.',
];
}
/**
* Configure the validator instance.
*/
public function withValidator($validator): void
{
$validator->after(function ($validator) {
// Validar que un admin no pueda crear/editar otro super_admin
// Esta validación se maneja en el controlador
});
}
}

View File

@@ -0,0 +1,43 @@
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class GaleriaRequest extends FormRequest
{
public function authorize(): bool
{
return true;
}
public function rules(): array
{
$rules = [
'titulo' => ['required', 'string', 'max:255'],
'descripcion' => ['nullable', 'string', 'max:1000'],
'tipo' => ['required', 'in:imagen,video'],
'archivo' => ['required', 'file', 'max:102400'],
'thumbnail' => ['nullable', 'image', 'max:10240'],
'orden' => ['nullable', 'integer', 'min:0'],
'activo' => ['nullable', 'boolean'],
];
if ($this->isMethod('PUT') || $this->isMethod('PATCH')) {
$rules['archivo'] = ['nullable', 'file', 'max:102400'];
}
return $rules;
}
public function messages(): array
{
return [
'titulo.required' => 'El titulo es obligatorio.',
'tipo.required' => 'Debes seleccionar el tipo (imagen o video).',
'archivo.required' => 'Debes subir un archivo.',
'archivo.mimes' => 'El formato del archivo no es valido.',
'archivo.max' => 'El archivo no puede exceder 100MB.',
];
}
}

View File

@@ -0,0 +1,31 @@
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class LoginRequest extends FormRequest
{
public function authorize(): bool
{
return true;
}
public function rules(): array
{
return [
'email' => ['required', 'string', 'email', 'max:255'],
'password' => ['required', 'string', 'min:1'],
];
}
public function messages(): array
{
return [
'email.required' => 'El email es obligatorio.',
'email.email' => 'El email debe ser una dirección válida.',
'email.max' => 'El email no puede exceder 255 caracteres.',
'password.required' => 'La contraseña es obligatoria.',
];
}
}

View File

@@ -0,0 +1,42 @@
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class MensajeRequest extends FormRequest
{
public function authorize(): bool
{
return true;
}
public function rules(): array
{
$rules = [
'nombre' => ['required', 'string', 'max:255'],
'email' => ['required', 'string', 'email', 'max:255'],
'telefono' => ['nullable', 'string', 'max:50', 'regex:/^[+]?[\d\s\-()]+$/'],
'mensaje' => ['required', 'string', 'min:1', 'max:10000'],
'leido' => ['nullable', 'boolean'],
];
return $rules;
}
public function messages(): array
{
return [
'nombre.required' => 'El nombre es obligatorio.',
'nombre.max' => 'El nombre no puede exceder 255 caracteres.',
'email.required' => 'El email es obligatorio.',
'email.email' => 'El email debe ser una dirección válida.',
'email.max' => 'El email no puede exceder 255 caracteres.',
'telefono.max' => 'El teléfono no puede exceder 50 caracteres.',
'telefono.regex' => 'El formato del teléfono no es válido.',
'mensaje.required' => 'El mensaje es obligatorio.',
'mensaje.min' => 'El mensaje no puede estar vacío.',
'mensaje.max' => 'El mensaje no puede exceder 10000 caracteres.',
];
}
}

View File

@@ -0,0 +1,55 @@
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class ProductoRequest extends FormRequest
{
public function authorize(): bool
{
return true;
}
public function rules(): array
{
$rules = [
'nombre' => ['required', 'string', 'max:255'],
'descripcion' => ['required', 'string', 'max:5000'],
'precio' => ['required', 'numeric', 'min:0', 'regex:/^\d+(\.\d{1,2})?$/'],
'imagen' => ['nullable', 'image', 'mimes:jpeg,png,gif,webp', 'max:10240'],
'categoria' => ['required', 'string', 'max:100'],
'destacado' => ['nullable', 'boolean'],
'activo' => ['nullable', 'boolean'],
'orden' => ['nullable', 'integer', 'min:0'],
];
// En actualización, imagen no es obligatoria
if ($this->isMethod('PATCH') || $this->isMethod('PUT')) {
$rules['imagen'] = ['nullable', 'image', 'mimes:jpeg,png,gif,webp', 'max:10240'];
}
return $rules;
}
public function messages(): array
{
return [
'nombre.required' => 'El nombre es obligatorio.',
'nombre.max' => 'El nombre no puede exceder 255 caracteres.',
'descripcion.required' => 'La descripción es obligatoria.',
'descripcion.max' => 'La descripción no puede exceder 5000 caracteres.',
'precio.required' => 'El precio es obligatorio.',
'precio.numeric' => 'El precio debe ser un número válido.',
'precio.min' => 'El precio no puede ser negativo.',
'precio.regex' => 'El precio debe tener como máximo 2 decimales.',
'imagen.image' => 'La imagen debe ser un archivo de imagen.',
'imagen.mimes' => 'El formato de imagen no es válido.',
'imagen.max' => 'La imagen no puede exceder 10MB.',
'categoria.required' => 'La categoría es obligatoria.',
'categoria.max' => 'La categoría no puede exceder 100 caracteres.',
'orden.integer' => 'El orden debe ser un número entero.',
'orden.min' => 'El orden no puede ser negativo.',
];
}
}