/** * — browse catalog, view orders, trigger fulfillment. * Shows catalog items, order creation flow, and order status tracking. */ class FolkCartShop extends HTMLElement { private shadow: ShadowRoot; private catalog: any[] = []; private orders: any[] = []; private view: "catalog" | "orders" = "catalog"; private loading = true; constructor() { super(); this.shadow = this.attachShadow({ mode: "open" }); } connectedCallback() { this.render(); this.loadData(); } private getApiBase(): string { const path = window.location.pathname; const parts = path.split("/").filter(Boolean); return parts.length >= 2 ? `/${parts[0]}/cart` : "/demo/cart"; } private async loadData() { this.loading = true; this.render(); try { const [catRes, ordRes] = await Promise.all([ fetch(`${this.getApiBase()}/api/catalog?limit=50`), fetch(`${this.getApiBase()}/api/orders?limit=20`), ]); const catData = await catRes.json(); const ordData = await ordRes.json(); this.catalog = catData.entries || []; this.orders = ordData.orders || []; } catch (e) { console.error("Failed to load cart data:", e); } this.loading = false; this.render(); } private render() { this.shadow.innerHTML = `

\u{1F6D2} Community Shop

${this.loading ? `
\u23F3 Loading...
` : this.view === "catalog" ? this.renderCatalog() : this.renderOrders()} `; this.shadow.querySelectorAll(".tab").forEach((el) => { el.addEventListener("click", () => { this.view = ((el as HTMLElement).dataset.view || "catalog") as "catalog" | "orders"; this.render(); }); }); } private renderCatalog(): string { if (this.catalog.length === 0) { return `
No items in the catalog yet. Ingest artifacts from rPubs or Swag Designer to list them here.
`; } return `
${this.catalog.map((entry) => `

${this.esc(entry.title || "Untitled")}

${entry.product_type ? `${this.esc(entry.product_type)}` : ""} ${(entry.required_capabilities || []).map((cap: string) => `${this.esc(cap)}`).join("")}
${entry.description ? `
${this.esc(entry.description)}
` : ""} ${entry.dimensions ? `
${entry.dimensions.width_mm}x${entry.dimensions.height_mm}mm
` : ""}
${entry.status}
`).join("")}
`; } private renderOrders(): string { if (this.orders.length === 0) { return `
No orders yet.
`; } return `
${this.orders.map((order) => `

${this.esc(order.artifact_title || "Order")}

${order.provider_name ? `Provider: ${this.esc(order.provider_name)}` : ""} ${order.quantity > 1 ? ` \u2022 Qty: ${order.quantity}` : ""}
${order.status}
$${parseFloat(order.total_price || 0).toFixed(2)}
`).join("")}
`; } private esc(s: string): string { const d = document.createElement("div"); d.textContent = s; return d.innerHTML; } } customElements.define("folk-cart-shop", FolkCartShop);