added file input

This commit is contained in:
Mamalizz
2025-02-18 23:39:53 +03:30
parent 15dae7f04c
commit 2d268801ed
+144
View File
@@ -0,0 +1,144 @@
<script setup lang="ts">
// imports
import { useToast } from "~/composables/global/useToast";
// types
type Props = {
modelValue: File[];
};
type Emits = {
"update:modelValue": [value: any];
};
// props
const props = defineProps<Props>();
const { modelValue } = toRefs(props);
// emits
const emit = defineEmits<Emits>();
// state
const { addToast } = useToast();
const dropZoneRef = ref<HTMLDivElement>();
const fileLimit = 1024 * 1024 * 2;
// methods
const onDrop = (files: File[] | null) => {
if (modelValue.value.length < 3) {
files?.forEach((file, index) => {
if (file.size > fileLimit) {
files.splice(index, 1);
addToast({
message: "حداکثر حجم فایل 2 مگابایت می باشد",
options: {
status: "error",
},
});
}
});
if (files.length > 3) {
emit("update:modelValue", [...files.slice(0, 3)]);
} else {
if (modelValue.value.length + files.length <= 3) {
files?.forEach((item) => {
emit("update:modelValue", [...modelValue.value, item]);
});
} else {
addToast({
message: `مجاز به آپلود ${
3 - modelValue.value.length
} فایل دیگر هستید`,
options: {
status: "error",
},
});
}
}
} else {
addToast({
message: "محدودیت تعداد را رعایت کنید",
options: {
status: "error",
},
});
}
};
const { isOverDropZone } = useDropZone(dropZoneRef, {
onDrop,
dataTypes: ["image/jpeg", "image/png", "image/jpg"],
});
const { open: openDialog, onChange } = useFileDialog({
accept: "image/*",
directory: false,
});
onChange((files: any) => {
let arr: File[] = [];
Object.keys(files).forEach((item) => {
arr.push(files[item]);
});
onDrop(arr);
});
const deleteFile = (index: number) => {
const clone = [...modelValue.value];
clone.splice(index, 1);
emit("update:modelValue", clone);
};
</script>
<template>
<div class="flex flex-col w-full h-max gap-5 pt-8">
<div
ref="dropZoneRef"
@click="openDialog"
class="bg-slate-50 flex-col-center w-full transition-all text-black/50 gap-3 h-[20rem] border border-dashed rounded-xl cursor-pointer select-none"
:class="isOverDropZone ? 'border-black' : ' border-slate-300'"
>
<Icon name="bi:file-earmark-arrow-down" size="32" />
<p class="font-bold text-dynamic-primary text-sm lg:text-[1rem]">
برای آپلود کلیک کنید یا فایل خود را اینجا بیاندازید
</p>
<p class="text-xs font-semibold">فرمت مجاز : jpg, png, jpeg</p>
<p class="text-xs font-semibold">تعداد فایل مجاز : 3 عدد</p>
<p class="text-xs font-semibold">حداکثر حجم فایل : 2 مگابایت</p>
</div>
<ul
v-for="(item, index) in modelValue"
:key="index"
v-auto-animate
class="flex flex-row-reverse items-center justify-between w-full px-2 animate__animated animate__fadeIn"
>
<li class="w-full flex items-center">
<div class="flex justify-end w-9/12">
<p class="text-sm text-black">{{ item.name }}</p>
</div>
<div class="w-2/12">
<p class="text-sm text-black">
{{ (item.size / 1024).toFixed(2) }}KB
</p>
</div>
<div class="w-1/12">
<Icon
name="ci:close"
class="**:stroke-red-500 cursor-pointer pb-1"
@click="deleteFile(index)"
size="28"
/>
</div>
</li>
</ul>
</div>
</template>