skillbox/client/src/components/content-forms/ImageForm.vue

153 lines
3.1 KiB
Vue

<template>
<div class="image-form">
<div
class="image-form__error"
v-if="hadError"
>
Ups, das scheint kein Bild zu sein. Bitte versuche es nochmal mit einer anderen Datei, oder lade die Datei als
<a
class="image-form__link"
@click="switchToDocument"
>Dokument</a
>
hoch.
</div>
<div
class="image-form__spinner"
v-if="loading"
>
<loading-icon class="image-form__loading-icon" />
</div>
<div
v-if="!value.url || hadError"
ref="uploadcare-panel"
/>
<div v-if="value.url && !hadError">
<img
alt=""
:src="previewUrl"
@error="error"
/>
</div>
</div>
</template>
<script>
import uploadcare from 'uploadcare-widget';
import LoadingIcon from '@/components/icons/LoadingIcon.vue';
export default {
props: ['value', 'index'],
components: { LoadingIcon },
data() {
return {
hadError: false,
uploadcarePanel: null,
url: '',
filename: '',
loading: false,
};
},
computed: {
previewUrl: function () {
if (this.value && this.value.url) {
return this.value.url + '-/preview/200x200/';
}
return null;
},
},
mounted() {
this.mountUploadcare();
},
methods: {
error() {
this.hadError = true;
setTimeout(() => {
this.mountUploadcare();
}, 0);
},
mountUploadcare() {
this.uploadcarePanel = uploadcare.openPanel(this.$refs['uploadcare-panel'], null, {
tabs: ['file'],
});
this.uploadcarePanel.done((panelResult) => {
this.loading = true;
panelResult.done((fileInfo) => {
this.hadError = false;
this.loading = false;
this.url = fileInfo.cdnUrl;
this.filename = fileInfo.name;
this.$emit('change-url', fileInfo.cdnUrl, this.index);
});
// the api also provides these methods
// panelResult.progress(p => {});
// panelResult.fail(uploadResult => {});
});
},
switchToDocument() {
this.$emit('switch-to-document', this.index, {
url: `${this.url}${this.filename}`,
});
},
},
};
</script>
<style scoped lang="scss">
@import 'styles/helpers';
.image-form {
&__error {
@include regular-text;
margin-bottom: $medium-spacing;
line-height: 1.5;
}
&__spinner {
width: 100%;
height: 150px;
display: flex;
align-items: center;
justify-content: center;
}
&__loading-icon {
@include spin;
fill: $color-silver-dark;
}
&__link {
text-decoration: underline;
@include regular-text;
cursor: pointer;
}
&__file-input {
width: 0.1px;
height: 0.1px;
overflow: hidden;
opacity: 0;
position: absolute;
z-index: -1;
& + label {
cursor: pointer;
background-color: $color-silver-light;
height: 150px;
display: flex;
width: 100%;
justify-content: center;
align-items: center;
font-family: $sans-serif-font-family;
font-weight: $font-weight-regular;
text-decoration: underline;
}
}
}
</style>