147 lines
4.0 KiB
Vue
147 lines
4.0 KiB
Vue
<template>
|
|
<div id="app">
|
|
<FilePond
|
|
ref="pond"
|
|
name="filepond-image"
|
|
:max-files="maxFiles"
|
|
store-as-file="true"
|
|
:server="{
|
|
process: {
|
|
url: API_URL + uploadEndpoint,
|
|
method: 'POST',
|
|
withCredentials: true,
|
|
headers: {
|
|
authorization: 'Bearer ' + Cookies.get('bm-token')
|
|
},
|
|
onload: (response) => handleProcessResponse(response)
|
|
},
|
|
revert: {
|
|
url: API_URL + deleteEndpoint,
|
|
method: 'DELETE',
|
|
withCredentials: true,
|
|
headers: {
|
|
authorization: 'Bearer ' + Cookies.get('bm-token')
|
|
},
|
|
onload: (response) => handleRevertResponse(response)
|
|
}
|
|
}"
|
|
label-idle="برای آپلود کلیک کنید"
|
|
label-tap-to-undo=" برای حذف کلیک کنید "
|
|
label-file-processing=" در حال آپلود "
|
|
label-file-processing-complete=" آپلود فایل تکمیل شد "
|
|
:allow-multiple="true"
|
|
v-model="uploadedFiles"
|
|
/>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup>
|
|
import { ref, watch, defineProps, computed } from 'vue';
|
|
import Cookies from 'js-cookie';
|
|
import vueFilePond from 'vue-filepond';
|
|
import 'filepond/dist/filepond.min.css';
|
|
import 'filepond-plugin-image-preview/dist/filepond-plugin-image-preview.min.css';
|
|
import FilePondPluginFileValidateType from 'filepond-plugin-file-validate-type';
|
|
import FilePondPluginImagePreview from 'filepond-plugin-image-preview';
|
|
|
|
// Define props
|
|
const props = defineProps({
|
|
uploadEndpoint: {
|
|
type: String,
|
|
required: true
|
|
},
|
|
deleteEndpoint: {
|
|
type: String,
|
|
required: true
|
|
},
|
|
maxFiles: {
|
|
type: Number,
|
|
default: 1
|
|
},
|
|
acceptedFiles: {
|
|
type: String,
|
|
default: ''
|
|
},
|
|
mode: {
|
|
type: String,
|
|
required: true,
|
|
default: 'public'
|
|
},
|
|
modelValue: {
|
|
type: Array,
|
|
required: false,
|
|
default: () => []
|
|
}
|
|
});
|
|
|
|
// Setup reactive variables
|
|
const API_URL = import.meta.env.VITE_API_URL;
|
|
const uploadedFiles = ref([...props.modelValue]);
|
|
|
|
// Define FilePond component
|
|
const FilePond = vueFilePond(FilePondPluginFileValidateType, FilePondPluginImagePreview);
|
|
const emit = defineEmits(['update:modelValue']);
|
|
|
|
// Handle server responses for file processing
|
|
function handleProcessResponse(response) {
|
|
const data = JSON.parse(response);
|
|
const fileName = data.data[0].fileRecord.fileName;
|
|
uploadedFiles.value.push(fileName);
|
|
emit('update:modelValue', uploadedFiles);
|
|
return fileName;
|
|
}
|
|
|
|
// Handle server responses for file revert
|
|
function handleRevertResponse(response) {
|
|
const data = JSON.parse(response);
|
|
const fileId = data.data.fileRecord.id;
|
|
|
|
// Find and remove the file name from uploadedFiles
|
|
const fileIndex = uploadedFiles.value.findIndex((name) => name === fileId);
|
|
if (fileIndex !== -1) {
|
|
uploadedFiles.value.splice(fileIndex, 1);
|
|
emit('update:modelValue', uploadedFiles);
|
|
}
|
|
|
|
return fileId;
|
|
}
|
|
</script>
|
|
|
|
<style>
|
|
/* Apply dark mode styles to FilePond component */
|
|
.filepond--root {
|
|
font-family: 'Estedad FD', sans-serif;
|
|
background-color: var(--surface-ground);
|
|
color: var(--text-color);
|
|
border-radius: 8px;
|
|
}
|
|
|
|
.app-dark .filepond--root {
|
|
background-color: var(--code-background);
|
|
border-radius: 8px;
|
|
}
|
|
|
|
.filepond--label {
|
|
color: var(--text-color-secondary);
|
|
}
|
|
|
|
.app-dark .filepond--label {
|
|
color: var(--code-color);
|
|
}
|
|
|
|
.app-dark .filepond--drop-label {
|
|
background-color: var(--code-background);
|
|
color: var(--code-color);
|
|
border: 1px solid var(--surface-border);
|
|
border-radius: 8px;
|
|
}
|
|
|
|
.filepond--item-panel {
|
|
background-color: var(--surface-card);
|
|
}
|
|
|
|
.app-dark .filepond--item-panel {
|
|
background-color: var(--code-background);
|
|
}
|
|
</style>
|