mirror of
https://gitlab.com/PronounsPage/PronounsPage.git
synced 2025-08-04 03:27:05 -04:00
103 lines
2.8 KiB
Vue
103 lines
2.8 KiB
Vue
<template>
|
|
<div>
|
|
<input
|
|
:id="id"
|
|
type="file"
|
|
:name="name + (multiple ? '[]' : '')"
|
|
:multiple="multiple"
|
|
:disabled="uploading"
|
|
:accept="mime"
|
|
@change="filesChange($event.target.name, $event.target.files)"
|
|
>
|
|
<label
|
|
:for="id"
|
|
:class="['uploader-container', form ? 'form-control p-2' : classes, drag ? 'drag' : '']"
|
|
@dragover="drag = true"
|
|
@dragleave="drag = false"
|
|
>
|
|
<p v-if="errorMessage" class="text-danger mb-0">
|
|
<Icon v="exclamation-circle" />
|
|
<T>{{ errorMessage }}</T>
|
|
</p>
|
|
<p v-else-if="uploading" class="mb-0">
|
|
<Spinner />
|
|
</p>
|
|
<p v-else class="mb-0">
|
|
<slot>
|
|
<Icon v="upload" />
|
|
<T>images.upload.instructionShort</T>
|
|
</slot>
|
|
</p>
|
|
</label>
|
|
</div>
|
|
</template>
|
|
|
|
<script>
|
|
export default {
|
|
props: {
|
|
url: { required: true },
|
|
multiple: { type: Boolean },
|
|
mime: { default: '*/*' },
|
|
name: { default: 'files' },
|
|
form: { type: Boolean },
|
|
classes: { default: 'btn btn-outline-primary btn-sm' },
|
|
},
|
|
data() {
|
|
return {
|
|
uploading: false,
|
|
drag: false,
|
|
errorMessage: '',
|
|
id: `upload-${this.name}`,
|
|
};
|
|
},
|
|
methods: {
|
|
async filesChange(fieldName, fileList) {
|
|
if (!fileList.length) {
|
|
return;
|
|
}
|
|
this.drag = false;
|
|
const formData = new FormData();
|
|
for (const file of fileList) {
|
|
formData.append(fieldName, file, file.name);
|
|
}
|
|
await this.save(formData);
|
|
},
|
|
async save(formData) {
|
|
this.uploading = true;
|
|
this.errorMessage = '';
|
|
try {
|
|
const ids = await $fetch(this.url, {
|
|
method: 'POST',
|
|
body: formData,
|
|
headers: {
|
|
'Content-Type': 'multipart/form-data',
|
|
},
|
|
});
|
|
this.$emit('uploaded', ids);
|
|
} catch (e) {
|
|
this.errorMessage = e?.response?.data?.error || 'error.invalidImage';
|
|
}
|
|
this.uploading = false;
|
|
},
|
|
},
|
|
};
|
|
</script>
|
|
|
|
<style lang="scss" scoped>
|
|
@import "../assets/variables";
|
|
|
|
.uploader-container {
|
|
position: relative;
|
|
cursor: pointer;
|
|
&.form-control {
|
|
&:hover, &.drag {
|
|
background: lighten($primary, 50%);
|
|
}
|
|
}
|
|
}
|
|
|
|
input[type="file"] {
|
|
display: none;
|
|
}
|
|
</style>
|