details view image component refactor
All checks were successful
/ Make image (push) Successful in 39s
All checks were successful
/ Make image (push) Successful in 39s
This commit is contained in:
parent
9d80345b77
commit
bb40d17e6b
5 changed files with 118 additions and 39 deletions
|
|
@ -31,8 +31,27 @@ function onModalClose() {
|
|||
previewImageUrl.value = ''
|
||||
}
|
||||
|
||||
function beforeUpload({ fileList: newFileList }) {
|
||||
return newFileList.length <= 1
|
||||
const fileInput = ref(null)
|
||||
|
||||
function triggerFileInput() {
|
||||
fileInput.value?.click()
|
||||
}
|
||||
|
||||
function onFileInputChange(event) {
|
||||
const files = event.target.files
|
||||
if (!files || files.length === 0) return
|
||||
|
||||
const file = files[0]
|
||||
handleUpload({
|
||||
fileList: [
|
||||
{
|
||||
file,
|
||||
name: file.name,
|
||||
status: 'pending',
|
||||
},
|
||||
],
|
||||
})
|
||||
event.target.value = ''
|
||||
}
|
||||
|
||||
async function handleUpload({ fileList: newFileList }) {
|
||||
|
|
@ -100,37 +119,31 @@ const cancelDelete = () => {
|
|||
|
||||
<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>
|
||||
<div v-if="fileList.length === 0" class="upload-wrapper" @click="triggerFileInput">
|
||||
<BoxIcon class="upload-icon" />
|
||||
<span class="upload-text">Click to Upload</span>
|
||||
</div>
|
||||
|
||||
<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 v-else class="preview-container clickable-image">
|
||||
<div>
|
||||
<img
|
||||
:src="fileList[0].url"
|
||||
alt="Preview"
|
||||
class="preview-image"
|
||||
@click="triggerFileInput"
|
||||
/>
|
||||
</div>
|
||||
<div class="button-container-evenly button-gap">
|
||||
<n-button type="primary" @click="handlePreview(fileList[0])">Preview</n-button>
|
||||
<n-button type="error" @click="deleteImageHandler">Delete</n-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<n-modal v-model:show="showModal" preset="card" title="Preview" @after-leave="onModalClose" class="image-preview-modal">
|
||||
<img :src="previewImageUrl" alt="Preview" class="preview-modal-image"/>
|
||||
</n-modal>
|
||||
|
||||
<n-modal v-model:show="showConfirmDelete" preset="dialog" title="Confirmation">
|
||||
<template #default>
|
||||
<p>Confirm delete image</p>
|
||||
|
|
@ -140,13 +153,22 @@ const cancelDelete = () => {
|
|||
<n-button @click="cancelDelete">Cancel</n-button>
|
||||
</template>
|
||||
</n-modal>
|
||||
|
||||
<input
|
||||
ref="fileInput"
|
||||
type="file"
|
||||
accept="image/*"
|
||||
style="display: none"
|
||||
@change="onFileInputChange"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.upload-trigger {
|
||||
.upload-wrapper {
|
||||
width: 300px;
|
||||
max-height: 600px;
|
||||
min-height: 180px;
|
||||
max-width: 300px;
|
||||
height: 300px;
|
||||
max-height: 300px;
|
||||
border: 1px dashed #ccc;
|
||||
border-radius: 8px;
|
||||
background-color: #fafafa;
|
||||
|
|
@ -160,14 +182,16 @@ const cancelDelete = () => {
|
|||
border-color 0.2s ease;
|
||||
}
|
||||
|
||||
.upload-trigger:hover {
|
||||
.upload-wrapper:hover {
|
||||
border-color: #18a058;
|
||||
background-color: #f0fdf4;
|
||||
}
|
||||
|
||||
.upload-icon {
|
||||
width: 150px;
|
||||
max-width: 150px;
|
||||
height: 150px;
|
||||
max-height: 150px;
|
||||
opacity: 0.6;
|
||||
}
|
||||
|
||||
|
|
@ -175,6 +199,32 @@ const cancelDelete = () => {
|
|||
margin-top: 8px;
|
||||
font-size: 14px;
|
||||
color: #555;
|
||||
background-color: rgba(24, 160, 88, 0.4);
|
||||
padding: 6px 12px;
|
||||
border-radius: 6px;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.preview-container {
|
||||
display: block;
|
||||
width: 100%;
|
||||
max-width: 400px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.preview-image {
|
||||
width: 100%;
|
||||
height: auto;
|
||||
display: block;
|
||||
max-width: 100%;
|
||||
object-fit: contain;
|
||||
}
|
||||
|
||||
.clickable-image {
|
||||
cursor: pointer;
|
||||
transition: opacity 0.2s;
|
||||
}
|
||||
.clickable-image:hover {
|
||||
opacity: 0.9;
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue