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

@@ -28,7 +28,7 @@ import { ThemeProvider, useThemeColors } from '@/src/shared/theme'
import { useUserStore } from '@/src/shared/stores'
import { useNotifications } from '@/src/shared/hooks'
import { initializePurchases } from '@/src/shared/services/purchases'
import { initializeAnalytics, getPostHogClient } from '@/src/shared/services/analytics'
import { initializeAnalytics, getPostHogClient, trackScreen } from '@/src/shared/services/analytics'
Notifications.setNotificationHandler({
handleNotification: async () => ({
@@ -105,7 +105,7 @@ function RootLayoutInner() {
<Stack.Screen
name="workout/[id]"
options={{
animation: 'slide_from_bottom',
animation: 'slide_from_right',
}}
/>
<Stack.Screen
@@ -137,13 +137,21 @@ function RootLayoutInner() {
</View>
)
// Skip PostHogProvider in dev to avoid SDK errors without a real API key
if (__DEV__) {
const posthogClient = getPostHogClient()
// Only wrap with PostHogProvider if client is initialized
if (!posthogClient) {
return content
}
return (
<PostHogProvider client={getPostHogClient() ?? undefined} autocapture={{ captureScreens: true }}>
<PostHogProvider
client={posthogClient}
autocapture={{
captureScreens: true,
captureTouches: true,
}}
>
{content}
</PostHogProvider>
)