import { html, list, attribute, hydrate } from 'wirejs-dom/v2'; import { AuthenticatedContent } from 'wirejs-components'; import { store, Product, Transaction } from 'internal-api'; import { Main } from '../layouts/main.js'; type LineItem = { productId: string; productName: string; price: string; quantity: number; } type SubscriptionLine = Awaited >[number]; function renderAmount(inCents: number) { return `$${(inCents/100).toFixed(2)}`; } function Storefront() { const self = html`

Products

    ${list('products', (p: Product) => html`
  1. ${p.name} : { const existing = self.data.cart.find(li => li.productId === p.id); if (existing) { const idx = self.data.cart.indexOf(existing); self.data.cart.splice(idx, 1, { ...existing, quantity: existing.quantity + 1 }); } else { self.data.cart.push({ productId: p.id, productName: p.name, price: `${renderAmount(p.unitAmount)}`, quantity: 1 }); } }} >add
  2. `)}

Cart

    ${list('cart', (li: LineItem) => html`
  1. ${li.productName} x ${li.quantity} : { self.data.cart.splice(self.data.cart.indexOf(li), 1); }} >remove
  2. `)}
{ event.preventDefault(); document.location = (await store.getCheckoutUrl(null, { cart: self.data.cart.map(li => ({ id: li.productId, quantity: li.quantity })), successUrl: document.location.href, cancelUrl: document.location.href, }))!; }}>

Transactions

${list('transactions', (t: Transaction) => html``)}
date amount items
${new Date(t.createdAt).toLocaleDateString()} ${renderAmount(t.amount)} ${(t.items || []).map(li => html``)}
${li.description} x ${li.quantity} = ${renderAmount(li.amount)}

Subscription Plans

${list('plans', (p: Product) => html``)}
Name Price
${p.name} ${renderAmount(p.unitAmount)} per ${p.interval} { self.data.planCart.push(p); self.data.plans.splice(self.data.plans.indexOf(p), 1); }} >add

Subscription Cart

${list('planCart', (p: Product) => html``)}
Name Price
${p.name} ${renderAmount(p.unitAmount)} per ${p.interval} { self.data.planCart.splice(self.data.planCart.indexOf(p), 1); self.data.plans.push(p); }} >remove
{ event.preventDefault(); document.location = (await store.getSubscribeUrl(null, { cart: self.data.planCart.map(plan => ({ id: plan.id })), successUrl: document.location.href, cancelUrl: document.location.href, }))!; }}>

Active Subscriptions

${list('subscriptions', (s: SubscriptionLine) => html``)}
Plan Quantity Amount
${s.name} ${s.quantity} x ${renderAmount(s.amount)} per ${s.interval} { const yes = confirm("Are you sure?"); if (!yes) return; try { await store.cancelSubscription(null, s.id); self.data.subscriptions.splice( self.data.subscriptions.indexOf(s), 1 ); } catch (error) { alert(error); } }} >cancel
`.onadd(async self => { const products = await store.listProducts(null); self.data.products = products.filter(p => p.type === 'one_time'); self.data.plans = products.filter(p => p.type !== 'one_time'); self.data.transactions = await store.listPayments(null); self.data.subscriptions = await store.listSubscriptions(null); }); return self; } async function App() { const self = html`
${await AuthenticatedContent({ authenticated: () => Storefront(), unauthenticated: () => html`
You need to sign in to buy things.
` })}
`; return self; } export async function generate() { return Main({ pageTitle: 'Simple Storefront Demo', content: await App(), }); } export function onload() { hydrate('app', App as any); }