95 lines
2.9 KiB
JavaScript
95 lines
2.9 KiB
JavaScript
import Head from 'next/head';
|
|
|
|
import ProductCard from '../../components/ProductCard';
|
|
import SiteLayout from '../../components/SiteLayout';
|
|
import { buildMediaUrl, fetchCategories, fetchProducts } from '../../lib/api';
|
|
|
|
const SAMPLE_PRODUCTS = [];
|
|
|
|
function normalizeProducts(products = []) {
|
|
return products.map((product) => ({
|
|
...product,
|
|
imageUrl: buildMediaUrl(product.hero_image),
|
|
isSample: false,
|
|
}));
|
|
}
|
|
|
|
export default function ProductsPage({ products, categories }) {
|
|
const items = normalizeProducts(products);
|
|
|
|
const groups = categories.reduce((acc, category) => {
|
|
acc[category.id] = { category, items: [] };
|
|
return acc;
|
|
}, {});
|
|
|
|
const uncategorized = [];
|
|
items.forEach((product) => {
|
|
const categoryId = product.category?.id;
|
|
if (categoryId && groups[categoryId]) {
|
|
groups[categoryId].items.push(product);
|
|
} else {
|
|
uncategorized.push(product);
|
|
}
|
|
});
|
|
|
|
const orderedGroups = Object.values(groups).filter((group) => group.items.length);
|
|
if (uncategorized.length) {
|
|
orderedGroups.push({
|
|
category: { name: 'Weekly specials' },
|
|
items: uncategorized,
|
|
});
|
|
}
|
|
|
|
const hasProducts = orderedGroups.length > 0;
|
|
|
|
return (
|
|
<SiteLayout>
|
|
<Head>
|
|
<title>Products · Full Moon Bakehouse</title>
|
|
<meta name="description" content="Browse the current Full Moon Bakehouse offerings." />
|
|
</Head>
|
|
|
|
<div className="wrapper">
|
|
<section className="section">
|
|
<div className="section-header">
|
|
<div>
|
|
<h2>Weekly menu</h2>
|
|
<p>
|
|
Availability updates in real time. Add items to your cart and checkout when you're
|
|
ready.
|
|
</p>
|
|
</div>
|
|
</div>
|
|
|
|
{hasProducts ? (
|
|
orderedGroups.map((group) => (
|
|
<div key={group.category.id || group.category.name} className="section" style={{ paddingTop: 0 }}>
|
|
<h3 className="section-title" style={{ fontFamily: 'Fraunces, serif', fontSize: '1.6rem' }}>
|
|
{group.category.name}
|
|
</h3>
|
|
<div className="product-grid">
|
|
{group.items.map((product) => (
|
|
<ProductCard key={product.id || product.slug} product={product} />
|
|
))}
|
|
</div>
|
|
</div>
|
|
))
|
|
) : (
|
|
<div className="flash info">Menu items will appear here once the API is populated.</div>
|
|
)}
|
|
</section>
|
|
</div>
|
|
</SiteLayout>
|
|
);
|
|
}
|
|
|
|
export async function getServerSideProps() {
|
|
try {
|
|
const [products, categories] = await Promise.all([fetchProducts(), fetchCategories()]);
|
|
return { props: { products, categories } };
|
|
} catch (error) {
|
|
console.warn('Products page data fallback', error);
|
|
return { props: { products: SAMPLE_PRODUCTS, categories: [] } };
|
|
}
|
|
}
|