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
|
|
@ -20,12 +20,27 @@
|
|||
justify-content: center;
|
||||
}
|
||||
|
||||
.center-button-container {
|
||||
.button-container-center {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.button-container-evenly {
|
||||
display: flex;
|
||||
justify-content: space-between !important;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.button-container-evenly .n-button {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.button-gap {
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.center-button {
|
||||
min-width: 320px;
|
||||
}
|
||||
|
|
@ -137,3 +152,17 @@ body,
|
|||
.main-content {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.image-preview-modal {
|
||||
width: 80%;
|
||||
max-width: 800px;
|
||||
}
|
||||
.image-preview-modal .n-card__content {
|
||||
padding: 0;
|
||||
text-align: center;
|
||||
}
|
||||
.preview-modal-image {
|
||||
max-width: 99%;
|
||||
max-height: 70vh;
|
||||
object-fit: contain;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -190,7 +190,7 @@ onMounted(() => {
|
|||
</n-card>
|
||||
<div v-else>Not found</div>
|
||||
|
||||
<div class="center-button-container">
|
||||
<div class="button-container-center">
|
||||
<n-button type="error" class="center-button" @click="onDelete">Delete</n-button>
|
||||
</div>
|
||||
|
||||
|
|
|
|||
|
|
@ -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,36 +119,30 @@ 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">
|
||||
<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-upload>
|
||||
|
||||
<n-modal
|
||||
v-model:show="showModal"
|
||||
preset="card"
|
||||
style="width: 600px"
|
||||
title="Preview"
|
||||
@after-leave="onModalClose"
|
||||
>
|
||||
<div v-else class="preview-container clickable-image">
|
||||
<div>
|
||||
<img
|
||||
:src="previewImageUrl"
|
||||
style="width: 100%; max-height: 600px; object-fit: contain"
|
||||
:src="fileList[0].url"
|
||||
alt="Preview"
|
||||
class="preview-image"
|
||||
@click="triggerFileInput"
|
||||
/>
|
||||
</n-modal>
|
||||
</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>
|
||||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -108,7 +108,7 @@ const insertAutoCompletedLink = () => {
|
|||
</script>
|
||||
|
||||
<template>
|
||||
<div v-if="props.origin === 'mandarake'" class="center-button-container mb-10">
|
||||
<div v-if="props.origin === 'mandarake'" class="button-container-center mb-10">
|
||||
<n-button type="warning" class="center-button" @click="insertAutoCompletedLink"
|
||||
>Insert auto-completed link</n-button
|
||||
>
|
||||
|
|
@ -127,7 +127,7 @@ const insertAutoCompletedLink = () => {
|
|||
<n-button size="small" type="primary" :loading="loading" @click="save">Save</n-button>
|
||||
<n-button size="small" @click="cancel">Cancel</n-button>
|
||||
</div>
|
||||
<div class="center-button-container">
|
||||
<div class="button-container-center">
|
||||
<n-button type="error" class="center-button" @click="clearLink">Clear link</n-button>
|
||||
</div>
|
||||
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ const onLogout = () => {
|
|||
{{ formattedDate }}
|
||||
</n-thing>
|
||||
</n-list-item>
|
||||
<div class="center-button-container">
|
||||
<div class="button-container-center">
|
||||
<n-button type="info" class="center-button" @click="onLogout">Log out</n-button>
|
||||
</div>
|
||||
</n-list>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue