This commit is contained in:
parent
c29caf01c8
commit
9d80345b77
7 changed files with 332 additions and 15 deletions
180
src/views/DetailsView/DetailsViewImages.vue
Normal file
180
src/views/DetailsView/DetailsViewImages.vue
Normal file
|
|
@ -0,0 +1,180 @@
|
|||
<script setup>
|
||||
import { onMounted, ref } from 'vue'
|
||||
import { NModal, NUpload, useMessage } from 'naive-ui'
|
||||
import BoxIcon from '@/components/icons/BoxIcon.vue'
|
||||
import { useMerchImagesApi } from '@/api/merchImages.js'
|
||||
|
||||
const { uploadImage, getImageUrl, deleteImage } = useMerchImagesApi()
|
||||
const message = useMessage()
|
||||
|
||||
const props = defineProps({
|
||||
merchUuid: { type: String, required: true },
|
||||
})
|
||||
|
||||
const showModal = ref(false)
|
||||
const previewImageUrl = ref('')
|
||||
const fileList = ref([])
|
||||
|
||||
function handlePreview(file) {
|
||||
if (file.file) {
|
||||
previewImageUrl.value = URL.createObjectURL(file.file)
|
||||
} else if (file.url) {
|
||||
previewImageUrl.value = file.url
|
||||
}
|
||||
showModal.value = true
|
||||
}
|
||||
|
||||
function onModalClose() {
|
||||
if (previewImageUrl.value && previewImageUrl.value.startsWith('blob:')) {
|
||||
URL.revokeObjectURL(previewImageUrl.value)
|
||||
}
|
||||
previewImageUrl.value = ''
|
||||
}
|
||||
|
||||
function beforeUpload({ fileList: newFileList }) {
|
||||
return newFileList.length <= 1
|
||||
}
|
||||
|
||||
async function handleUpload({ fileList: newFileList }) {
|
||||
const file = newFileList[newFileList.length - 1]
|
||||
try {
|
||||
await uploadImage(props.merchUuid, file.file)
|
||||
|
||||
const { imgUrl } = await getImageUrl(props.merchUuid, 'full')
|
||||
|
||||
message.success('Image uploaded successfully.')
|
||||
|
||||
fileList.value = [
|
||||
{
|
||||
name: file.name,
|
||||
url: imgUrl,
|
||||
status: 'finished',
|
||||
},
|
||||
]
|
||||
} catch (error) {
|
||||
message.error('Upload error: ' + (error.message || 'Unknown error.'))
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
try {
|
||||
const { imgUrl } = await getImageUrl(props.merchUuid, 'full')
|
||||
fileList.value = [
|
||||
{
|
||||
name: 'full.jpg',
|
||||
url: imgUrl,
|
||||
status: 'finished',
|
||||
},
|
||||
]
|
||||
} catch (error) {
|
||||
fileList.value = []
|
||||
if (!error.message?.includes('404')) {
|
||||
console.error('Error getting image: ', error)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
const showConfirmDelete = ref(false)
|
||||
|
||||
const deleteImageHandler = async () => {
|
||||
showConfirmDelete.value = true
|
||||
return false //prevents instant "delete image" in n-upload before confirm
|
||||
}
|
||||
|
||||
const confirmDeleteImage = async () => {
|
||||
try {
|
||||
await deleteImage(props.merchUuid)
|
||||
fileList.value = []
|
||||
message.success('Image deleted successfully.')
|
||||
} catch (error) {
|
||||
message.error('Image delete error: ' + (error.message || 'Unknown error.'))
|
||||
} finally {
|
||||
showConfirmDelete.value = false
|
||||
}
|
||||
}
|
||||
|
||||
const cancelDelete = () => {
|
||||
showConfirmDelete.value = false
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<n-upload
|
||||
v-model:file-list="fileList"
|
||||
:default-upload="false"
|
||||
list-type="image-card"
|
||||
:max="1"
|
||||
:before-upload="beforeUpload"
|
||||
@before-preview="handlePreview"
|
||||
@change="handleUpload"
|
||||
@remove="deleteImageHandler"
|
||||
>
|
||||
<div class="upload-trigger" v-if="fileList.length === 0">
|
||||
<BoxIcon class="upload-icon" />
|
||||
<span class="upload-text">Click to Upload</span>
|
||||
</div>
|
||||
</n-upload>
|
||||
|
||||
<n-modal
|
||||
v-model:show="showModal"
|
||||
preset="card"
|
||||
style="width: 600px"
|
||||
title="Preview"
|
||||
@after-leave="onModalClose"
|
||||
>
|
||||
<img
|
||||
:src="previewImageUrl"
|
||||
style="width: 100%; max-height: 600px; object-fit: contain"
|
||||
alt="Preview"
|
||||
/>
|
||||
</n-modal>
|
||||
</div>
|
||||
|
||||
<n-modal v-model:show="showConfirmDelete" preset="dialog" title="Confirmation">
|
||||
<template #default>
|
||||
<p>Confirm delete image</p>
|
||||
</template>
|
||||
<template #action>
|
||||
<n-button @click="confirmDeleteImage" type="error">Delete</n-button>
|
||||
<n-button @click="cancelDelete">Cancel</n-button>
|
||||
</template>
|
||||
</n-modal>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.upload-trigger {
|
||||
width: 300px;
|
||||
max-height: 600px;
|
||||
min-height: 180px;
|
||||
border: 1px dashed #ccc;
|
||||
border-radius: 8px;
|
||||
background-color: #fafafa;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
cursor: pointer;
|
||||
transition:
|
||||
background-color 0.2s ease,
|
||||
border-color 0.2s ease;
|
||||
}
|
||||
|
||||
.upload-trigger:hover {
|
||||
border-color: #18a058;
|
||||
background-color: #f0fdf4;
|
||||
}
|
||||
|
||||
.upload-icon {
|
||||
width: 150px;
|
||||
height: 150px;
|
||||
opacity: 0.6;
|
||||
}
|
||||
|
||||
.upload-text {
|
||||
margin-top: 8px;
|
||||
font-size: 14px;
|
||||
color: #555;
|
||||
}
|
||||
|
||||
</style>
|
||||
Loading…
Add table
Add a link
Reference in a new issue