feat: Apple Watch app + Paywall + Privacy Policy + rebranding

## Major Features
- Apple Watch companion app (6 phases complete)
  - WatchConnectivity iPhone ↔ Watch
  - HealthKit integration (HR, calories)
  - SwiftUI premium UI
  - 9 complication types
  - Always-On Display support

- Paywall screen with RevenueCat integration
- Privacy Policy screen
- App rebranding: tabatago → TabataFit
- Bundle ID: com.millianlmx.tabatafit

## Changes
- New: ios/TabataFit Watch App/ (complete Watch app)
- New: app/paywall.tsx (subscription UI)
- New: app/privacy.tsx (privacy policy)
- New: src/features/watch/ (Watch sync hooks)
- New: admin-web/ (admin dashboard)
- Updated: app.json, package.json (branding)
- Updated: profile.tsx (paywall + privacy links)
- Updated: i18n translations (EN/FR/DE/ES)
- New: app icon 1024x1024

## Watch App Files
- TabataFitWatchApp.swift (entry point)
- ContentView.swift (premium UI)
- HealthKitManager.swift (HR + calories)
- WatchSessionManager.swift (communication)
- Complications/ (WidgetKit)
- UserDefaults+Shared.swift (data sharing)
This commit is contained in:
Millian Lamiaux
2026-03-11 09:43:53 +01:00
parent f80798069b
commit 2ad7ae3a34
86 changed files with 19648 additions and 365 deletions

View File

@@ -29,7 +29,7 @@ import type { ThemeColors } from '@/src/shared/theme/types'
import { SPACING, LAYOUT } from '@/src/shared/constants/spacing'
import { RADIUS } from '@/src/shared/constants/borderRadius'
import { DURATION, EASE, SPRING } from '@/src/shared/constants/animations'
import { track } from '@/src/shared/services/analytics'
import { track, identifyUser, setUserProperties, trackScreen } from '@/src/shared/services/analytics'
import type { FitnessLevel, FitnessGoal, WeeklyFrequency } from '@/src/shared/types'
@@ -938,25 +938,43 @@ export default function OnboardingScreen() {
// Track onboarding_started + first step viewed on mount
useEffect(() => {
trackScreen('onboarding')
track('onboarding_started')
track('onboarding_step_viewed', { step: 1, step_name: STEP_NAMES[1] })
}, [])
const finishOnboarding = useCallback(
(plan: 'free' | 'premium-monthly' | 'premium-yearly') => {
const totalTime = Date.now() - onboardingStartTime.current
track('onboarding_completed', {
plan,
total_time_ms: Date.now() - onboardingStartTime.current,
total_time_ms: totalTime,
steps_completed: step,
})
completeOnboarding({
const userData = {
name: name.trim() || 'Athlete',
fitnessLevel: level,
goal,
weeklyFrequency: frequency,
barriers,
}
completeOnboarding(userData)
// Identify user in PostHog for session replay linking
const userId = `user_${Date.now()}` // In production, use actual user ID from backend
identifyUser(userId, {
name: userData.name,
fitness_level: level,
fitness_goal: goal,
weekly_frequency: frequency,
subscription_plan: plan,
onboarding_completed_at: new Date().toISOString(),
barriers: barriers.join(','),
})
if (plan !== 'free') {
setSubscription(plan)
}