exercises_page.dart 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. import 'package:flutter/material.dart';
  2. import '../walking/walking_page.dart';
  3. import 'exercises_validation/exercise_validation_page.dart';
  4. import 'exercises_validation/models/exercise.dart';
  5. import 'services/exercises_service.dart';
  6. class ExercisesPage extends StatelessWidget {
  7. const ExercisesPage({Key? key}) : super(key: key);
  8. @override
  9. Widget build(BuildContext context) {
  10. return Scaffold(
  11. body: Padding(
  12. padding: const EdgeInsets.all(16.0),
  13. child: Column(
  14. mainAxisAlignment: MainAxisAlignment.center,
  15. children: [
  16. const Center(
  17. child: Text(
  18. "Exercises",
  19. textAlign: TextAlign.center,
  20. style: TextStyle(
  21. fontSize: 28,
  22. fontWeight: FontWeight.bold,
  23. // color: Colors.white,
  24. ),
  25. ),
  26. ),
  27. const SizedBox(height: 24),
  28. const TextField(
  29. decoration: InputDecoration(
  30. border: OutlineInputBorder(),
  31. hintText: "Search exercise...",
  32. ),
  33. ),
  34. const SizedBox(height: 24),
  35. Row(
  36. mainAxisAlignment: MainAxisAlignment.spaceEvenly,
  37. children: [
  38. FilterChip(
  39. label: const Text("Easy", style: TextStyle(color: Colors.black, fontSize: 18)),
  40. selected: true,
  41. backgroundColor: Colors.green.shade300,
  42. selectedColor: Colors.green.shade300,
  43. checkmarkColor: Colors.black,
  44. onSelected: (_) {},
  45. ),
  46. FilterChip(
  47. label: const Text("Normal", style: TextStyle(color: Colors.black, fontSize: 18)),
  48. selected: true,
  49. backgroundColor: Colors.orange.shade300,
  50. selectedColor: Colors.orange.shade300,
  51. checkmarkColor: Colors.black,
  52. onSelected: (_) {},
  53. ),
  54. FilterChip(
  55. label: const Text("Hard", style: TextStyle(color: Colors.black, fontSize: 18)),
  56. selected: true,
  57. backgroundColor: Colors.red.shade300,
  58. selectedColor: Colors.red.shade300,
  59. checkmarkColor: Colors.black,
  60. onSelected: (_) {},
  61. ),
  62. ],
  63. ),
  64. const SizedBox(height: 48),
  65. FutureBuilder<List<Exercise>>(
  66. future: ExercisesService.getExercises(),
  67. builder: (context, snapshot) {
  68. if (snapshot.connectionState == ConnectionState.waiting) {
  69. return const Center(child: CircularProgressIndicator());
  70. }
  71. final exercises = snapshot.data!;
  72. exercises.sort((a, b) => a.difficulty.compareTo(b.difficulty));
  73. return Flexible(
  74. child: Scrollbar(
  75. isAlwaysShown: true,
  76. thickness: 8,
  77. child: ListView(
  78. shrinkWrap: true,
  79. children: [
  80. const WalkExerciseTile(),
  81. ...exercises.map((exercise) => ExerciseTile(exercise: exercise))
  82. ],
  83. ),
  84. ),
  85. );
  86. },
  87. )
  88. ],
  89. ),
  90. ),
  91. );
  92. }
  93. }
  94. class ExerciseTile extends StatelessWidget {
  95. final Exercise exercise;
  96. const ExerciseTile({
  97. required this.exercise,
  98. Key? key,
  99. }) : super(key: key);
  100. Color get cardColor {
  101. if (exercise.difficulty == 0) return Colors.green.shade300;
  102. if (exercise.difficulty == 1) return Colors.orange.shade300;
  103. if (exercise.difficulty == 2) return Colors.red.shade300;
  104. return Colors.blueGrey;
  105. }
  106. @override
  107. Widget build(BuildContext context) {
  108. return Center(
  109. child: Card(
  110. color: cardColor,
  111. elevation: 3,
  112. child: ListTile(
  113. iconColor: Colors.black,
  114. textColor: Colors.black,
  115. title: Text(
  116. exercise.name.toUpperCase(),
  117. textAlign: TextAlign.center,
  118. style: const TextStyle(
  119. fontSize: 18,
  120. fontWeight: FontWeight.bold,
  121. letterSpacing: 1.8,
  122. ),
  123. ),
  124. trailing: const Icon(Icons.arrow_forward),
  125. onTap: exercise.startMovement != null // not all exercises have validation right now
  126. ? () {
  127. Navigator.push(
  128. context,
  129. MaterialPageRoute(
  130. builder: (_) => ExerciseValidationPage(exercise: exercise),
  131. ),
  132. );
  133. }
  134. : null,
  135. ),
  136. ),
  137. );
  138. }
  139. }
  140. class WalkExerciseTile extends StatelessWidget {
  141. const WalkExerciseTile({
  142. Key? key,
  143. }) : super(key: key);
  144. @override
  145. Widget build(BuildContext context) {
  146. return Center(
  147. child: Card(
  148. color: Colors.green.shade300,
  149. elevation: 3,
  150. child: ListTile(
  151. iconColor: Colors.black,
  152. textColor: Colors.black,
  153. title: Text(
  154. "walk".toUpperCase(),
  155. textAlign: TextAlign.center,
  156. style: const TextStyle(
  157. fontSize: 18,
  158. fontWeight: FontWeight.bold,
  159. letterSpacing: 1.8,
  160. ),
  161. ),
  162. trailing: const Icon(Icons.arrow_forward),
  163. onTap: () {
  164. Navigator.push(
  165. context,
  166. MaterialPageRoute(
  167. builder: (_) => WalkingPage(),
  168. ),
  169. );
  170. },
  171. ),
  172. ),
  173. );
  174. }
  175. }