parfum_agsd/parfum-shop/src/pages/SmallBatchPage.jsx

124 lines
4.0 KiB
JavaScript

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 (
<div className="small-requirement">
<span>{label}</span>
<strong className={met ? "met" : ""}>{children || (met ? "met" : "open")}</strong>
</div>
);
}
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 (
<div className="small-page">
<SharedNavbar variant="light" />
<main className="small-shell">
<section className="small-hero">
<span className="small-kicker">SMALL BATCH / ARCHIVE / PROTOTYPE</span>
<h1>EARLY ACCESS</h1>
<p>
Limited releases are reserved for customers with enough purchase
history to understand the atmos material language.
</p>
</section>
{!user ? (
<section className="small-panel">
<span className="small-kicker">LOGIN REQUIRED</span>
<h2>Sign in to check access.</h2>
<p>Small Batch access is calculated from your completed orders.</p>
<button type="button" onClick={openProfile}>
Login / Register
</button>
</section>
) : (
<>
<section className="small-panel">
<span className="small-kicker">ACCESS STATUS</span>
<h2>{loyalty.unlocked ? "Unlocked" : "Locked"}</h2>
<div className="small-requirements">
<Requirement label="Discovery Set" met={loyalty.hasDiscoverySet} />
<Requirement label="Full Size" met={loyalty.hasFullSize} />
<Requirement label="Purchases" met={loyalty.purchases >= 3}>
{loyalty.purchases}/3 Purchases
</Requirement>
<Requirement label="Spend" met={loyalty.spent_cents > 50000}>
{formatChf(loyalty.spent_cents)} / CHF 500+
</Requirement>
</div>
</section>
{state.error && <p className="small-error">{state.error}</p>}
{state.loading && <p className="small-error">Loading access...</p>}
{loyalty.unlocked && (
<section className="release-grid">
{state.releases.map((release) => (
<article className="release-card" key={release.name}>
<span>{release.type}</span>
<h3>{release.name}</h3>
<p>{release.note}</p>
<button type="button">Request Allocation</button>
</article>
))}
</section>
)}
</>
)}
</main>
</div>
);
}
export default SmallBatchPage;