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.
This commit is contained in:
Millian Lamiaux
2026-04-22 00:41:19 +02:00
parent e28bebea79
commit 0f5b7b9e18
23 changed files with 4423 additions and 340 deletions

View File

@@ -6,11 +6,11 @@ import Foundation
enum FitnessLevel: String, Codable, CaseIterable {
case beginner, intermediate, advanced
var label: String {
var label: LocalizedStringResource {
switch self {
case .beginner: "Beginner"
case .intermediate: "Intermediate"
case .advanced: "Advanced"
case .beginner: L10n.level.beginner
case .intermediate: L10n.level.intermediate
case .advanced: L10n.level.advanced
}
}
}
@@ -19,12 +19,12 @@ enum FitnessGoal: String, Codable, CaseIterable {
case weightLoss = "weight-loss"
case cardio, strength, wellness
var label: String {
var label: LocalizedStringResource {
switch self {
case .weightLoss: "Weight Loss"
case .cardio: "Cardio"
case .strength: "Strength"
case .wellness: "Wellness"
case .weightLoss: L10n.goal.weightLoss
case .cardio: L10n.goal.cardio
case .strength: L10n.goal.strength
case .wellness: L10n.goal.wellness
}
}
}