Fix admin product image handling and clarify support phone settings.
This commit is contained in:
@@ -14,7 +14,7 @@ import { useToast } from '@/composables/useToast'
|
||||
import { formatCurrency, formatNumber } from '@/utils/format'
|
||||
import type { Catalog, Product } from '@/types'
|
||||
import AdminCurrencyInput from '@/components/ui/AdminCurrencyInput.vue'
|
||||
import { fileToCatalogImage } from '@/utils/catalogImage'
|
||||
import { fileToCatalogImage, toCssBackgroundUrl } from '@/utils/catalogImage'
|
||||
|
||||
const productList = ref<Product[]>([])
|
||||
const catalogs = ref<Catalog[]>([])
|
||||
@@ -219,6 +219,36 @@ function removeProductImage(index: number) {
|
||||
form.extraImageUrls.splice(index, 1)
|
||||
}
|
||||
|
||||
function buildProductMedia() {
|
||||
const colorEntries: Array<{ name: string; imageUrl?: string }> = []
|
||||
const imageUrls: string[] = []
|
||||
const seen = new Set<string>()
|
||||
|
||||
const pushImage = (url?: string) => {
|
||||
const trimmed = url?.trim()
|
||||
if (!trimmed || seen.has(trimmed)) return
|
||||
seen.add(trimmed)
|
||||
imageUrls.push(trimmed)
|
||||
}
|
||||
|
||||
form.colorRows.forEach((row, index) => {
|
||||
const imageUrl = row.imageUrl.trim() || undefined
|
||||
const name =
|
||||
row.name.trim() ||
|
||||
(index === 0 ? form.color.trim() : '') ||
|
||||
(imageUrl ? `رنگ ${index + 1}` : '')
|
||||
if (!name && !imageUrl) return
|
||||
if (name) {
|
||||
colorEntries.push({ name, imageUrl })
|
||||
}
|
||||
pushImage(imageUrl)
|
||||
})
|
||||
|
||||
form.extraImageUrls.forEach((url) => pushImage(url))
|
||||
|
||||
return { colorEntries, imageUrls }
|
||||
}
|
||||
|
||||
function closeModal() {
|
||||
modalMode.value = null
|
||||
editingId.value = null
|
||||
@@ -237,12 +267,7 @@ async function submitProduct() {
|
||||
return
|
||||
}
|
||||
|
||||
const colorEntries = form.colorRows
|
||||
.map((row) => ({
|
||||
name: row.name.trim(),
|
||||
imageUrl: row.imageUrl.trim() || undefined,
|
||||
}))
|
||||
.filter((row) => row.name)
|
||||
const { colorEntries, imageUrls } = buildProductMedia()
|
||||
const catalogPayload = {
|
||||
usageCategory: form.usageCategory,
|
||||
season: form.season,
|
||||
@@ -252,7 +277,7 @@ async function submitProduct() {
|
||||
rollMeters: form.rollMeters,
|
||||
isNew: form.isNew,
|
||||
colorsJson: colorEntries,
|
||||
imageUrlsJson: form.extraImageUrls,
|
||||
imageUrlsJson: imageUrls,
|
||||
}
|
||||
const productCode = form.productCode.trim() || `${cat.code}-NEW`
|
||||
saving.value = true
|
||||
@@ -294,6 +319,9 @@ async function submitProduct() {
|
||||
}
|
||||
closeModal()
|
||||
} catch (err) {
|
||||
if (err instanceof ApiError && err.status === 0) {
|
||||
formError.value = err.message
|
||||
}
|
||||
toast.error(err instanceof ApiError ? err.message : 'ذخیره محصول انجام نشد.')
|
||||
} finally {
|
||||
saving.value = false
|
||||
@@ -384,7 +412,7 @@ function clearFilters() {
|
||||
<span
|
||||
class="product-thumb"
|
||||
:class="{ 'product-thumb--empty': !product.imageUrls?.[0] }"
|
||||
:style="product.imageUrls?.[0] ? { backgroundImage: `url(${product.imageUrls[0]})` } : undefined"
|
||||
:style="product.imageUrls?.[0] ? { backgroundImage: toCssBackgroundUrl(product.imageUrls[0]) } : undefined"
|
||||
/>
|
||||
</td>
|
||||
<td>{{ product.productCode }}</td>
|
||||
@@ -538,7 +566,10 @@ function clearFilters() {
|
||||
|
||||
<div class="admin-form__field">
|
||||
<label>رنگها و تصویر هر رنگ</label>
|
||||
<p class="color-variants__hint">برای هر رنگ یک نام و یک عکس جدا بگذارید؛ در فروشگاه با انتخاب همان رنگ، همان عکس نمایش داده میشود.</p>
|
||||
<p class="color-variants__hint">
|
||||
برای هر رنگ نام و عکس بگذارید. اگر فقط عکس دارید، نام رنگ اصلی (بالا) یا «رنگ ۱» استفاده میشود.
|
||||
تصویر با زدن «ذخیره تغییرات» روی سرور ثبت میشود.
|
||||
</p>
|
||||
<div class="color-variants">
|
||||
<div v-for="(row, index) in form.colorRows" :key="index" class="color-variant">
|
||||
<AdminImagePicker
|
||||
@@ -565,13 +596,14 @@ function clearFilters() {
|
||||
|
||||
<div class="admin-form__field">
|
||||
<label>تصاویر عمومی محصول (اختیاری)</label>
|
||||
<p class="color-variants__hint">پس از انتخاب فایل، حتماً دکمه ذخیره را بزنید.</p>
|
||||
<div class="product-images">
|
||||
<div
|
||||
v-for="(src, index) in form.extraImageUrls"
|
||||
:key="`${index}-${src.slice(0, 24)}`"
|
||||
class="product-images__item"
|
||||
>
|
||||
<span class="product-images__thumb" :style="{ backgroundImage: `url(${src})` }" />
|
||||
<span class="product-images__thumb" :style="{ backgroundImage: toCssBackgroundUrl(src) }" />
|
||||
<button type="button" class="product-images__remove" @click="removeProductImage(index)">
|
||||
حذف
|
||||
</button>
|
||||
|
||||
@@ -241,7 +241,9 @@ async function sendBroadcast() {
|
||||
<div class="admin-form__field">
|
||||
<label for="support-phone">تلفن پشتیبانی</label>
|
||||
<input id="support-phone" v-model="settings.supportPhone" type="text" class="admin-input" dir="ltr" />
|
||||
<p class="settings-page__hint">این شماره در صفحه ورود اپ (پشتیبانی و تماس با ما) نمایش داده میشود.</p>
|
||||
<p class="settings-page__hint">
|
||||
این شماره در صفحه ورود اپ و بخش پشتیبانی سایدبار دسکتاپ نمایش داده میشود.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="admin-form__field">
|
||||
|
||||
Reference in New Issue
Block a user