158 lines
4.9 KiB
Vue
158 lines
4.9 KiB
Vue
<script setup lang="ts">
|
|
// imports
|
|
|
|
import useUpdateAccount from "~/composables/api/account/useUpdateAccount";
|
|
import { useToast } from "~/composables/global/useToast";
|
|
|
|
// types
|
|
|
|
type Props = {
|
|
modelValue: File | null;
|
|
isShow: boolean;
|
|
};
|
|
|
|
type Emits = {
|
|
"update:modelValue": [value: File];
|
|
"update:isShow": [value: boolean];
|
|
};
|
|
|
|
// props
|
|
|
|
const props = defineProps<Props>();
|
|
|
|
const { modelValue, isShow } = toRefs(props);
|
|
|
|
// emits
|
|
|
|
const emit = defineEmits<Emits>();
|
|
|
|
// state
|
|
|
|
const visible = computed({
|
|
get: () => isShow.value ?? false,
|
|
set: (value: boolean) => emit("update:isShow", value),
|
|
});
|
|
|
|
const { addToast } = useToast();
|
|
|
|
const {
|
|
open: openFileDialog,
|
|
reset: resetFileDialog,
|
|
onChange: onFileDialogChange,
|
|
} = useFileDialog({
|
|
accept: ".jpg, .jpeg, .png",
|
|
directory: false,
|
|
});
|
|
|
|
const avatars = ref([
|
|
"/img/avatars/1.jpg",
|
|
"/img/avatars/2.jpg",
|
|
"/img/avatars/3.jpg",
|
|
"/img/avatars/4.jpg",
|
|
"/img/avatars/5.jpg",
|
|
]);
|
|
|
|
// queries
|
|
|
|
const { isPending: updateAccountIsPending } = useUpdateAccount();
|
|
|
|
// computed
|
|
|
|
const currentProfile = computed({
|
|
get: () =>
|
|
!!modelValue.value ? URL.createObjectURL(modelValue.value) : null,
|
|
set: (value: File) => emit("update:modelValue", value),
|
|
});
|
|
|
|
// methods
|
|
|
|
onFileDialogChange((files: any) => {
|
|
const file = files[0];
|
|
|
|
if (file.size > 2 * 1024 * 1024) {
|
|
addToast({
|
|
message: "محدودیت حجم فایل حداکثر ۲ مگابایت می باشد",
|
|
options: {
|
|
status: "error",
|
|
},
|
|
});
|
|
return;
|
|
}
|
|
emit("update:modelValue", file);
|
|
resetFileDialog();
|
|
});
|
|
</script>
|
|
|
|
<template>
|
|
<Modal v-model="visible" title="عکس پروفایل" icon="bi:image" iconSize="20">
|
|
<template #trigger>
|
|
<button
|
|
class="bg-black text-slate-100 rounded-full p-2 flex-center absolute -bottom-0 -right-0"
|
|
>
|
|
<Icon name="bi:pencil" class="**:fill-slate-100" size="12" />
|
|
</button>
|
|
</template>
|
|
<template #content>
|
|
<div class="w-max">
|
|
<div
|
|
class="w-full flex flex-col-reverse items-center justify-between py-10 gap-10 px-4"
|
|
>
|
|
<div
|
|
class="flex items-center justify-between w-full flex-wrap gap-4 max-w-[500px]"
|
|
>
|
|
<button
|
|
v-for="(avatar, index) in avatars"
|
|
:key="index"
|
|
class="size-20 rounded-full focus:ring-2 focus:ring-offset-1 focus:ring-black transition-all"
|
|
>
|
|
<Avatar
|
|
:src="avatar"
|
|
:alt="`avatar-${index}`"
|
|
class="size-full"
|
|
/>
|
|
</button>
|
|
</div>
|
|
|
|
<div
|
|
class="w-full flex-center gap-4 max-w-[500px] flex-wrap"
|
|
>
|
|
<button
|
|
class="size-8 rounded-full bg-orange-100 whitespace-nowrap ring-2 hover:ring-black ring-slate-200 ring-offset-3"
|
|
/>
|
|
<button
|
|
class="size-8 rounded-full bg-orange-200 whitespace-nowrap ring-2 hover:ring-black ring-slate-200 ring-offset-3"
|
|
/>
|
|
<button
|
|
class="size-8 rounded-full bg-amber-600 whitespace-nowrap ring-2 hover:ring-black ring-slate-200 ring-offset-3"
|
|
/>
|
|
<button
|
|
class="size-8 rounded-full bg-amber-700 whitespace-nowrap ring-2 hover:ring-black ring-slate-200 ring-offset-3"
|
|
/>
|
|
<button
|
|
class="size-8 rounded-full bg-amber-800 whitespace-nowrap ring-2 hover:ring-black ring-slate-200 ring-offset-3"
|
|
/>
|
|
</div>
|
|
|
|
<div class="w-full flex-col-center gap-5">
|
|
<Avatar :src="currentProfile" alt="" class="!size-32" />
|
|
<Button
|
|
class="rounded-full w-[8rem]"
|
|
@click="openFileDialog"
|
|
:loading="updateAccountIsPending"
|
|
size="md"
|
|
>
|
|
<Icon
|
|
v-if="updateAccountIsPending"
|
|
name="svg-spinners:3-dots-bounce"
|
|
/>
|
|
<span v-else>آپلود عکس شما</span>
|
|
</Button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
</Modal>
|
|
</template>
|
|
|
|
<style scoped></style>
|