import { useEffect, useState } from "react"; import SharedNavbar from "../components/SharedNavbar"; import { formatChf } from "../shop/money"; import { useShop } from "../shop/useShop"; import "./SmallBatchPage.css"; function Requirement({ label, met, children }) { return (
{label} {children || (met ? "met" : "open")}
); } function SmallBatchPage() { const { openProfile, token, user } = useShop(); const [state, setState] = useState({ loading: false, error: "", loyaltyStatus: user?.loyaltyStatus || null, releases: [], }); useEffect(() => { if (!token) return; fetch("/api/small-batch", { headers: { Authorization: `Bearer ${token}` }, }) .then(async (response) => { const data = await response.json().catch(() => ({})); if (!response.ok) throw new Error(data.error || "Small Batch request failed."); setState({ loading: false, error: "", loyaltyStatus: data.loyaltyStatus, releases: data.releases || [], }); }) .catch((error) => { setState((current) => ({ ...current, loading: false, error: error instanceof Error ? error.message : "Shop API unreachable. Start it with npm run dev and try again.", })); }); }, [token, user?.loyaltyStatus]); const loyalty = state.loyaltyStatus || { hasDiscoverySet: false, hasFullSize: false, purchases: 0, spent_cents: 0, unlocked: false, }; return (
SMALL BATCH / ARCHIVE / PROTOTYPE

EARLY ACCESS

Limited releases are reserved for customers with enough purchase history to understand the atmos material language.

{!user ? (
LOGIN REQUIRED

Sign in to check access.

Small Batch access is calculated from your completed orders.

) : ( <>
ACCESS STATUS

{loyalty.unlocked ? "Unlocked" : "Locked"}

= 3}> {loyalty.purchases}/3 Purchases 50000}> {formatChf(loyalty.spent_cents)} / CHF 500+
{state.error &&

{state.error}

} {state.loading &&

Loading access...

} {loyalty.unlocked && (
{state.releases.map((release) => (
{release.type}

{release.name}

{release.note}

))}
)} )}
); } export default SmallBatchPage;