Files
trainhub-flutter/lib/presentation/plan_editor/widgets/plan_exercise_tile.dart
Kazimierz Ciołek 782986a632 Initial commit
2026-02-19 02:49:29 +01:00

166 lines
5.4 KiB
Dart

import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:trainhub_flutter/domain/entities/training_exercise.dart';
import 'package:trainhub_flutter/domain/entities/training_plan.dart';
import 'package:trainhub_flutter/presentation/plan_editor/plan_editor_controller.dart';
class PlanExerciseTile extends ConsumerWidget {
final TrainingExerciseEntity exercise;
final int sectionIndex;
final int exerciseIndex;
final TrainingPlanEntity plan;
const PlanExerciseTile({
super.key,
required this.exercise,
required this.sectionIndex,
required this.exerciseIndex,
required this.plan,
});
@override
Widget build(BuildContext context, WidgetRef ref) {
final controller = ref.read(planEditorControllerProvider(plan.id).notifier);
return Card(
margin: const EdgeInsets.symmetric(vertical: 4),
elevation: 0,
color: Theme.of(context).colorScheme.surfaceContainerLow,
shape: RoundedRectangleBorder(
side: BorderSide(color: Theme.of(context).colorScheme.outlineVariant),
borderRadius: BorderRadius.circular(8),
),
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
children: [
Row(
children: [
Expanded(
child: Text(
exercise.name,
style: const TextStyle(fontWeight: FontWeight.bold),
),
),
IconButton(
icon: const Icon(Icons.close, size: 18),
padding: EdgeInsets.zero,
constraints: const BoxConstraints(),
onPressed: () => controller.removeExerciseFromSection(
sectionIndex,
exerciseIndex,
),
),
],
),
const SizedBox(height: 8),
Row(
children: [
_buildNumberInput(
context,
label: 'Sets',
value: exercise.sets,
onChanged: (val) => controller.updateExerciseParams(
sectionIndex,
exerciseIndex,
sets: val,
),
),
const SizedBox(width: 8),
_buildNumberInput(
context,
label: exercise.isTime ? 'Secs' : 'Reps',
value: exercise.value,
onChanged: (val) => controller.updateExerciseParams(
sectionIndex,
exerciseIndex,
value: val,
),
),
const SizedBox(width: 8),
_buildNumberInput(
context,
label: 'Rest(s)',
value: exercise.rest,
onChanged: (val) => controller.updateExerciseParams(
sectionIndex,
exerciseIndex,
rest: val,
),
),
const SizedBox(width: 8),
// Toggle Time/Reps
InkWell(
onTap: () => controller.updateExerciseParams(
sectionIndex,
exerciseIndex,
isTime: !exercise.isTime,
),
child: Container(
padding: const EdgeInsets.all(8),
decoration: BoxDecoration(
border: Border.all(
color: Theme.of(context).colorScheme.outline,
),
borderRadius: BorderRadius.circular(4),
color: exercise.isTime
? Theme.of(context).colorScheme.primaryContainer
: null,
),
child: Icon(
Icons.timer,
size: 16,
color: exercise.isTime
? Theme.of(context).colorScheme.onPrimaryContainer
: null,
),
),
),
],
),
],
),
),
);
}
Widget _buildNumberInput(
BuildContext context, {
required String label,
required int value,
required Function(int) onChanged,
}) {
return Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(label, style: Theme.of(context).textTheme.labelSmall),
SizedBox(
height: 40,
child: TextField(
controller: TextEditingController(text: value.toString())
..selection = TextSelection.fromPosition(
TextPosition(offset: value.toString().length),
),
keyboardType: TextInputType.number,
decoration: const InputDecoration(
border: OutlineInputBorder(),
contentPadding: EdgeInsets.symmetric(
horizontal: 8,
vertical: 0,
),
),
onChanged: (val) {
final intVal = int.tryParse(val);
if (intVal != null) {
onChanged(intVal);
}
},
),
),
],
),
);
}
}