Commit graph

1,004 commits

Author SHA1 Message Date
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
e98356ffa0 Add activities module foundation (Phase 0)
Nostr-native communal events module using NIP-52 Calendar Events.
Includes types (activity, ticket, category, NIP-52 parsers/builders),
services (ActivitiesNostrService, TicketApiService, PaymentProvider
abstraction with LNbits implementation), Pinia store with deduplication,
module plugin with DI registration, i18n (EN/FR/ES), and placeholder views.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-19 18:46:04 +02:00
Patrick Mulligan
6e4449ac3d Optimize market images with pict-rs thumbnails
Market components were serving full-resolution images regardless of
display size. Now uses pict-rs on-the-fly processing to serve WebP
thumbnails at appropriate sizes:

- ProductCard: 400px thumbnails (was full-res for 192px cards)
- CartItem: 128px thumbnails (was full-res for 64px display)
- CartSummary: 64px thumbnails (was full-res for 32px display)
- CheckoutPage: 128px thumbnails (was full-res for 64px display)
- StallView logo: 128px thumbnails (was full-res for 56px display)

Adds useImageOptimizer composable wrapping ImageUploadService.

Closes #8

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 22:59:59 -04:00
Patrick Mulligan
667b8eebc2 Pin Add Expense dialog to top of viewport
Prevents the dialog from shifting up/down as account search results
change the content height, which caused it to move behind the
virtual keyboard on mobile.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 22:01:15 -04:00
Patrick Mulligan
4a89c02dbd Add fuzzy search to expense account selector
Users can now type to search accounts instead of manually navigating
the hierarchy. Uses existing FuzzySearch component with Fuse.js.
Search matches against account names and descriptions. The hierarchical
browser remains available when the search input is empty.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 13:04:26 -04:00
Patrick Mulligan
fd5eb9824e Restore multi-action FAB on Home page
The simplified Home.vue lost the useQuickActions system, which meant
module quick actions (expenses, submit link) were no longer accessible.
Restore the expandable FAB that shows all registered module actions.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 12:54:39 -04:00
Patrick Mulligan
8176ea9c69 Refactor: extract links and tasks into independent modules
- Create links module (link aggregator from atio branch) with SubmissionService,
  LinkPreviewService, voting, ranking, and full submission UI
- Create tasks module with TaskService (own relay subscription for kinds
  31922/31925), extracted from nostr-feed's ScheduledEventService
- Promote ProfileService and ReactionService to base module as shared services
- Replace Home.vue feed with SubmissionList from links module
- Disable nostr-feed module (kept in codebase for future re-enablement)
- Add links and tasks to app.config, app.ts, navigation, and DI container

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 12:32:32 -04:00
c74fd29bb0 update images for atio 2026-01-09 16:30:25 +01:00
651e8c035c Fix NIP-04 decryption for outgoing messages in chat
The processIncomingMessage function was also being called for outgoing
messages from loadRecentMessagesForPeer, but was using the wrong pubkey
for decryption. NIP-04 requires YOUR private key + the OTHER party's
public key.

For outgoing messages, event.pubkey is the user's own pubkey, but it
should use the recipient's pubkey from the p-tag for decryption.

This fix:
- Detects if message is outgoing (event.pubkey === userPubkey)
- For outgoing: gets recipient pubkey from p-tag
- For incoming: uses event.pubkey (sender)
- Sets sent flag correctly based on direction
- Associates message with the correct peer

Fixes "aes/pcks5: wrong padding" console errors.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-09 16:24:05 +01:00
465dcf988e Add LNbits attribution to sidebar footer
- Add "Powered by LNbits" link to both desktop and mobile sidebars
- Links to lnbits.com in new tab
- Includes separator divider above attribution

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-09 16:24:04 +01:00
32ccd3fa92 Fix profile dropdown width to show full currency display
- Increase dropdown width from w-56 to w-64
- Prevents EverQuest-style coin display from being cut off

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-09 16:24:04 +01:00
73e0cf8567 Comment out unimplemented Settings and Relay Hub Status links
- Comment out Settings link in both desktop and mobile sidebars
- Comment out Relay Hub Status in user menu dropdown
- Add TODO comments to review implementing these in the future
- Comment out unused imports to fix TypeScript errors

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-09 16:24:04 +01:00
db4c330b03 Add styled order message cards in chat
- Create ChatMessageContent component to detect and render order messages
- Display order details in a clean card format instead of raw JSON
- Show item count, shipping zone with truck icon, and short order ID
- Falls back to plain text for non-order messages

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-09 16:24:03 +01:00
a18e0697e4 Fix View My Orders navigation to select orders tab
- Add query parameter support (?tab=orders) to Market Dashboard
- Update CheckoutPage to navigate with tab=orders query param
- Dashboard validates tab param against allowed values

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-09 16:24:02 +01:00
d14902c737 Simplify checkout flow and payment options
- Combine shipping and contact info into single step
- Remove BTC Onchain and Cashu payment options (Lightning only for now)
- Add collapsible section for optional contact info (email, npub, address)
- Keep shipping address visible when required for physical delivery
- Keep message to merchant visible by default
- Add TODO comment for future payment method expansion

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-09 16:24:01 +01:00
4a89652ad8 Fix stall update API to use PUT with full object
- Changed updateStall from PATCH to PUT (LNbits API requirement)
- Updated to send full stall object instead of partial update
- Merges form values with existing stall data before sending

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-09 16:23:34 +01:00
2ee4aafd05 Fix z-index layering for page headers below app top bar
- Changed Home.vue sticky header from z-40 to z-30
- Changed SubmissionDetail.vue sticky header from z-40 to z-30
- AppTopBar remains at z-40, ensuring it stays above page content

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-09 16:23:23 +01:00
4f596b7d97 use aio logo 2026-01-09 16:23:10 +01:00
012073c42f commit target-ui for reference 2026-01-06 23:33:37 +01:00
Patrick Mulligan
02482720fa feat(layout): Replace top navbar with sidebar layout
- Add new sidebar-based layout components:
  - AppLayout.vue: Main layout wrapper with sidebar + topbar
  - AppSidebar.vue: Desktop sidebar with navigation, theme, language
  - AppTopBar.vue: Top bar with notifications, cart, profile
  - MobileDrawer.vue: Slide-out drawer for mobile navigation
- Add Shadcn Sheet component for mobile drawer
- Update App.vue to use new AppLayout (except login page)
- Rename old Navbar.vue to Navbar.old.vue for reference

Layout structure:
- Desktop: Fixed 288px sidebar + offset content area
- Mobile: Hidden sidebar with drawer triggered from top bar
- Cart only shown when market module is enabled
- Combined notifications (chat unread count)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-06 20:22:55 +01:00