58 lines
1.2 KiB
Vue
58 lines
1.2 KiB
Vue
<template>
|
|
<div class="flex flex-wrap items-center gap-3">
|
|
<ProfileAvatar
|
|
size="lg"
|
|
/>
|
|
<UButton
|
|
:label="$t('profile.choose')"
|
|
color="neutral"
|
|
:loading="uploading"
|
|
@click="onFileClick"
|
|
/>
|
|
<input
|
|
ref="fileRef"
|
|
type="file"
|
|
class="hidden"
|
|
accept=".jpg, .jpeg, .png, .gif"
|
|
@change="onFileChange"
|
|
>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
const { t } = useI18n()
|
|
const toast = useToast()
|
|
|
|
const fileRef = ref<HTMLInputElement>()
|
|
const uploading = ref(false)
|
|
|
|
async function onFileChange(e: Event) {
|
|
const input = e.target as HTMLInputElement
|
|
|
|
const files = input.files
|
|
try {
|
|
uploading.value = true
|
|
if (!files || files.length === 0) {
|
|
throw new Error('You must select an image to upload.')
|
|
}
|
|
const file = files[0]
|
|
await useAvatar().uploadAvatar(file!)
|
|
|
|
toast.add({
|
|
title: t('profile.success'),
|
|
description: t('profile.avatarUploaded'),
|
|
icon: 'i-lucide-check',
|
|
color: 'success'
|
|
})
|
|
} catch (error) {
|
|
toast.add({ color: 'error', description: (error as Error).message })
|
|
} finally {
|
|
uploading.value = false
|
|
}
|
|
}
|
|
|
|
function onFileClick() {
|
|
fileRef.value?.click()
|
|
}
|
|
</script>
|