171 lines
4.9 KiB
Vue
171 lines
4.9 KiB
Vue
<template>
|
|
<section class="seller-thirdy-step">
|
|
<ul>
|
|
<li>
|
|
<UploadImage v-model="form.coverImage" cover @update:modelValue="delete errors.coverImage" />
|
|
<small v-if="errors.coverImage">{{ errors.coverImage }}</small>
|
|
</li>
|
|
<li v-for="(_, i) in form.images" :key="i">
|
|
<UploadImage v-model="form.images[i]" @update:modelValue="update" />
|
|
<small v-if="errors.images && i < 1">{{ errors.images }}</small>
|
|
</li>
|
|
</ul>
|
|
<div>
|
|
<Button v-bind="btns.prev.props" @click="step--" />
|
|
<Button v-bind="btns.submit.props" :loading="loading" @click="submit()" />
|
|
</div>
|
|
</section>
|
|
</template>
|
|
|
|
<script setup>
|
|
import UploadImage from '../َUploadImage.vue'
|
|
|
|
const { btns } = inject('init')
|
|
const { toast, t } = inject('service')
|
|
const router = useRouter()
|
|
const form = inject('form')
|
|
const step = inject('step')
|
|
const loading = ref(false)
|
|
const errors = ref({})
|
|
|
|
const update = () => {
|
|
form.images = form.images.filter((image) => image != null)
|
|
form.images.push(null)
|
|
|
|
delete errors.value.images;
|
|
}
|
|
|
|
const submit = async () => {
|
|
errors.value = {}
|
|
const images = form.images.filter((image) => image != null)
|
|
|
|
if (!form.coverImage)
|
|
errors.value.coverImage = t('required')
|
|
|
|
if (images.length < 1)
|
|
errors.value.images = t('required')
|
|
|
|
|
|
if (Object.keys(errors.value).length < 1) {
|
|
loading.value = true
|
|
const body = Object.assign({}, form)
|
|
body.images = body.images.filter((image) => image)
|
|
const { minBuy: min, maxBuy: max } = body
|
|
body.orderRange = { min, max }
|
|
delete body.minBuy
|
|
delete body.maxBuy
|
|
|
|
//Upload File
|
|
if (typeof body.coverImage === 'object') {
|
|
const formData = new FormData()
|
|
formData.append('images', form.coverImage)
|
|
|
|
const { status, data, error } = await useFetch('/api/images/upload', {
|
|
headers: { Authorization: useCookie("token") }, params: { type: 1 }, body: formData, method: 'post'
|
|
})
|
|
|
|
if (status.value == 'success')
|
|
body.coverImage = data.value.urls[0]
|
|
else {
|
|
loading.value = false
|
|
return toast.add({
|
|
life: 2000, severity: 'error', summary: t('error'), detail: error.value.msg
|
|
})
|
|
}
|
|
|
|
}
|
|
|
|
//upload images
|
|
const files = body.images.filter((image) => typeof image === 'object')
|
|
if (files.length > 0) {
|
|
const formData = new FormData()
|
|
files.forEach((image, i) => {
|
|
formData.append('images', image)
|
|
});
|
|
|
|
const { status, data, error } = await useFetch('/api/images/upload', {
|
|
headers: { Authorization: useCookie("token") }, params: { type: 1 }, body: formData, method: 'post'
|
|
})
|
|
|
|
if (status.value == 'success') {
|
|
body.images = body.images.map((image) => {
|
|
if (typeof image === 'object')
|
|
return data.value.urls.shift();
|
|
return image;
|
|
})
|
|
|
|
} else {
|
|
loading.value = false
|
|
return toast.add({
|
|
life: 2000, severity: 'error', summary: t('error'), detail: error.value.msg
|
|
})
|
|
}
|
|
|
|
}
|
|
|
|
let endPoint = '/api/products'
|
|
let method = 'post'
|
|
|
|
if (body.id) {
|
|
endPoint += '/' + body.id
|
|
method = 'put'
|
|
}
|
|
|
|
const { status, data, error } = await useFetch(endPoint, {
|
|
headers: { Authorization: useCookie("token") }, method, body
|
|
})
|
|
|
|
if (status.value == 'success')
|
|
router.push('/panel/seller/products')
|
|
else if (error.value.statusCode == 422)
|
|
errors.value = error.value.data
|
|
else toast.add({
|
|
life: 3000, severity: 'error', summary: t('error'), detail: error.value.message
|
|
})
|
|
|
|
loading.value = false
|
|
}
|
|
}
|
|
|
|
onMounted(() => {
|
|
if (form.id) update()
|
|
})
|
|
</script>
|
|
|
|
<style lang="scss">
|
|
.seller-thirdy-step {
|
|
@apply w-full flex flex-col gap-8 pb-20 lg:gap-[3.8rem];
|
|
|
|
&>ul {
|
|
@apply flex flex-wrap gap-6;
|
|
|
|
li {
|
|
small {
|
|
@apply text-red-500 font-vazir;
|
|
}
|
|
|
|
&:has(small) * {
|
|
@apply border-red-500 #{!important};
|
|
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
&>div {
|
|
@apply inset-x-0 bottom-0 flex gap-3 w-full lg:w-[27.1rem] self-end;
|
|
@apply max-lg:fixed max-lg:border-t max-lg:shadow-[0_-2px_5px_#0000000a];
|
|
@apply h-[4.8rem] px-6 pt-3 lg:p-0 lg:h-max bg-white;
|
|
|
|
&>button {
|
|
@apply w-full h-[2.9rem] lg:h-14 #{!important};
|
|
|
|
.p-button-label {
|
|
@apply text-sm lg:text-xl font-medium font-vazir;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
}
|
|
</style> |