Commit graph

1,023 commits

Author SHA1 Message Date
c0be2ca053 merge: wallet standalone 2026-05-02 09:14:13 +02:00
a162b0789f merge: forum rename 2026-05-02 09:14:13 +02:00
55324a0501 feat: add standalone forum PWA build
Adds a standalone forum PWA at forum.${domain}, built from the
existing src/modules/forum plugin (NIP-72 communities + kind 1111
posts + voting). Same standalone pattern as the other modules:
- forum.html entry, vite.forum.config.ts (outDir: dist-forum,
  manifest id: forum-app, theme: blue #2563eb — Vishuddha chakra)
- src/forum-app/{main.ts, app.ts, app.config.ts, App.vue} bootstraps
  base + forum only, with acceptTokenFromUrl for shared auth from hub
- new ForumListPage view + /forum route added to the forum module
  (previously the list was only embedded in Home.vue)
- npm run dev:forum / build:forum / preview:forum
- main app SW denylist extended with /forum/, /submit/, /submission/

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-02 09:00:58 +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
455dc6571e feat: add standalone marketplace PWA build
Adds a standalone Nostr marketplace PWA at market.${domain}, built
from the existing src/modules/market plugin. Same standalone pattern
as wallet/chat/castle/activities:
- market.html entry, vite.market.config.ts (outDir: dist-market,
  manifest id: market-app, theme: red #dc2626 — Muladhara chakra)
- src/market-app/{main.ts, app.ts, app.config.ts, App.vue} bootstraps
  base + market only, with acceptTokenFromUrl for shared auth from hub
- npm run dev:market / build:market / preview:market
- main app SW denylist extended with /market/, /cart/, /checkout/

Closes #18.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-02 08:57:34 +02:00
ee8f1d9ba6 feat: add standalone chat PWA build
Adds a standalone encrypted chat PWA at chat.${domain}, built from
the existing src/modules/chat plugin. Same standalone pattern as
wallet/castle/activities:
- chat.html entry, vite.chat.config.ts (outDir: dist-chat,
  manifest id: chat-app, theme: green #16a34a — Anahata chakra)
- src/chat-app/{main.ts, app.ts, app.config.ts, App.vue} bootstraps
  base + chat only, with acceptTokenFromUrl for shared auth from hub
- npm run dev:chat / build:chat / preview:chat
- main app SW denylist extended with /chat/

Closes #20.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-02 08:56:13 +02:00
455cfbc764 feat: add standalone wallet PWA build
Adds a standalone Lightning wallet PWA at wallet.${domain}, built
from the existing src/modules/wallet plugin. Mirrors the Castle and
Activities standalone patterns:
- wallet.html entry, vite.wallet.config.ts (outDir: dist-wallet,
  manifest id: wallet-app, theme: yellow #eab308 — Manipura chakra)
- src/wallet-app/{main.ts, app.ts, app.config.ts, App.vue} bootstraps
  base + wallet only, with acceptTokenFromUrl for shared auth from hub
- npm run dev:wallet / build:wallet / preview:wallet
- main app SW denylist extended with /wallet/

Closes #19.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-02 08:54:36 +02:00
af338016c6 refactor: rename links module to forum
The links module already implements a reddit-style link aggregator
(NIP-72 communities + kind 1111 + voting). Renaming to forum aligns
the module name with its purpose ahead of extracting it as a
standalone PWA at forum.${domain}.

This is a pure rename — no behavior changes. Affects:
- src/modules/links → src/modules/forum (git mv)
- linksModule export → forumModule
- appConfig.modules.links → appConfig.modules.forum
- log/event source strings: 'links' → 'forum'

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-02 08:52:37 +02:00
f4d5594bef feat: add login icon in top-right of Castle app when not authenticated
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-27 19:55:45 +02:00
7181b55d52 fix: scope PWA service workers to prevent cross-app interference
When multiple SPAs share the same origin (e.g., /sortir/ and /castle/
on demo.aiolabs.dev), their service workers conflict. Each app's
workbox now scopes its navigateFallback with navigateFallbackAllowlist,
and the main app excludes standalone paths via navigateFallbackDenylist.

- Main app: denylist /sortir/ and /castle/ from its service worker
- Sortir: allowlist only /sortir/ paths, fallback to activities.html
- Castle: allowlist only /castle/ paths, fallback to castle.html
- Icon paths use relative URLs (work with any base path)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-27 19:48:45 +02:00
87f649f048 feat: add login icon button when user is not authenticated
Shows a LogIn icon next to the refresh button on the activities
page when the user isn't logged in.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-27 19:12:47 +02:00
f60b9ca1d4 fix: handle nullable event_end_date in EventsPage and useEvents
event_end_date is now optional (null when not provided). Update
formatDate to accept null, and pastEvents filter to fall back
to event_start_date.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-27 18:58:02 +02:00
5ec8f21986 feat: add geohash map picker coming soon indicator on event form
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-27 18:31:14 +02:00
31efc50fad refactor: use single POST /events endpoint with invoice key
Remove proposeEvent(), consolidate to createEvent() with invoice key.
Backend determines approval status based on user role and settings.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-27 18:24:36 +02:00
f44c3827b1 feat: use propose endpoint for user event creation
Replace CreateActivityDialog (direct Nostr publish) with
CreateEventDialog (LNbits propose flow) on ActivitiesPage.
Users submit events via POST /events/propose with invoice key.
Admin reviews and approves before events go live.

Add proposeEvent() to TicketApiService for invoice-key auth.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-27 18:13:53 +02:00
dcb26db685 feat: simplify event creation form, add location + categories
- Only title and start date are required
- Description, location, categories, image, tickets visible by default
- End date and promo codes in collapsible "More options" section
- Categories use badge toggles matching the activities module
- Use ScrollArea for proper shadcn scrolling
- Update CreateEventRequest and TicketedEvent types for new fields

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-27 18:07:44 +02:00
38492ad592 fix: support demo login in standalone apps
Standalone apps now conditionally load LoginDemo.vue when
VITE_DEMO_MODE=true, matching the main app's behavior.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-27 17:51:33 +02:00
1edea25862 feat: support path-based deployment for standalone apps
Add VITE_BASE_PATH support to standalone app configs so they can be
served under a path prefix (e.g., app.domain.com/sortir/) instead of
a separate subdomain. This enables shared auth via same-origin
localStorage.

- Vite configs: configurable base path via VITE_BASE_PATH env var
- Routers: use import.meta.env.BASE_URL for history base
- PWA manifests: use base path for start_url and scope
- Default: / (backward compatible with subdomain mode)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-27 17:43:49 +02:00
cf08b76515 fix: improve task event filtering in activities feed
Filter by both event-type:task tag and presence of status tag
(NIP-52 calendar events don't have status on kind 31922, only
on RSVP kind 31925). This catches manually-created task events
that may not have the event-type tag.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-27 00:12:12 +02:00
680b1a97e6 fix: filter out task events from activities feed
Tasks reuse NIP-52 kind 31922 but tag events with event-type:task.
Filter these out in parseNostrEventToActivity so household chores
don't show up as community activities.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-27 00:00:08 +02:00
357ec3f3e1 fix: use POST endpoint for ticket purchase (upstream API compat)
The GET /tickets/{event_id}/user/{user_id} endpoint was a custom
addition not present in the upstream LNbits events extension. Use
the canonical POST /tickets/{event_id} with user_id in the body.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-26 23:44:39 +02:00
b265296210 fix: register activities module in main app
The activities module was only registered in the standalone Sortir app,
not the main app. When events module was removed, its registration was
deleted but activities was never added in its place.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-26 23:26:09 +02:00
e61d3c4d46 Consolidate events ticketing into activities module
Absorb the disabled events module into the active activities module,
eliminating duplicated LNbits events extension API surface and legacy
imports. Activities now owns all ticketing UI (EventsPage, MyTicketsPage
with QR codes, PurchaseTicketDialog, CreateEventDialog) alongside its
existing Nostr NIP-52 calendar event discovery.

- Internalize payInvoiceWithWallet in PaymentService (core LNbits endpoint)
- Enhance TicketApiService with createEvent and getCurrencies methods
- Add TICKET_API DI token for canonical ticket service access
- Port composables (useTicketPurchase, useUserTickets, useEvents) with DI
- Port components (PurchaseTicketDialog, CreateEventDialog)
- Replace MyTicketsPage placeholder with full QR-code ticket display
- Add /events route to activities module
- Delete src/modules/events/, src/lib/api/events.ts, src/lib/types/event.ts

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-26 22:26:28 +02:00
bac9fd091e Fix balance sign interpretation on Castle balance page
Castle API returns positive = user owes castle, negative = castle owes
user. The display was inverted, showing "you owe" after submitting an
expense when it should show "owed to you".

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-25 17:07:26 +02:00
b0729ea23d Add demo login page behind VITE_DEMO_MODE feature flag
Restores LoginDemo.vue from the demo-login branch. When
VITE_DEMO_MODE=true, the main app uses LoginDemo.vue which allows
instant demo account creation with auto-generated credentials.

Production deployments are unaffected (flag defaults to false).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-25 16:39:55 +02:00
d498030da0 Add standalone Castle accounting app
New standalone app at castle.html with its own Vite config, app shell,
and bottom nav (Record, Transactions, Balance, Wallet, Settings). Reuses
existing expenses and wallet modules with base module for a focused
accounting experience.

Features:
- Expense submission via existing AddExpense dialog
- Income submission placeholder (feature-flagged, pending backend)
- Balance page with pending expense tracking
- Expense drafts with receipt photo upload and BTC price snapshots
- Cross-subdomain auth token relay via ?token= URL parameter
- i18n support (en/fr/es)
- PWA with offline support

Also adds token relay to activities-app for consistent cross-app auth.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-25 16:08:53 +02:00
Patrick Mulligan
b1e8534ca7 merge nostrized-events module into unified main
Adds the standalone activities/events PWA build:
- vite.activities.config.ts (standalone entry point)
- build:activities npm script
- i18n support (Spanish Latin American translations)
- Map/calendar UI improvements

Conflicts resolved keeping main-unified's module system
(links, tasks, expenses, di-container, navigation).
2026-04-25 07:38:17 -04:00
Patrick Mulligan
efacc43429 merge atio features into unified main branch
Merge atio's UI improvements (sidebar layout, chat fixes, checkout
simplification, z-index fixes) into cfaun's module system (links,
tasks, expenses).

Conflicts resolved keeping cfaun's versions for:
- Home.vue (multi-action FAB with quick actions)
- di-container.ts, useModularNavigation.ts (module registry)
- nostr-feed/index.ts (disabled, replaced by links)
- package.json/lock (cfaun's dependency tree)

Branding files kept as cfaun's — per-target branding should come
from build-time config, not branches.

Removed: target-ui.md (atio reference doc, no longer needed)

Next: refactor app.config.ts to read enabled modules from VITE_*
env vars so per-target config lives in the deploy flake.
2026-04-25 04:09:20 -04:00
93c2a73e21 Internationalize all UI strings and localize date formatting
All hardcoded English strings now use t() with i18n keys: bottom nav
tabs, search placeholder, empty states, favorites page, settings page.

Added useDateLocale composable that maps the current i18n language to
the corresponding date-fns locale (fr/es/enUS). All date formatting
across ActivityCard, ActivityDetailPage, DatePickerStrip, calendar
view, and search overlay now passes the locale to date-fns format().
Month names, day names, and date labels change with language switch.

Added nav, search, favorites, and settings i18n sections to all three
locales (EN/FR/ES).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-21 07:24:43 +02:00
f782cd1a7a Replace inline search with dropdown overlay for mobile
New ActivitySearchOverlay component: compact dropdown anchored to the
search input showing thumbnail, title, date, and location for each
result. Limited to 8 results, scrollable. Stays visible above the
keyboard on mobile. Tap a result to navigate, tap outside or clear
to dismiss. Uses the same Fuse.js fuzzy search under the hood.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-20 17:25:07 +02:00
a75885ca76 Only fit map bounds on initial load, not on every activity update
Prevents the map from resetting zoom/pan when new activities stream
in from relays. Users can now freely zoom and pan without being
snapped back to the world view.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-20 15:46:39 +02:00
276e1a8135 Fix empty state icon: use CalendarSearch with element opacity
Replaces Calendar with CalendarSearch for better empty-state semantics.
Uses opacity-30 on the element instead of text color opacity to avoid
visible stroke overlaps on SVG icons.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-20 15:43:57 +02:00
36c8cb8c7a Add Spanish (Latin American) activities translations
Full activities i18n for Spanish: categories, detail page, tickets,
filters. Uses Latin American terminology (boleto instead of entrada,
charla instead of ponencia). Added Spanish to the standalone app
Settings language picker alongside French and English.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-20 13:08:37 +02:00
2ceedf8bbf Add env vars for default locale and map center
VITE_DEFAULT_LOCALE (fr/en/es) sets the initial language for the
standalone app when no user preference is saved. VITE_DEFAULT_MAP_CENTER
(lat,lng) configures the default map center point. Both fall back to
sensible defaults (fr and France center) when not set.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-20 12:55:08 +02:00
8a3ff14568 Skip activities with invalid dates in calendar view
Prevents RangeError from format() on activities with unparseable
start timestamps.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-20 12:44:49 +02:00
4926c3a313 Add map and calendar views (Phase 5)
Map view: Leaflet + OpenStreetMap with markers from NIP-52 geohash
tags. Click popup navigates to activity detail. Auto-fits bounds to
show all markers. Geohash decoding via ngeohash added to Activity
model conversion.

Calendar view: Month grid with activity dots (up to 3 per day).
Click a day to see activities listed below the calendar. Month
navigation with prev/next buttons.

New dependencies: leaflet, @types/leaflet, ngeohash, @types/ngeohash.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-20 12:41:38 +02:00
e0dde90adc Show toast with login link instead of redirecting for bookmark/RSVP
Both BookmarkButton and RSVPButton now show a toast notification
with a "Log in" action button when tapped by unauthenticated users.
RSVP buttons are now always visible (not hidden behind v-if).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-20 12:35:37 +02:00
bd6ba375b3 Replace plain text search with Fuse.js fuzzy search
Uses the existing FuzzySearch component and useFuzzySearch composable
(same pattern as market module). Searches across title (50%), summary
(20%), description (15%), location (10%), and tags (5%) with threshold
0.35. Fuzzy search feeds into the display list after temporal/category/
date filters are applied. Removed manual string search from filter
composable.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-20 08:42:10 +02:00
272288f1e2 Move bookmark heart from image overlay to title row in card
Heart is now next to the title text in the caption area where
it's always visible regardless of the background image.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-20 08:36:58 +02:00
ced192b65e Show bookmark heart to all users, redirect to login if not authenticated
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-20 08:34:47 +02:00
c62229c795 Add social features: bookmarks, RSVP, organizer profiles (Phase 4)
Bookmarks (NIP-51 kind 10003): useBookmarks composable publishes/reads
bookmark lists with 'a' tag references to calendar events. BookmarkButton
(heart icon) on activity cards and detail page. Favorites page shows
bookmarked activities.

RSVP (NIP-52 kind 31925): useRSVP composable publishes addressable RSVP
events with accepted/declined/tentative status. RSVPButton with Going/
Maybe/Not Going toggle and attendee count on detail page.

Organizer profiles (NIP-01 kind 0): useOrganizerProfile fetches metadata
from relays with global cache. OrganizerCard displays avatar, name, and
nip05. useBatchProfiles for bulk fetching.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-20 08:31:21 +02:00
703e093488 Add dist-* to gitignore for standalone app build outputs
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-20 08:23:25 +02:00
05befc8a24 Fix date strip to show all 7 days on mobile
Use CSS grid (grid-cols-7) instead of flex with min-width so all days
always fit. Single-letter day names (M T W T F S S) instead of
three-letter abbreviations to save horizontal space.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-20 08:12:11 +02:00
0238716acf Fix date filtering and timestamp parsing
- parseTimestamp now handles unix seconds, milliseconds, and ISO strings;
  returns NaN for unparseable values instead of 0 (which caused Jan 1 1970)
- Events with unparseable start timestamps are rejected by the parser
- ActivityCard safely handles invalid dates without crashing
- DatePickerStrip day selection now filters activities to that date
- Selecting a day clears temporal pills; selecting a pill clears the day
- Feed shows all activities sorted by date (no more upcoming/past split)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-20 08:09:37 +02:00
021198ab0f Keep temporal filter pills on single row
Use horizontal scroll with hidden scrollbar instead of flex-wrap.
Pills stay on one line and scroll on narrow screens.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-20 08:02:07 +02:00
76840567cb Remove Upcoming/Past tabs from activities feed
Replace tabbed layout with a single continuous feed matching p'a semana
style. Temporal filter pills already handle time-based filtering.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-20 08:01:06 +02:00
63c20e39ae Move refresh to compact icon button in header row
Refresh is now a ghost icon-only button next to the title instead of
a full-width outlined button. Create button text hidden on mobile
(icon-only). Saves vertical space on small screens.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-20 08:00:01 +02:00
ac163d3b82 Add activity creation and publishing (Phase 2)
CreateActivityDialog with vee-validate + Zod form: title, summary,
description, start/end date+time, location, categories (multi-select),
and image URL. Signs NIP-52 kind 31923 events with user's signing key
via nostr-tools finalizeEvent and publishes through RelayHub. Fixed
ActivitiesNostrService.publishCalendarEvent to properly sign events
before publishing. CategorySelector and LocationPicker helper components.
Create button visible only to authenticated users.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-20 07:58:41 +02:00
00eddc9189 Add standalone Sortir activities app (sortir.ariege.io)
Second Vite entry point for deploying the activities module as an
independent PWA at sortir.ariege.io. Includes its own App.vue with
bottom navigation bar (p'a semana style: Feed, Calendar, Map, Favorites,
Settings), stripped-down app config (base + activities only), French
PWA manifest, and SPA fallback plugin for dev server. New routes for
calendar, map, and favorites views (placeholder). Settings page with
theme toggle, language switcher (FR/EN), and auth.

Build: npm run build:activities -> dist-activities/
Dev:   npm run dev:activities -> localhost:5173

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-20 07:40:26 +02:00
eebc1865c9 Add activities event discovery UI (Phase 1)
Composables (useActivities, useActivityFilters, useActivityDetail) for
subscribing to NIP-52 calendar events, filtering by temporal range and
category, and loading single activity details. Components: ActivityCard
with image/placeholder, date, location, category badge; ActivityList
with responsive grid, loading skeletons, and empty state; TemporalFilterBar
(today/tomorrow/week/month pills); CategoryFilterBar (25 categories);
DatePickerStrip (horizontal week calendar). Full ActivitiesPage with
search, filters, upcoming/past tabs. ActivityDetailPage with hero image,
organizer info, and description. Activities nav link added (no auth required).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-19 18:48:53 +02:00