Deploy
This commit is contained in:
@@ -0,0 +1,65 @@
|
|||||||
|
'use client'
|
||||||
|
import { useState, useEffect } from 'react'
|
||||||
|
import type { VulaProduct } from './useProducts'
|
||||||
|
|
||||||
|
interface UseFeaturedProductsResult {
|
||||||
|
products: VulaProduct[]
|
||||||
|
loading: boolean
|
||||||
|
isLoading: boolean
|
||||||
|
error: string | null
|
||||||
|
}
|
||||||
|
|
||||||
|
export function useFeaturedProducts(fallbackLimit = 8): UseFeaturedProductsResult {
|
||||||
|
const [products, setProducts] = useState<VulaProduct[]>([])
|
||||||
|
const [loading, setLoading] = useState(true)
|
||||||
|
const [error, setError] = useState<string | null>(null)
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
let cancelled = false
|
||||||
|
|
||||||
|
async function load() {
|
||||||
|
try {
|
||||||
|
// Step 1: fetch curated IDs from Vula CMS
|
||||||
|
const cmsRes = await fetch('/api/content/featured_products', { cache: 'no-store' })
|
||||||
|
let ids: string[] = []
|
||||||
|
if (cmsRes.ok) {
|
||||||
|
const cmsData = await cmsRes.json()
|
||||||
|
const items: Array<{ data: { product_ids?: unknown } }> = cmsData.items ?? []
|
||||||
|
const first = items[0]?.data?.product_ids
|
||||||
|
ids = Array.isArray(first) ? (first as string[]).filter(Boolean) : []
|
||||||
|
}
|
||||||
|
|
||||||
|
let fetched: VulaProduct[] = []
|
||||||
|
if (ids.length > 0) {
|
||||||
|
// Step 2: hydrate from Vula Commerce by ID
|
||||||
|
const params = new URLSearchParams()
|
||||||
|
ids.forEach((id) => params.append('id[]', id))
|
||||||
|
params.set('limit', String(ids.length))
|
||||||
|
const res = await fetch(`/api/products?${params}`)
|
||||||
|
if (res.ok) {
|
||||||
|
const data = await res.json()
|
||||||
|
fetched = data.products ?? []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fetched.length === 0) {
|
||||||
|
// Step 3: fallback — latest products from Vula Commerce
|
||||||
|
const fallbackRes = await fetch(`/api/products?limit=${fallbackLimit}`)
|
||||||
|
if (fallbackRes.ok) {
|
||||||
|
const data = await fallbackRes.json()
|
||||||
|
fetched = data.products ?? []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!cancelled) { setProducts(fetched); setLoading(false) }
|
||||||
|
} catch (err) {
|
||||||
|
if (!cancelled) { setError(String(err)); setLoading(false) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
load()
|
||||||
|
return () => { cancelled = true }
|
||||||
|
}, [fallbackLimit])
|
||||||
|
|
||||||
|
return { products, loading, isLoading: loading, error }
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user