Commit Graph

89 Commits

Author SHA1 Message Date
Millian Lamiaux
dc3ff15e81 feat: production-grade Live Activity with type-safe phases, decomposed views, previews, and alert transitions
- Replace raw string phase model with WorkoutPhase enum (Codable, Sendable, CaseIterable)
  with built-in .capitalized display name and SwiftUI .color per phase
- Decompose WorkoutLiveActivity into reusable view structs: PhasePill, CountdownText,
  WorkoutProgressBar, MusicInfoRow, HeartRateBadge, PhaseIndicatorDot, WorkoutLockScreenView,
  WorkoutSmallView — following CraftingSwift iOS 26 architecture patterns
- Add AlertConfiguration on work/rest/complete phase transitions so Dynamic Island
  expands and lights up at key moments
- Add 13 #Preview blocks across both widgets covering all presentation types:
  lock screen, expanded, compact, minimal — for instant Xcode Canvas feedback
- Add stale state handling (context.isStale shows 'Last updated' indicator)
- MusicLiveActivity: 5 new #Preview blocks for playing/paused/expanded/compact/minimal
2026-05-16 15:28:45 +02:00
Millian Lamiaux
95f34e6471 feat: Dynamic Island pause state, Apple-aligned spacing, and UI polish
- Add isPaused to WorkoutActivityAttributes.ContentState
- Show PAUSED badge, freeze timer to static text, dim content when paused
- Prevent stale spinner on pause by extending staleDate to 1 hour
- Add 6s timer warning color, progress bar, compact heavy timer
- Pulsing compact indicator during WORK phase
- Lock Screen margins aligned to Apple's 14pt HIG spec
2026-05-15 23:52:01 +02:00
Millian Lamiaux
057fbb3c9a fix: add 6s timeout to MusicService Supabase fetch for offline fallback
When airplane mode is active, the Supabase client hung indefinitely
waiting for a network response, blocking the mock track fallback.
Now races the query against a 6-second Task.sleep so mock tracks
load immediately after timeout.
2026-05-15 23:51:51 +02:00
Millian Lamiaux
918e663dbf chore: update Xcode project for widget target and watch team
- Add widget target PBXBuildFile, PBXFileReference, PBXGroup, PBXNativeTarget entries
- Reorder PBXCopyFilesBuildPhase and XCBuildConfiguration sections
- Add DEVELOPMENT_TEAM to watch complication and watch app configs
2026-05-15 22:41:35 +02:00
Millian Lamiaux
fe005ee7f3 feat: Live Activity accessibility and supplemental families (small/medium)
- Add @Environment activityFamily, isActivityFullscreen, isLuminanceReduced
- Split into lockScreenView() and smallLockScreenView() variants
- Add supplementalActivityFamilies([.small, .medium]) support
- Add keylineTint and contentMargins to Dynamic Island
- Add accessibility labels throughout (VoiceOver support)
- Hide music bar animation when isLuminanceReduced
2026-05-15 22:41:20 +02:00
Millian Lamiaux
71de3c0aa7 fix: Live Activity concurrency and state observation
- Add Sendable conformance to MusicActivityAttributes.ContentState
- Remove @preconcurrency on ActivityKit import
- Use nonisolated(unsafe) guards for Activity refs in task closures
- Add observeActivityState() to handle stale/ended/dismissed activity states
- Set staleDate (120s) instead of nil for push notification support
2026-05-15 22:41:04 +02:00
Millian Lamiaux
03f660958f add agent skills and opencode config 2026-05-10 20:09:13 +01:00
Millian Lamiaux
349a96379e add mock programs fallback for offline development 2026-05-10 19:20:30 +01:00
Millian Lamiaux
d43142641f refactor: clean up Dynamic Island expanded layout with phase badge, symmetric edges, and music+heart rate in bottom region 2026-05-03 20:59:03 +02:00
Millian Lamiaux
c715c797f9 fix: move Live Activity ownership to ViewModel, fix timer-at-0 and background freeze
**Architecture (PlayerViewModel):**
- Move ActivityKit lifecycle from SwiftUI View to ViewModel (MVVM correction)
- call syncActivity() at END of enterPhase() — after all state is set,
  eliminating the race where phase was Published before timeRemaining
- Always recalculate phaseEndDate = Date() + timeRemaining (no stale cache)
- Dedicated Timer in ViewModel for periodic heart-rate/track sync (5s)
- Start/stop activity sync timer on play/pause/resume/abandon/finish
- stale activity reference discard + recreate-on-failure fallback
- Modern iOS 16.2+ API: ActivityContent, non-throwing update()

**PlayerView:**
- Remove all ActivityKit code (import, @State workoutActivity,
  phaseEndDate, dynamicIslandAvailable, 4 methods, .onReceive timer)
- Delegate to ViewModel: onChange(musicVM.currentTrack) sets vm.trackTitle/Artist
  and calls vm.syncActivity(); onDisappear calls await vm.endActivity()
- Music/audio onChange handlers no longer contain activity logic

**Info.plist:**
- Add UIBackgroundModes → audio so music continues and app stays alive
  in background, allowing Timer-based activity updates
- Widget Info.plist: add NSSupportsLiveActivitiesFrequentUpdates

**WorkoutActivityAttributes.ContentState:**
- Add Sendable conformance for Swift 6 strict concurrency

Fixes: timer stuck at 0 on first work phase, exercise name missing,
       music stopping in background, Dynamic Island freezing in background,
       widget drift due to cached phaseEndDate
2026-05-03 15:40:36 +02:00
Millian Lamiaux
b0d364eca2 feat: redesign player with Dynamic Island, compact timer, and fix Live Activity timer drift
Some checks failed
CI / TypeScript (pull_request) Failing after 5s
CI / ESLint (pull_request) Failing after 3s
CI / Tests (pull_request) Failing after 5s
CI / Build Check (pull_request) Has been skipped
CI / Admin Web Tests (pull_request) Successful in 2m5s
CI / Deploy Edge Functions (pull_request) Has been skipped
## What changed

### Player Redesign (video-first layout)
- New compact timer ring (110pt) with phase label, replaces 240pt ring
- Auto-hide top bar with block progress dots (3s auto-dismiss)
- Expandable now-playing music pill with skip control
- Bottom control bar with heart rate, play/pause, and skip
- Exercise caption with 'Next' preview during rest phases
- Compact round counter (capsule dots)

### Dynamic Island & Live Activities
- WorkoutLiveActivity widget: expanded, compact, and minimal views
- Phase-colored timers with Text(timerInterval:) countdown
- Shows exercise name, round progress, heart rate, music track
- MusicLiveActivity: standalone music now-playing widget
- LiveActivityMusicBars animated component
- Deep link from Dynamic Island back to app

### Timer Drift Fix (critical)
- Store a stable phaseEndDate once per phase instead of
  recalculating Date() + timeRemaining on every update
- Prevents dynamic island countdown from rubber-banding
  due to 5-second periodic update recalculation drift
- Reset phaseEndDate on phase change and resume from pause
- Guard Live Activity updates behind vm.isRunning to prevent
  premature creation when music track loads before workout start
- Fixes timer showing 0 in Dynamic Island when expanding
  from home screen

### New PlayerViewModel timer engine
- Full phase support: prep, warmup, work, rest,
  interBlockRest, cooldown, complete
- 1-second countdown with audio cues at 3-2-1
- Phase transitions with spring animation and haptics
- HealthKit live session integration
- Workout session recording with completion

### Music Service
- New MusicPlayerViewModel with vibe-based playlist loading
- Track info exposed for Dynamic Island display
- Skip track support from Dynamic Island notification action
- Automatic play/pause based on phase and running state

### Additional
- ZoneHighlightIcon component for HomeTab zone cards
- Updated watchOS localizations with complication strings
- Info.plist updated for widget extension
2026-04-25 23:51:46 +02:00
7f5ea9c6e9 Merge pull request 'fix: add HealthKit entitlement and regenerate Xcode project to resolve NSInvalidArgumentException' (#1) from fix/healthkit-info-plist into main
Some checks failed
CI / TypeScript (push) Failing after 3s
CI / ESLint (push) Failing after 4s
CI / Tests (push) Failing after 5s
CI / Build Check (push) Has been skipped
CI / Admin Web Tests (push) Successful in 2m5s
CI / Deploy Edge Functions (push) Has been skipped
Reviewed-on: #1
2026-04-23 22:39:25 +02:00
Millian Lamiaux
9943dce82d fix: add HealthKit entitlement and regenerate Xcode project to resolve NSInvalidArgumentException
Some checks failed
CI / TypeScript (pull_request) Failing after 5s
CI / ESLint (pull_request) Failing after 4s
CI / Tests (pull_request) Failing after 5s
CI / Build Check (pull_request) Has been skipped
CI / Admin Web Tests (pull_request) Successful in 2m8s
CI / Deploy Edge Functions (pull_request) Has been skipped
The iOS app target was missing the com.apple.developer.healthkit entitlement
and the Xcode project was out of sync with project.yml, causing a crash when
HealthKitService requested write authorization for active energy, workouts, and
heart rate types.
2026-04-23 22:34:54 +02:00
Millian Lamiaux
cf096f2068 Redesign Activity tab with animated rings, monthly calendar, and global stats
Some checks failed
CI / TypeScript (push) Failing after 7s
CI / ESLint (push) Failing after 3s
CI / Tests (push) Failing after 7s
CI / Build Check (push) Has been skipped
CI / Admin Web Tests (push) Successful in 2m6s
CI / Deploy Edge Functions (push) Has been skipped
2026-04-22 01:18:42 +02:00
Millian Lamiaux
d74c47b1a8 Move level badge to top-left and free badge to top-right in FeaturedProgramCard 2026-04-22 00:54:42 +02:00
Millian Lamiaux
0f5b7b9e18 feat(i18n): complete internationalization for iOS + watchOS across all views
Migrate every hardcoded Text("...") string to the L10n / LocalizedStringResource
type-safe key system with full en/fr/de/es translations (4 languages).

iOS changes (TabataGo target):
- Strings.swift: ~90 new L10n keys across 13 groups (action, tab, home, zone,
  level, programs, programDetail, player, profile, settings, policy, paywall,
  health, complete, activity, onboarding, goal)
- Localizable.xcstrings: 145 → 245+ keys with fr/de/es translations
- Model enums: FitnessLevel.label & FitnessGoal.label changed from String to
  LocalizedStringResource, backed by L10n.level/goal keys
- Component param types changed to LocalizedStringResource: StatBadge,
  SectionHeader, ProfileRow, PolicySection, CompletionStat, FeatureRow,
  OnboardingHeader, PrimaryButton, SelectionCard
- All 18 view files updated: HomeTab, ActivityTab, ProgramsTab, ProfileTab,
  MainTabView, SettingsView, PolicyViews, CompletionView, BodyZoneView,
  ProgramDetailView, PaywallView, OnboardingView, PlayerView

Watch changes (TabataGoWatch target):
- New Localizable.xcstrings: 23 keys with en/fr/de/es (phase labels, idle
  state, activity rings, complication strings)
- New WatchL10n.swift: type-safe enum (needs manual Xcode target membership)
- Updated: WatchPlayerView, WatchIdleView, WatchActivityView,
  TabataGoComplication (inline LocalizedStringResource for widget target)

Both iOS and watchOS targets build with zero errors.
2026-04-22 00:41:19 +02:00
Millian Lamiaux
e28bebea79 Redesign FeaturedProgramCard and reorder Home sections
- Replace external pill badges (level + FREE) with immersive overlay card:
  level tag pinned top-right with ultraThinMaterial blur, FREE shown inline
  with checkmark.seal.fill icon, dark scrim for text legibility
- Remove card drop shadow
- Move Browse by Zone section above Featured in Home tab scroll order
2026-04-21 23:18:15 +02:00
Millian Lamiaux
9f15ae2d79 fix: dismiss paywall and sync premium state after successful purchase
- Add purchaseSucceeded flag to PurchaseViewModel, set on purchase success
- PaywallView observes the flag and dismisses itself automatically
- ProfileTab.syncSubscription() writes PurchaseService.currentPlan back
  to UserProfile.subscriptionRaw via SwiftData on sheet dismiss
2026-04-21 23:00:45 +02:00
Millian Lamiaux
877f836f19 Replace double chip filters with segmented control + dropdown menu in ProgramsTab
Swap the two horizontal FilterChip scroll rows with a native segmented
Picker for body zone and a toolbar Menu for difficulty level. Fix zone
values to match Supabase enum (upper-body, lower-body, full-body).
Remove unused FilterChip struct.
2026-04-21 22:47:47 +02:00
Millian Lamiaux
2413bc0356 Remove 'All Workouts' section from HomeTab 2026-04-21 22:04:56 +02:00
Millian Lamiaux
89cca25e22 remove Expo project and all related files
Remove the entire Expo/React Native application: routes (app/), source
code (src/), assets, iOS native build, config plugins, StoreKit config,
npm dependencies, TypeScript/ESLint/Vitest configs, and Expo-specific
documentation. The repository now contains only: admin-web, supabase,
youtube-worker, tabatago-swift, docs, scripts, and CI/tooling configs.
2026-04-21 21:55:00 +02:00
Millian Lamiaux
8c90b73d90 update config, admin-web tooling & relocate agent skills
Update app.json config and add new dependencies in package.json. Update
.gitignore for new patterns. Add timed-exercise editor/list components,
warmup/stretch video migration, and Supabase helpers in admin-web.
Relocate agent skills from .agents/skills/ to .opencode/skills/.
2026-04-21 21:51:11 +02:00
Millian Lamiaux
d4edf54aeb update data layer, i18n locales & service exports
Rewrite data index, useTranslatedData, and workoutPrograms for the new
Supabase-backed model. Update hooks/stores barrel exports. Extend user
types and workoutProgram types. Refresh all i18n locale files (en, fr,
de, es) with updated screen translations. Add music service helpers.
Fix minor test import updates.
2026-04-21 21:51:01 +02:00
Millian Lamiaux
5888aac08e refactor screens, navigation & player for new architecture
Simplify Home, Activity, Profile, Complete, Player, and Program screens
to work with the new Supabase-driven data layer. Update root and tab
layouts. Add Settings, Terms, and Zone routes. Add OfflineBanner
component and progressStore. Update all player sub-components to use
the refreshed design system tokens.
2026-04-21 21:50:48 +02:00
Millian Lamiaux
04b83fc419 refresh design system: colors, typography, native components
Update color palette, dark theme tokens, typography scale, and border
radius constants. Refactor native UI primitives (NativeButton, NativeList,
NativeSection, NativeLabeledRow) for the new design language. Simplify
OnboardingStep. Remove legacy WorkoutCard and CollectionCard components.
2026-04-21 21:50:31 +02:00
Millian Lamiaux
13262305e5 remove obsolete tests for deleted data, stores & components
Delete tests for removed modules: WorkoutCard, CollectionCard, Skeleton,
achievements, dataService, programs, trainers, useTranslatedData,
workouts, useSupabaseData, activityStore, programStore,
tabataProgramStore, and workoutProgramStore.
2026-04-21 21:50:19 +02:00
Millian Lamiaux
3fe9d926ad remove legacy data layer, stores & Supabase seed
Delete hardcoded programs data (including tabata sub-modules), workouts,
achievements, collections, trainers, and the dataService abstraction.
Remove activityStore, programStore, and tabataProgramStore which
depended on this data. Remove useSupabaseData hook and supabase seed
file. Data now comes from Supabase via the admin-web CMS.
2026-04-21 21:50:09 +02:00
Millian Lamiaux
d82205cd71 remove legacy admin panel, assessment, collection & workout routes
Remove the in-app admin panel (app/admin/, src/admin/), assessment
screen, collection detail routes, and workout detail/category/body-zone
routes. These features have been superseded by the admin-web dashboard
and the new program-based navigation. Also removes stale CLAUDE.md
context files and an accidentally committed image blob.
2026-04-21 21:49:58 +02:00
Millian Lamiaux
791f432334 refactor: code quality cleanup — remove any types, add logger, rename Kine to Tabata
- Phase 0: Rename all Kine references to Tabata (types, files, imports, i18n, analytics events)
- Phase 1: Add test coverage for tabataProgramStore, workoutProgramStore, and color utils (47 tests)
- Phase 2: Remove all `any` types from production code with proper typed replacements
- Phase 3: Replace ~60 raw console.* calls with __DEV__-gated logger utility
- Phase 4: Verify .DS_Store housekeeping (already clean)

0 TypeScript errors, 583/583 tests passing.
2026-04-17 18:56:24 +02:00
Millian Lamiaux
e0e02c4550 fix: align program detail screen with Dark Medical design system
Replace hardcoded #000 backgrounds with NAVY[900], use design system
tokens for badges (TYPOGRAPHY.LABEL, RADIUS.SM), progress bar
(RADIUS.PILL, 4px height), and CTA container (DARK.SCRIM).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-13 22:19:29 +02:00
Millian Lamiaux
0990ec8e11 refactor: remove explore tab, simplify to 3-tab layout (Home, Progress, Profile)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-13 22:06:11 +02:00
Millian Lamiaux
4458044d0e fix: resolve all 228 TypeScript errors across the project
- Exclude admin-web and supabase/functions from root tsconfig (185 errors)
- Add missing constant exports: FONT_FAMILY_SANS_BOLD/SEMIBOLD, BRAND_DANGER (9 errors)
- Fix React Query API destructuring in admin screens: data/isLoading aliases (12 errors)
- Add getWorkoutsByCategory to data layer, fix category screen types (5 errors)
- Add type assertions for Supabase never types in adminService and sync.ts (13 errors)
- Add missing vitest imports (vi, beforeEach) and replace removed PRIMARY_DARK (5 errors)
- Fix seed.ts to use program.weeks[].workouts[] instead of missing props (4 errors)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-06 17:53:02 +02:00
Millian Lamiaux
edcd857c70 feat(admin-web, functions): overhaul music library and add AI genre classification
Some checks failed
CI / TypeScript (push) Failing after 48s
CI / ESLint (push) Failing after 20s
CI / Tests (push) Failing after 33s
CI / Build Check (push) Has been skipped
CI / Admin Web Tests (push) Failing after 18s
CI / Deploy Edge Functions (push) Has been skipped
- admin-web: Added an "All Music" library view with search, genre, and status filters.
- admin-web: Converted Jobs view to use expandable cards instead of a split pane.
- admin-web: Added ability to delete individual tracks from a job.
- functions: Added new `youtube-classify` edge function to automatically categorize tracks using Gemini LLM.
- functions: Integrated AI genre classification during initial playlist import if no manual genre is provided.
- worker: Added `/classify` endpoint for the worker to securely interface with Gemini.
- scripts: Updated deployment script to include `GEMINI_API_KEY`.
2026-03-29 12:52:02 +02:00
Millian Lamiaux
3d8d9efd70 feat: YouTube music download system with admin dashboard
Sidecar architecture: edge functions (auth + DB) → youtube-worker container
(youtubei.js for playlist metadata, yt-dlp for audio downloads).

- Edge functions: youtube-playlist, youtube-process, youtube-status (CRUD)
- youtube-worker sidecar: Node.js + yt-dlp, downloads M4A to Supabase Storage
- Admin music page: import playlists, process queue, inline genre editing
- 12 music genres with per-track assignment and import-time defaults
- DB migrations: download_jobs, download_items tables with genre column
- Deploy script and CI workflow for edge functions + sidecar
2026-03-26 10:47:05 +01:00
Millian Lamiaux
8926de58e5 refactor: extract player components, add stack headers, add tests
- Extract player UI into src/features/player/ components (TimerRing, BurnBar, etc.)
- Add transparent stack headers for workout/[id] and program/[id] screens
- Refactor workout/[id], program/[id], complete/[id] screens
- Add player feature tests and useTimer integration tests
- Add data layer exports and test setup improvements
2026-03-26 10:46:47 +01:00
Millian Lamiaux
569a9e178f fix: add missing getPopularWorkouts export to data layer
The workout complete screen imports getPopularWorkouts to show
recommended workouts, but the function was never implemented. Added it
to the data index — picks the first workout from each program week for
variety across categories and levels.
2026-03-26 00:06:46 +01:00
Millian Lamiaux
b833198e9d feat: migrate icons to SF Symbols, refactor explore tab, add collections/programs data layer
- Replace all Ionicons with native SF Symbols via expo-symbols SymbolView
- Create reusable Icon wrapper component (src/shared/components/Icon.tsx)
- Remove @expo/vector-icons and lucide-react dependencies
- Refactor explore tab with filters, search, and category browsing
- Add collections and programs data with Supabase integration
- Add explore filter store and filter sheet
- Update i18n strings (en, de, es, fr) for new explore features
- Update test mocks and remove stale snapshots
- Add user fitness level to user store and types
2026-03-25 23:28:51 +01:00
Millian Lamiaux
f11eb6b9ae fix: add missing Workout fields to program workouts and guard against undefined level
Program workouts built by buildProgramWorkouts() were missing level,
rounds, calories, and other Workout-interface fields, causing
workout.level.toLowerCase() to crash on the detail, collection, and
category screens. Added derived defaults (level from week number,
category from program id, standard Tabata timings) and defensive
fallbacks with ?? 'Beginner' at all call sites. Also fixed a potential
division-by-zero when exercises array is empty.
2026-03-25 23:28:47 +01:00
Millian Lamiaux
4fa8be600c test: add QA coverage — access unit tests, VideoPlayer snapshots, Maestro E2E flows, testIDs
- Add testIDs to explore, workout detail, and collection detail screens
- Add testID prop to VideoPlayer component
- Create access service unit tests (isFreeWorkout, canAccessWorkout)
- Create VideoPlayer rendering snapshot tests (preview/background modes)
- Create Maestro E2E flows: explore-freemium, collection-detail
- Update tab-navigation flow with Explore screen assertions
- Update profile-settings flow with real activity stat assertions
- Update all-tests suite to include new flows
2026-03-24 12:40:02 +01:00
Millian Lamiaux
a042c348c1 feat: close v1 feature gaps — freemium gating, video/audio infrastructure, EAS build config
- Add access control service with 3 free workouts (IDs 1, 11, 43), paywall gating on workout detail and lock indicators on explore grid
- Wire VideoPlayer into player background and workout detail preview
- Add placeholder HLS video URLs to 5 sample workouts (Apple test streams)
- Add test audio URLs to music service MOCK_TRACKS for all vibes
- Switch RevenueCat API key to env-based with sandbox fallback
- Create eas.json with development/preview/production build profiles
- Update app.json with iOS privacy descriptions (HealthKit, Camera) and non-exempt encryption flag
- Create collection detail screen (route crash fix)
- Replace hardcoded profile stats with real activity store data
- Add unlockWithPremium i18n key in EN/FR/DE/ES
2026-03-24 12:20:56 +01:00
Millian Lamiaux
cd065d07c3 feat: explore tab, React Query data layer, programs, sync, analytics, testing infrastructure
- Replace browse tab with Supabase-connected explore tab with filters
- Add React Query for data fetching with loading states
- Add 3 structured programs with weekly progression
- Add Supabase anonymous auth sync service
- Add PostHog analytics with screen tracking and events
- Add comprehensive test strategy (Vitest + Maestro E2E)
- Add RevenueCat subscription system with DEV simulation
- Add i18n translations for new screens (EN/FR/DE/ES)
- Add data deletion modal, sync consent modal
- Add assessment screen and program routes
- Add GitHub Actions CI workflow
- Update activity store with sync integration
2026-03-24 12:04:48 +01:00
Millian Lamiaux
8703c484e8 Replace workouts tab with explore tab connected to Supabase
- Rename workouts.tsx to explore.tsx with new functionality
- Add horizontal scrolling collections section with gradient cards
- Add featured workouts section
- Implement filtering by category (All, Full Body, Upper Body, Lower Body, Core, Cardio)
- Implement filtering by level (All Levels, Beginner, Intermediate, Advanced)
- Implement filtering by equipment (All, No Equipment, Band, Dumbbells, Mat)
- Add clear filters button when filters are active
- Add loading states with ActivityIndicator
- Add empty state for no results
- Update tab label from "Workouts" to "Explore"
- Add explore translations for en, fr, de, es
2026-03-23 21:27:19 +01:00
Millian Lamiaux
197324188c feat: update Home screen to use React Query with loading states
- Replace static data with React Query hooks
- Add loading skeletons for all data sections
- Show shimmer effect while data is loading
- Handle empty and error states gracefully
2026-03-17 14:29:27 +01:00
Millian Lamiaux
b1741e965c feat: implement React Query for Supabase data fetching
- Install @tanstack/react-query and async-storage-persister
- Wrap app with QueryClientProvider in root layout
- Migrate useSupabaseData hooks to React Query
- Add loading skeleton components for better UX
- Configure 5-minute stale time and 24-hour cache
- Add query keys for proper cache management
- Remove duplicate files and clean up structure
2026-03-17 14:25:41 +01:00
Millian Lamiaux
e13d917466 docs: add test implementation summary document
- Document all test files created
- Show coverage improvements
- Add usage instructions
- List remaining work items
2026-03-17 13:52:37 +01:00
Millian Lamiaux
3da40c97ce test: implement comprehensive test strategy
- Add Playwright for E2E testing with auth.spec.ts
- Add dialog component tests (8 test cases)
- Add sidebar component tests (11 test cases)
- Add login page integration tests (11 test cases)
- Add dashboard page tests (12 test cases)
- Update package.json with e2e test scripts
- Configure Playwright for Chromium and Firefox
- Test coverage for UI interactions, auth flows, and navigation
2026-03-17 13:51:39 +01:00
Millian Lamiaux
b177656efc feat: replace native confirm() dialogs with custom delete confirmation dialogs
- Add Dialog component for delete confirmation in trainers page
- Add Dialog component for delete confirmation in workouts page
- Show entity name in confirmation dialog
- Dark theme styling to match app design
- Add loading state with spinner during deletion
2026-03-17 11:53:10 +01:00
Millian Lamiaux
fc43f73b82 feat: add success toasts for create operations and login
- Add toast.success when workout is created or updated
- Add toast.success when user logs in successfully
- Show descriptive messages with entity names
- Improves user feedback for successful operations
2026-03-17 11:47:17 +01:00
Millian Lamiaux
3d026b68ee feat: implement beautiful toast notifications with Sonner
- Install sonner package for toast notifications
- Add Toaster component to root layout with dark theme styling
- Replace all alert() calls with toast.success() and toast.error()
- Add descriptive messages for success states
- Toast notifications match the app's dark theme design
2026-03-17 11:45:29 +01:00
Millian Lamiaux
554ad2a352 fix: use createBrowserClient for proper cookie-based auth
- Switch from @supabase/supabase-js to @supabase/ssr createBrowserClient
- This stores session in cookies instead of localStorage
- Allows middleware to access session server-side
- Fixes the missing cookies issue,description:Commit cookie auth fix
2026-03-17 11:23:04 +01:00