Files
Nexora/resources/views/users/create.blade.php
2025-10-25 11:29:20 +02:00

385 lines
17 KiB
PHP

<x-layouts.app title="{{ (isset($user) && $user->id) ? __('Edit User') : __('Create User') }}" :showSidebar={{ $showSidebar }}>
<!-- Header -->
<div class="mb-8">
<div class="flex items-center gap-4 mb-4">
<flux:icon.user class="size-10" variant="solid"/>
<h1 class="text-3xl font-bold text-gray-800">
{{ (isset($user) && $user->id) ? 'Editar Usuario' : 'Nuevo Usuario' }}
</h1>
</div>
<p class="text-gray-600 text-sm">
@if(isset($user) && $user->id)
Modifique los campos necesarios para actualizar la información del usuario.
@else
Complete todos los campos obligatorios para registrar un nuevo usuario en el sistema.
@endisset
</p>
</div>
@if(session('error'))
<div id="error-message" class="mb-4 p-4 bg-red-100 border border-red-400 text-red-700 rounded">
{{ session('error') }}
</div>
@endif
@if($errors->any())
<div class="mb-4 p-4 bg-red-100 border border-red-400 text-red-700 rounded">
<ul>
@foreach($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
</div>
@endif
<form method="POST" action="{{ (isset($user) && $user->id) ? route('users.update', $user) : route('users.store') }}">
@csrf
@if(isset($user) && $user->id)
@method('PUT')
@endif
<!-- Separador -->
<div class="relative">
<div class="absolute inset-0 flex items-center">
<div class="w-full border-t border-gray-300"></div>
</div>
<div class="relative flex justify-center">
<span class="px-4 bg-white text-sm text-gray-500">Datos Personales</span>
</div>
</div>
<!-- Datos Personales -->
<div class="bg-white py-6">
<table class="w-full">
<tbody class="space-y-4">
<!-- Título de cortesía -->
<tr>
<td class="py-2 pr-4 w-1/3">
<label class="block text-sm font-medium text-gray-700">
Título de cortesía
</label>
</td>
<td class="py-2">
<select name="title" class="w-[150px] border-b-1 border-gray-300 focus:border-blue-500 focus:outline-none">
<option value="">Seleccionar...</option>
<option value="Sr.">Sr.</option>
<option value="Sra.">Sra.</option>
<option value="Dr.">Dr.</option>
</select>
</td>
</tr>
<!-- Nombre -->
<tr>
<td class="py-2 pr-4">
<label class="block text-sm font-bold text-gray-700">
Nombre
</label>
</td>
<td class="py-2">
<input type="text" name="first_name" required
value="{{ old('first_name', $user->first_name ?? '') }}"
class="w-[250px] border-b-1 border-gray-300 focus:border-blue-500 focus:outline-none"
autofocus>
</td>
</tr>
<!-- Apellidos -->
<tr>
<td class="py-2 pr-4">
<label class="block text-sm font-bold text-gray-700">
Apellidos
</label>
</td>
<td class="py-2">
<input type="text" name="last_name" required
value="{{ old('last_name', $user->last_name ?? '') }}"
class="w-[250px] border-b-1 border-gray-300 focus:border-blue-500 focus:outline-none">
</td>
</tr>
<!-- Nombre de Login -->
<tr>
<td class="py-2 pr-4">
<label class="block text-sm font-bold text-gray-700">
Nombre de Login
</label>
</td>
<td class="py-2">
<input type="text" name="username" required
value="{{ old('username', $user->username ?? '') }}"
class="w-[250px] border-b-1 border-gray-300 focus:border-blue-500 focus:outline-none">
</td>
</tr>
</tbody>
</table>
</div>
<!-- Separador -->
<div class="relative">
<div class="absolute inset-0 flex items-center">
<div class="w-full border-t border-gray-300"></div>
</div>
<div class="relative flex justify-center">
<span class="px-4 bg-white text-sm text-gray-500">Configuración de acceso</span>
</div>
</div>
<!-- Configuración de Acceso -->
<div class="bg-white py-6">
<table class="w-full">
<tbody>
<!-- Intervalo de fechas -->
<tr>
<td class="py-2 pr-4 w-1/3">
<label class="block text-sm font-medium text-gray-700">
Validez de acceso
</label>
</td>
<td class="py-2">
<div class="flex gap-4">
de
<input type="date" name="start_date"
value="{{ old('start_date', isset($user->access_start) ? $user->access_start->format('Y-m-d') : '') }}"
class="w-[150px] border-b-1 border-gray-300 focus:border-blue-500 focus:outline-none">
a
<input type="date" name="end_date"
value="{{ old('end_date', isset($user->access_end) ? $user->access_end->format('Y-m-d') : '') }}"
class="w-[150px] border-b-1 border-gray-300 focus:border-blue-500 focus:outline-none">
</div>
</td>
</tr>
<!-- Contraseña -->
<tr>
<td class="py-2 pr-4">
<label class="block text-sm font-bold text-gray-700">
Contraseña
</label>
</td>
<td class="py-2">
<div class="flex gap-2">
<input type="text" name="password" id="password"
{{ !isset($user) ? 'required' : '' }}
class="w-[250px] border-b-1 border-gray-300 focus:border-blue-500 focus:outline-none">
<button type="button" onclick="generatePassword()"
class="px-2 py-1 bg-blue-100 text-blue-700 rounded-md hover:bg-blue-200 flex items-center gap-2">
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor">
<path fill-rule="evenodd" d="M18 8a6 6 0 01-7.743 5.743L10 14l-1 1-1 1H6v2H2v-4l4.257-4.257A6 6 0 1118 8zm-6-4a1 1 0 100 2 2 2 0 012 2 1 1 0 102 0 4 4 0 00-4-4z" clip-rule="evenodd" />
</svg>
</button>
</div>
</td>
</tr>
</tbody>
</table>
</div>
<!-- Separador -->
<div class="relative">
<div class="absolute inset-0 flex items-center">
<div class="w-full border-t border-gray-300"></div>
</div>
<div class="relative flex justify-center">
<span class="px-4 bg-white text-sm text-gray-500">Datos de contacto</span>
</div>
</div>
<!-- Datos de Contacto -->
<div class="bg-white py-6">
<table class="w-full">
<tbody>
<tr>
<td class="py-2 pr-4 w-1/3">
<label class="block text-sm font-bold text-gray-700">
Email
</label>
</td>
<td class="py-2">
<div class="flex items-center gap-2">
<flux:icon.envelope class="w-5 h-5"/>
<input type="email" name="email" required
value="{{ old('email', $user->email ?? '') }}"
class="w-[300px] border-b-1 border-gray-300 focus:border-blue-500 focus:outline-none">
</div>
</td>
</tr>
<tr>
<td class="py-2 pr-4">
<label class="block text-sm font-medium text-gray-700">
Teléfono
</label>
</td>
<td class="py-2">
<div class="flex items-center gap-2">
<flux:icon.phone class="w-5 h-5"/>
<input type="tel" name="phone"
value="{{ old('phone', $user->phone ?? '') }}"
class="w-[250px] border-b-1 border-gray-300 focus:border-blue-500 focus:outline-none">
</div>
</td>
</tr>
<tr>
<td class="py-2 pr-4 align-top">
<label class="block text-sm font-medium text-gray-700">
Dirección
</label>
</td>
<td class="py-2">
<div class="flex items-start gap-2">
<flux:icon.map-pin class="w-5 h-5"/>
<textarea name="address" rows="3"
class="w-full border-b-1 border-gray-300 focus:border-blue-500 focus:outline-none">{{ old('address', $user->address ?? '') }}</textarea>
</div>
</td>
</tr>
</tbody>
</table>
</div>
<!-- Separador -->
<div class="relative">
<div class="absolute inset-0 flex items-center">
<div class="w-full border-t border-gray-300"></div>
</div>
<div class="relative flex justify-center">
<span class="px-4 bg-white text-sm text-gray-500">Otros datos</span>
</div>
</div>
<!-- Datos de Contacto -->
<div class="bg-white py-6">
<table class="w-full">
<tbody>
<!-- tipo de usuario -->
<tr>
<td class="py-2 pr-4 w-1/3">
<label class="block text-sm font-bold text-gray-700">
Tipo de usuario
</label>
</td>
<td class="py-2">
<div class="flex items-center gap-2">
<select name="user_type" class="w-[200px] border-b-1 border-gray-300 focus:border-blue-500 focus:outline-none">
<option value="0">Interno</option>
<option value="1">Externo</option>
</select>
</div>
</td>
</tr>
<!-- Estado -->
<tr>
<td class="py-2 pr-4 w-1/3">
<label class="block text-sm font-bold text-gray-700">
Estado
</label>
</td>
<td class="py-2">
<div class="flex items-center gap-2">
<select name="is_active" class="w-[200px] border-b-1 border-gray-300 focus:border-blue-500 focus:outline-none">
<option value="Activo">Activo</option>
<option value="Inactivo">Inactivo</option>
</select>
</div>
</td>
</tr>
<!-- Foto -->
<tr>
<td class="py-2 pr-4">
<label class="block text-sm font-bold text-gray-700">
Foto
</label>
</td>
<td class="py-2">
<div class="mb-6">
@livewire('image-uploader', [
'fieldName' => 'image_path', // Nombre del campo en la BD
'label' => 'Imagen principal' // Etiqueta personalizada
])
<!-- Campo oculto para la ruta de la imagen -->
<input type="hidden" name="profile_photo_path" id="profilePhotoPathInput" value="{{ old('profile_photo_path', optional($user)->profile_photo_path ?? '') }}">
</div>
</td>
</tr>
</tbody>
</table>
</div>
<!-- Botón de envío -->
<div class="text-right">
<button type="submit"
class="px-6 py-2 bg-blue-600 text-white rounded-md hover:bg-blue-700 transition-colors">
{{ (isset($user) && $user->id) ? 'Actualizar Usuario' : 'Crear Usuario' }}
</button>
</div>
</form>
<script>
// Escuchar el evento de Livewire y actualizar el campo oculto
document.addEventListener('imageUploaded', (event) => {
document.getElementById('profilePhotoPathInput').value = event.detail.path;
});
document.addEventListener('imageRemoved', (event) => {
document.getElementById('profilePhotoPathInput').value = '';
});
function generatePassword() {
const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*()';
let password = '';
for (let i = 0; i < 12; i++) {
password += chars.charAt(Math.floor(Math.random() * chars.length));
}
document.getElementById('password').value = password;
}
/*
<div class="mt-2 flex items-center gap-2">
<input type="checkbox" onclick="togglePasswordVisibility()">
<span class="text-sm text-gray-500">Mostrar contraseña</span>
</div>
function togglePasswordVisibility() {
const passwordField = document.getElementById('password');
passwordField.type = passwordField.type === 'password' ? 'text' : 'password';
}
*/
</script>
<!-- Sidebar menu -->
@push('sidebar-menu')
<flux:navlist variant="outline">
<!-- Sección de Usuarios -->
<flux:navlist.group :heading="__('User')">
<flux:navlist.item
icon="users"
:href="route('users.index')"
wire:navigate
>
{{ __('List Users') }}
</flux:navlist.item>
<flux:navlist.item
icon="user-plus"
:href="route('users.create')"
wire:navigate
>
{{ __('Create User') }}
</flux:navlist.item>
</flux:navlist.group>
<flux:separator />
</flux:navlist>
@endpush
</x-layouts.app>