121 lines
3.0 KiB
Vue
121 lines
3.0 KiB
Vue
<!-- TODO: extract logic to a composable -->
|
|
<template>
|
|
<div>
|
|
<div
|
|
id="ignore"
|
|
class="file is-primary"
|
|
>
|
|
<label
|
|
class="file-label"
|
|
v-bind="$attrs"
|
|
>
|
|
<input
|
|
class="file-input"
|
|
ref="file-input"
|
|
type="file"
|
|
:id="docid"
|
|
:multiple="multiple ?? true"
|
|
name="resume"
|
|
@change="doChange"
|
|
/>
|
|
<span class="file-cta px-3 py-1.5">
|
|
<span class="icon-text is-gap-0.5 is-align-items-center">
|
|
<slot name="icon">
|
|
<Icon
|
|
name="material-symbols:attach-file-rounded"
|
|
:size="20"
|
|
/>
|
|
</slot>
|
|
<slot />
|
|
</span>
|
|
</span>
|
|
</label>
|
|
</div>
|
|
<Modal
|
|
v-bind="showmodal"
|
|
@close="showmodal = undefined"
|
|
@files="getFiles"
|
|
/>
|
|
</div>
|
|
</template>
|
|
<script setup>
|
|
defineOptions({
|
|
inheritAttrs: false,
|
|
});
|
|
|
|
const props = defineProps({
|
|
type: Array,
|
|
convert: String,
|
|
quality: Number,
|
|
multiple: Boolean,
|
|
});
|
|
|
|
const emit = defineEmits(["files"]);
|
|
const { $id, $snackbar, $upload } = useNuxtApp();
|
|
|
|
const fileInput = useTemplateRef("file-input");
|
|
const vtype = props.type || ["image"];
|
|
const files = ref(); // files selected in <input>
|
|
const dataFiles = ref(); // files returned by $upload
|
|
const showmodal = ref();
|
|
const docid = $id();
|
|
|
|
function getFileExtension(fileName) {
|
|
if (!fileName || typeof fileName !== "string") return "";
|
|
const parts = fileName.split(".");
|
|
return parts.length > 1 ? parts.pop().toLowerCase() : "";
|
|
}
|
|
|
|
function getType(ext) {
|
|
// copied from 01-common.js
|
|
const imageFormat = ["png", "jpg", "jpeg", "bmp", "gif", "svg", "webp"];
|
|
const videoFormat = ["wmv", "avi", "mp4", "flv", "mov", "mpg", "amv", "rm"];
|
|
|
|
if (ext === "pdf") return "pdf";
|
|
if (imageFormat.includes(ext)) return "image";
|
|
if (videoFormat.includes(ext)) return "video";
|
|
return "file";
|
|
}
|
|
|
|
function doChange() {
|
|
if (fileInput.value.files.length === 0) return;
|
|
dataFiles.value = [];
|
|
files.value = Array.from(fileInput.value.files);
|
|
|
|
// Xác định giá trị convert: "1" nếu convert được bật, "0" nếu không
|
|
const convertValue = props.convert ? "1" : "0";
|
|
const qualityValue = props.convert && props.quality ? props.quality : null;
|
|
|
|
for (const file of files.value) {
|
|
const ext = getFileExtension(file.name);
|
|
const type = getType(ext);
|
|
|
|
if (!vtype.includes(type)) {
|
|
$snackbar(`Định dạng file "${ext}" không hợp lệ`);
|
|
fileInput.value.value = "";
|
|
return;
|
|
}
|
|
|
|
const dataFile = $upload(file, type, 1, convertValue, qualityValue);
|
|
dataFiles.value.push(dataFile);
|
|
}
|
|
|
|
showmodal.value = {
|
|
component: "media/UploadProgress",
|
|
title: "Upload Files",
|
|
width: "700px",
|
|
height: "auto",
|
|
vbind: { files: dataFiles.value },
|
|
};
|
|
|
|
fileInput.value.value = ""; // clear input
|
|
}
|
|
|
|
function getFiles(files) {
|
|
emit("files", files);
|
|
// setTimeout(() => {
|
|
// showmodal.value = undefined;
|
|
// }, 3000);
|
|
}
|
|
</script>
|