// Just Works page template — renders the platform-hosted merchant page // locally from /api/business. This is the design surface for the stable // justworks.cash/{slug} page: module CTAs, the QR that never moves, and the // pointer to the sovereign nsite copy rendered at /site. import {mountLogo} from './ds/logo.js'; import {link} from './ds/frame.js'; const app=document.querySelector('#app'); const base=location.pathname.split('/').slice(0,-1).join('/'); const npub=new URLSearchParams(location.search).get('npub')?.trim()||''; const esc=value=>String(value??'').replace(/[&<>"']/g,char=>({'&':'&','<':'<','>':'>','"':'"',"'":'''}[char])); const qr=text=>`${base}/api/qr?text=${encodeURIComponent(text)}`; const moduleMeta={ order:{name:'Order to table',copy:'Scan, order, and pay from the table. No app for customers, no terminal for staff.',glyph:'+',target:'order'}, pay:{name:'Pay Bill',copy:'Close the table from the customer side. A confirmed Lightning payment settles instantly.',glyph:'€',target:'pay'}, payandgo:{name:'Just Pay',copy:'Pay a paper receipt in sats. Type the total, get an invoice, done.',glyph:'₿',target:'payandgo'}, booking:{name:'Bookings',copy:'Book a table now or later, straight from the page.',glyph:'⌁',target:'book'}, }; function fail(message){ app.innerHTML=`
⌁

${esc(message)}

Use /page?npub=npub1…
`; } function fact(term,value,href){ return `
${esc(term)}
${href?`${esc(value)} ↗`:esc(value)}
`; } function moduleCard(id,state){ const meta=moduleMeta[id]; if(!meta||!state.enabled||state.status==='coming-soon')return ''; const url=link(meta.target); return `

${meta.glyph}${esc(meta.name)} ${state.status==='live'?'Live service':'Preview'}

${esc(meta.copy)}

${id==='order'?``:''} Open ${esc(meta.name)} →
`; } function render(data){ const merchant=data.merchant,about=(data.profile?.about||'').trim(),hero=data.images[0]||''; const facts=[merchant.hours,merchant.address,merchant.phone].filter(Boolean); document.title=`${merchant.name} — Just Works`; const cards=Object.entries(moduleMeta).map(([id,meta])=>moduleCard(id,data.modules[id]||{})).filter(Boolean).join(''); app.innerHTML=`
${hero?'
':''}
${esc([merchant.category,merchant.area].filter(Boolean).join(' · ')||'Merchant')}

${esc(merchant.name)}

${about?`

${esc(about)}

`:''} ${facts.length?`
${facts.map(item=>`${esc(item)}`).join('')}
`:''}
${cards?`

Just Works modules

Run the place from the page.

${cards}
`:''} ${data.images.length>1?``:''} ${(merchant.address||merchant.hours||merchant.phone||merchant.website)?`

Visit

Find us.

${merchant.address?fact('Address',merchant.address):''}${merchant.hours?fact('Hours',merchant.hours):''}${merchant.phone?fact('Phone',merchant.phone,`tel:${esc(merchant.phone)}`):''}${merchant.website?fact('Website',merchant.website.replace(/^https?:\/\//,''),merchant.website):''}${merchant.rating?fact('Rating',`★ ${merchant.rating} / 5`):''}
`:''}

Ownership

This page has a sovereign copy.

The same page is signed by the merchant and published to Nostr relays and Blossom storage. It resolves even if Just Works disappears.

View the nsite copy ↗
`; document.querySelectorAll('[data-logo]').forEach(host=>mountLogo(host,{icon:true})); } if(!npub)fail('Add the merchant npub.'); else fetch(`${base}/api/business?npub=${encodeURIComponent(npub)}`,{cache:'no-store'}) .then(async response=>{const data=await response.json();if(!response.ok)throw new Error(data.error||'Page unavailable');render(data)}) .catch(error=>fail(error.message));