Commit Graph

130 Commits

Author SHA1 Message Date
Trey t
bcd8b36a9b Fix TokenStorage stale cache bug and add user-friendly error messages
- Fix TokenStorage.getToken() returning stale cached token after login/logout
- Add comprehensive ErrorMessageParser with 80+ error code mappings
- Add Suite9 and Suite10 UI test files for E2E integration testing
- Fix accessibility identifiers in RegisterView and ResidenceFormView
- Fix UITestHelpers logout to target alert button specifically
- Update various UI components with proper accessibility identifiers

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-17 11:48:35 -06:00
Trey t
fbe45da9ff Remove summary from list responses, calculate client-side
- Remove summary field from MyResidencesResponse and TaskColumnsResponse
- Update HomeScreen and ResidencesScreen to observe DataManager.totalSummary
- Load tasks when residence views appear to ensure accurate summary
- Add pull-to-refresh for tasks on ResidencesScreen
- Update iOS views to use client-side calculated summary

Summary is now calculated via refreshSummaryFromKanban() from cached
kanban data. This ensures summary is always up-to-date after CRUD
operations and when residence views are shown.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-16 17:06:48 -06:00
Trey t
6dfc4ee57c Fix home screen summary showing zeros
The setAllTasks() function was not calling refreshSummaryFromKanban()
after loading kanban data, so the summary statistics (totalTasks,
totalOverdue, etc.) were never calculated - they stayed at zero.

Also switch API environment back to DEV.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-16 16:06:01 -06:00
Trey t
96ea1f4686 Improve error handling for Echo backend error format
- Update ErrorResponse model to make detail and statusCode optional since
  backend now returns simple {"error": "message"} format
- Update AuthApi to parse actual backend error messages instead of generic
  "Registration failed"/"Login failed" strings
- Update ErrorParser to prioritize the "error" field and add fallback for
  simple error map responses
- Update iOS ViewModels (Login, Register, AppleSignIn) to properly handle
  400 and 409 status codes by displaying backend error messages

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-16 14:01:33 -06:00
Trey t
e44bcdd988 Add full-screen iOS parity screens and navigation
- Add CompleteTaskScreen for full-screen task completion (matches iOS CompleteTaskView)
- Add ManageUsersScreen for full-screen user management (matches iOS ManageUsersView)
- Add PhotoViewerScreen with swipeable gallery and pinch-to-zoom
- Add UpgradeScreen for full-screen subscription flow (matches iOS UpgradeFeatureView)
- Add navigation routes for new screens (CompleteTaskRoute, ManageUsersRoute, PhotoViewerRoute, UpgradeRoute)
- Wire navigation callbacks into AllTasksScreen, ResidenceDetailScreen, ProfileScreen
- Add overdue count with red color to Summary Card
- Add pulsing animation to residence cards when overdue
- Add property type, isPrimary star, and street address to Residence Card
- Add Edit Profile, Privacy Policy, and App Version to ProfileScreen
- Add string resources for new UI elements and localization

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-14 17:02:08 -06:00
Trey t
b150c20e4b Reorganize share UI with Easy Share on top
Move Easy Share (.casera file) section above Share Code section in the
invite users dialog. Both platforms now have consistent UI with both
buttons using the same filled button style.

iOS changes:
- Move share functionality into ManageUsersView
- Remove share button from ResidenceDetailView toolbar
- Redesign ShareCodeCard with Easy Share on top

Android changes:
- Update ManageUsersDialog with matching layout
- Connect share package callback to existing share function

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-14 13:17:19 -06:00
Trey t
e2d264da7e Add client-side summary calculation and lookup resolution from cache
- Add calculateSummaryFromKanban() to compute summary stats from cached kanban data
- Add refreshSummaryFromKanban() called after task CRUD operations
- Fix column name matching to use API format (e.g., "overdue_tasks" not "overdue")
- Fix tasksDueNextMonth to only include due_soon tasks (not upcoming)
- Update TaskResponse computed properties to resolve from DataManager cache
- Update iOS task cards to use computed properties for priority/frequency/category
- This enables API to skip preloading lookups for better performance

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-14 01:04:52 -06:00
Trey t
4592c4493c Cache contractors at startup and filter by residence from cache
- Load contractors during initializeLookups() when authenticated
- Update getContractorsByResidence() to filter from cache instead of making network call
- Only fetch from API if cache is empty or stale

This eliminates the /contractors/by-residence/{id}/ call when visiting residences.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-13 23:38:43 -06:00
Trey t
33ee445aea Add custom interval days support for task frequency
- Add customIntervalDays field to Kotlin models (TaskResponse, TaskCreateRequest, TaskUpdateRequest)
- Update Android AddTaskDialog to show interval field only for "Custom" frequency
- Update Android EditTaskScreen for custom frequency support
- Update iOS TaskFormView for custom frequency support
- Fix preview data in TaskCard and TasksSection to include new field
- Add customIntervalDays to OnboardingFirstTaskView

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-13 19:05:59 -06:00
Trey t
311a30ed2d Add haptic feedback, rich task completion, and Google Sign-In preparation
- Add platform haptic feedback abstraction (HapticFeedback.kt) with
  implementations for Android, iOS, JVM, JS, and WASM
- Enhance CompleteTaskDialog with interactive 5-star rating, image
  thumbnails, and haptic feedback
- Add ImageBitmap platform abstraction for displaying selected images
- Localize TaskTemplatesBrowserSheet with string resources
- Add Android widgets infrastructure (small, medium, large sizes)
- Add Google Sign-In button components and auth flow preparation
- Update strings.xml with new localization keys for completions,
  templates, and document features
- Integrate haptic feedback into ThemePickerDialog

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-13 01:06:02 -06:00
Trey t
a3e1c338d2 Add X-Timezone header to all API requests
Send the device's IANA timezone identifier (e.g., "America/Los_Angeles")
with every API request to enable timezone-aware overdue task detection.

Platform implementations:
- Android/JVM: TimeZone.getDefault().id
- iOS: NSTimeZone.localTimeZone.name
- JS/WASM: Intl.DateTimeFormat().resolvedOptions().timeZone

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-13 00:04:44 -06:00
Trey t
258ccf7354 Improve error message handling with user-friendly messages
- Add ErrorMessageParser in Kotlin and Swift to detect network errors
  and technical messages, replacing them with human-readable text
- Update all ViewModels to use ErrorMessageParser.parse() for error display
- Remove redundant error popup from LoginView (error shows inline only)

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-11 20:46:43 -06:00
Trey t
1839bd0e11 Add nextDueDate field to TaskResponse for recurring task support
- Add nextDueDate field to TaskResponse model (from API's next_due_date)
- Add effectiveDueDate computed property (nextDueDate ?? dueDate)
- Update DynamicTaskCard, TaskCard to display effectiveDueDate
- Update WidgetDataManager to save effectiveDueDate to widget cache
- Update TaskFormView to use effectiveDueDate when editing
- Fix preview mock data to include nextDueDate parameter

This ensures recurring tasks show the correct next due date after completion
instead of the original due date.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-11 11:10:56 -06:00
Trey t
cbe073aa21 Add push notification deep linking and sharing subscription checks
- Add deep link navigation from push notifications to specific task column on kanban board
- Fix subscription check in push notification handler to allow navigation when limitations disabled
- Add pendingNavigationTaskId to handle notifications when app isn't ready
- Add ScrollViewReader to AllTasksView for programmatic scrolling to task column
- Add canShareResidence() and canShareContractor() subscription checks (iOS & Android)
- Add test APNS file for simulator push notification testing

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-10 23:17:28 -06:00
Trey t
ed14a1c69e Update myResidences when residence is deleted
DataManager.removeResidence() now also updates _myResidences so the
residence list view updates immediately without requiring a manual refresh.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-08 23:24:22 -06:00
Trey t
4a04aff1e6 Replace status_id with in_progress boolean across mobile apps
- Remove TaskStatus model and status_id foreign key references
- Add in_progress boolean field to task models and forms
- Update TaskApi to use dedicated POST endpoints for task actions:
  - POST /tasks/:id/cancel/ instead of PATCH with is_cancelled
  - POST /tasks/:id/uncancel/
  - POST /tasks/:id/archive/
  - POST /tasks/:id/unarchive/
- Fix iOS TaskViewModel to use error-first pattern for Kotlin-Swift
  generic type bridging issues
- Update iOS callback signatures to pass full TaskResponse instead
  of just taskId to avoid stale closure lookups
- Add in_progress localization strings
- Update widget preview data to use inProgress boolean

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-08 20:47:59 -06:00
Trey t
c5b08befea Update API layer to use TotalSummary from CRUD responses
Frontend changes:
- Add generic WithSummaryResponse<T> model for CRUD responses
- Update TaskApi, TaskCompletionApi, ResidenceApi return types
- Update APILayer to extract summary from responses and call DataManager.setTotalSummary()
- Replace refreshTasks() calls with DataManager.updateTask() for local cache updates
- Remove redundant refreshMyResidences() calls
- Remove unused helper methods (refreshTasks, refreshMyResidences, refreshSummary)
- Add summary field to JoinResidenceResponse model

This pairs with the backend changes to eliminate redundant network calls
after CRUD operations - dashboard stats now update from the mutation response.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-08 10:39:53 -06:00
Trey t
c334ce0bd0 Add PostHog analytics integration for Android and iOS
Implement comprehensive analytics tracking across both platforms:

Android (Kotlin):
- Add PostHog SDK dependency and initialization in MainActivity
- Create expect/actual pattern for cross-platform analytics (commonMain/androidMain/iosMain/jvmMain/jsMain/wasmJsMain)
- Track screen views: registration, login, residences, tasks, contractors, documents, notifications, profile
- Track key events: user_registered, user_signed_in, residence_created, task_created, contractor_created, document_created
- Track paywall events: contractor_paywall_shown, documents_paywall_shown
- Track sharing events: residence_shared, contractor_shared
- Track theme_changed event

iOS (Swift):
- Add PostHog iOS SDK via SPM
- Create PostHogAnalytics wrapper and AnalyticsEvents constants
- Initialize SDK in iOSApp with session replay support
- Track same screen views and events as Android
- Track user identification after login/registration

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-07 23:53:00 -06:00
Trey t
6cbcff116f Add Daily Digest notification preferences with custom time support
- Add dailyDigest and dailyDigestHour fields to Kotlin NotificationPreference model
- Update NotificationPreferencesViewModel to support new fields
- Add Daily Summary toggle with time picker to Android NotificationPreferencesScreen
- Add Daily Summary toggle with time picker to iOS NotificationPreferencesView
- Add localized strings for Daily Summary in all 10 languages

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-07 22:51:50 -06:00
Trey t
bb4ff216b1 Add pulsing icon for residences with overdue tasks
- Add overdueCount field to ResidenceResponse model
- ResidenceCard shows PulsingIconView when residence has overdue tasks
- SummaryCard uses static CaseraIconView (never pulses)
- APILayer refreshes residence data after task completion to update
  overdue counts and animation state

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-07 12:19:28 -06:00
Trey t
9d6e7c4f2a Add per-user notification time preferences
Allow users to customize when they receive notification reminders:
- Add hour fields to NotificationPreference model
- Add timezone conversion utilities (localHourToUtc, utcHourToLocal)
- Add time picker UI for iOS (wheel picker in sheet)
- Add time picker UI for Android (hour chip selector dialog)
- Times stored in UTC, displayed in user's local timezone
- Add localized strings for time picker UI

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-07 00:25:38 -06:00
Trey t
83e2cd14a6 Add residence sharing via .casera files
- Add SharedResidence model and package type detection for .casera files
- Add generateSharePackage API endpoint integration
- Create ResidenceSharingManager for iOS and Android
- Add share button to residence detail screens (owner only)
- Add residence import handling with confirmation dialogs
- Update Quick Look extensions to show house icon for residence packages
- Route .casera imports by type (contractor vs residence)

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-06 18:54:46 -06:00
Trey t
04c3389e4d Persist lookup data to disk and refresh on app foreground
- DataManager now persists lookup data (residence types, task categories,
  priorities, statuses, specialties, templates) to disk
- Loads cached lookups on app startup for faster launch
- iOS: Refresh lookups when app becomes active, refresh widget on background
- Android: Initialize DataManager in onCreate, already had onResume refresh
- Only send ETag if lookup data is actually in memory to avoid 304 with no data

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-06 11:29:14 -06:00
Trey t
e13f2702a5 Add auto-login after password reset on iOS and Android
- Add LOGGING_IN step to PasswordResetStep enum on both platforms
- Auto-login with new credentials after successful password reset
- Navigate directly to main app (or verification screen if unverified)
- Show "Logging in..." state during auto-login process
- Hide back button during auto-login to prevent interruption
- Fall back to "Return to Login" if auto-login fails

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-06 00:19:47 -06:00
Trey t
859a6679ed Add contractor sharing feature and move settings to navigation bar
Contractor Sharing:
- Add .casera file format for sharing contractors between users
- Create SharedContractor model with JSON serialization
- Implement ContractorSharingManager for iOS (Swift) and Android (Kotlin)
- Register .casera file type in iOS Info.plist and Android manifest
- Add share button to ContractorDetailView (iOS) and ContractorDetailScreen (Android)
- Add import confirmation, success, and error dialogs
- Create expect/actual platform implementations for sharing and import handling

Navigation Changes:
- Remove Profile tab from bottom tab bar (iOS and Android)
- Add settings gear icon to left side of "My Properties" title
- Settings gear opens Profile/Settings screen as sheet (iOS) or navigates (Android)
- Add property button to top right action bar

Bug Fixes:
- Fix ResidenceUsersResponse to match API's flat array response format
- Fix GenerateShareCodeResponse handling to access nested shareCode property
- Update ManageUsersDialog to accept residenceOwnerId parameter

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-05 22:30:19 -06:00
Trey t
2965ec4031 Add actionable push notifications for iOS and Android
iOS:
- Add notification categories with action buttons (complete, view, cancel, etc.)
- Handle notification actions in AppDelegate with API calls
- Add navigation to specific task from notification tap
- Register UNNotificationCategory for each task state

Android:
- Add NotificationActionReceiver BroadcastReceiver for handling actions
- Update MyFirebaseMessagingService to show action buttons
- Add deep link handling in MainActivity for task navigation
- Register receiver in AndroidManifest.xml

Shared:
- Add navigateToTaskId parameter to App for cross-platform navigation
- Add notification observers in MainTabView/AllTasksView for refresh

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-05 14:23:25 -06:00
Trey t
771f5d2bd3 Add task template suggestions for quick task creation
- Add TaskTemplate model with category grouping support
- Add TaskTemplateApi for fetching templates from backend
- Add TaskSuggestionDropdown component for Android task form
- Add TaskTemplatesBrowserSheet for browsing all templates
- Add TaskSuggestionsView and TaskTemplatesBrowserView for iOS
- Update DataManager to cache task templates
- Update APILayer with template fetch and search methods
- Update TaskFormView (iOS) with template suggestions
- Update AddTaskDialog (Android) with template suggestions
- Update onboarding task view to use templates

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-05 09:06:58 -06:00
Trey t
fd8f6d612c add support button, icon view 2025-12-04 23:59:39 -06:00
Trey t
22bf109cf7 Add email notification preference for task completion
- Add emailTaskCompleted field to NotificationPreference model
- Add email preference toggle to notification settings UI (iOS & Android)
- Add localized strings for email notifications section
- Update ViewModel to support email preference updates

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-04 20:04:42 -06:00
Trey t
fff1032c29 Add onboarding UI tests and improve app data management
- Add Suite0_OnboardingTests with fresh install and login test flows
- Add accessibility identifiers to onboarding views for UI testing
- Remove deprecated DataCache in favor of unified DataManager
- Update API layer to support public upgrade-triggers endpoint
- Improve onboarding first task view with better date handling
- Update various views with accessibility identifiers for testing
- Fix subscription feature comparison view layout
- Update document detail view improvements

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-04 15:55:34 -06:00
Trey t
43f5b9514f Add Android onboarding flow matching iOS implementation
Implement complete onboarding experience for Android with the following screens:
- Welcome screen with "Start Fresh" and "Join Existing Home" options
- Value props carousel showcasing app features (Tasks, Documents, Contractors, Family)
- Residence naming screen for new property setup
- Account creation with email registration (no Apple Sign In on Android)
- Email verification with 6-digit code
- Join residence screen for share code entry
- First task selection with 6 category templates
- Subscription upsell with monthly/yearly plans

Key implementation details:
- OnboardingViewModel manages all state and API integration
- AnimatedContent provides smooth screen transitions
- HorizontalPager for feature carousel
- Onboarding completion persisted in DataManager
- New users start at onboarding, returning users go to login

Files added:
- OnboardingViewModel.kt
- OnboardingScreen.kt (coordinator)
- OnboardingWelcomeContent.kt
- OnboardingValuePropsContent.kt
- OnboardingNameResidenceContent.kt
- OnboardingCreateAccountContent.kt
- OnboardingVerifyEmailContent.kt
- OnboardingJoinResidenceContent.kt
- OnboardingFirstTaskContent.kt
- OnboardingSubscriptionContent.kt

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-03 17:21:44 -06:00
Trey t
63a54434ed Add 1-hour cache timeout and fix pull-to-refresh across iOS
- Add configurable cache timeout (CACHE_TIMEOUT_MS) to DataManager
- Fix cache to work with empty results (contractors, documents, residences)
- Change Documents/Warranties view to use client-side filtering for cache efficiency
- Add pull-to-refresh support for empty state views in ListAsyncContentView
- Fix ContractorsListView to pass forceRefresh parameter correctly
- Fix TaskViewModel loading spinner not stopping after refresh completes
- Remove duplicate cache checks in iOS ViewModels, delegate to Kotlin APILayer

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-03 09:50:57 -06:00
Trey t
cf0cd1cda2 Add unified DataManager as single source of truth for all app data
- Create DataManager.kt with StateFlows for all cached data:
  - Authentication (token, user)
  - Residences, tasks, documents, contractors
  - Subscription status and upgrade triggers
  - All lookup data (residence types, task categories, etc.)
  - Theme preferences and state metadata

- Add PersistenceManager with platform-specific implementations:
  - Android: SharedPreferences
  - iOS: NSUserDefaults
  - JVM: Properties file
  - WasmJS: localStorage

- Migrate APILayer to update DataManager on every API response
- Update Kotlin ViewModels to use DataManager for token access
- Deprecate LookupsRepository (delegates to DataManager)
- Create iOS DataManagerObservable Swift wrapper for SwiftUI
- Update iOS auth flow to use DataManager.isAuthenticated()

Data flow: User Action → API Call → DataManager Updated → All Screens React

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-03 00:21:24 -06:00
Trey t
00e303c3be Update task completion to use local kanban state update
- Add updatedTask field to TaskCompletionResponse model from API
- Modify CompleteTaskView callback to pass back the updated task
- Add updateTaskInKanban() function to AllTasksView and ResidenceDetailView
- Move completed tasks to correct kanban column without additional API call
- Remove debug print statements from ResidenceDetailView

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-02 20:50:25 -06:00
Trey t
0ddd542080 Add AuthenticatedImage components for secure media access
iOS:
- Add AuthenticatedImage.swift component with auth header support
- Update PhotoViewerSheet, ImageViewerSheet, DocumentDetailView, DocumentFormView
- Use TokenStorage for auth and ApiClient.getMediaBaseUrl() for URLs
- In-memory image caching for performance

Android/KMM:
- Add AuthenticatedImage.kt Compose component using Coil3 httpHeaders
- Add mediaUrl field to TaskCompletionImage and DocumentImage models
- Update PhotoViewerDialog, DocumentDetailScreen, DocumentFormScreen
- Use authenticated media URLs instead of public image URLs

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-02 19:47:48 -06:00
Trey t
374c0d1e9c added new strings 2025-12-02 13:08:04 -06:00
Trey t
db65fe125b Add 5 new language translations: Chinese, Japanese, Korean, Italian, Dutch
Expand localization support across all platforms with professional translations:
- KMM: Added strings.xml for zh, ja, ko, it, nl (473 strings each)
- iOS: Updated Localizable.xcstrings with ~1,500 new translation entries

App now supports 10 languages: en, es, fr, de, pt, zh, ja, ko, it, nl

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-02 08:43:41 -06:00
Trey t
c726320c1e Add comprehensive i18n localization for KMM and iOS
KMM (Android/Shared):
- Add strings.xml with 200+ localized strings
- Add translation files for es, fr, de, pt languages
- Update all screens to use stringResource() for i18n
- Add Accept-Language header to API client for all platforms

iOS:
- Add L10n.swift helper with type-safe string accessors
- Add Localizable.xcstrings with translations for all 5 languages
- Update all SwiftUI views to use L10n.* for localized strings
- Localize Auth, Residence, Task, Contractor, Document, and Profile views

Supported languages: English, Spanish, French, German, Portuguese

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-02 02:02:00 -06:00
Trey t
e62e7d4371 Add contractors section to residence detail and fix search filtering
- Add GET /contractors/by-residence/:id endpoint integration
- Display contractors on residence detail screen (iOS & Android)
- Fix contractor search/filter to use client-side filtering
- Backend doesn't support search query params, so filter locally

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-01 20:38:57 -06:00
Trey t
fe2e8275f5 Fix iOS widget date formatting for RFC3339 dates
- Add centralized formatWidgetDate() helper that handles both yyyy-MM-dd and ISO8601 formats
- Update widget date display to show "Today", "in X days", or "X days ago"
- Fix isTaskOverdue() to parse ISO8601 dates from Go API
- Remove duplicate date formatting functions from widget views
- Switch API environment back to DEV

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-01 18:09:16 -06:00
Trey t
c07821711f Add centralized DateUtils and enhance contractor detail views
- Add DateUtils.kt for shared Kotlin date formatting with formatDate,
  formatDateMedium, formatDateTime, formatRelativeDate, and isOverdue
- Add DateUtils.swift for iOS with matching date formatting functions
- Enhance ContractorDetailScreen (Android) with quick action buttons
  (call, email, website, directions), clickable contact rows, residence
  association, statistics section, and metadata
- Enhance ContractorDetailView (iOS) with same features, refactored into
  smaller @ViewBuilder functions to fix Swift compiler type-check timeout
- Fix empty string handling in iOS - check !isEmpty in addition to != nil
  for optional fields like phone, email, website, address
- Update various task and document views to use centralized DateUtils

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-01 14:08:45 -06:00
Trey t
94781f4c48 update profile and UI tweaks 2025-11-30 12:37:15 -06:00
Trey t
b0838d85df Add residence picker to contractor create/edit screens
Kotlin/KMM:
- Update Contractor model with optional residenceId and specialties array
- Rename averageRating to rating, update address field names
- Add ContractorMinimal model for task references
- Add residence picker and multi-select specialty chips to AddContractorDialog
- Fix ContractorsScreen and ContractorDetailScreen field references

iOS:
- Rewrite ContractorFormSheet with residence and specialty pickers
- Update ContractorDetailView with FlowLayout for specialties
- Add FlowLayout component for wrapping badge layouts
- Fix ContractorCard and CompleteTaskView field references
- Update ContractorFormState with residence/specialty selection

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-29 18:42:18 -06:00
Trey t
c748f792d0 Add notification preferences UI and subscription verification on launch
- Add NotificationPreferencesScreen (Android) and NotificationPreferencesView (iOS)
- Add NotificationPreferencesViewModel for shared business logic
- Wire up notification preferences from ProfileScreen on both platforms
- Add subscription verification on app launch for iOS (StoreKit) and Android (Google Play Billing)
- Update SubscriptionApi to match Go backend endpoints (/subscription/purchase/)
- Update StoreKit Configuration with correct product IDs and pricing ($2.99/month, $27.99/year)
- Update Android placeholder prices to match App Store pricing
- Fix NotificationPreference model to match Go backend schema

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-29 14:01:35 -06:00
Trey t
5a1a87fe8d Add Sign in with Apple for iOS
Kotlin Shared Layer:
- Add AppleSignInRequest and AppleSignInResponse models
- Add appleSignIn method to AuthApi and APILayer
- Add appleSignInState and appleSignIn() to AuthViewModel

iOS App:
- Create AppleSignInManager for AuthenticationServices integration
- Create AppleSignInViewModel to coordinate Apple auth flow
- Update LoginView with "Sign in with Apple" button
- Add Sign in with Apple entitlement
- Add accessibility identifier for UI testing

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-29 01:17:38 -06:00
Trey t
daa70bbe20 Fix build issues after Casera rebranding
- Update google-services.json package name to com.example.casera
- Fix Xcode project paths from MyCrib/ to Casera/
- Update app display name and usage descriptions

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-28 21:19:22 -06:00
Trey t
c6eef720ed Rebrand from MyCrib to Casera
- Rename Kotlin package from com.example.mycrib to com.example.casera
- Update Android app name, namespace, and application ID
- Update iOS bundle identifiers and project settings
- Rename iOS directories (MyCribTests -> CaseraTests, etc.)
- Update deep link schemes from mycrib:// to casera://
- Update app group identifiers
- Update subscription product IDs
- Update all UI strings and branding

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-28 21:10:38 -06:00
Trey t
fa1fab0e4a Fix Document API field names to match Go backend
- Change residence to residence_id with @SerialName annotation
- Change contractor to contractor_id with @SerialName annotation
- Update DocumentApi.kt to use correct field names in form data and JSON requests
- Fixes iOS document creation failing with "missing residence_id" error

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-28 21:00:42 -06:00
Trey t
2baf5484e0 Add task completion history feature and UI improvements
- Add CompletionHistorySheet for viewing task completion history (Android & iOS)
- Update TaskCard and DynamicTaskCard with completion history access
- Add getTaskCompletions API endpoint to TaskApi and APILayer
- Update models (CustomTask, Document, TaskCompletion, User) for Go API alignment
- Improve TaskKanbanView with completion history integration
- Update iOS TaskViewModel with completion history loading

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-28 12:01:56 -06:00
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