All checks were successful
build-and-deploy / build-and-deploy (push) Successful in 52s
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.
161 lines
3.7 KiB
Vue
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>
|