Files
perfil/nuxt4/app/components/auth/EditProfileButton.vue
josedario87 ca3b23c1d3
All checks were successful
build-and-deploy / build-and-deploy (push) Successful in 52s
Fix: Agregar v-if al modal de editar perfil para evitar clicks inesperados
Se agregó v-if="isOpen" al UModal para que solo se renderice en el DOM cuando
esté abierto. Esto soluciona el problema de que el modal se activaba al hacer
clic en áreas vacías del componente.
2025-10-16 20:21:53 -06:00

161 lines
3.7 KiB
Vue

<template>
<UButton
icon="i-heroicons-pencil-square"
color="primary"
variant="soft"
:loading="isLoading"
@click="openModal"
>
Editar Perfil
</UButton>
<UModal v-if="isOpen" v-model="isOpen">
<UCard>
<template #header>
<div class="flex items-center justify-between">
<h3 class="text-lg font-semibold">Editar Perfil</h3>
<UButton
color="neutral"
variant="ghost"
icon="i-heroicons-x-mark"
@click="isOpen = false"
/>
</div>
</template>
<form @submit.prevent="updateProfile" class="space-y-4">
<UFormGroup label="Nombre Completo" name="name">
<UInput
v-model="formData.name"
placeholder="Tu nombre completo"
:disabled="isUpdating"
/>
</UFormGroup>
<UFormGroup label="Email" name="email">
<UInput
v-model="formData.email"
type="email"
placeholder="tu@email.com"
:disabled="isUpdating"
/>
</UFormGroup>
<UFormGroup label="Username" name="username">
<UInput
v-model="formData.username"
disabled
:ui="{ base: 'cursor-not-allowed opacity-50' }"
/>
<template #help>
<span class="text-xs text-gray-500">El username no se puede cambiar</span>
</template>
</UFormGroup>
</form>
<template #footer>
<div class="flex justify-end gap-2">
<UButton
color="neutral"
variant="ghost"
:disabled="isUpdating"
@click="isOpen = false"
>
Cancelar
</UButton>
<UButton
color="primary"
:loading="isUpdating"
@click="updateProfile"
>
Guardar Cambios
</UButton>
</div>
</template>
</UCard>
</UModal>
</template>
<script setup lang="ts">
const { user } = useAuthentik()
const toast = useToast()
const isOpen = ref(false)
const isLoading = ref(false)
const isUpdating = ref(false)
const formData = ref({
name: '',
email: '',
username: ''
})
const openModal = async () => {
isLoading.value = true
try {
// Obtener información del usuario desde Authentik
const userData = await $fetch<{
name?: string
email?: string
username?: string
}>('/api/authentik/user')
formData.value = {
name: userData.name || '',
email: userData.email || '',
username: userData.username || ''
}
isOpen.value = true
} catch (error: any) {
toast.add({
title: 'Error',
description: error.message || 'No se pudo cargar la información del usuario',
color: 'error',
icon: 'i-heroicons-x-circle'
})
} finally {
isLoading.value = false
}
}
const updateProfile = async () => {
isUpdating.value = true
try {
await $fetch('/api/authentik/user', {
method: 'PATCH',
body: {
name: formData.value.name,
email: formData.value.email
}
})
toast.add({
title: 'Perfil Actualizado',
description: 'Los cambios se han guardado correctamente. Recarga la página para verlos.',
color: 'success',
icon: 'i-heroicons-check-circle',
actions: [{
label: 'Recargar',
onClick: () => {
window.location.reload()
}
}]
})
isOpen.value = false
} catch (error: any) {
toast.add({
title: 'Error',
description: error.message || 'No se pudo actualizar el perfil',
color: 'error',
icon: 'i-heroicons-x-circle'
})
} finally {
isUpdating.value = false
}
}
</script>