Deploy
This commit is contained in:
@@ -0,0 +1,75 @@
|
||||
import { Suspense } from 'react'
|
||||
import Link from 'next/link'
|
||||
import { ArrowLeft } from 'lucide-react'
|
||||
import ProductDetailClient from '@/components/shop/ProductDetailClient'
|
||||
|
||||
export const dynamic = 'force-dynamic'
|
||||
export const revalidate = 0
|
||||
|
||||
const BACKEND_URL = process.env.VULA_ECOMMERCE_BACKEND_URL || 'http://vula-ecommerce:9000'
|
||||
const PUB_KEY = process.env.NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY || ''
|
||||
|
||||
async function getProduct(productId: string) {
|
||||
try {
|
||||
const regRes = await fetch(`${BACKEND_URL}/store/regions?limit=1`, {
|
||||
headers: { 'x-publishable-api-key': PUB_KEY },
|
||||
cache: 'no-store',
|
||||
signal: AbortSignal.timeout(8000),
|
||||
})
|
||||
const regData = regRes.ok ? await regRes.json() : {}
|
||||
const regionId = regData.regions?.[0]?.id
|
||||
const params = new URLSearchParams({
|
||||
fields: '+variants.prices.amount,+variants.prices.currency_code,+collection,+categories,+images',
|
||||
})
|
||||
if (regionId) params.set('region_id', regionId)
|
||||
const res = await fetch(`${BACKEND_URL}/store/products/${productId}?${params}`, {
|
||||
headers: { 'x-publishable-api-key': PUB_KEY },
|
||||
cache: 'no-store',
|
||||
signal: AbortSignal.timeout(8000),
|
||||
})
|
||||
if (!res.ok) return null
|
||||
const { product } = await res.json()
|
||||
if (product?.variants) {
|
||||
product.variants = product.variants.map((v: any) => ({
|
||||
...v,
|
||||
prices: v.prices?.length ? v.prices : v.calculated_price
|
||||
? [{ amount: v.calculated_price.calculated_amount, currency_code: v.calculated_price.currency_code }]
|
||||
: [],
|
||||
}))
|
||||
}
|
||||
return product
|
||||
} catch {
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
interface PageProps { params: { productId: string } }
|
||||
|
||||
export default async function ProductDetailPage({ params }: PageProps) {
|
||||
const product = await getProduct(params.productId)
|
||||
return (
|
||||
<main className="min-h-screen bg-background">
|
||||
<div className="container mx-auto px-4 py-10 max-w-6xl">
|
||||
<nav className="flex items-center gap-2 text-sm text-muted-foreground mb-8">
|
||||
<Link href="/products" className="hover:text-foreground transition-colors flex items-center gap-1">
|
||||
<ArrowLeft className="h-4 w-4" />
|
||||
All Products
|
||||
</Link>
|
||||
{product?.collection?.title && (
|
||||
<>
|
||||
<span>/</span>
|
||||
<span className="text-foreground">{product.collection.title}</span>
|
||||
</>
|
||||
)}
|
||||
</nav>
|
||||
<Suspense fallback={
|
||||
<div className="flex justify-center py-20">
|
||||
<div className="animate-spin rounded-full h-10 w-10 border-b-2 border-primary" />
|
||||
</div>
|
||||
}>
|
||||
<ProductDetailClient product={product} productId={params.productId} />
|
||||
</Suspense>
|
||||
</div>
|
||||
</main>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user