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

228
SUPABASE_SETUP.md Normal file
View File

@@ -0,0 +1,228 @@
# TabataFit Supabase Integration
This document explains how to set up and use the Supabase backend for TabataFit.
## Overview
TabataFit now uses Supabase as its backend for:
- **Database**: Storing workouts, trainers, collections, programs, and achievements
- **Storage**: Managing video files, thumbnails, and trainer avatars
- **Authentication**: Admin dashboard access control
- **Real-time**: Future support for live features
## Setup Instructions
### 1. Create Supabase Project
1. Go to [Supabase Dashboard](https://app.supabase.com)
2. Create a new project
3. Note your project URL and anon key
### 2. Configure Environment Variables
Create a `.env` file in the project root:
```bash
EXPO_PUBLIC_SUPABASE_URL=your_supabase_project_url
EXPO_PUBLIC_SUPABASE_ANON_KEY=your_supabase_anon_key
```
### 3. Run Database Migrations
1. Go to your Supabase project's SQL Editor
2. Open `supabase/migrations/001_initial_schema.sql`
3. Run the entire script
This creates:
- All necessary tables (workouts, trainers, collections, programs, achievements)
- Storage buckets (videos, thumbnails, avatars)
- Row Level Security policies
- Triggers for auto-updating timestamps
### 4. Seed the Database
Run the seed script to populate your database with initial data:
```bash
npx ts-node supabase/seed.ts
```
This will import all 50 workouts, 5 trainers, 6 collections, 3 programs, and 8 achievements.
### 5. Set Up Admin User
1. Go to Supabase Dashboard → Authentication → Users
2. Create a new user with email/password
3. Go to SQL Editor and run:
```sql
INSERT INTO admin_users (id, email, role)
VALUES ('USER_UUID_HERE', 'admin@example.com', 'admin');
```
Replace `USER_UUID_HERE` with the actual user UUID from step 2.
### 6. Configure Storage
In Supabase Dashboard → Storage:
1. Verify buckets exist: `videos`, `thumbnails`, `avatars`
2. Set bucket privacy to public for all three
3. Configure CORS if needed for your domain
## Architecture
### Data Flow
```
┌─────────────────┐ ┌──────────────┐ ┌─────────────────┐
│ React Native │────▶│ Supabase │────▶│ PostgreSQL │
│ Client │ │ Client │ │ Database │
└─────────────────┘ └──────────────┘ └─────────────────┘
│ ┌──────────────┐
└──────────────▶│ Admin │
│ Dashboard │
└──────────────┘
```
### Key Components
1. **Supabase Client** (`src/shared/supabase/`)
- `client.ts`: Configured Supabase client
- `database.types.ts`: TypeScript definitions for tables
2. **Data Service** (`src/shared/data/dataService.ts`)
- `SupabaseDataService`: Handles all database operations
- Falls back to mock data if Supabase is not configured
3. **React Hooks** (`src/shared/hooks/useSupabaseData.ts`)
- `useWorkouts`, `useTrainers`, `useCollections`, etc.
- Automatic loading states and error handling
4. **Admin Service** (`src/admin/services/adminService.ts`)
- CRUD operations for content management
- File upload/delete for storage
- Admin authentication
5. **Admin Dashboard** (`app/admin/`)
- `/admin/login`: Authentication screen
- `/admin`: Main dashboard with stats
- `/admin/workouts`: Manage workouts
- `/admin/trainers`: Manage trainers
- `/admin/collections`: Manage collections
- `/admin/media`: Storage management
## Database Schema
### Tables
| Table | Description |
|-------|-------------|
| `trainers` | Trainer profiles with colors and avatars |
| `workouts` | Workout definitions with exercises and metadata |
| `collections` | Curated workout collections |
| `collection_workouts` | Many-to-many link between collections and workouts |
| `programs` | Multi-week workout programs |
| `program_workouts` | Link between programs and workouts with week/day |
| `achievements` | User achievement definitions |
| `admin_users` | Admin dashboard access control |
### Storage Buckets
| Bucket | Purpose | Access |
|--------|---------|--------|
| `videos` | Workout videos | Public read, Admin write |
| `thumbnails` | Workout thumbnails | Public read, Admin write |
| `avatars` | Trainer avatars | Public read, Admin write |
## Using the App
### As a User
The app works seamlessly:
- If Supabase is configured: Loads data from the cloud
- If not configured: Falls back to local mock data
### As an Admin
1. Navigate to `/admin` in the app
2. Sign in with your admin credentials
3. Manage content through the dashboard:
- View all workouts, trainers, collections
- Delete items (create/edit coming soon)
- Upload media files
## Development
### Adding New Workouts
```typescript
import { adminService } from '@/src/admin/services/adminService'
await adminService.createWorkout({
title: 'New Workout',
trainer_id: 'emma',
category: 'full-body',
level: 'Beginner',
duration: 4,
calories: 45,
rounds: 8,
prep_time: 10,
work_time: 20,
rest_time: 10,
equipment: ['No equipment'],
music_vibe: 'electronic',
exercises: [
{ name: 'Jumping Jacks', duration: 20 },
// ...
],
})
```
### Uploading Media
```typescript
const videoUrl = await adminService.uploadVideo(file, 'workout-1.mp4')
const thumbnailUrl = await adminService.uploadThumbnail(file, 'workout-1.jpg')
```
## Troubleshooting
### "Supabase is not configured" Warning
This is expected if environment variables are not set. The app will use mock data.
### Authentication Errors
1. Verify admin user exists in `admin_users` table
2. Check that email/password match
3. Ensure user is confirmed in Supabase Auth
### Storage Upload Failures
1. Verify storage buckets exist
2. Check RLS policies allow admin uploads
3. Ensure file size is within limits
### Data Not Syncing
1. Check network connection
2. Verify Supabase URL and key are correct
3. Check browser console for errors
## Security Considerations
- Row Level Security (RLS) is enabled on all tables
- Public can only read content
- Only admin users can write content
- Storage buckets have public read access
- Storage uploads restricted to admin users
## Future Enhancements
- [ ] Real-time workout tracking
- [ ] User progress sync across devices
- [ ] Offline support with local caching
- [ ] Push notifications
- [ ] Analytics and user insights