143 lines
3.4 KiB
Vue
143 lines
3.4 KiB
Vue
<template>
|
|
<UForm
|
|
id="settings"
|
|
:schema="profileSchema"
|
|
:state="profile"
|
|
@submit="onSubmit"
|
|
>
|
|
<UPageCard
|
|
:title="$t('profile.title')"
|
|
:description="$t('profile.description')"
|
|
variant="naked"
|
|
orientation="horizontal"
|
|
class="mb-4"
|
|
>
|
|
<UButton
|
|
form="settings"
|
|
:label="$t('profile.save')"
|
|
color="neutral"
|
|
type="submit"
|
|
class="w-fit lg:ms-auto"
|
|
/>
|
|
</UPageCard>
|
|
|
|
<UPageCard variant="subtle">
|
|
<UFormField
|
|
name="name"
|
|
:label="$t('profile.name')"
|
|
:description="$t('profile.nameDescription')"
|
|
required
|
|
class="flex max-sm:flex-col justify-between items-start gap-4"
|
|
>
|
|
<UInput
|
|
v-model="profile.name"
|
|
autocomplete="off"
|
|
/>
|
|
</UFormField>
|
|
<USeparator />
|
|
<UFormField
|
|
name="email"
|
|
:label="$t('profile.email')"
|
|
:description="$t('profile.emailDescription')"
|
|
required
|
|
class="flex max-sm:flex-col justify-between items-start gap-4"
|
|
>
|
|
<UInput
|
|
:model-value="user?.email"
|
|
type="email"
|
|
autocomplete="off"
|
|
disabled
|
|
/>
|
|
</UFormField>
|
|
<USeparator />
|
|
<UFormField
|
|
name="avatar"
|
|
:label="$t('profile.avatar')"
|
|
:description="$t('profile.avatarDescription')"
|
|
class="flex max-sm:flex-col justify-between sm:items-center gap-4"
|
|
>
|
|
<ProfileAvatarUpload />
|
|
</UFormField>
|
|
<USeparator />
|
|
<UFormField
|
|
name="delete"
|
|
:label="$t('profile.delete')"
|
|
:description="$t('profile.deleteDescription')"
|
|
class="flex max-sm:flex-col justify-between sm:items-center gap-4"
|
|
>
|
|
<UModal
|
|
:title="$t('profile.delete')"
|
|
:description="$t('profile.deleteWarning')"
|
|
:ui="{ footer: 'justify-end' }"
|
|
:close="false"
|
|
>
|
|
<UButton
|
|
:label="$t('profile.delete')"
|
|
color="error"
|
|
/>
|
|
<template #footer="{ close }">
|
|
<UButton
|
|
:label="$t('cancel')"
|
|
color="neutral"
|
|
variant="outline"
|
|
@click="close"
|
|
/>
|
|
<UButton
|
|
:label="$t('profile.delete')"
|
|
color="error"
|
|
@click="onDelete"
|
|
/>
|
|
</template>
|
|
</UModal>
|
|
</UFormField>
|
|
</UPageCard>
|
|
</UForm>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import * as z from 'zod'
|
|
|
|
definePageMeta({
|
|
middleware: ['auth']
|
|
})
|
|
|
|
const { t } = useI18n()
|
|
const { user, updateUser, deleteUser } = useUser()
|
|
|
|
const profileSchema = z.object({
|
|
name: z.string().min(2, t('profile.tooShort'))
|
|
})
|
|
|
|
type ProfileSchema = z.output<typeof profileSchema>
|
|
const profile = reactive<Partial<ProfileSchema>>({
|
|
name: user?.name ?? ''
|
|
})
|
|
|
|
const toast = useToast()
|
|
async function onSubmit() {
|
|
try {
|
|
if (profile.name) {
|
|
await updateUser({ name: profile.name })
|
|
}
|
|
toast.add({
|
|
title: t('profile.success'),
|
|
description: t('profile.settingsUpdated'),
|
|
icon: 'i-lucide-check',
|
|
color: 'success'
|
|
})
|
|
} catch (error) {
|
|
toast.add({ color: 'error', description: (error as Error).message })
|
|
console.warn(error)
|
|
}
|
|
}
|
|
|
|
const onDelete = async () => {
|
|
try {
|
|
await deleteUser()
|
|
navigateTo('/')
|
|
} catch (error) {
|
|
toast.add({ color: 'error', description: (error as Error).message })
|
|
}
|
|
}
|
|
</script>
|