Files
web/app/components/media/FileUpload.vue
2026-05-15 15:50:40 +07:00

122 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-if="showmodal"
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>