added file input
This commit is contained in:
@@ -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>
|
||||
Reference in New Issue
Block a user