Commit graph

12 commits

Author SHA1 Message Date
2cc8e34b9d feat(layout): re-enable "Back to hub" with a sticky sheet footer
Reverses the events-only hide (c037d45) now that the link has a real
home. Three parts:

- Add a @brand-hub-logo alias (brandHubLogoAliasEntry) resolving to the
  brand's primary/global logo — the HUB's logo, never the per-standalone
  @brand-app-logo. Wired into all 9 app vite configs since the shared
  ProfileSheetContent renders it.
- Restructure the profile sheet into a fixed-height flex column: a
  flex-1 min-h-0 overflow-y-auto scroll region over a shrink-0 footer,
  so "Back to hub" + the log-in/out bar stay pinned to the bottom while
  the identity/preferences area scrolls.
- Move the edit-profile Dialog out of the flex root (it portals to body,
  so it's not part of the sheet flow).

Logo bumped to w-8 h-8, centered, with tightened footer padding.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-20 00:26:52 +02:00
5700ac1d1a feat(branding): migrate hardcoded @brand/logo.png to SVG-aware alias
The four shared layout/login components (Login, LoginDemo,
AppSidebar, MobileDrawer) hardcoded `<img src="@brand/logo.png">`,
which means an SVG-only brand kit (like cfaun's) fails the build
with "Could not load @brand/logo.png".

Switch the four to `<img src="@brand-app-logo">` — the alias registered
via brandAppLogoAliasEntry() (already used by events module) resolves
to whichever of logo.{svg,png} exists in BRAND_DIR (SVG preferred),
with per-app overrides under BRAND_DIR/icons/<app>/.

Also register brandAppLogoAliasEntry in the 8 vite configs that
didn't have it (only events did before), converting their alias maps
to array form so the regex-based logo entry doesn't get shadowed by
the bare-string `@brand` and `@` aliases.

Verified:
- AIO default brand (PNG-only): builds, ships logo-<hash>.png — no regression.
- cfaun brand (SVG-only): builds, ships logo-<hash>.svg — previous
  ENOENT on logo.png gone.

Unblocks cfaun deploy with an SVG-only brand kit (no manual
rasterization needed).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-06-11 00:23:01 +02:00
3efae30e84 feat(branding): auto-generate icons on vite build/dev start
vite-branding.ts now exports brandAssetsPlugin() — a Vite plugin
whose buildStart hook runs scripts/generate-pwa-assets.mjs once per
build / dev-server start. All 9 vite configs register it first in
plugins[], so PWA icons under public/icons/ are guaranteed to exist
before VitePWA's includeAssets / manifest.icons get processed and
before the public/ → dist/ copy.

Removes the "did you remember to pnpm generate-pwa-assets?" failure
mode. Dev mode now also auto-populates icons (no more dev 404s on
/icons/favicon.ico).

Verified build from clean state (no public/icons/ pre-existing): the
plugin generates, all 6 icons land in dist-wallet/icons/.

Part of aiolabs/webapp#95.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-06-09 23:43:50 +02:00
faf41cd1c0 refactor(branding): switch to /icons/ paths and remove committed binaries
PWA icons now ship from public/icons/ (generated by
@vite-pwa/assets-generator, gitignored). The seven hand-crafted
binaries at public/ root come out of the tree.

Changes:
- 7 deleted: public/{favicon.ico, apple-touch-icon.png, mask-icon.svg,
  icon-{192,512}.png, icon-maskable-{192,512}.png}
- 9 HTML: <link rel="icon"|"apple-touch-icon"> hrefs prefixed with
  /icons/. mask-icon link dropped (PNG source → no sharp SVG; modern
  browsers prefer favicon.svg anyway, which we can revisit when an
  SVG brand source lands).
- 8 vite configs: includeAssets[] + manifest.icons[].src prefixed
  with icons/. Vite rewrites /icons/foo → <base>/icons/foo when base
  is set (so /events/icons/favicon.ico under /events/ deploys).

Build is now dependent on `pnpm generate-pwa-assets` running first
(or whatever invokes the generator — Phase 2 NixOS builds wire this
into buildNpmPackage). Standalone dev runs the generator on first
boot or whenever BRAND_DIR changes.

Part of aiolabs/webapp#95.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-06-09 23:37:55 +02:00
ce5a1a6a56 feat(branding): drive PWA manifest from brand.json
vite-branding.ts now loads brand.json into a typed `brand` object and
exports a `brandManifestName()` helper. Schema:

  { name (required), shortName?, themeColor?, backgroundColor? }

Default brand.json drops themeColor/backgroundColor — they're optional
overrides; per-app accents (wallet yellow, chat green, …) keep working
via `?? '<existing>'` fallbacks in each standalone's vite config.

events: manifest.name/short_name driven by brand. VITE_APP_NAME env
override stays (Phase 2 server-deploy migration still in flight) and,
when set, overrides both name and short_name to preserve pre-#95
behavior. cfaun's VITE_APP_NAME=Bouge keeps working unchanged.

hub (vite.config.ts): brand.name flows into %VITE_APP_NAME% Hub title.

7 other standalones (wallet, chat, market, forum, tasks, restaurant,
libra): only theme_color/background_color get brand overrides. Their
manifest.name/short_name stay hardcoded so multi-PWA home-screen
labels remain differentiated ("Wallet", "Chat", …) rather than all
collapsing to the brand short_name.

Verified default build: events manifest name=AIO; wallet keeps
"Wallet — Lightning" + #eab308 accent.
Verified VITE_APP_NAME=Sortir override: events name+short_name=Sortir.

Part of aiolabs/webapp#95.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-06-09 23:11:30 +02:00
eebb566323 feat(branding): add @brand vite alias + migrate in-app img consumers
vite-branding.ts is the shared resolver. Exports BRAND_DIR (absolute,
defaults to ./branding/default) and brandAlias for spreading into each
vite config's resolve.alias map.

All 9 vite configs now spread brandAlias so `@brand/<file>` resolves
to the active brand dir at build time.

Migrates the four <img src="@/assets/logo.png"> consumers
(Login.vue, LoginDemo.vue, AppSidebar.vue, MobileDrawer.vue) to
@brand/logo.png. Unused Navbar.old.vue left as-is.

Build verified: dist/assets/logo-<hash>.png emits from the aliased
import. Future deployers point BRAND_DIR at their brand kit and the
in-app logo follows automatically.

Part of aiolabs/webapp#95.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-06-09 22:55:42 +02:00
a0187a6604 fix(vite): rewrite to <app>.html when query has dots (JWT tokens)
The dev SPA-fallback plugin used `!req.url.includes('.')` to skip asset
requests, which also matched JWT-shaped `?token=hdr.body.sig` query
strings — so `localhost:5185/?token=...` fell through to the hub
`index.html` instead of `market.html`, breaking the hub→standalone
auth-relay link. Strip the query before the extension check.

Applied to all 7 standalone vite configs.
2026-05-03 16:02:06 +02:00
ae68eb09c4 fix(vite): give each app its own cacheDir to stop dep-race 504s
VitePWA-disabled was supposed to fix stale dev artefacts but each
of the 8 vite servers was still sharing one node_modules/.vite/deps
directory. Concurrent dep optimization runs (any of: server
restart, config edit, new import) raced for that single cache,
producing intermittent 504 "Outdated Optimize Dep" responses for
hashes the requesting tab still held — followed by Vue Router
"Failed to fetch dynamically imported module" cascades when the
victim was a route component (e.g., MarketPage.vue).

Each app now has its own cache dir:
  hub        node_modules/.vite-hub
  castle     node_modules/.vite-castle
  activities node_modules/.vite-activities
  wallet     node_modules/.vite-wallet
  chat       node_modules/.vite-chat
  forum      node_modules/.vite-forum
  market     node_modules/.vite-market
  tasks      node_modules/.vite-tasks

Set via vite's `cacheDir` option in each config. No more racing.
.gitignore already covers node_modules so the new dirs are ignored
automatically.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-02 14:56:58 +02:00
14b81bf3eb fix(vite): @/app.config alias must precede @ (first-match-wins)
@rollup/plugin-alias (which Vite uses) iterates alias entries in
definition order and uses the first match. Listing the broad '@' →
./src alias before the specific '@/app.config' → per-app override
means '@/app.config' is matched by '@' first and resolves to
./src/app.config — i.e. the hub config, not the standalone's.

For market this surfaced as:
  TypeError: Cannot read properties of undefined (reading 'config')
    at new NostrmarketAPI (nostrmarketAPI.ts:170:45)

(nostrmarketAPI reads appConfig.modules.market.config; the hub
config has only base.) The same bug affected castle (ExpensesAPI
reads modules.expenses.config) and wallet (WalletWebSocketService
reads modules.wallet.config.websocket) — both would crash on first
use even though their dev servers started fine. Castle and wallet
silently haven't been exercised yet in this session, so the bug
only surfaced from market.

Fix: put '@/app.config' first in the alias object in all 6
standalone vite configs (castle, market, wallet, chat, forum,
tasks). Comment added at each call site explaining the constraint.

The hub's vite.config.ts doesn't need the override — its
'@/app.config' resolves to ./src/app.config naturally, which IS
the hub config.

Activities (sortir) doesn't need the override either — its app.ts
imports from './app.config' (relative), and no module file under
src/modules/activities reads from '@/app.config'.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-02 14:53:40 +02:00
613a925e45 fix(pwa): disable service worker in dev across all 8 vite configs
Was: every standalone (and the hub) registered a service worker
during \`npm run dev\` via VitePWA's devOptions.enabled = true.

Problem: the dev SW caches index.html and the JS bundle on first
load and survives across vite restarts. Any code change that
required a server restart (e.g. fixing a vite.config.ts merge
conflict) resulted in browsers continuing to serve the cached
pre-restart bundle until the user manually unregistered the SW.
This caused the hub at localhost:5173 to redirect to /market on
refresh — the cached bundle was from the broken-config period
which still had the old monolithic main app's market route.

PWA features (offline, install prompts, manifest) are still tested
by running:
  npm run preview            # for the hub
  npm run preview:<name>     # for any standalone

against a real production build, which is the more accurate
environment for PWA verification anyway.

Recovery for anyone with a stale SW lingering in their browser
(needed once after pulling, then never again):
  1. DevTools → Application → Service Workers → Unregister
  2. DevTools → Application → Storage → Clear site data
  3. Hard reload (Ctrl-Shift-R)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-02 10:58:34 +02:00
9a1e5e3994 chore(dev): pin standalone ports + add dev:all script
Fixed-port assignments for each standalone vite dev server, with
strictPort to fail loud if a port is taken (no silent +1 increment
that would break the hub's hardcoded VITE_HUB_<NAME>_URL targets):

  hub        5173  (npm run dev)
  castle     5180
  sortir     5181  (activities)
  wallet     5182
  chat       5183
  forum      5184
  market     5185
  tasks      5186

`npm run dev:all` boots the hub and all 7 standalones concurrently
via the existing concurrently devDep. The hub's chakra tiles point
at these ports via VITE_HUB_<NAME>_URL in .env.local for end-to-end
local testing of the cross-subdomain auth relay.

Pure dev infrastructure — no production behaviour change.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-02 10:10:43 +02:00
3f88ea731e feat: add standalone tasks PWA build
Adds a standalone tasks PWA at tasks.${domain}, built from the
existing src/modules/tasks plugin (Nostr calendar events, kind
31922/31925). Same standalone pattern as the other modules:
- tasks.html entry, vite.tasks.config.ts (outDir: dist-tasks,
  manifest id: tasks-app, theme: indigo #4338ca — Ajna chakra)
- src/tasks-app/{main.ts, app.ts, app.config.ts, App.vue} bootstraps
  base + tasks only, with acceptTokenFromUrl for shared auth from hub
- npm run dev:tasks / build:tasks / preview:tasks
- main app SW denylist extended with /tasks/

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-02 08:58:54 +02:00