feat: minimal AIO hub with chakra grid + bottom dock

The all-in-one app at app.${domain} is a minimal hub: only the base
module (auth, profile, relays, PWA, image upload) plus a chakra-
themed entry point linking out to the seven standalone module PWAs
(market, sortir, wallet, chat, forum, tasks, castle), with an
eighth tile reserved for a forthcoming restaurant module.

UI:
- 2-column grid of 8 module tiles with Lucide icons, occupying the
  full viewport between the title and the bottom dock. Status hints
  (alpha/beta/coming soon) shown beneath each label.
- Faint chakra-mandala column rendered behind the tiles (peeks
  through their translucent backgrounds), plus a subtle vertical
  hue gradient (red at the bottom → violet at the top) — the chakras
  inform the visual frame without forcing a 1:1 module mapping.
- Bottom dock with system-level controls: Profile (Sheet hosting
  the existing ProfileSettings.vue), Theme (light/dark/system),
  Language (uses available locales), and a Currency placeholder.
- Each tile is a link to VITE_HUB_<NAME>_URL with the user's
  lnbits_access_token appended as ?token= so the destination logs
  in via the existing acceptTokenFromUrl() relay.

Wiring:
- src/App.vue: stripped to the same minimal shell as the standalone
  apps (no AppLayout/AppSidebar — the hub is the navigation).
- src/app.ts: only base module is registered. Hub is the / route.
- src/app.config.ts: only base module config remains.
- public/chakras/*.svg: 7 chakra mandala SVGs copied from the legacy
  frontend (Atitlan.io).
- nginx.conf.example: rewritten with one server block per subdomain
  pointing at its own dist-<name>/ output.

Closes #26.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Padreug 2026-05-02 09:04:14 +02:00
commit 9a3e3ae0ed
12 changed files with 1024 additions and 332 deletions

View file

@ -1,45 +1,125 @@
# Main context
worker_processes auto; # Automatically determine worker processes based on CPU cores
worker_processes auto;
events {
worker_connections 1024; # Maximum connections per worker
worker_connections 1024;
}
http {
default_type application/octet-stream;
# Trust the custom Docker network subnet
set_real_ip_from 0.0.0.0;
real_ip_header X-Forwarded-For;
real_ip_recursive on;
# Reusable location blocks
# JS / CSS / image MIME and caching
map $sent_http_content_type $cache_static {
default "off";
~image/ "6M";
}
# ───────────────────────────────────────────────────────────────
# AIO hub — minimal app at app.<domain>
# Serves only the chakra icon hub + base infra (profile, relays).
# ───────────────────────────────────────────────────────────────
server {
listen 8080;
server_name <domain>.<com>;
server_name app.<domain>.<com>;
root /app;
root /var/www/aio/dist;
index index.html;
location / {
try_files $uri $uri/ /index.html;
}
location ~* \.js$ {
types { application/javascript js; }
default_type application/javascript;
location / { try_files $uri $uri/ /index.html; }
location ~* \.js$ { types { application/javascript js; } default_type application/javascript; }
location ~* \.css$ { types { text/css css; } default_type text/css; }
location ~* \.(png|jpe?g|webp|ico|svg)$ { expires 6M; access_log off; }
}
# Serve CSS files with the correct MIME type
location ~* \.css$ {
types { text/css css; }
default_type text/css;
# ───────────────────────────────────────────────────────────────
# Standalone module PWAs — one server block per subdomain
# ───────────────────────────────────────────────────────────────
# Marketplace — Muladhara
server {
listen 8080;
server_name market.<domain>.<com>;
root /var/www/aio/dist-market;
index market.html;
location / { try_files $uri $uri/ /market.html; }
location ~* \.js$ { types { application/javascript js; } default_type application/javascript; }
location ~* \.css$ { types { text/css css; } default_type text/css; }
location ~* \.(png|jpe?g|webp|ico|svg)$ { expires 6M; access_log off; }
}
# Serve image files
location ~* \.(png|jpe?g|webp|ico)$ {
expires 6M; # Optional: Cache static assets for 6 months
access_log off;
# Activities — Swadhisthana
server {
listen 8080;
server_name sortir.<domain>.<com>;
root /var/www/aio/dist-activities;
index activities.html;
location / { try_files $uri $uri/ /activities.html; }
location ~* \.js$ { types { application/javascript js; } default_type application/javascript; }
location ~* \.css$ { types { text/css css; } default_type text/css; }
location ~* \.(png|jpe?g|webp|ico|svg)$ { expires 6M; access_log off; }
}
# Wallet — Manipura
server {
listen 8080;
server_name wallet.<domain>.<com>;
root /var/www/aio/dist-wallet;
index wallet.html;
location / { try_files $uri $uri/ /wallet.html; }
location ~* \.js$ { types { application/javascript js; } default_type application/javascript; }
location ~* \.css$ { types { text/css css; } default_type text/css; }
location ~* \.(png|jpe?g|webp|ico|svg)$ { expires 6M; access_log off; }
}
# Chat — Anahata
server {
listen 8080;
server_name chat.<domain>.<com>;
root /var/www/aio/dist-chat;
index chat.html;
location / { try_files $uri $uri/ /chat.html; }
location ~* \.js$ { types { application/javascript js; } default_type application/javascript; }
location ~* \.css$ { types { text/css css; } default_type text/css; }
location ~* \.(png|jpe?g|webp|ico|svg)$ { expires 6M; access_log off; }
}
# Forum — Vishuddha
server {
listen 8080;
server_name forum.<domain>.<com>;
root /var/www/aio/dist-forum;
index forum.html;
location / { try_files $uri $uri/ /forum.html; }
location ~* \.js$ { types { application/javascript js; } default_type application/javascript; }
location ~* \.css$ { types { text/css css; } default_type text/css; }
location ~* \.(png|jpe?g|webp|ico|svg)$ { expires 6M; access_log off; }
}
# Tasks — Ajna
server {
listen 8080;
server_name tasks.<domain>.<com>;
root /var/www/aio/dist-tasks;
index tasks.html;
location / { try_files $uri $uri/ /tasks.html; }
location ~* \.js$ { types { application/javascript js; } default_type application/javascript; }
location ~* \.css$ { types { text/css css; } default_type text/css; }
location ~* \.(png|jpe?g|webp|ico|svg)$ { expires 6M; access_log off; }
}
# Castle — Sahasrara (accounting)
server {
listen 8080;
server_name castle.<domain>.<com>;
root /var/www/aio/dist-castle;
index castle.html;
location / { try_files $uri $uri/ /castle.html; }
location ~* \.js$ { types { application/javascript js; } default_type application/javascript; }
location ~* \.css$ { types { text/css css; } default_type text/css; }
location ~* \.(png|jpe?g|webp|ico|svg)$ { expires 6M; access_log off; }
}
}