Commit Graph

12 Commits

Author SHA1 Message Date
Trey t
60c824447d Update Kotlin models and iOS Swift to align with new Go API format
- Update all Kotlin API models to match Go API response structures
- Fix Swift type aliases (TaskDetail→TaskResponse, Residence→ResidenceResponse, etc.)
- Update TaskCompletionCreateRequest to simplified Go API format (taskId, notes, actualCost, photoUrl)
- Fix optional handling for frequency, priority, category, status in task models
- Replace isPrimaryOwner with ownerId comparison against current user
- Update ResidenceUsersResponse to use owner.id instead of ownerId
- Fix non-optional String fields to use isEmpty checks instead of optional binding
- Add type aliases for backwards compatibility in Kotlin models

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-27 11:03:00 -06:00
Trey t
7b0a0e5d85 Implement Android subscription system with freemium limitations
Major subscription system implementation for Android:

BillingManager (Android):
- Full Google Play Billing Library integration
- Product loading, purchase flow, and acknowledgment
- Backend verification via APILayer.verifyAndroidPurchase()
- Purchase restoration for returning users
- Error handling and connection state management

SubscriptionHelper (Shared):
- New limit checking methods: isResidencesBlocked(), isTasksBlocked(),
  isContractorsBlocked(), isDocumentsBlocked()
- Add permission checks: canAddProperty(), canAddTask(),
  canAddContractor(), canAddDocument()
- Enforces freemium rules based on backend limitationsEnabled flag

Screen Updates:
- ContractorsScreen: Show upgrade prompt when contractors limit=0
- DocumentsScreen: Show upgrade prompt when documents limit=0
- ResidencesScreen: Show upgrade prompt when properties limit reached
- ResidenceDetailScreen: Show upgrade prompt when tasks limit reached

UpgradeFeatureScreen:
- Enhanced with feature benefits comparison
- Dynamic content from backend upgrade triggers
- Platform-specific purchase buttons

Additional changes:
- DataCache: Added O(1) lookup maps for ID resolution
- New minimal models (TaskMinimal, ContractorMinimal, ResidenceMinimal)
- TaskApi: Added archive/unarchive endpoints
- Added Google Billing Library dependency
- iOS SubscriptionCache and UpgradePromptView updates

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-25 11:23:53 -06:00
Trey t
f1f71224aa Add Android theme system and fix package naming issues
This commit adds a comprehensive theming system to Android matching iOS, and fixes package declarations throughout the codebase to match directory structure.

Theme System Additions:
- Added 11 themes matching iOS: Default, Teal, Ocean, Forest, Sunset, Monochrome, Lavender, Crimson, Midnight, Desert, Mint
- Created ThemeColors.kt with exact iOS color values for light/dark modes
- Added ThemeManager.kt for dynamic theme switching
- Created Spacing.kt with standardized spacing constants (xs/sm/md/lg/xl)
- Added ThemePickerDialog.kt for theme selection UI
- Integrated theme switching in ProfileScreen.kt
- Updated App.kt to observe ThemeManager for reactive theming

Component Library:
- Added StandardCard.kt and CompactCard.kt for consistent card styling
- Added FormTextField.kt with error/helper text support
- Added FormSection.kt for grouping related form fields
- Added StandardEmptyState.kt for empty state UI

Package Migration:
- Fixed all package declarations to match directory structure (com.example.mycrib.*)
- Updated package declarations in commonMain, androidMain, and iosMain
- Fixed all import statements across entire codebase
- Ensures compilation on both Android and iOS platforms

iOS Theme Rename:
- Renamed "Default" theme to "Teal" in iOS
- Renamed "Bright" theme to "Default" in iOS to make vibrant colors the default

Build Status:
-  Android builds successfully
-  iOS builds successfully

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-22 10:44:54 -06:00
Trey t
dd5e050025 Make residence address fields optional (only name required)
Updated Kotlin models, Android UI, and iOS UI to make all address fields
optional for residences. Only the residence name is now required.

Changes:
- Kotlin: Made propertyType, streetAddress, city, stateProvince, postalCode,
  country nullable in Residence, ResidenceSummary, ResidenceWithTasks models
- Kotlin: Updated navigation routes to handle nullable address fields
- Android: Updated ResidenceFormScreen and ResidenceDetailScreen to handle nulls
- iOS: Updated ResidenceFormView validation to only check name field
- iOS: Updated PropertyHeaderCard and ResidenceCard to use optional binding
  for address field displays

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-20 23:03:45 -06:00
Trey t
b9c82ffc37 Update client models to handle numeric decimals from optimized API
Model type updates:
- Change decimal cost fields from String to Double for better type safety
- actualCost: String? → Double? (TaskCompletion, TaskCompletionCreateRequest)
- estimatedCost: String? → Double? (CustomTask, TaskCreateRequest, TaskDetail)
- purchasePrice: String? → Double? (Residence, ResidenceCreateRequest)

TaskDetail model fixes:
- Add missing residenceName, createdBy, createdByUsername fields
- Add missing intervalDays field to match backend response
- Remove actualCost and notes fields (not in backend TaskDetailSerializer)
- Ensure 100% compatibility with Django API TaskDetailSerializer

UI input/output conversions:
- EditTaskScreen: Convert Double to String for display, String to Double for API
- AddTaskDialog: Convert String input to Double for API requests
- CompleteTaskDialog: Convert String input to Double for API requests
- App.kt: Handle type conversions in navigation route parameters

Display improvements:
- TaskCard: Update preview data to use numeric literals (150.00 vs "150.00")
- Cost display already handles Double correctly with string interpolation

Benefits:
- Type-safe numeric handling throughout the app
- Smaller JSON payloads (numbers vs quoted strings)
- Better performance with direct numeric deserialization
- Aligns with REST API best practices
- 100% backend compatibility verified

Testing:
- All models now match backend serializer field types exactly
- Build successful with no errors
- Ready for integration with optimized Django API

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-15 22:55:50 -06:00
Trey t
bb5664c954 Implement fully dynamic task summary UI from API data
Updated both iOS and Android to build residence task summary UI entirely
from API response data, with no hardcoded categories, icons, colors, or labels.

**Changes:**

**Backend Integration:**
- Updated TaskSummary model to use dynamic categories list instead of static fields
- Added TaskColumnCategory and TaskColumnIcon models for metadata
- Categories now include: name, displayName, icons (ios/android/web), color, count

**Android (ResidencesScreen.kt):**
- Removed hardcoded category extraction (overdue_tasks, current_tasks, in_progress_tasks)
- Now dynamically iterates over first 3 categories from API
- Added getIconForCategory() helper to map icon names to Material Icons
- Added parseHexColor() helper that works in commonMain (no Android-specific code)
- Uses category.displayName, category.icons.android, category.color from API

**iOS (ResidenceCard.swift):**
- Removed hardcoded category extraction and SF Symbol names
- Now dynamically iterates over first 3 categories using ForEach
- Uses category.displayName, category.icons.ios, category.color from API
- Leverages existing Color(hex:) extension for color parsing

**Component Organization:**
- Moved TaskSummaryCard.kt from commonMain to androidMain (uses Android-specific APIs)
- Created TaskSummaryCard.swift for iOS with dynamic category rendering

**Benefits:**
 Backend controls all category metadata (icons, colors, display names)
 Apps automatically reflect backend changes without redeployment
 No platform-specific hardcoded values
 Single source of truth in task/constants.py TASK_COLUMNS

**Files Changed:**
- Residence.kt: Added TaskColumnCategory, TaskColumnIcon models
- ResidencesScreen.kt: Dynamic category rendering with helpers
- ResidenceCard.swift: Dynamic category rendering with ForEach
- TaskSummaryCard.kt: Moved to androidMain
- TaskSummaryCard.swift: New iOS dynamic component

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-15 11:13:37 -06:00
Trey t
364f98a303 Fix logout, share code display, loading states, and multi-user support
iOS Logout Fix:
- Use @EnvironmentObject in MainTabView and ProfileTabView
- Pass loginViewModel from LoginView to MainTabView
- Handle logout by dismissing main tab when isAuthenticated becomes false
- Logout button now properly returns user to login screen

Share Code UX:
- Clear share code on ManageUsers screen open (iOS & Android)
- Remove auto-loading of share codes
- User must explicitly generate code each time
- Improves security with fresh codes

Loading State Improvements:
- iOS ResidenceDetailView shows loading immediately on navigation
- Android ResidenceDetailScreen enhanced with "Loading residence..." text
- Better user feedback during API calls

Multi-User Support:
- Add isPrimaryOwner and userCount to ResidenceWithTasks model
- Update iOS toResidences() extension to include new fields
- Sync with backend API changes for shared user access

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-08 10:51:51 -06:00
Trey t
2be3a5a3a8 wip 2025-11-05 10:38:46 -06:00
Trey t
025fcf677a wip 2025-11-04 23:11:18 -06:00
Trey t
f2ade0a1e2 wip 2025-11-04 12:19:17 -06:00
Trey t
ba27ddda71 wip 2025-11-04 11:42:00 -06:00
Trey t
78c62cfc52 Initial commit: Kotlin Multiplatform project setup
🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-04 09:15:49 -06:00