From 3cb9222332d9583b012f5d7a6419b00f06d419a9 Mon Sep 17 00:00:00 2001 From: Marina Milo Date: Thu, 2 Oct 2025 20:07:26 -0300 Subject: [PATCH 01/13] feat: add FotoPerfilUploader component for profile picture upload and URL input - Implemented FotoPerfilUploader.svelte to handle image uploads via file input or URL. - Integrated FotoPerfilUploader into InstitucionForm.svelte for user profile picture management. - Updated form validation to include checks for uploaded images and URLs. - Added utility function enfocarPrimerCampoConError to focus on the first error field during form submission. --- .../registro/ColaboradorForm.svelte | 630 ++++++------------ .../registro/FotoPerfilUploader.svelte | 315 +++++++++ .../registro/InstitucionForm.svelte | 494 ++++---------- frontend/src/lib/utils/forms.ts | 10 + 4 files changed, 662 insertions(+), 787 deletions(-) create mode 100644 frontend/src/lib/components/registro/FotoPerfilUploader.svelte create mode 100644 frontend/src/lib/utils/forms.ts diff --git a/frontend/src/lib/components/registro/ColaboradorForm.svelte b/frontend/src/lib/components/registro/ColaboradorForm.svelte index af1d9777..14a7ed17 100644 --- a/frontend/src/lib/components/registro/ColaboradorForm.svelte +++ b/frontend/src/lib/components/registro/ColaboradorForm.svelte @@ -3,155 +3,98 @@ import DatePicker from '$lib/components/ui/elementos/DatePicker.svelte'; import Button from '$lib/components/ui/elementos/Button.svelte'; import Select from '$lib/components/ui/elementos/Select.svelte'; + import FotoPerfilUploader from '$lib/components/registro/FotoPerfilUploader.svelte'; import { createEventDispatcher } from 'svelte'; - const dispatch = createEventDispatcher(); - import { - validarCorreo, - validarContrasena, + validarUsername, validarNombre, validarApellido, - isValidDni, esAdulto, - validarUsername, - isValidCuit, + validarUrl, MENSAJES_ERROR } from '$lib/utils/validaciones'; + import type { + Usuario, + Colaborador as ColaboradorTipo, + Organizacion as OrganizacionTipo + } from '$lib/types/Usuario'; + import { enfocarPrimerCampoConError } from '$lib/utils/forms'; - let enviando = false; - let tipo: 'persona' | 'organizacion' = 'persona'; - let mostrarPassword = false; - let mostrarRepassword = false; - let intentoEnvio = false; - - // Datos persona - let nombre = ''; - let apellido = ''; - let docTipo = 'DNI'; - let docOtro = ''; - let docNumero = ''; - let nacimiento: Date | null = null; - let cuil = ''; // ! quitar cuando corrijamos signin - - // Datos organización - let razonSocial = ''; - let cuit = ''; // ! quitar cuando corrijamos signin - let repNombre = ''; - let repApellido = ''; - let repDocTipo = 'DNI'; - let repDocOtro = ''; - let repDocNumero = ''; - let repNacimiento: Date | null = null; - - // Usuario y contraseña - let username = ''; - let email = ''; - let password = ''; - let repassword = ''; - - $: errores = { - // Persona - nombre: - tipo === 'persona' && !nombre.trim() - ? MENSAJES_ERROR.obligatorio - : tipo === 'persona' && !validarNombre(nombre) - ? MENSAJES_ERROR.nombreInvalido - : '', - - apellido: - tipo === 'persona' && !apellido.trim() - ? MENSAJES_ERROR.obligatorio - : tipo === 'persona' && !validarApellido(apellido) - ? MENSAJES_ERROR.apellidoInvalido - : '', - - docOtro: - tipo === 'persona' && docTipo === 'Otro' && !docOtro.trim() - ? MENSAJES_ERROR.specifyDocument - : '', - - docNumero: - tipo === 'persona' && !docNumero.trim() - ? MENSAJES_ERROR.obligatorio - : tipo === 'persona' && docTipo === 'DNI' && !isValidDni(docNumero) - ? MENSAJES_ERROR.dniInvalid - : '', - - nacimiento: - tipo === 'persona' && nacimiento && esAdulto(nacimiento) - ? '' - : tipo === 'persona' - ? MENSAJES_ERROR.requisitoEdad - : '', - - // ! quitar cuando corrijamos signin - cuil: tipo === 'persona' && !cuil.trim() ? MENSAJES_ERROR.obligatorio : '', - - // Organización - razonSocial: tipo === 'organizacion' && !razonSocial.trim() ? MENSAJES_ERROR.obligatorio : '', - - // ! quitar cuando corrijamos signin - cuit: - tipo === 'organizacion' && !cuit.trim() - ? MENSAJES_ERROR.obligatorio - : tipo === 'organizacion' && !isValidCuit(cuit) - ? MENSAJES_ERROR.cuitInvalid - : '', + const dispatch = createEventDispatcher(); - repNombre: - tipo === 'organizacion' && !repNombre.trim() - ? MENSAJES_ERROR.obligatorio - : tipo === 'organizacion' && !validarNombre(repNombre) - ? MENSAJES_ERROR.nombreInvalido - : '', + type ColaboradorFormData = Pick< + Usuario, + 'username' | 'nombre' | 'apellido' | 'fecha_nacimiento' | 'url_foto' + > & + Pick; - repApellido: - tipo === 'organizacion' && !repApellido.trim() - ? MENSAJES_ERROR.obligatorio - : tipo === 'organizacion' && !validarApellido(repApellido) - ? MENSAJES_ERROR.apellidoInvalido - : '', + type OrganizacionFormData = Pick & { + con_fines_de_lucro: boolean | null; + }; - repDocOtro: - tipo === 'organizacion' && repDocTipo === 'Otro' && !repDocOtro.trim() - ? MENSAJES_ERROR.specifyDocument - : '', + let enviando = false; + let intentoEnvio = false; + let tipoColaborador: 'unipersonal' | 'organizacion' = 'unipersonal'; + let archivoFoto: File | null = null; + + let colaborador: ColaboradorFormData = { + username: '', + nombre: '', + apellido: '', + fecha_nacimiento: undefined, + url_foto: '', + tipo_colaborador: 'unipersonal' + }; - repDocNumero: - tipo === 'organizacion' && !repDocNumero.trim() - ? MENSAJES_ERROR.obligatorio - : tipo === 'organizacion' && repDocTipo === 'DNI' && !isValidDni(repDocNumero) - ? MENSAJES_ERROR.dniInvalid - : '', + let fechaNacimiento: Date | null = null; + let organizacion: OrganizacionFormData = { + razon_social: '', + con_fines_de_lucro: null + }; + let conFinesDeLucroSeleccion = ''; - repNacimiento: - tipo === 'organizacion' && repNacimiento && esAdulto(repNacimiento) - ? '' - : tipo === 'organizacion' - ? MENSAJES_ERROR.requisitoEdad - : '', + $: colaborador.tipo_colaborador = tipoColaborador; + $: colaborador.fecha_nacimiento = fechaNacimiento ?? undefined; + $: organizacion.con_fines_de_lucro = + conFinesDeLucroSeleccion === '' ? null : conFinesDeLucroSeleccion === 'true'; - // Credenciales - username: !username.trim() + $: errores = { + username: !colaborador.username.trim() ? MENSAJES_ERROR.obligatorio - : !validarUsername(username) + : !validarUsername(colaborador.username) ? MENSAJES_ERROR.usuarioInvalido : '', - - email: !email.trim() + nombre: !colaborador.nombre.trim() ? MENSAJES_ERROR.obligatorio - : !validarCorreo(email) - ? MENSAJES_ERROR.correoInvalido + : !validarNombre(colaborador.nombre) + ? MENSAJES_ERROR.nombreInvalido : '', - - password: - password.length < 8 - ? MENSAJES_ERROR.requisitosContrasena - : !validarContrasena(password) - ? MENSAJES_ERROR.requisitosContrasena - : '', - - repassword: repassword !== password ? MENSAJES_ERROR.contrasenasNoCoinciden : '' + apellido: !colaborador.apellido.trim() + ? MENSAJES_ERROR.obligatorio + : !validarApellido(colaborador.apellido) + ? MENSAJES_ERROR.apellidoInvalido + : '', + fecha_nacimiento: + fechaNacimiento && esAdulto(fechaNacimiento) ? '' : MENSAJES_ERROR.requisitoEdad, + url_foto: archivoFoto + ? '' + : colaborador.url_foto.trim() + ? validarUrl(colaborador.url_foto.trim()) + ? '' + : MENSAJES_ERROR.urlInvalida + : '', + razon_social: + tipoColaborador === 'organizacion' + ? !organizacion.razon_social.trim() + ? MENSAJES_ERROR.obligatorio + : '' + : '', + con_fines_de_lucro: + tipoColaborador === 'organizacion' + ? organizacion.con_fines_de_lucro === null + ? MENSAJES_ERROR.obligatorio + : '' + : '' }; $: tieneErrores = Object.values(errores).some((error) => error !== ''); @@ -160,361 +103,176 @@ event.preventDefault(); intentoEnvio = true; if (tieneErrores) { - setTimeout(() => { - const primerError = document.querySelector('.border-red-400, .ring-red-400'); - if (primerError && typeof primerError.scrollIntoView === 'function') { - primerError.scrollIntoView({ behavior: 'smooth', block: 'center' }); - (primerError as HTMLElement).focus?.(); - } - }, 50); + enfocarPrimerCampoConError(); return; } - enviando = true; + enviando = true; setTimeout(() => { enviando = false; - dispatch('submit'); - }, 1200); + dispatch('submit', { colaborador, organizacion, archivoFoto }); + }, 800); }
-

- Registro de colaborador/a -

-

- Completá tus datos personales o los de tu organización para sumarte a iniciativas solidarias. -

- - -
- - -
- - -
- - -
- - -
- - -
- {/if} - - -
- - -
- - -
- - -
- - -
- - -
- - {:else} - -
-
- - +

+ Registro de colaborador/a +

+

+ Elegí si actuás como persona física o en representación de una organización y completá tus + datos. +

+ + +
+ + Tipo de colaborador/a * + +
+
- -
- - Unipersonal + + Sos una persona física que colabora con proyectos solidarios. + + +
-
- {/if} + Organización + + Representás a una entidad que ofrece recursos o acompañamiento. + + + + - -
+
- +
- - +
- -
-
+ {#if tipoColaborador === 'organizacion'} +
+ Datos de la organización
-
- - -
- -
-
+
{/if} -
diff --git a/frontend/src/lib/components/registro/FotoPerfilUploader.svelte b/frontend/src/lib/components/registro/FotoPerfilUploader.svelte new file mode 100644 index 00000000..2b03691f --- /dev/null +++ b/frontend/src/lib/components/registro/FotoPerfilUploader.svelte @@ -0,0 +1,315 @@ + + +
+ + {label} + {#if optionalLabel} + {optionalLabel} + {/if} + +
+
+

{helperText}

+
+ {#each botonesModo as boton} + + {/each} +
+
+ + {#if modoActivo === 'url'} +
+ + +
+ {:else} +
+ + + + +
+ {/if} + + {#if vistaPrevia} +
+
+
+ Vista previa de la foto seleccionada +
+
+

+ {file?.name ?? 'Vista previa desde URL externa'} +

+

+ {file ? 'Origen: archivo cargado manualmente.' : 'Origen: enlace proporcionado.'} +

+
+
+
+ +
+
+ {/if} + + {#if mensajeErrorGlobal} + + {/if} + + {#if mensajeEstado} +

{mensajeEstado}

+ {/if} +
+
diff --git a/frontend/src/lib/components/registro/InstitucionForm.svelte b/frontend/src/lib/components/registro/InstitucionForm.svelte index 7f11cdc5..7dddaf69 100644 --- a/frontend/src/lib/components/registro/InstitucionForm.svelte +++ b/frontend/src/lib/components/registro/InstitucionForm.svelte @@ -2,113 +2,89 @@ import Input from '$lib/components/ui/Input.svelte'; import DatePicker from '$lib/components/ui/elementos/DatePicker.svelte'; import Button from '$lib/components/ui/elementos/Button.svelte'; - import Select from '$lib/components/ui/elementos/Select.svelte'; + import FotoPerfilUploader from '$lib/components/registro/FotoPerfilUploader.svelte'; import { createEventDispatcher } from 'svelte'; - const dispatch = createEventDispatcher(); - import { - validarCorreo, - validarContrasena, validarUsername, - isValidCuit, - esAdulto, validarNombre, validarApellido, - isValidDni, + esAdulto, + validarUrl, MENSAJES_ERROR } from '$lib/utils/validaciones'; + import type { Usuario, Institucion as InstitucionTipo } from '$lib/types/Usuario'; + import { enfocarPrimerCampoConError } from '$lib/utils/forms'; + + const dispatch = createEventDispatcher(); + + type InstitucionFormData = Pick< + Usuario, + 'username' | 'nombre' | 'apellido' | 'fecha_nacimiento' | 'url_foto' + > & + Pick; - // Estados iniciales let enviando = false; - let mostrarPassword = false; - let mostrarRepassword = false; let intentoEnvio = false; + let archivoFoto: File | null = null; - let institucion = { - nombre: '', - tipo: 'Escuela', - otroTipo: '', + let institucion: InstitucionFormData = { username: '', - email: '', - cuit: '', // ! quitar cuando corrijamos signin - password: '', - repassword: '' + nombre: '', + apellido: '', + fecha_nacimiento: undefined, + url_foto: '', + nombre_legal: '', + tipo_institucion: 'escuela' }; - let representante = { - repNombre: '', - repApellido: '', - repDocTipo: 'DNI', - repDocOtro: '', - repDocNumero: '', - repNacimiento: null - }; + let fechaNacimiento: Date | null = null; + const opcionesTipoInstitucion: Array<{ value: string; label: string }> = [ + { value: 'escuela', label: 'Escuela' }, + { value: 'hospital', label: 'Hospital' }, + { value: 'comedor', label: 'Comedor comunitario' }, + { value: 'fundacion', label: 'Fundación' }, + { value: 'iglesia', label: 'Iglesia' }, + { value: 'otro', label: 'Otro' } + ]; + let opcionTipoInstitucion: (typeof opcionesTipoInstitucion)[number]['value'] = 'escuela'; + let tipoInstitucionPersonalizado = ''; + + $: institucion.fecha_nacimiento = fechaNacimiento ?? undefined; + $: institucion.tipo_institucion = + opcionTipoInstitucion === 'otro' ? tipoInstitucionPersonalizado.trim() : opcionTipoInstitucion; $: errores = { - nombre: institucion.nombre.trim() - ? validarNombre(institucion.nombre) - ? '' - : MENSAJES_ERROR.nombreInvalido - : MENSAJES_ERROR.obligatorio, - - otroTipo: - institucion.tipo === 'Otro' && institucion.otroTipo.trim() === '' - ? MENSAJES_ERROR.tipoInstitucionObligatorio - : '', - username: !institucion.username.trim() ? MENSAJES_ERROR.obligatorio : !validarUsername(institucion.username) ? MENSAJES_ERROR.usuarioInvalido : '', - - email: !institucion.email.trim() - ? MENSAJES_ERROR.obligatorio - : !validarCorreo(institucion.email) - ? MENSAJES_ERROR.correoInvalido - : '', - - // ! quitar cuando corrijamos signin - cuit: - institucion.cuit.trim() && isValidCuit(institucion.cuit) ? '' : MENSAJES_ERROR.cuitInvalid, - - password: - institucion.password.length < 8 - ? MENSAJES_ERROR.requisitosContrasena - : !validarContrasena(institucion.password) - ? MENSAJES_ERROR.requisitosContrasena - : '', - - repassword: - institucion.repassword !== institucion.password ? MENSAJES_ERROR.contrasenasNoCoinciden : '', - - repNombre: !representante.repNombre.trim() + nombre: !institucion.nombre.trim() ? MENSAJES_ERROR.obligatorio - : !validarNombre(representante.repNombre) + : !validarNombre(institucion.nombre) ? MENSAJES_ERROR.nombreInvalido : '', - - repApellido: !representante.repApellido.trim() + apellido: !institucion.apellido.trim() ? MENSAJES_ERROR.obligatorio - : !validarApellido(representante.repApellido) + : !validarApellido(institucion.apellido) ? MENSAJES_ERROR.apellidoInvalido : '', - - repDocOtro: - representante.repDocTipo === 'Otro' && representante.repDocOtro.trim() === '' - ? MENSAJES_ERROR.specifyDocument + fecha_nacimiento: + fechaNacimiento && esAdulto(fechaNacimiento) ? '' : MENSAJES_ERROR.requisitoEdad, + url_foto: archivoFoto + ? '' + : institucion.url_foto.trim() + ? validarUrl(institucion.url_foto.trim()) + ? '' + : MENSAJES_ERROR.urlInvalida : '', - - repDocNumero: !representante.repDocNumero.trim() - ? MENSAJES_ERROR.obligatorio - : representante.repDocTipo === 'DNI' && !isValidDni(representante.repDocNumero) - ? MENSAJES_ERROR.dniInvalid - : '', - - repNacimiento: - representante.repNacimiento && esAdulto(new Date(representante.repNacimiento)) - ? '' - : MENSAJES_ERROR.requisitoEdad + nombre_legal: !institucion.nombre_legal.trim() ? MENSAJES_ERROR.obligatorio : '', + tipo_institucion: + opcionTipoInstitucion === 'otro' + ? tipoInstitucionPersonalizado.trim() + ? '' + : MENSAJES_ERROR.tipoInstitucionObligatorio + : '' }; $: tieneErrores = Object.values(errores).some((error) => error !== ''); @@ -117,331 +93,147 @@ event.preventDefault(); intentoEnvio = true; if (tieneErrores) { - setTimeout(() => { - const primerError = document.querySelector('.border-red-400, .ring-red-400'); - if (primerError && typeof primerError.scrollIntoView === 'function') { - primerError.scrollIntoView({ behavior: 'smooth', block: 'center' }); - (primerError as HTMLElement).focus?.(); - } - }, 50); + enfocarPrimerCampoConError(); return; } - enviando = true; + enviando = true; setTimeout(() => { enviando = false; - dispatch('submit'); - }, 1200); + dispatch('submit', { institucion, archivoFoto }); + }, 800); }
-

- Registro de institución -

-

- Completá los datos de tu organización para comenzar a publicar proyectos solidarios. -

- - -
- +
+

+ Registro de institución +

+

+ Ingresá los datos del representante legal y la información básica de la institución para + continuar. +

+
+ +
-
-
- - -
- {/if} - -
-
-
-
-
-
- -
-
- - -
- - - - - - Datos del representante legal - - -
- -
- - -
- - -
- - -
- - -
- - -
- {/if} - - -
- - -
+ {/each} +
- + {#if opcionTipoInstitucion === 'otro'}
-
-
-
+ {/if} + -
diff --git a/frontend/src/lib/utils/forms.ts b/frontend/src/lib/utils/forms.ts new file mode 100644 index 00000000..d3e94900 --- /dev/null +++ b/frontend/src/lib/utils/forms.ts @@ -0,0 +1,10 @@ +/** + * Enfoca y desplaza suavemente al primer campo marcado como error. + * @param selector Selector CSS que identifica campos con error visual. + */ +export function enfocarPrimerCampoConError(selector = '.border-red-400, .ring-red-400'): void { + const primerError = document.querySelector(selector); + if (!(primerError instanceof HTMLElement)) return; + primerError.scrollIntoView({ behavior: 'smooth', block: 'center' }); + primerError.focus?.(); +} \ No newline at end of file From fbf788ac874815505c24aeb50dd77b1cdb871684 Mon Sep 17 00:00:00 2001 From: Marina Milo Date: Thu, 2 Oct 2025 21:38:39 -0300 Subject: [PATCH 02/13] fix: improve button accessibility with aria attributes and error handling --- .../lib/components/registro/ColaboradorForm.svelte | 6 +++++- .../lib/components/registro/InstitucionForm.svelte | 6 +++++- .../src/lib/components/ui/elementos/Button.svelte | 12 +++++++----- 3 files changed, 17 insertions(+), 7 deletions(-) diff --git a/frontend/src/lib/components/registro/ColaboradorForm.svelte b/frontend/src/lib/components/registro/ColaboradorForm.svelte index 14a7ed17..dfe462d2 100644 --- a/frontend/src/lib/components/registro/ColaboradorForm.svelte +++ b/frontend/src/lib/components/registro/ColaboradorForm.svelte @@ -271,7 +271,11 @@
diff --git a/frontend/src/lib/components/registro/InstitucionForm.svelte b/frontend/src/lib/components/registro/InstitucionForm.svelte index 7dddaf69..901fbeb1 100644 --- a/frontend/src/lib/components/registro/InstitucionForm.svelte +++ b/frontend/src/lib/components/registro/InstitucionForm.svelte @@ -232,7 +232,11 @@
diff --git a/frontend/src/lib/components/ui/elementos/Button.svelte b/frontend/src/lib/components/ui/elementos/Button.svelte index db24ed75..6642d017 100644 --- a/frontend/src/lib/components/ui/elementos/Button.svelte +++ b/frontend/src/lib/components/ui/elementos/Button.svelte @@ -15,9 +15,11 @@ export let customClass = ''; export let customAriaLabel: string | null = null; export let type: 'button' | 'submit' | 'reset' = 'submit'; + export let ariaDisabled: boolean | undefined = undefined; $: ariaLabel = customAriaLabel ?? (href ? `Ir a ${href}` : undefined); $: isDisabled = disabled || loading; $: busyLabel = loadingLabel ?? label; + $: computedAriaDisabled = ariaDisabled ?? isDisabled; const dispatch = createEventDispatcher(); function handleClick(event: MouseEvent) { @@ -58,7 +60,7 @@ tabindex="0" aria-label={ariaLabel} aria-busy={loading || undefined} - aria-disabled={isDisabled} + aria-disabled={computedAriaDisabled} disabled={isDisabled} > @@ -84,7 +86,7 @@ {:else} @@ -127,7 +129,7 @@ tabindex="0" aria-label={ariaLabel} aria-busy={loading || undefined} - aria-disabled={isDisabled} + aria-disabled={computedAriaDisabled} disabled={isDisabled} > @@ -153,7 +155,7 @@ {:else} @@ -198,7 +200,7 @@ tabindex="0" aria-label={ariaLabel} aria-busy={loading || undefined} - aria-disabled={isDisabled} + aria-disabled={computedAriaDisabled} disabled={isDisabled} > {#if loading} From a1d0013343b779b7af788c23d806add1d3bb5826 Mon Sep 17 00:00:00 2001 From: Marina Milo Date: Thu, 2 Oct 2025 22:04:12 -0300 Subject: [PATCH 03/13] fix: synchronize date input changes with internal value handling --- .../components/ui/elementos/DatePicker.svelte | 41 +++++++++++++++---- 1 file changed, 34 insertions(+), 7 deletions(-) diff --git a/frontend/src/lib/components/ui/elementos/DatePicker.svelte b/frontend/src/lib/components/ui/elementos/DatePicker.svelte index f66894d2..0964bbe7 100644 --- a/frontend/src/lib/components/ui/elementos/DatePicker.svelte +++ b/frontend/src/lib/components/ui/elementos/DatePicker.svelte @@ -8,8 +8,8 @@ export let error = ''; let internal = ''; + let ultimaCadenaProcesada: string | null = null; - // Formatea Date -> "YYYY-MM-DD" function formatForInput(d: Date | null): string { if (!d) return ''; const year = d.getFullYear(); @@ -18,14 +18,41 @@ return `${year}-${month}-${day}`; } - // sincroniza cambios del padre -> input + function actualizarValorDesdeCadena(cadena: string): Date | null { + if (!cadena) { + value = null; + return null; + } + + const fecha = new Date(`${cadena}T00:00:00`); + if (Number.isNaN(fecha.getTime())) { + value = null; + return null; + } + + value = fecha; + return fecha; + } + $: internal = formatForInput(value); - // convierte cambios del input -> Date - function onChange(e: Event) { - const v = (e.target as HTMLInputElement).value; - value = v ? new Date(v + 'T00:00:00') : null; + $: if (internal !== ultimaCadenaProcesada) { + ultimaCadenaProcesada = internal; + actualizarValorDesdeCadena(internal); + } + + function handleEntrada(e: Event) { + actualizarValorDesdeCadena((e.target as HTMLInputElement).value); } - + From 8497f0e5c25da0df4a9b218f145b46f517a1487e Mon Sep 17 00:00:00 2001 From: Marina Milo Date: Thu, 2 Oct 2025 22:28:40 -0300 Subject: [PATCH 04/13] fix: enhance radio button accessibility and styling in forms --- .../registro/ColaboradorForm.svelte | 44 ++++++++++------- .../registro/FotoPerfilUploader.svelte | 2 +- .../registro/InstitucionForm.svelte | 30 +++++++----- frontend/src/lib/utils/validaciones.ts | 47 ------------------- frontend/src/routes/registrarse/+page.svelte | 4 +- 5 files changed, 47 insertions(+), 80 deletions(-) diff --git a/frontend/src/lib/components/registro/ColaboradorForm.svelte b/frontend/src/lib/components/registro/ColaboradorForm.svelte index dfe462d2..15937aca 100644 --- a/frontend/src/lib/components/registro/ColaboradorForm.svelte +++ b/frontend/src/lib/components/registro/ColaboradorForm.svelte @@ -131,36 +131,44 @@ Tipo de colaborador/a *
-
diff --git a/frontend/src/lib/components/registro/FotoPerfilUploader.svelte b/frontend/src/lib/components/registro/FotoPerfilUploader.svelte index 2b03691f..03c15df4 100644 --- a/frontend/src/lib/components/registro/FotoPerfilUploader.svelte +++ b/frontend/src/lib/components/registro/FotoPerfilUploader.svelte @@ -189,7 +189,7 @@ - - - - {#if urlGoogleMaps && !editandoUrlMapaGoogle} -
-
- + +
+ + + {#if urlGoogleMaps && !editandoUrlMapaGoogle} +
+
+ +
+
+ {/if} {/if} diff --git a/frontend/src/lib/components/ui/Stepper.svelte b/frontend/src/lib/components/ui/Stepper.svelte index 64150668..d5b41f67 100644 --- a/frontend/src/lib/components/ui/Stepper.svelte +++ b/frontend/src/lib/components/ui/Stepper.svelte @@ -1,12 +1,12 @@ diff --git a/frontend/src/lib/components/validaciones/ValidacionInstitucion.svelte b/frontend/src/lib/components/validaciones/ValidacionInstitucion.svelte index d512f51b..975005c8 100644 --- a/frontend/src/lib/components/validaciones/ValidacionInstitucion.svelte +++ b/frontend/src/lib/components/validaciones/ValidacionInstitucion.svelte @@ -19,6 +19,8 @@ let aceptoDeclaracion = false; let errorFormulario: string | null = null; + $: botonEnviarDeshabilitado = !aceptoDeclaracion; + const renaperDisponible = false; function actualizarArchivos(event: Event) { @@ -236,6 +238,8 @@ label="Enviar" on:click={enviarDocumentos} customClass="w-full sm:w-auto" + disabled={botonEnviarDeshabilitado} + ariaDisabled={botonEnviarDeshabilitado} /> diff --git a/frontend/src/routes/registrarse/+page.svelte b/frontend/src/routes/registrarse/+page.svelte index 98d6b8bd..d9551a6e 100644 --- a/frontend/src/routes/registrarse/+page.svelte +++ b/frontend/src/routes/registrarse/+page.svelte @@ -191,7 +191,7 @@ {#if etapa === 'select'}
- +

Unite a @@ -232,7 +232,7 @@

{:else if etapa === 'form'}
- +