"use client"; import { useEffect, useState } from "react"; type Product = { stripeProductId: string; stripePriceId: string; name: string; description?: string | null; unitAmount: number; currency: string; active: boolean; }; export default function AdminProductsPage() { const [products, setProducts] = useState([]); const [loading, setLoading] = useState(false); const [message, setMessage] = useState(""); async function loadProducts() { setLoading(true); setMessage(""); try { const res = await fetch("/api/admin/products/list"); const data = await res.json(); if (!res.ok) throw new Error(data.error || "Failed to load products"); setProducts(data.products || []); } catch (err: any) { setMessage(err.message || "Failed to load products."); } finally { setLoading(false); } } useEffect(() => { loadProducts(); }, []); async function refreshFromStripe() { setLoading(true); setMessage(""); try { const res = await fetch("/api/admin/products/refresh", { method: "POST" }); const data = await res.json(); if (!res.ok) throw new Error(data.error || "Failed to refresh products"); await loadProducts(); } catch (err: any) { setMessage(err.message || "Failed to refresh products."); } finally { setLoading(false); } } async function updateProduct(p: Product) { setLoading(true); setMessage(""); try { const res = await fetch("/api/admin/products/update", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ productId: p.stripeProductId, name: p.name, description: p.description, unitAmount: p.unitAmount, active: p.active, }), }); const data = await res.json(); if (!res.ok) throw new Error(data.error || "Failed to update product"); setMessage("Saved."); } catch (err: any) { setMessage(err.message || "Failed to update product."); } finally { setLoading(false); } } return (

Admin: Product Cache

This dashboard manages cached products shown on the storefront.

{message ?
{message}
: null}
{products.map((p) => (
setProducts((prev) => prev.map((item) => item.stripeProductId === p.stripeProductId ? { ...item, name: e.target.value } : item ) ) } />