chore: initial import

This commit is contained in:
2025-11-09 00:26:00 -06:00
commit 67fb60e6ca
76 changed files with 3925 additions and 0 deletions

View File

@@ -0,0 +1,94 @@
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&apos;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: [] } };
}
}