fix bug
This commit is contained in:
@@ -1,16 +1,16 @@
|
||||
<template>
|
||||
<section class="container-page py-10">
|
||||
<RouterLink to="/marketplace" class="mb-6 inline-flex text-sm font-bold text-brand-700">
|
||||
<- Kembali ke Marketplace
|
||||
← Kembali ke Marketplace
|
||||
</RouterLink>
|
||||
|
||||
<div v-if="loading" class="card p-10 text-center">
|
||||
<h1 class="text-2xl font-extrabold">Memuat produk...</h1>
|
||||
</div>
|
||||
|
||||
<div v-else-if="product" class="grid gap-8 lg:grid-cols-2">
|
||||
<div class="grid gap-4 sm:grid-cols-[88px_1fr]">
|
||||
<div class="order-2 flex gap-3 overflow-x-auto sm:order-1 sm:grid sm:max-h-[520px] sm:overflow-y-auto">
|
||||
<div v-else-if="product" class="grid gap-8 lg:grid-cols-[minmax(0,1fr)_minmax(380px,520px)]">
|
||||
<div class="grid items-start gap-4 sm:grid-cols-[88px_minmax(0,1fr)]">
|
||||
<div class="order-2 flex gap-3 overflow-x-auto sm:order-1 sm:grid sm:content-start sm:max-h-[78vh] sm:overflow-y-auto">
|
||||
<button
|
||||
v-for="(image, index) in productImages"
|
||||
:key="`${image}-${index}`"
|
||||
@@ -19,12 +19,20 @@
|
||||
:class="selectedImage === image ? 'border-brand-600' : 'border-slate-200'"
|
||||
@click="selectedImage = image"
|
||||
>
|
||||
<img :src="getProductImageUrl(image)" :alt="`${product.title} ${index + 1}`" class="h-full w-full object-cover" />
|
||||
<img
|
||||
:src="getProductImageUrl(image)"
|
||||
:alt="`${product.title} ${index + 1}`"
|
||||
class="h-full w-full object-cover"
|
||||
/>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="card order-1 overflow-hidden sm:order-2">
|
||||
<img :src="getProductImageUrl(selectedImage)" :alt="product.title" class="aspect-[4/3] w-full object-cover" />
|
||||
<div class="order-1 sm:order-2">
|
||||
<img
|
||||
:src="getProductImageUrl(selectedImage)"
|
||||
:alt="product.title"
|
||||
class="block h-auto max-h-[78vh] w-auto max-w-full rounded-2xl object-contain shadow-sm"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -32,22 +40,31 @@
|
||||
<span class="rounded-full bg-brand-50 px-3 py-1 text-sm font-bold text-brand-700">
|
||||
{{ product.category }}
|
||||
</span>
|
||||
<h1 class="mt-4 text-3xl font-extrabold text-slate-950">{{ product.title }}</h1>
|
||||
<p class="mt-3 text-3xl font-extrabold text-brand-700">{{ formatRupiah(product.price) }}</p>
|
||||
|
||||
<h1 class="mt-4 text-3xl font-extrabold text-slate-950">
|
||||
{{ product.title }}
|
||||
</h1>
|
||||
|
||||
<p class="mt-3 text-3xl font-extrabold text-brand-700">
|
||||
{{ formatRupiah(product.price) }}
|
||||
</p>
|
||||
|
||||
<div class="mt-6 grid gap-3 sm:grid-cols-2">
|
||||
<div class="card p-4">
|
||||
<p class="text-xs font-bold uppercase text-slate-500">Kondisi</p>
|
||||
<p class="mt-1 font-bold">{{ product.condition }}</p>
|
||||
</div>
|
||||
|
||||
<div class="card p-4">
|
||||
<p class="text-xs font-bold uppercase text-slate-500">Lokasi</p>
|
||||
<p class="mt-1 font-bold">{{ product.location }}</p>
|
||||
</div>
|
||||
|
||||
<div class="card p-4">
|
||||
<p class="text-xs font-bold uppercase text-slate-500">Penjual</p>
|
||||
<p class="mt-1 font-bold">{{ product.seller }}</p>
|
||||
</div>
|
||||
|
||||
<div class="card p-4">
|
||||
<p class="text-xs font-bold uppercase text-slate-500">WhatsApp</p>
|
||||
<p class="mt-1 font-bold">{{ product.whatsapp }}</p>
|
||||
@@ -56,11 +73,16 @@
|
||||
|
||||
<div class="mt-6">
|
||||
<h2 class="text-lg font-extrabold">Deskripsi</h2>
|
||||
<p class="mt-2 leading-7 text-slate-600">{{ product.description }}</p>
|
||||
<p class="mt-2 leading-7 text-slate-600">
|
||||
{{ product.description }}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="mt-8 flex flex-wrap gap-3">
|
||||
<a :href="waLink" target="_blank" class="btn-primary">Hubungi via WhatsApp</a>
|
||||
<a :href="waLink" target="_blank" class="btn-primary">
|
||||
Hubungi via WhatsApp
|
||||
</a>
|
||||
|
||||
<button class="btn-secondary" @click="toggleSave">
|
||||
{{ saved ? "Hapus dari Tersimpan" : "Simpan Barang" }}
|
||||
</button>
|
||||
@@ -70,7 +92,9 @@
|
||||
|
||||
<div v-else class="card p-10 text-center">
|
||||
<h1 class="text-2xl font-extrabold">Produk tidak ditemukan</h1>
|
||||
<RouterLink to="/marketplace" class="btn-primary mt-5">Lihat Marketplace</RouterLink>
|
||||
<RouterLink to="/marketplace" class="btn-primary mt-5">
|
||||
Lihat Marketplace
|
||||
</RouterLink>
|
||||
</div>
|
||||
</section>
|
||||
</template>
|
||||
@@ -79,17 +103,28 @@
|
||||
import { computed, onMounted, ref, watch } from "vue"
|
||||
import { useRoute } from "vue-router"
|
||||
import { products as defaultProducts } from "../data/products"
|
||||
import { fetchProduct, formatRupiah, getProductImageUrl, getSavedProducts, setSavedProducts } from "../utils"
|
||||
import {
|
||||
fetchProduct,
|
||||
formatRupiah,
|
||||
getProductImageUrl,
|
||||
getSavedProducts,
|
||||
setSavedProducts
|
||||
} from "../utils"
|
||||
|
||||
const route = useRoute()
|
||||
const id = Number(route.params.id)
|
||||
|
||||
const product = ref(null)
|
||||
const loading = ref(true)
|
||||
const selectedImage = ref("")
|
||||
|
||||
const productImages = computed(() => {
|
||||
if (!product.value) return []
|
||||
const images = product.value.images?.length ? product.value.images : [product.value.image]
|
||||
|
||||
const images = product.value.images?.length
|
||||
? product.value.images
|
||||
: [product.value.image]
|
||||
|
||||
return [...new Set(images.filter(Boolean))]
|
||||
})
|
||||
|
||||
@@ -104,11 +139,18 @@ watch(
|
||||
)
|
||||
|
||||
const savedIds = ref(getSavedProducts())
|
||||
const saved = computed(() => savedIds.value.includes(id))
|
||||
|
||||
const saved = computed(() => {
|
||||
return savedIds.value.includes(id)
|
||||
})
|
||||
|
||||
const waLink = computed(() => {
|
||||
if (!product.value) return "#"
|
||||
const text = encodeURIComponent(`Halo, saya tertarik dengan ${product.value.title} di SecondTech Market.`)
|
||||
|
||||
const text = encodeURIComponent(
|
||||
`Halo, saya tertarik dengan ${product.value.title} di SecondTech Market.`
|
||||
)
|
||||
|
||||
return `https://wa.me/${product.value.whatsapp}?text=${text}`
|
||||
})
|
||||
|
||||
@@ -118,17 +160,22 @@ function toggleSave() {
|
||||
} else {
|
||||
savedIds.value.push(id)
|
||||
}
|
||||
|
||||
setSavedProducts(savedIds.value)
|
||||
}
|
||||
|
||||
async function loadProduct() {
|
||||
loading.value = true
|
||||
|
||||
try {
|
||||
const data = await fetchProduct(id)
|
||||
product.value = data.product
|
||||
} catch {
|
||||
const fallbackProduct = defaultProducts.find((item) => Number(item.id) === id) || null
|
||||
product.value = fallbackProduct ? { ...fallbackProduct, images: [fallbackProduct.image] } : null
|
||||
|
||||
product.value = fallbackProduct
|
||||
? { ...fallbackProduct, images: [fallbackProduct.image] }
|
||||
: null
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user