Add training plan and GIF exercise catalog

This commit is contained in:
Hamza-Ayed
2026-10-04 01:49:43 +03:00
parent 98490a17e6
commit b1e5aa2f98
5 changed files with 859 additions and 123 deletions
+20 -123
View File
@@ -5,6 +5,7 @@ import '../models/workout.dart';
import '../screens/history_screen.dart';
import '../services/sync_service.dart';
import '../services/auth_service.dart';
import 'training_screens.dart';
import '../utils/formatters.dart';
import 'phone_login_screen.dart';
@@ -113,9 +114,7 @@ class HomeScreen extends StatelessWidget {
style:
TextStyle(color: _muted, fontSize: 14, height: 1.65)),
const SizedBox(height: 22),
_WeeklyPlanCard(
onStartWalk: () =>
workoutCtrl.startWorkout(WorkoutType.walking)),
const TrainingPlanSpotlight(),
const SizedBox(height: 26),
Row(children: [
const Text('ابدأ الآن',
@@ -177,14 +176,24 @@ class HomeScreen extends StatelessWidget {
detail: 'تذكير بسيط للعناية بنفسك.',
tag: 'عافية'),
const SizedBox(height: 25),
const Text('برنامج الأسبوع',
style: TextStyle(
color: _ink,
fontSize: 18,
fontWeight: FontWeight.w600)),
const SizedBox(height: 12),
const _DayStrip(),
const SizedBox(height: 25),
Row(children: [
const Text('برامج التمرين',
style: TextStyle(
color: _ink,
fontSize: 18,
fontWeight: FontWeight.w600)),
const Spacer(),
TextButton(
onPressed: () =>
Get.to(() => const TrainingLibraryScreen()),
child: const Text('عرض المكتبة'),
),
]),
const SizedBox(height: 6),
const Text(
'الخطط والجلسات تُحمّل من الخادم وتُحفظ للعرض دون اتصال.',
style: TextStyle(color: _muted, fontSize: 11, height: 1.5)),
const SizedBox(height: 20),
Container(
padding: const EdgeInsets.all(18),
decoration: BoxDecoration(
@@ -241,79 +250,6 @@ String _arabicToday() {
return '${weekdays[now.weekday - 1]}، $day ${months[now.month - 1]}';
}
class _WeeklyPlanCard extends StatelessWidget {
const _WeeklyPlanCard({required this.onStartWalk});
final VoidCallback onStartWalk;
@override
Widget build(BuildContext context) => Container(
padding: const EdgeInsets.all(20),
decoration: BoxDecoration(
color: _green, borderRadius: BorderRadius.circular(22)),
child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
Row(children: [
const Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('خطة بداية متوازنة',
style: TextStyle(
color: Colors.white,
fontSize: 17,
fontWeight: FontWeight.w600)),
SizedBox(height: 4),
Text('أسبوع تمهيدي • حركة خفيفة',
style: TextStyle(color: Color(0xFFDCE8DA), fontSize: 11)),
])),
SizedBox(
width: 76,
height: 70,
child: CustomPaint(painter: _PathPainter())),
]),
const SizedBox(height: 17),
Row(children: [
const Expanded(
child: Text('مشي مريح لمدة ٢٠ دقيقة',
style: TextStyle(color: Colors.white, fontSize: 13))),
TextButton(
onPressed: onStartWalk,
style: TextButton.styleFrom(
backgroundColor: Colors.white,
foregroundColor: _green,
padding: const EdgeInsets.symmetric(horizontal: 14)),
child: const Text('ابدأ المشي',
style:
TextStyle(fontSize: 11, fontWeight: FontWeight.w600))),
]),
const SizedBox(height: 3),
const Text('عدّل المدة أو خذ يوم راحة حسب شعورك.',
style: TextStyle(color: Color(0xFFDCE8DA), fontSize: 10)),
]),
);
}
class _PathPainter extends CustomPainter {
@override
void paint(Canvas canvas, Size size) {
final paint = Paint()
..color = const Color(0xFFB8CAA9)
..style = PaintingStyle.stroke
..strokeWidth = 1.5;
final path = Path()
..moveTo(4, size.height * .82)
..cubicTo(size.width * .18, size.height * .12, size.width * .48,
size.height * .98, size.width * .68, size.height * .38)
..quadraticBezierTo(size.width * .86, size.height * .02, size.width * .98,
size.height * .24);
canvas.drawPath(path, paint);
canvas.drawCircle(Offset(size.width * .68, size.height * .38), 4,
Paint()..color = Colors.white);
}
@override
bool shouldRepaint(covariant CustomPainter oldDelegate) => false;
}
class _ActionCard extends StatelessWidget {
const _ActionCard(
{required this.title,
@@ -449,42 +385,3 @@ class _HabitCard extends StatelessWidget {
]),
);
}
class _DayStrip extends StatelessWidget {
const _DayStrip();
static const days = [
('ح', 'راحة'),
('ن', 'مشي'),
('ث', 'قوة'),
('ر', 'مشي'),
('خ', 'راحة'),
('ج', 'نشاط'),
('س', 'راحة')
];
@override
Widget build(BuildContext context) => Row(children: [
for (var i = 0; i < days.length; i++)
Expanded(
child: Padding(
padding: EdgeInsetsDirectional.only(
end: i == days.length - 1 ? 0 : 7),
child: Container(
padding: const EdgeInsets.symmetric(vertical: 10),
decoration: BoxDecoration(
color: i == 0 ? _green : Colors.white,
borderRadius: BorderRadius.circular(13)),
child: Column(children: [
Text(days[i].$1,
style: TextStyle(
color: i == 0 ? Colors.white : _ink,
fontSize: 13,
fontWeight: FontWeight.w700)),
const SizedBox(height: 4),
Text(days[i].$2,
style: TextStyle(
color: i == 0 ? Colors.white70 : _muted,
fontSize: 8))
]),
)))
]);
}