- Replace unused lastError state with alertIsPresented boolean
- OK button now clears viewModel.error to prevent re-trigger
- Add onChange observer to show alert when error becomes non-nil
- Applies to both ClubsView.swift and ChallengesView.swift
Co-Authored-By: Paperclip <noreply@paperclip.ing>
P0: Fix variable shadowing in ClubService.createClub/updateClub and
ChallengeService.createChallenge/updateChallenge — renamed local
'var request' to 'var urlRequest' so JSONEncoder encodes the
typed parameter, not the URLRequest.
P1: Wire CreateClubSheet and CreateChallengeSheet to parent ViewModel —
sheets now receive viewModel and call createClub/createChallenge
before dismissing.
P2: Extract HTTPMethod enum to shared Utils/HTTPMethod.swift (was
defined in NotificationService). Remove dead 'body' parameter from
buildRequest in all three services. Add error alert UI to
ClubsView and ChallengesView.
P3: Replace forced URL unwrap with static let defaultBaseURL in all
three services. Fix MockChallengeService.updateChallenge to track
updateCalled instead of always throwing notFound.
Co-Authored-By: Paperclip <noreply@paperclip.ing>
- Add getUnreadCount() endpoint to NotificationsServiceProtocol
- Add NotificationUnreadCountResponse model
- Add badgeCount and fetchUnreadCount() to NotificationsViewModel
- Update markAsRead/markAllAsRead to decrement badge count
- Create MainTabView with Home, Challenges, Clubs, Notifications tabs
- Add unread badge on notification tab using .badge() modifier
- Support injected ViewModel in NotificationsView for shared state
- Add badge count tests to NotificationServiceTests
- Fetch unread count on app launch and tab switch
Co-Authored-By: Paperclip <noreply@paperclip.ing>
Implement full MVVM stack for two new community features:
Clubs:
- Persistent runner groups with type, privacy, and member management
- Club discovery, creation, join/leave, and invite workflows
- Member roles (Owner, Admin, Member) and capacity limits
Challenges:
- Time-bound competitive goals with progress tracking and leaderboards
- Challenge types: distance, time, frequency, elevation, calories, streak
- Progress submission, participation status, and ranking
Files:
- Models: Club.swift, Challenge.swift
- Services: ClubService.swift, ChallengeService.swift
- ViewModels: ClubViewModel.swift, ChallengeViewModel.swift
- Views: ClubsView.swift, ClubDetailView.swift, ChallengesView.swift, ChallengeDetailView.swift
- Tests: ClubServiceTests.swift, ChallengeServiceTests.swift
- Updated README.md with new feature documentation
- Create NotificationsView.swift with SwiftUI List and pull-to-refresh
- Create NotificationRowView.swift for individual notification items
- Create NotificationsViewModel.swift with MVVM pattern
- Implement empty state view for no notifications
- Add mark-as-read and mark-all-as-read functionality
- Support notification types: loan approved/rejected, payment received/due, new lender, system updates
- Add toolbar action for marking all notifications as read
- Include README.md with architecture documentation and integration guide
Next: Connect tRPC notifications router for data fetching