- Add fetchCommentReactions() to load reactions for all comments after EOSE
- Add updateCommentVotes() to refresh comment votes from ReactionService
- Add dislikeEvent() and undislikeEvent() to ReactionService for downvotes
- Update downvoteComment() to use ReactionService for persistence
- Fix vote button styling in SubmissionComment to properly show active state
- Wire up comment vote handlers in SubmissionDetail
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add subscribeToSubmission() to fetch submission + comments by ID
- Fix isComment check order - check before parseSubmission (which fails for comments)
- Update comment count on submission when comments are added
- Add duplicate comment detection to prevent double-display
- Update useSubmission composable to auto-subscribe on mount
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add createComment() method to SubmissionService for posting comments
- Add getSortedComments() with sort options: best, new, old, controversial
- Wire up comment submission in SubmissionDetail.vue
- Add comment sort dropdown in detail view
- Support replying to specific comments or root submission
- Display comment submission errors
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Create SubmitComposer.vue with post type selector (text/link/media)
- Add debounced link preview fetching on URL input
- Wire up submission publishing via SubmissionService.createSubmission()
- Add /submit route with SubmitPage.vue wrapper
- Support community query param for pre-selection
- Include NSFW toggle and form validation
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add SubmissionDetail.vue for full post view with content display
- Add SubmissionComment.vue for recursive threaded comments
- Add SubmissionDetailPage.vue route wrapper
- Add /submission/:id route to module
- Update SubmissionList share URL to use correct route
- Update test page to navigate to detail view on click
- Update plan document with Phase 4 completion
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add LinkAggregatorTest.vue with mock data and live submission views
- Include direct relay connection for testing kind 1111 events
- Add submission composer with self/link post types
- Add route at /link-aggregator-test
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Implement minimal, information-dense submission feed UI inspired by
old Reddit and Lemmy designs.
New components:
- VoteControls.vue: Compact vertical upvote/downvote arrows with score
- SubmissionThumbnail.vue: Small square thumbnail with fallback icons
- SubmissionRow.vue: Single submission row with title, metadata, actions
- SortTabs.vue: Sort tabs (hot, new, top, controversial) with time range
- SubmissionList.vue: Main container composing all components
UI features:
- Dense layout showing many items at once
- Hover-reveal secondary actions (share, save, hide, report)
- Domain display for link posts
- NSFW blur/badge support
- Rank numbers (optional)
- Time-ago formatting
- Score formatting (e.g., 1.2k)
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
Implement Reddit-style link aggregator foundation using NIP-72 (Moderated
Communities) and NIP-22 (Comments) specifications.
New files:
- types/submission.ts: Complete type definitions for submissions, voting,
communities, link previews, and ranking algorithms
- services/SubmissionService.ts: Core service for kind 1111 submission
events with parsing, creation, voting, and comment threading
- services/LinkPreviewService.ts: Open Graph metadata fetching with
caching, CORS proxy support, and oEmbed fallbacks
- composables/useSubmissions.ts: Vue composable for reactive submission
state management
- LINK_AGGREGATOR_PLAN.md: Implementation roadmap
Features:
- Three post types: link, media, self (text)
- NIP-22 compliant community-scoped posts
- NIP-92 media attachments with imeta tags
- Hot/Top/New/Controversial ranking algorithms
- Threaded comment support
- Upvote/downvote via NIP-25 reactions
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Added full CRUD for shipping zones in MarketSettings.vue
- Added updateZone and deleteZone API methods to nostrmarketAPI.ts
- Zone form supports name, cost, and countries/regions
- Edit and delete zones with confirmation dialog
- Loading states and proper error handling with toast notifications
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Rewrote MarketSettings.vue to use real Stall model fields
- Added updateStall API method to nostrmarketAPI.ts
- Editable fields: name, description, imageUrl
- Read-only fields: currency, shipping zones (set at creation)
- Form validation with Zod schema
- Loading states and proper error handling
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The CreateStoreDialog already shows a success toast with helpful message.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Call /api/v1/currencies endpoint on LNbits core (not nostrmarket extension)
- Ensure 'sat' is always first in the currency list and used as default
- Add loading state for currency dropdown
- Add key prop to Select component for proper reactivity
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Remove duplicate Add Product button from store header (keep the one in Products tab)
- Grey out Satisfaction card with "Coming Soon" badge (feature not yet implemented)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Remove Customer Actions and Merchant Actions cards from Overview
- Simplify My Store to single-store management (remove multi-store grid)
- Auto-select user's store when available
- Remove "Back to Stores" navigation (no longer needed)
- Clean up unused imports and functions
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
**Problem:**
Task status changes (claim/start/complete/unclaim/delete) would update the
local UI state even when the Nostr event failed to publish to ANY relays.
This caused users to see "completed" tasks that were never actually published,
leading to confusion when the UI reverted after page refresh.
**Root Cause:**
ScheduledEventService optimistically updated local state after calling
publishEvent(), without checking if any relays accepted the event. If all
relay publishes failed (result.success = 0), the UI still updated.
**Solution:**
Modified RelayHub.publishEvent() to throw an error when no relays accept the
event (success = 0). This ensures:
- Existing try-catch blocks handle the error properly
- Error toast shown to user: "Failed to publish event - none of X relay(s) accepted it"
- Local state NOT updated (UI remains accurate)
- Consistent behavior across all services using publishEvent()
**Changes:**
- relay-hub.ts: Add check after publish - throw error if successful === 0
- ScheduledEventService.ts: Update comments to reflect new behavior
**Benefits:**
- Single source of truth for publish failure handling
- No code duplication (no need to check result.success everywhere)
- Better UX: Users immediately see error instead of false success
- UI state always matches server state after operations
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Added ability for task authors to delete their own tasks from the expanded
view in the task feed.
**Features:**
- Delete button visible only to task author in expanded task view
- Confirmation dialog with destructive styling
- Publishes NIP-09 deletion event (kind 5) with 'a' tag referencing the
task's event address (kind:pubkey:d-tag format)
- Real-time deletion handling via FeedService routing
- Optimistic local state update for immediate UI feedback
**Implementation:**
- Added deleteTask() method to ScheduledEventService
- Added handleTaskDeletion() for processing incoming deletion events
- Updated FeedService to route kind 31922 deletions to ScheduledEventService
- Added delete button and dialog flow to ScheduledEventCard component
- Integrated with existing confirmation dialog pattern
**Permissions:**
- Only task authors can delete tasks (enforced by isAuthor check)
- NIP-09 validation: relays only accept deletion from event author
- Pubkey verification in handleTaskDeletion()
**Testing:**
- Created tasks and verified delete button appears for author only
- Confirmed deletion removes task from UI immediately
- Verified deletion persists after refresh
- Tested with multiple users - others cannot delete
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Require users to confirm they've communicated with the team before unclaiming a task to prevent coordination issues.
Changes:
- Add hasConfirmedCommunication checkbox state
- Show checkbox in unclaim confirmation dialog
- Disable "Unclaim Task" button until checkbox is checked
- Reset checkbox state when dialog is closed/cancelled
- Update dialog description to prompt communication
UX Flow:
1. User clicks "Unclaim" button
2. Dialog appears with message about removing claim
3. Checkbox: "I have communicated this to the team"
4. "Unclaim Task" button disabled until checkbox checked
5. Forces user acknowledgment before unclaiming
This prevents situations where:
- Someone unclaims without notifying others working on related tasks
- Team members are left confused about task status
- Work gets duplicated or blocked due to lack of communication
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Refine unclaim button visibility to prevent confusing UX where users could "unclaim" status updates they didn't claim.
Changes:
- Only show "Unclaim" button when task is in "claimed" state
- Remove "Unclaim" button from in-progress and completed states
- Maintain check that current user must be the claimer
Rationale:
- Prevents confusion where user marks task in-progress but sees "Unclaim"
- "Unclaim" makes sense only for the original claim action
- Users can still update status (mark in-progress/complete) on any task
- But only the claimer can unclaim the original claim
Example scenarios:
- Alice claims task → Alice sees "Unclaim" button
- Bob marks Alice's task as in-progress → Bob does NOT see "Unclaim"
- Only Alice can unclaim, reverting task to unclaimed state
This simple rule prevents UX confusion until we implement full per-user status tracking.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Previously, users could see and click "Unclaim" button for tasks claimed by others, leading to failed deletion attempts and temporary UI inconsistencies.
Changes:
- Add auth service injection to ScheduledEventCard
- Add canUnclaim computed property checking if current user created the current status
- Only show "Unclaim" button when canUnclaim is true (user owns the current status)
- Applies NIP-09 rule: users can only delete their own events
Behavior:
- Alice claims task → only Alice sees "Unclaim" button
- Bob marks task in-progress → only Bob sees "Unclaim" button
- Prevents failed deletion attempts and optimistic update bugs
- Follows Nostr protocol permissions correctly
This is a quick fix. Future enhancement will track per-user status for full collaborative workflow support.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Enable users to skip intermediate task states in the expanded view. Users can now directly mark tasks as in-progress or complete without going through all workflow steps.
Changes:
- Add "Mark In Progress" button for unclaimed tasks (skips claiming)
- Add "Mark Complete" button for unclaimed and claimed tasks (skips intermediate states)
- Maintain existing workflow buttons (Claim Task, Start Task, Unclaim)
- Use concise, industry-standard button labels following common task management UX
Button layout:
- Unclaimed: "Claim Task" (default), "Mark In Progress" (outline), "Mark Complete" (outline)
- Claimed: "Start Task" (default), "Mark Complete" (outline), "Unclaim" (outline)
- In Progress: "Mark Complete" (default), "Unclaim" (outline)
- Completed: "Unclaim" (outline)
This provides maximum flexibility for different task management workflows while maintaining clear visual hierarchy with primary/outline button variants.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Add deletion event handling to enable real-time UI updates when tasks are unclaimed. Previously, unclaiming a task required manual refresh to see the update.
Changes:
- Add handleDeletionEvent() to ScheduledEventService to process kind 5 deletion events
- Update FeedService to route kind 31925 deletions to ScheduledEventService
- Implement NIP-09 validation (only author can delete their own events)
- Remove completions from reactive Map to trigger Vue reactivity
Technical details:
- Subscription to kind 5 events was already in place
- Issue was lack of routing for kind 31925 (RSVP/completion) deletions
- Now follows same pattern as reaction and post deletions
- Deletion events properly update the _completions reactive Map
- UI automatically reflects unclaimed state through Vue reactivity
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Added granular task state management to scheduled events/tasks with three states plus unclaimed. Tasks now support a full workflow from claiming to completion with visual feedback at each stage.
**New Task States:**
- **Unclaimed** (no RSVP event) - Task available for anyone to claim
- **Claimed** - User has reserved the task but hasn't started
- **In Progress** - User is actively working on the task
- **Completed** - Task is done
- **Blocked** - Task is stuck (supported but not yet used in UI)
- **Cancelled** - Task won't be completed (supported but not yet used in UI)
**Service Layer (ScheduledEventService.ts):**
- Updated `EventCompletion` interface: replaced `completed: boolean` with `taskStatus: TaskStatus`
- Added `TaskStatus` type: `'claimed' | 'in-progress' | 'completed' | 'blocked' | 'cancelled'`
- New methods: `claimTask()`, `startTask()`, `getTaskStatus()`
- Refactored `completeEvent()` and renamed `uncompleteEvent()` to `unclaimTask()`
- Internal `updateTaskStatus()` method handles all state changes
- Uses `task-status` tag instead of `completed` tag in Nostr events
- `unclaimTask()` publishes deletion event (kind 5) to remove RSVP
- Backward compatibility: reads old `completed` tag and converts to new taskStatus
**Composable (useScheduledEvents.ts):**
- Exported new methods: `claimTask`, `startTask`, `unclaimTask`, `getTaskStatus`
- Updated `completeEvent` signature to accept occurrence parameter
- Marked `toggleComplete` as deprecated (still works for compatibility)
**UI (ScheduledEventCard.vue):**
- Context-aware action buttons based on current task status:
- Unclaimed: "Claim Task" button
- Claimed: "Start Task" + "Unclaim" buttons
- In Progress: "Mark Complete" + "Unclaim" buttons
- Completed: "Unclaim" button only
- Status badges with icons and color coding:
- 👋 Claimed (blue)
- 🔄 In Progress (orange)
- ✓ Completed (green)
- Shows who claimed/is working on/completed each task
- Unified confirmation dialog for all actions
- Quick action buttons in collapsed view
- Full button set in expanded view
**Feed Integration (NostrFeed.vue):**
- Added handlers: `onClaimTask`, `onStartTask`, `onCompleteTask`, `onUnclaimTask`
- Passes `getTaskStatus` prop to ScheduledEventCard
- Wired up all new event emitters
**Nostr Protocol:**
- Uses NIP-52 Calendar Event RSVP (kind 31925)
- Custom `task-status` tag for granular state tracking
- Deletion events (kind 5) for unclaiming tasks
- Fully decentralized - all state stored on Nostr relays
🐢 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Changed terminology in the scheduled events section of NostrFeed to use "Tasks" instead of "Events" to prevent confusion with the Events module (which handles event ticketing).
**Changes:**
- "Today's Events" → "Today's Tasks"
- "Yesterday's Events" → "Yesterday's Tasks"
- "Tomorrow's Events" → "Tomorrow's Tasks"
- "Events for Mon, Jan 15" → "Tasks for Mon, Jan 15"
- Updated comments: "Scheduled Events" → "Scheduled Tasks"
**Rationale:**
- **NostrFeed scheduled items** = Daily tasks and announcements (NIP-52 calendar events)
- **Events module** = Event ticketing system (concerts, conferences, etc.)
- Using "Tasks" makes it clear these are to-do items, not ticketed events
Empty state message already correctly used "tasks" terminology and remains unchanged.
🐢 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Removed redundant subtitle and simplified header to just "Transaction History" for cleaner, more concise UI.
Before:
- Title: "My Transactions"
- Subtitle: "View your recent transaction history"
After:
- Title: "Transaction History"
- No subtitle
🐢 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Synchronized TransactionsPage with castle LNbits extension API updates that introduced custom date range filtering.
**API Changes (ExpensesAPI.ts):**
- Updated `getUserTransactions()` to support `start_date` and `end_date` parameters (YYYY-MM-DD format)
- Custom date range takes precedence over preset days parameter
- Updated comment: default changed from 5 to 15 days, options now 15/30/60 (removed 5 and 90)
**UI Changes (TransactionsPage.vue):**
- **New defaults**: Changed default from 5 days to 15 days
- **New preset options**: 15, 30, 60 days (removed 5 and 90 day options)
- **Custom date range**: Added "Custom" option with date picker inputs
- From/To date inputs using native HTML5 date picker
- Apply button to load transactions for custom range
- Auto-clears custom dates when switching back to preset days
- **State management**:
- `dateRangeType` ref supports both numbers (15, 30, 60) and 'custom' string
- `customStartDate` and `customEndDate` refs for custom date range
- **Smart loading**: Only loads transactions after user provides both dates and clicks Apply
**Priority Logic:**
- Custom date range (start_date + end_date) takes precedence
- Falls back to preset days if custom not selected
- Defaults to 15 days if custom selected but dates not provided
Matches castle extension implementation exactly (see castle extension git diff in fava_client.py, views_api.py, and static/js/index.js).
🐢 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Fixed issue where users could only see 20 transactions at a time despite having more transactions in the selected time period.
Changes:
- **Removed pagination controls**: Eliminated prev/next page buttons and page counter
- **Load all transactions**: Set limit to 1000 to fetch all transactions for the selected time period
- **Natural scrolling**: Users can now scroll through all their transactions
- **Improved fuzzy search**: Search now works across ALL transactions, not just the current page
- **Simplified UI**: Cleaner interface without pagination complexity
- **Updated transaction count**: Now shows total count instead of "X-Y of Z"
Previous behavior:
- Limited to 20 transactions per page
- Required manual pagination to see more
- Fuzzy search only searched current page (20 transactions)
New behavior:
- Loads up to 1000 transactions at once
- Single scrollable list
- Fuzzy search works across all loaded transactions
- Lightweight (text-only data)
🐢 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Dramatically reduced wasted space and improved mobile UX by:
- **Compact header**: Moved refresh button inline with title, similar to NostrFeed
- **Compact controls**: All day filter buttons now on one row with Calendar icon
- **Removed nested cards**: Eliminated Card wrapper around transactions list
- **Full-width layout**: Transactions now use full screen width on mobile (border-b) and rounded cards on desktop (md:border md:rounded-lg)
- **Consistent padding**: Uses px-0 on mobile, px-4 on desktop, matching NostrFeed patterns
- **Reduced vertical space**: Compacted header section to about half the original height
- **Cleaner imports**: Removed unused Card, CardContent, CardHeader, CardTitle, CardDescription, and Separator components
Layout now follows NostrFeed's mobile-optimized patterns with max-w-3xl container and responsive spacing.
Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Features:
- Created TransactionsPage with mobile-optimized layout
- Card-based transaction items with status indicators
- Fuzzy search by description, payee, reference, username, and tags
- Day filter options (5, 30, 60, 90 days)
- Pagination support
- Responsive design for mobile and desktop
- Added getUserTransactions API method to ExpensesAPI
- Supports filtering by days, user ID, and account type
- Returns paginated transaction data
- Updated AddExpense component with success confirmation
- Shows success message in same dialog after submission
- Provides option to navigate to transactions page
- Clean single-dialog approach
- Added "My Transactions" link to navbar menu
- Added Transaction and TransactionListResponse types
- Added permission management types and API methods (grantPermission, listPermissions, revokePermission)
- Installed alert-dialog component for UI consistency
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Adds support for the new exclude_virtual parameter added to the Castle backend API.
Changes:
- Added excludeVirtual parameter to getAccounts() (defaults to true)
- Added excludeVirtual parameter to getAccountHierarchy() (defaults to true)
- Both methods now pass the parameter to the backend API
This ensures virtual parent accounts are excluded from user views by default,
while still allowing permission inheritance to work correctly on the backend.
The default value of true means existing code automatically benefits from
the change without modification - virtual accounts won't appear in user
account selectors.
🤖 Generated with Claude Code (https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Updates the description of the `amount` and `currency` fields in the `ExpenseEntryRequest` interface to clarify that the amount is in the specified currency (or satoshis if currency is None).
Updates the description placeholder in the AddExpense component to provide more specific and helpful examples for users.
This aims to guide users in providing more detailed and relevant descriptions of their expenses, improving the overall expense tracking experience.
Improves the visual presentation of the selected account in the add expense form by using a badge.
This makes the selected account more prominent and provides a clearer distinction from other text elements.
Improves the expense tracking component by fetching user information to determine equity eligibility.
This allows displaying the "Convert to equity" checkbox only to eligible users, enhancing the user experience and ensuring accurate expense categorization.
Also includes error handling to prevent the form from breaking if user information cannot be loaded.
Ensures that the account selector only displays accounts
that the user has permissions for.
This change modifies the `ExpensesAPI` to include a
`filterByUser` parameter when fetching accounts, which is
then passed to the backend to retrieve only authorized
accounts. A log statement was added to confirm proper
filtering.
Enhances the Add Expense dialog's layout for better usability.
Reduces the maximum height of the dialog, adjusts padding and margins,
and ensures scrollable content has a minimum height for a more consistent
user experience.
Refactors the AddExpense component to utilize the Dialog component
from the UI library. This provides a more structured and accessible
modal for adding expenses, and includes a header with title and description.
It also improves the layout using flexbox for better content management
and scrollability.
Ensures the expense form defaults to the LNbits instance's configured currency.
This change retrieves the default currency from the LNbits API and sets it as the initial value in the expense form. If no default is configured, it falls back to the first available currency or EUR.
Allows users to select a currency when adding an expense.
Fetches available currencies from the backend and displays them
in a dropdown menu, defaulting to EUR if the fetch fails.
The expense submission process now includes the selected currency.
Updates the expense input fields to accept and display amounts in Euros instead of satoshis.
This change ensures that the amount field is configured to handle decimal values with a minimum value of €0.01.
Implements components for granting and revoking account permissions.
This introduces a `GrantPermissionDialog` for assigning access rights to users,
and a `PermissionManager` component to list and revoke existing permissions.
The UI provides options to view permissions grouped by user or by account.
Changes the "Account from equity" label and description
to "Convert to equity contribution" for clarity.
The updated description explains that instead of cash
reimbursement, the expense will increase the user's
equity stake.
Updates expense submission to require a user wallet.
Retrieves wallet information from the authentication context
and includes it in the expense submission request to the backend.
This ensures that expenses are correctly associated with the user's
wallet, enabling accurate tracking and management of expenses.
Also adds error handling and user feedback.
Adds a new module for tracking user expenses.
The module includes:
- Configuration settings for the LNbits API endpoint and timeouts.
- An ExpensesAPI service for fetching accounts and submitting expense entries.
- A UI component for adding expenses, including account selection and form input.
- Dependency injection for the ExpensesAPI service.
This allows users to submit expense entries with account selection and reference data, which will be linked to their wallet.
Introduces a dynamic quick action system, allowing modules to register actions that appear in a floating action button menu.
This provides a flexible way for modules to extend the application's functionality with common tasks like composing notes or initiating payments.
Refines project documentation to reflect recent architectural changes and coding standards.
Adds detailed explanations of the BaseService pattern, module structure, and JavaScript best practices to enhance developer understanding and consistency.
Clarifies CSS styling guidelines, emphasizing semantic classes for theme-aware styling.
Includes critical bug prevention techniques related to JavaScript falsy values and correct usage of the nullish coalescing operator.
Updates build configuration details, environment variable requirements, and mobile browser workaround strategies.
Refines the presentation of scheduled events by adjusting spacing and text displayed when there are no tasks. This enhances visual clarity and provides a more user-friendly experience.