From d4be30cf742bf721c8a2dd182e0700ffdceb8377 Mon Sep 17 00:00:00 2001 From: Patryk Hegenberg Date: Wed, 21 Jan 2026 14:55:09 +0100 Subject: [PATCH] feat: add timer to timebased Exercises --- lib/l10n/app_de.arb | 2 + lib/l10n/app_en.arb | 2 + .../presentation/screens/login_screen.dart | 9 - .../presentation/screens/hub_screen.dart | 15 - .../presentation/screens/lobby_screen.dart | 3 - .../application/battle_controller.dart | 32 ++ .../workout_generator_service.dart | 4 +- .../presentation/screens/battle_screen.dart | 366 ++++++++++++++++++ .../presentation/widgets/timer_widget.dart | 187 +++++++-- lib/src/shared/data/remote/api_client.dart | 5 - 10 files changed, 567 insertions(+), 58 deletions(-) diff --git a/lib/l10n/app_de.arb b/lib/l10n/app_de.arb index 0fa31f7..f161f1d 100644 --- a/lib/l10n/app_de.arb +++ b/lib/l10n/app_de.arb @@ -123,6 +123,8 @@ }, "battleWeight": "GEWICHT", "battleReps": "WH", + "battleTime": "ZEIT", + "battleStartTimer": "Timer starten", "battleAssistance": "UNTERSTÜTZUNG", "battleCompleteSet": "SATZ ABSCHLIESSEN", "battleRest": "PAUSE", diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb index 70e3548..ec35798 100644 --- a/lib/l10n/app_en.arb +++ b/lib/l10n/app_en.arb @@ -123,6 +123,8 @@ }, "battleWeight": "WEIGHT", "battleReps": "REPS", + "battleTime": "TIME", + "battleStartTimer": "Start Timer", "battleAssistance": "ASSISTANCE", "battleCompleteSet": "COMPLETE SET", "battleRest": "REST", diff --git a/lib/src/features/authentication/presentation/screens/login_screen.dart b/lib/src/features/authentication/presentation/screens/login_screen.dart index 634fe5a..bac2393 100644 --- a/lib/src/features/authentication/presentation/screens/login_screen.dart +++ b/lib/src/features/authentication/presentation/screens/login_screen.dart @@ -104,7 +104,6 @@ class _LoginScreenState extends ConsumerState { crossAxisAlignment: CrossAxisAlignment.stretch, children: [ const Spacer(), - Container( width: 100, height: 100, @@ -127,7 +126,6 @@ class _LoginScreenState extends ConsumerState { ), ), const SizedBox(height: 32), - Text( l10n.loginWelcomeBack, style: Theme.of(context).textTheme.displayMedium, @@ -140,7 +138,6 @@ class _LoginScreenState extends ConsumerState { textAlign: TextAlign.center, ), const SizedBox(height: 48), - if (_errorMessage != null) Container( padding: const EdgeInsets.all(16), @@ -173,7 +170,6 @@ class _LoginScreenState extends ConsumerState { ], ), ), - TextFormField( controller: _emailController, focusNode: _emailFocusNode, @@ -198,8 +194,6 @@ class _LoginScreenState extends ConsumerState { }, ), const SizedBox(height: 16), - - // Password Field TextFormField( controller: _passwordController, focusNode: _passwordFocusNode, @@ -234,7 +228,6 @@ class _LoginScreenState extends ConsumerState { }, ), const SizedBox(height: 32), - ElevatedButton( onPressed: _isLoading ? null : _handleLogin, style: ElevatedButton.styleFrom( @@ -262,7 +255,6 @@ class _LoginScreenState extends ConsumerState { ), ), const SizedBox(height: 16), - Row( mainAxisAlignment: MainAxisAlignment.center, children: [ @@ -278,7 +270,6 @@ class _LoginScreenState extends ConsumerState { ), ], ), - const Spacer(), ], ), diff --git a/lib/src/features/dashboard/presentation/screens/hub_screen.dart b/lib/src/features/dashboard/presentation/screens/hub_screen.dart index 8150536..5caeeef 100644 --- a/lib/src/features/dashboard/presentation/screens/hub_screen.dart +++ b/lib/src/features/dashboard/presentation/screens/hub_screen.dart @@ -494,21 +494,6 @@ class _HubScreenState extends ConsumerState { ), ), const SizedBox(height: 24), - // if (cycle != null) - // Padding( - // padding: const EdgeInsets.symmetric(horizontal: 32), - // child: Row( - // mainAxisAlignment: MainAxisAlignment.spaceEvenly, - // children: [ - // _StatBox( - // label: l10n.hubCycleLabel, - // value: '#${cycle.cycleNumber}'), - // _StatBox( - // label: l10n.hubActiveLabel, - // value: l10n.hubActiveYes), - // ], - // ), - // ), const Spacer(flex: 1), Container( padding: const EdgeInsets.symmetric( diff --git a/lib/src/features/multiplayer/presentation/screens/lobby_screen.dart b/lib/src/features/multiplayer/presentation/screens/lobby_screen.dart index 327ee26..b372514 100644 --- a/lib/src/features/multiplayer/presentation/screens/lobby_screen.dart +++ b/lib/src/features/multiplayer/presentation/screens/lobby_screen.dart @@ -185,9 +185,6 @@ class _LobbyScreenState extends ConsumerState { await ref .read(partyRepositoryProvider) .startRaid(party.id, customHp: raidHp); - // ref - // .read(partyRepositoryProvider) - // .startRaid(party.id); }, child: Text( l10n.lobbyStartRaid, diff --git a/lib/src/features/workout_runner/application/battle_controller.dart b/lib/src/features/workout_runner/application/battle_controller.dart index 0dc8de2..0f23d18 100644 --- a/lib/src/features/workout_runner/application/battle_controller.dart +++ b/lib/src/features/workout_runner/application/battle_controller.dart @@ -13,6 +13,8 @@ class BattleState { final bool isResting; final int restSeconds; final String? error; + final bool isExerciseTimerActive; + final int exerciseTimerSeconds; const BattleState({ this.exercises = const [], @@ -22,6 +24,8 @@ class BattleState { this.isLoading = true, this.isResting = false, this.restSeconds = 0, + this.isExerciseTimerActive = false, + this.exerciseTimerSeconds = 0, this.error, }); @@ -33,6 +37,8 @@ class BattleState { bool? isLoading, bool? isResting, int? restSeconds, + bool? isExerciseTimerActive, + int? exerciseTimerSeconds, String? error, }) { return BattleState( @@ -43,6 +49,9 @@ class BattleState { isLoading: isLoading ?? this.isLoading, isResting: isResting ?? this.isResting, restSeconds: restSeconds ?? this.restSeconds, + isExerciseTimerActive: + isExerciseTimerActive ?? this.isExerciseTimerActive, + exerciseTimerSeconds: exerciseTimerSeconds ?? this.exerciseTimerSeconds, error: error ?? this.error, ); } @@ -93,7 +102,30 @@ class BattleController extends _$BattleController { state = state.copyWith(isResting: false, restSeconds: 0); } + void startExerciseTimer(int seconds) { + state = state.copyWith( + isExerciseTimerActive: true, exerciseTimerSeconds: seconds); + } + + void tickExerciseTimer() { + if (state.exerciseTimerSeconds > 0) { + state = + state.copyWith(exerciseTimerSeconds: state.exerciseTimerSeconds - 1); + } else { + state = state.copyWith(isExerciseTimerActive: false); + } + } + + void stopExerciseTimer() { + state = + state.copyWith(isExerciseTimerActive: false, exerciseTimerSeconds: 0); + } + void completeSet({required int repsActual}) { + if (state.isExerciseTimerActive) { + state = state.copyWith(isExerciseTimerActive: false); + } + final currentExercise = state.exercises[state.currentExerciseIndex]; final currentSet = currentExercise.sets[state.currentSetIndex]; diff --git a/lib/src/features/workout_runner/application/workout_generator_service.dart b/lib/src/features/workout_runner/application/workout_generator_service.dart index 1d976ed..14e3169 100644 --- a/lib/src/features/workout_runner/application/workout_generator_service.dart +++ b/lib/src/features/workout_runner/application/workout_generator_service.dart @@ -169,7 +169,7 @@ class WorkoutGeneratorService { accessories.add(createSimple('curl', 'Barbell Curl', 3, 10, weight: calculateWeight(pullupTm, 0.2))); - accessories.add(createSimple('plank', 'Plank (30s)', 3, 1)); + accessories.add(createSimple('plank', 'Plank (30s)', 3, 30)); accessories.add(_createIntervalExercise( id: 'kb_swing', @@ -217,7 +217,7 @@ class WorkoutGeneratorService { ExerciseType.scapularPull, 3, 10)); exercises.add(createAccessory( - 'plank', 'Core Plank (45s)', ExerciseType.plank, 3, 1)); + 'plank', 'Core Plank (45s)', ExerciseType.plank, 3, 45)); break; case 2: diff --git a/lib/src/features/workout_runner/presentation/screens/battle_screen.dart b/lib/src/features/workout_runner/presentation/screens/battle_screen.dart index 099a94d..471efc4 100644 --- a/lib/src/features/workout_runner/presentation/screens/battle_screen.dart +++ b/lib/src/features/workout_runner/presentation/screens/battle_screen.dart @@ -8,6 +8,7 @@ import 'package:slrpg_app/src/features/multiplayer/presentation/screens/lobby_sc import 'package:slrpg_app/src/features/workout_runner/application/battle_controller.dart'; import 'package:slrpg_app/src/features/workout_runner/application/workout_completion_service.dart'; import 'package:slrpg_app/src/features/workout_runner/application/workout_loader_service.dart'; +import 'package:slrpg_app/src/features/workout_runner/presentation/widgets/timer_widget.dart'; import 'package:slrpg_app/src/shared/domain/entities/exercise.dart'; import 'package:slrpg_app/src/shared/domain/entities/workout_set.dart'; @@ -68,6 +69,11 @@ class _BattleScreenState extends ConsumerState { } } + bool _isTimeBasedExercise(String exerciseId) { + final id = exerciseId.toLowerCase(); + return id.contains('plank') || id.contains('hold') || id.contains('static'); + } + String _getEnemyAsset(String exerciseId) { switch (exerciseId) { case 'squat': @@ -560,6 +566,356 @@ class _BattleScreenState extends ConsumerState { ); } + Widget _buildTimeBasedView( + Exercise currentExercise, + WorkoutSet currentSet, + PlateLoadResult plateResult, + int completedHP, + int totalHP, + ) { + final l10n = AppLocalizations.of(context)!; + final state = ref.watch(battleControllerProvider); + final controller = ref.read(battleControllerProvider.notifier); + + return Column( + children: [ + Flexible( + flex: 3, + child: Stack( + alignment: Alignment.center, + children: [ + Padding( + padding: const EdgeInsets.only(bottom: 20), + child: Image.asset( + _getEnemyAsset(currentExercise.exerciseId), + fit: BoxFit.contain, + color: Colors.white.withValues(alpha: 0.9), + colorBlendMode: BlendMode.modulate, + ), + ), + Positioned( + top: 16, + right: 16, + child: Container( + padding: + const EdgeInsets.symmetric(horizontal: 12, vertical: 6), + decoration: BoxDecoration( + color: Colors.black54, + borderRadius: BorderRadius.circular(20), + border: Border.all(color: Colors.white24), + ), + child: Text( + l10n.battleWave( + state.currentExerciseIndex + 1, + state.exercises.length, + ), + style: const TextStyle( + color: Colors.white, + fontWeight: FontWeight.bold, + fontSize: 12, + ), + ), + ), + ), + Positioned( + bottom: 10, + left: 32, + right: 32, + child: Column( + children: [ + const Icon(Icons.favorite, + color: AppTheme.errorColor, size: 24), + const SizedBox(height: 4), + widget.partyId != null + ? _buildMultiplayerHpBar() + : EnemyHPBar( + current: totalHP - completedHP, + max: totalHP, + ), + ], + ), + ), + ], + ), + ), + Expanded( + flex: 7, + child: Container( + decoration: BoxDecoration( + color: AppTheme.surfaceColor.withValues(alpha: 0.95), + borderRadius: + const BorderRadius.vertical(top: Radius.circular(24)), + boxShadow: [ + BoxShadow( + color: Colors.black.withValues(alpha: 0.5), + blurRadius: 20, + offset: const Offset(0, -5), + ) + ], + ), + child: Column( + children: [ + Expanded( + child: SingleChildScrollView( + padding: const EdgeInsets.fromLTRB(24, 24, 24, 100), + child: Column( + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text( + currentExercise.exerciseName, + style: Theme.of(context) + .textTheme + .headlineMedium + ?.copyWith( + color: AppTheme.primaryColor, + fontWeight: FontWeight.bold, + ), + textAlign: TextAlign.center, + ), + IconButton( + icon: const Icon(Icons.info_outline, + color: Colors.white54), + onPressed: () => _showExerciseGuide( + currentExercise.exerciseId), + ), + ], + ), + + Text( + l10n.battleSet( + state.currentSetIndex + 1, + currentExercise.sets.length, + ), + style: + Theme.of(context).textTheme.titleMedium?.copyWith( + color: Colors.white70, + ), + ), + + const SizedBox(height: 24), + + Container( + padding: const EdgeInsets.all(24), + decoration: BoxDecoration( + color: + AppTheme.backgroundColor.withValues(alpha: 0.5), + borderRadius: BorderRadius.circular(16), + border: Border.all( + color: + AppTheme.primaryColor.withValues(alpha: 0.3), + width: 2, + ), + ), + child: TimerWidget( + key: ValueKey( + '${currentExercise.exerciseId}_${state.currentExerciseIndex}_${state.currentSetIndex}', + ), + durationSeconds: currentSet.repsTarget, + onComplete: () { + controller.stopExerciseTimer(); + _showTimeBasedCompleteDialog(currentSet); + }, + ), + ), + + const SizedBox(height: 24), + + if (currentSet.targetWeightTotal > 0) ...[ + Container( + padding: const EdgeInsets.all(16), + decoration: BoxDecoration( + color: AppTheme.surfaceColor, + borderRadius: BorderRadius.circular(12), + border: Border.all(color: Colors.white10), + ), + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + const Icon(Icons.fitness_center, + color: AppTheme.primaryColor), + const SizedBox(width: 12), + Text( + '${currentSet.targetWeightTotal} kg', + style: const TextStyle( + color: Colors.white, + fontSize: 24, + fontWeight: FontWeight.bold, + ), + ), + ], + ), + ), + const SizedBox(height: 16), + ], + + // // Reps Info (falls vorhanden) + // if (currentSet.repsTarget > 0) + // Container( + // padding: const EdgeInsets.symmetric( + // horizontal: 16, + // vertical: 12, + // ), + // decoration: BoxDecoration( + // color: AppTheme.secondaryColor + // .withValues(alpha: 0.1), + // borderRadius: BorderRadius.circular(8), + // border: + // Border.all(color: AppTheme.secondaryColor), + // ), + // child: Text( + // '${currentSet.repsTarget} ${currentSet.isAmrap ? "+" : ""} Reps', + // style: const TextStyle( + // color: AppTheme.secondaryColor, + // fontSize: 18, + // fontWeight: FontWeight.bold, + // ), + // ), + // ), + ], + ), + ), + ), + Container( + color: AppTheme.surfaceColor, + padding: const EdgeInsets.all(16), + child: SafeArea( + top: false, + child: SizedBox( + width: double.infinity, + child: ElevatedButton( + onPressed: () { + controller.stopExerciseTimer(); + _showTimeBasedCompleteDialog(currentSet); + }, + style: ElevatedButton.styleFrom( + padding: const EdgeInsets.symmetric(vertical: 16), + backgroundColor: AppTheme.successColor, + foregroundColor: Colors.white, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(12), + ), + ), + child: Text( + l10n.battleCompleteSet, + style: const TextStyle( + fontSize: 18, + fontWeight: FontWeight.bold, + letterSpacing: 1.2, + ), + ), + ), + ), + ), + ), + ], + ), + ), + ), + ], + ); + } + + void _showTimeBasedCompleteDialog(WorkoutSet currentSet) { + final l10n = AppLocalizations.of(context)!; + + if (currentSet.repsTarget > 0) { + int tempReps = currentSet.repsTarget; + + showModalBottomSheet( + context: context, + backgroundColor: AppTheme.surfaceColor, + isScrollControlled: true, + shape: const RoundedRectangleBorder( + borderRadius: BorderRadius.vertical(top: Radius.circular(24)), + ), + builder: (context) { + return StatefulBuilder( + builder: (context, setModalState) { + return Padding( + padding: const EdgeInsets.all(24), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + const Icon(Icons.timer_off, + size: 48, color: AppTheme.successColor), + const SizedBox(height: 16), + Text( + 'Time Complete!', + style: Theme.of(context).textTheme.titleLarge?.copyWith( + color: Colors.white, + fontWeight: FontWeight.bold, + ), + ), + const SizedBox(height: 8), + const Text( + 'How many reps did you complete?', + style: TextStyle(color: Colors.grey), + ), + const SizedBox(height: 32), + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + _CounterButton( + icon: Icons.remove, + onTap: tempReps > 0 + ? () => setModalState(() => tempReps--) + : null, + ), + Container( + width: 120, + alignment: Alignment.center, + child: Text( + '$tempReps', + style: const TextStyle( + fontSize: 72, + fontWeight: FontWeight.bold, + color: Colors.white, + ), + ), + ), + _CounterButton( + icon: Icons.add, + onTap: () => setModalState(() => tempReps++), + ), + ], + ), + const SizedBox(height: 32), + SizedBox( + width: double.infinity, + height: 56, + child: ElevatedButton( + onPressed: () { + Navigator.pop(context); + _completeSetAndProgress(tempReps); + }, + style: ElevatedButton.styleFrom( + backgroundColor: AppTheme.successColor, + foregroundColor: Colors.white, + ), + child: const Text( + 'CONFIRM', + style: TextStyle( + fontSize: 18, + fontWeight: FontWeight.bold, + ), + ), + ), + ), + const SizedBox(height: 16), + ], + ), + ); + }, + ); + }, + ); + } else { + _completeSetAndProgress(0); + } + } + Widget _buildWorkoutScreen( Exercise currentExercise, WorkoutSet currentSet, @@ -572,6 +928,16 @@ class _BattleScreenState extends ConsumerState { return _buildEmomView(currentExercise, currentSet, completedHP, totalHP); } + if (_isTimeBasedExercise(currentExercise.exerciseId)) { + return _buildTimeBasedView( + currentExercise, + currentSet, + plateResult, + completedHP, + totalHP, + ); + } + final l10n = AppLocalizations.of(context)!; final state = ref.watch(battleControllerProvider); diff --git a/lib/src/features/workout_runner/presentation/widgets/timer_widget.dart b/lib/src/features/workout_runner/presentation/widgets/timer_widget.dart index bd575d9..659c561 100644 --- a/lib/src/features/workout_runner/presentation/widgets/timer_widget.dart +++ b/lib/src/features/workout_runner/presentation/widgets/timer_widget.dart @@ -3,16 +3,35 @@ import 'dart:async'; import '../../../../core/theme/app_theme.dart'; class TimerWidget extends StatefulWidget { - const TimerWidget({super.key}); + final int durationSeconds; + final VoidCallback? onComplete; + final bool autoStart; + + const TimerWidget({ + super.key, + required this.durationSeconds, + this.onComplete, + this.autoStart = true, + }); @override State createState() => _TimerWidgetState(); } class _TimerWidgetState extends State { - int _seconds = 0; + late int _secondsRemaining; Timer? _timer; bool _isRunning = false; + bool _isCompleted = false; + + @override + void initState() { + super.initState(); + _secondsRemaining = widget.durationSeconds; + if (widget.autoStart) { + _start(); + } + } @override void dispose() { @@ -21,8 +40,19 @@ class _TimerWidgetState extends State { } void _start() { + if (_isCompleted) return; + _timer = Timer.periodic(const Duration(seconds: 1), (timer) { - setState(() => _seconds++); + setState(() { + if (_secondsRemaining > 0) { + _secondsRemaining--; + } else { + _timer?.cancel(); + _isRunning = false; + _isCompleted = true; + widget.onComplete?.call(); + } + }); }); setState(() => _isRunning = true); } @@ -35,42 +65,151 @@ class _TimerWidgetState extends State { void _reset() { _timer?.cancel(); setState(() { - _seconds = 0; + _secondsRemaining = widget.durationSeconds; _isRunning = false; + _isCompleted = false; }); } + void _skip() { + _timer?.cancel(); + setState(() { + _secondsRemaining = 0; + _isRunning = false; + _isCompleted = true; + }); + widget.onComplete?.call(); + } + String _formatTime() { - final minutes = _seconds ~/ 60; - final secs = _seconds % 60; + final minutes = _secondsRemaining ~/ 60; + final secs = _secondsRemaining % 60; return '${minutes.toString().padLeft(2, '0')}:${secs.toString().padLeft(2, '0')}'; } + Color _getTimerColor() { + if (_isCompleted) return AppTheme.successColor; + if (_secondsRemaining <= 10) return AppTheme.errorColor; + if (_secondsRemaining <= 30) return Colors.orange; + return AppTheme.primaryColor; + } + @override Widget build(BuildContext context) { - return Row( - mainAxisAlignment: MainAxisAlignment.center, + final progress = widget.durationSeconds > 0 + ? _secondsRemaining / widget.durationSeconds + : 0.0; + + return Column( + mainAxisSize: MainAxisSize.min, children: [ - Text( - _formatTime(), - style: Theme.of(context).textTheme.headlineMedium?.copyWith( - color: AppTheme.primaryColor, - fontFamily: 'monospace', + Stack( + alignment: Alignment.center, + children: [ + SizedBox( + width: 200, + height: 200, + child: CircularProgressIndicator( + value: progress, + strokeWidth: 12, + backgroundColor: AppTheme.xpBarBackground, + color: _getTimerColor(), ), + ), + Column( + mainAxisSize: MainAxisSize.min, + children: [ + Text( + _formatTime(), + style: Theme.of(context).textTheme.displayLarge?.copyWith( + fontSize: 48, + fontWeight: FontWeight.bold, + color: _getTimerColor(), + fontFamily: 'monospace', + ), + ), + if (_isCompleted) + const Padding( + padding: EdgeInsets.only(top: 8), + child: Text( + 'COMPLETE!', + style: TextStyle( + color: AppTheme.successColor, + fontSize: 16, + fontWeight: FontWeight.bold, + letterSpacing: 1.5, + ), + ), + ), + ], + ), + ], ), - const SizedBox(width: 16), - IconButton( - icon: Icon(_isRunning ? Icons.pause : Icons.play_arrow), - onPressed: _isRunning ? _pause : _start, - color: AppTheme.primaryColor, - ), - IconButton( - icon: const Icon(Icons.refresh), - onPressed: _reset, - color: AppTheme.primaryColor, + const SizedBox(height: 24), + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + if (!_isCompleted) ...[ + ElevatedButton.icon( + onPressed: _isRunning ? _pause : _start, + icon: Icon(_isRunning ? Icons.pause : Icons.play_arrow), + label: Text(_isRunning ? 'PAUSE' : 'START'), + style: ElevatedButton.styleFrom( + backgroundColor: + _isRunning ? Colors.orange : AppTheme.primaryColor, + foregroundColor: Colors.white, + padding: const EdgeInsets.symmetric( + horizontal: 24, + vertical: 12, + ), + ), + ), + const SizedBox(width: 12), + OutlinedButton.icon( + onPressed: _reset, + icon: const Icon(Icons.refresh), + label: const Text('RESET'), + style: OutlinedButton.styleFrom( + foregroundColor: AppTheme.primaryColor, + side: const BorderSide(color: AppTheme.primaryColor), + padding: const EdgeInsets.symmetric( + horizontal: 24, + vertical: 12, + ), + ), + ), + const SizedBox(width: 12), + OutlinedButton.icon( + onPressed: _skip, + icon: const Icon(Icons.skip_next), + label: const Text('SKIP'), + style: OutlinedButton.styleFrom( + foregroundColor: Colors.grey, + side: const BorderSide(color: Colors.grey), + padding: const EdgeInsets.symmetric( + horizontal: 24, + vertical: 12, + ), + ), + ), + ] else ...[ + ElevatedButton.icon( + onPressed: _reset, + icon: const Icon(Icons.replay), + label: const Text('RESTART'), + style: ElevatedButton.styleFrom( + backgroundColor: AppTheme.primaryColor, + foregroundColor: Colors.white, + padding: const EdgeInsets.symmetric( + horizontal: 32, + vertical: 12, + ), + ), + ), + ], + ], ), ], ); } } - diff --git a/lib/src/shared/data/remote/api_client.dart b/lib/src/shared/data/remote/api_client.dart index 34c0f7b..ccf24c8 100644 --- a/lib/src/shared/data/remote/api_client.dart +++ b/lib/src/shared/data/remote/api_client.dart @@ -104,11 +104,6 @@ class ApiClient { return handler.next(error); } } - // onError: (error, handler) async { - // if (error.response?.statusCode == 401) { - // _logger.w('Unauthorized - clearing token'); - // await _storage.delete(key: AppConstants.keyAuthToken); - // } return handler.next(error); }, ),