Formulario mejorado con iconos, headers y nuevos campos
All checks were successful
build-and-deploy / build-and-deploy (push) Successful in 54s

- Reorganizar formulario en 4 secciones con headers:
  * Información Básica (username, UID, nombre, email)
  * Conectividad (contraseña WiFi)
  * Información Personal (teléfono, cédula, fecha, avatar)
  * Seguridad y Acceso (NFC, PIN, código Nucleo)
- Agregar UID de Authentik (solo lectura)
- Agregar contraseña WiFi Nucleo (solo lectura)
- Iconos en todos los campos y secciones
- Labels personalizados con iconos heroicons
- Indicador de campos requeridos (*)
- Textos de ayuda mejorados
- Estilos glassmorphism para secciones
- Modo oscuro completo
- Responsive design mejorado
This commit is contained in:
2025-10-17 00:19:22 -06:00
parent e535f8d937
commit 196108752a

View File

@@ -18,129 +18,218 @@
</div> </div>
<form @submit.prevent="handleSubmit" class="form-content"> <form @submit.prevent="handleSubmit" class="form-content">
<div class="form-grid"> <!-- Sección: Información Básica -->
<!-- Nombre de usuario (readonly) --> <div class="form-section">
<UFormGroup label="Nombre de usuario" name="username"> <h3 class="section-title">
<UInput <UIcon name="i-heroicons-identification" class="w-5 h-5" />
:model-value="user?.username" Información Básica
disabled </h3>
:ui="{ base: 'cursor-not-allowed opacity-50' }" <div class="form-grid">
/> <!-- Nombre de usuario (readonly) -->
<template #help> <div class="form-field">
<span class="text-xs text-gray-500">El nombre de usuario no se puede cambiar</span> <label class="field-label">
</template> <UIcon name="i-heroicons-at-symbol" class="w-4 h-4" />
</UFormGroup> Nombre de usuario
</label>
<UInput
:model-value="user?.username"
disabled
:ui="{ base: 'cursor-not-allowed opacity-50' }"
/>
<span class="field-help">No se puede cambiar</span>
</div>
<!-- Nombre completo --> <!-- UID de Authentik (readonly) -->
<UFormGroup label="Nombre completo" name="name" required> <div class="form-field">
<UInput <label class="field-label">
v-model="formData.name" <UIcon name="i-heroicons-finger-print" class="w-4 h-4" />
placeholder="Tu nombre completo" UID de Authentik
:disabled="isSubmitting" </label>
/> <UInput
</UFormGroup> :model-value="user?.uid || 'No disponible'"
disabled
:ui="{ base: 'cursor-not-allowed opacity-50' }"
/>
<span class="field-help">Identificador único del sistema</span>
</div>
<!-- Email --> <!-- Nombre completo -->
<UFormGroup label="Correo electrónico" name="email" required> <div class="form-field">
<UInput <label class="field-label">
v-model="formData.email" <UIcon name="i-heroicons-user" class="w-4 h-4" />
type="email" Nombre completo
placeholder="tu@email.com" <span class="required">*</span>
:disabled="isSubmitting" </label>
/> <UInput
</UFormGroup> v-model="formData.name"
placeholder="Tu nombre completo"
:disabled="isSubmitting"
/>
</div>
<!-- Avatar URL (deshabilitado) --> <!-- Email -->
<UFormGroup label="URL del avatar" name="avatar"> <div class="form-field">
<UInput <label class="field-label">
v-model="formData.avatar" <UIcon name="i-heroicons-envelope" class="w-4 h-4" />
placeholder="https://ejemplo.com/avatar.jpg" Correo electrónico
disabled <span class="required">*</span>
:ui="{ base: 'cursor-not-allowed opacity-50' }" </label>
/> <UInput
<template #help> v-model="formData.email"
<span class="text-xs text-gray-500">Próximamente disponible</span> type="email"
</template> placeholder="tu@email.com"
</UFormGroup> :disabled="isSubmitting"
/>
</div>
</div>
</div>
<!-- Teléfono (deshabilitado) --> <!-- Sección: Conectividad -->
<UFormGroup label="Teléfono" name="phone"> <div class="form-section">
<UInput <h3 class="section-title">
v-model="formData.phone" <UIcon name="i-heroicons-wifi" class="w-5 h-5" />
placeholder="+506 1234-5678" Conectividad
disabled </h3>
:ui="{ base: 'cursor-not-allowed opacity-50' }" <div class="form-grid">
/> <!-- Contraseña WiFi (readonly) -->
<template #help> <div class="form-field full-width">
<span class="text-xs text-gray-500">Próximamente disponible</span> <label class="field-label">
</template> <UIcon name="i-heroicons-key" class="w-4 h-4" />
</UFormGroup> Contraseña WiFi Nucleo
</label>
<UInput
value="Nucleo2024WiFi!"
disabled
type="text"
:ui="{ base: 'cursor-not-allowed opacity-50' }"
/>
<span class="field-help">Contraseña de la red WiFi de Nucleo</span>
</div>
</div>
</div>
<!-- Cédula (deshabilitado) --> <!-- Sección: Información Personal -->
<UFormGroup label="Cédula" name="cedula"> <div class="form-section">
<UInput <h3 class="section-title">
v-model="formData.cedula" <UIcon name="i-heroicons-user-circle" class="w-5 h-5" />
placeholder="1-2345-6789" Información Personal
disabled </h3>
:ui="{ base: 'cursor-not-allowed opacity-50' }" <div class="form-grid">
/> <!-- Teléfono (deshabilitado) -->
<template #help> <div class="form-field">
<span class="text-xs text-gray-500">Próximamente disponible</span> <label class="field-label">
</template> <UIcon name="i-heroicons-phone" class="w-4 h-4" />
</UFormGroup> Teléfono
</label>
<UInput
v-model="formData.phone"
placeholder="+506 1234-5678"
disabled
:ui="{ base: 'cursor-not-allowed opacity-50' }"
/>
<span class="field-help">Próximamente disponible</span>
</div>
<!-- Fecha de nacimiento (deshabilitado) --> <!-- Cédula (deshabilitado) -->
<UFormGroup label="Fecha de nacimiento" name="birthdate"> <div class="form-field">
<UInput <label class="field-label">
v-model="formData.birthdate" <UIcon name="i-heroicons-identification" class="w-4 h-4" />
type="date" Cédula
disabled </label>
:ui="{ base: 'cursor-not-allowed opacity-50' }" <UInput
/> v-model="formData.cedula"
<template #help> placeholder="1-2345-6789"
<span class="text-xs text-gray-500">Próximamente disponible</span> disabled
</template> :ui="{ base: 'cursor-not-allowed opacity-50' }"
</UFormGroup> />
<span class="field-help">Próximamente disponible</span>
</div>
<!-- NFC vinculada (deshabilitado) --> <!-- Fecha de nacimiento (deshabilitado) -->
<UFormGroup label="NFC vinculada" name="nfc"> <div class="form-field">
<UInput <label class="field-label">
v-model="formData.nfc" <UIcon name="i-heroicons-cake" class="w-4 h-4" />
placeholder="ID de tarjeta NFC" Fecha de nacimiento
disabled </label>
:ui="{ base: 'cursor-not-allowed opacity-50' }" <UInput
/> v-model="formData.birthdate"
<template #help> type="date"
<span class="text-xs text-gray-500">Próximamente disponible</span> disabled
</template> :ui="{ base: 'cursor-not-allowed opacity-50' }"
</UFormGroup> />
<span class="field-help">Próximamente disponible</span>
</div>
<!-- PIN numérico (deshabilitado) --> <!-- Avatar URL (deshabilitado) -->
<UFormGroup label="PIN numérico" name="pin"> <div class="form-field">
<UInput <label class="field-label">
v-model="formData.pin" <UIcon name="i-heroicons-photo" class="w-4 h-4" />
type="password" URL del avatar
placeholder="••••" </label>
disabled <UInput
:ui="{ base: 'cursor-not-allowed opacity-50' }" v-model="formData.avatar"
/> placeholder="https://ejemplo.com/avatar.jpg"
<template #help> disabled
<span class="text-xs text-gray-500">Próximamente disponible</span> :ui="{ base: 'cursor-not-allowed opacity-50' }"
</template> />
</UFormGroup> <span class="field-help">Próximamente disponible</span>
</div>
</div>
</div>
<!-- Código Nucleo V2 (deshabilitado) --> <!-- Sección: Seguridad y Acceso -->
<UFormGroup label="Código Nucleo V2" name="nucleoCode"> <div class="form-section">
<UInput <h3 class="section-title">
v-model="formData.nucleoCode" <UIcon name="i-heroicons-shield-check" class="w-5 h-5" />
placeholder="NUCLEO-XXXX-XXXX" Seguridad y Acceso
disabled </h3>
:ui="{ base: 'cursor-not-allowed opacity-50' }" <div class="form-grid">
/> <!-- NFC vinculada (deshabilitado) -->
<template #help> <div class="form-field">
<span class="text-xs text-gray-500">Próximamente disponible</span> <label class="field-label">
</template> <UIcon name="i-heroicons-credit-card" class="w-4 h-4" />
</UFormGroup> NFC vinculada
</label>
<UInput
v-model="formData.nfc"
placeholder="ID de tarjeta NFC"
disabled
:ui="{ base: 'cursor-not-allowed opacity-50' }"
/>
<span class="field-help">Próximamente disponible</span>
</div>
<!-- PIN numérico (deshabilitado) -->
<div class="form-field">
<label class="field-label">
<UIcon name="i-heroicons-lock-closed" class="w-4 h-4" />
PIN numérico
</label>
<UInput
v-model="formData.pin"
type="password"
placeholder="••••"
disabled
:ui="{ base: 'cursor-not-allowed opacity-50' }"
/>
<span class="field-help">Próximamente disponible</span>
</div>
<!-- Código Nucleo V2 (deshabilitado) -->
<div class="form-field">
<label class="field-label">
<UIcon name="i-heroicons-qr-code" class="w-4 h-4" />
Código Nucleo V2
</label>
<UInput
v-model="formData.nucleoCode"
placeholder="NUCLEO-XXXX-XXXX"
disabled
:ui="{ base: 'cursor-not-allowed opacity-50' }"
/>
<span class="field-help">Próximamente disponible</span>
</div>
</div>
</div> </div>
<!-- Botones de acción --> <!-- Botones de acción -->
@@ -270,12 +359,60 @@ const handleSubmit = async () => {
gap: 2rem; gap: 2rem;
} }
.form-section {
display: flex;
flex-direction: column;
gap: 1rem;
}
.section-title {
display: flex;
align-items: center;
gap: 0.5rem;
font-size: 1.125rem;
font-weight: 600;
color: var(--color-gray-800);
margin: 0 0 0.5rem 0;
padding-bottom: 0.75rem;
border-bottom: 2px solid rgba(var(--color-primary-500), 0.2);
}
.form-grid { .form-grid {
display: grid; display: grid;
grid-template-columns: repeat(2, 1fr); grid-template-columns: repeat(2, 1fr);
gap: 1.5rem; gap: 1.5rem;
} }
.form-field {
display: flex;
flex-direction: column;
gap: 0.5rem;
}
.form-field.full-width {
grid-column: 1 / -1;
}
.field-label {
display: flex;
align-items: center;
gap: 0.5rem;
font-size: 0.875rem;
font-weight: 600;
color: var(--color-gray-700);
}
.field-label .required {
color: rgb(var(--color-error-500));
margin-left: 0.125rem;
}
.field-help {
font-size: 0.75rem;
color: var(--color-gray-500);
font-style: italic;
}
.form-actions { .form-actions {
display: flex; display: flex;
justify-content: flex-end; justify-content: flex-end;
@@ -294,11 +431,19 @@ const handleSubmit = async () => {
font-size: 1.5rem; font-size: 1.5rem;
} }
.section-title {
font-size: 1rem;
}
.form-grid { .form-grid {
grid-template-columns: 1fr; grid-template-columns: 1fr;
gap: 1rem; gap: 1rem;
} }
.form-field.full-width {
grid-column: 1;
}
.form-actions { .form-actions {
flex-direction: column; flex-direction: column;
} }
@@ -319,6 +464,19 @@ const handleSubmit = async () => {
color: var(--color-gray-100) !important; color: var(--color-gray-100) !important;
} }
.dark .section-title {
color: var(--color-gray-100) !important;
border-bottom-color: rgba(var(--color-primary-500), 0.3) !important;
}
.dark .field-label {
color: var(--color-gray-300) !important;
}
.dark .field-help {
color: var(--color-gray-400) !important;
}
.dark .form-actions { .dark .form-actions {
border-top-color: rgba(255, 255, 255, 0.1); border-top-color: rgba(255, 255, 255, 0.1);
} }