This commit is contained in:
Vula Builder
2026-07-27 17:52:31 +00:00
parent cd5d3be4be
commit 108b49bd06
+65
View File
@@ -0,0 +1,65 @@
'use client'
import { useState, useEffect } from 'react'
import type { MedusaProduct } from './useMedusaProducts'
interface UseFeaturedProductsResult {
products: MedusaProduct[]
loading: boolean
isLoading: boolean
error: string | null
}
export function useFeaturedProducts(fallbackLimit = 8): UseFeaturedProductsResult {
const [products, setProducts] = useState<MedusaProduct[]>([])
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: MedusaProduct[] = []
if (ids.length > 0) {
// Step 2: hydrate from Medusa by ID
const params = new URLSearchParams()
ids.forEach((id) => params.append('id[]', id))
params.set('limit', String(ids.length))
const medusaRes = await fetch(`/api/medusa/products?${params}`)
if (medusaRes.ok) {
const data = await medusaRes.json()
fetched = data.products ?? []
}
}
if (fetched.length === 0) {
// Step 3: fallback — latest products from Medusa
const fallbackRes = await fetch(`/api/medusa/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 }
}