diff --git a/apps/web/package.json b/apps/web/package.json index 614c306..f169a2f 100644 --- a/apps/web/package.json +++ b/apps/web/package.json @@ -8,6 +8,7 @@ }, "dependencies": { "@profullstack/affiliates": "0.3.0", + "@profullstack/footer": "latest", "@profullstack/profile": "0.1.6", "@profullstack/redeem-credits": "0.2.0", "@profullstack/sealed-secrets": "0.1.0", diff --git a/apps/web/public/index.html b/apps/web/public/index.html index b8c6939..f2c58ba 100644 --- a/apps/web/public/index.html +++ b/apps/web/public/index.html @@ -33,6 +33,7 @@
Product + Health tracker Get paid Agents Import @@ -339,12 +340,6 @@

- © Profullstack, Inc. - Listed on built.indieGet it on pwamart - Terms - Privacy -

diff --git a/apps/web/src/app.js b/apps/web/src/app.js index 1a24784..5ceb43b 100644 --- a/apps/web/src/app.js +++ b/apps/web/src/app.js @@ -7,7 +7,7 @@ import { Hono } from 'hono'; import { x402Gateway } from '@profullstack/x402-gateway/hono'; import { createCrawlGate } from './crawl-gate.js'; import { api, coinpayWebhook, saveSignup } from './api.js'; -import { withPitFooter } from './pit-footer.js'; +import { withUniversalFooter } from './universal-footer.js'; import * as auth from './auth.js'; import { config } from './config.js'; import * as credits from './credits.js'; @@ -35,12 +35,28 @@ export const crawlGate = createCrawlGate(); if (crawlGate) app.use('*', x402Gateway(crawlGate)); // The landing page is built from the design canvas (design/Main.dc.html). Every -// page gets the pit.world network footer as the last thing in . +// HTML page gets the shared Profullstack footer as the last thing in . const page = async (c, name) => - c.html(await withPitFooter(pub(name).toString().replace('', String(new Date().getFullYear())))); + c.html(await withUniversalFooter(pub(name).toString().replace('', String(new Date().getFullYear())))); app.get('/', (c) => page(c, 'index.html')); app.get('/healthz', (c) => c.text('ok')); +// The personal health tracker is a local-first PWA. It has no account or API +// calls; readings live in the visitor's IndexedDB and never reach the server. +app.get('/health/', (c) => c.redirect('/health', 301)); +app.get('/health', (c) => + c.body(pub('health/index.html'), 200, { 'content-type': 'text/html; charset=utf-8', 'cache-control': 'no-cache' }), +); +app.get('/health/health.css', (c) => + c.body(pub('health/health.css'), 200, { 'content-type': 'text/css; charset=utf-8', 'cache-control': 'no-cache' }), +); +app.get('/health/health.js', (c) => + c.body(pub('health/health.js'), 200, { 'content-type': 'text/javascript; charset=utf-8', 'cache-control': 'no-cache' }), +); +app.get('/health/manifest.webmanifest', (c) => + c.body(pub('health/manifest.webmanifest'), 200, { 'content-type': 'application/manifest+json', 'cache-control': 'no-cache' }), +); + // The app: one shell for the team, patients and sign-in. It talks only to /api/v1. // The shared profile fields (@profullstack/profile) ride in the shell as a //