Add training plan and GIF exercise catalog
This commit is contained in:
@@ -0,0 +1,175 @@
|
||||
class TrainingPlan {
|
||||
const TrainingPlan({
|
||||
required this.uuid,
|
||||
required this.slug,
|
||||
required this.title,
|
||||
required this.summary,
|
||||
required this.goal,
|
||||
required this.level,
|
||||
required this.weeksDuration,
|
||||
required this.safetyNotes,
|
||||
required this.sessions,
|
||||
});
|
||||
|
||||
final String uuid;
|
||||
final String slug;
|
||||
final String title;
|
||||
final String summary;
|
||||
final String goal;
|
||||
final String level;
|
||||
final int weeksDuration;
|
||||
final List<String> safetyNotes;
|
||||
final List<TrainingSession> sessions;
|
||||
|
||||
factory TrainingPlan.fromJson(Map<String, dynamic> json) => TrainingPlan(
|
||||
uuid: json['plan_uuid'] as String? ?? '',
|
||||
slug: json['slug'] as String? ?? '',
|
||||
title: json['title_ar'] as String? ?? 'خطة تدريب',
|
||||
summary: json['summary_ar'] as String? ?? '',
|
||||
goal: json['goal'] as String? ?? '',
|
||||
level: json['level'] as String? ?? 'beginner',
|
||||
weeksDuration: _asInt(json['weeks_duration']),
|
||||
safetyNotes: _stringList(json['safety_notes_ar']),
|
||||
sessions: _mapList(json['sessions'])
|
||||
.map(TrainingSession.fromJson)
|
||||
.toList(growable: false),
|
||||
);
|
||||
}
|
||||
|
||||
class TrainingSession {
|
||||
const TrainingSession({
|
||||
required this.week,
|
||||
required this.day,
|
||||
required this.title,
|
||||
required this.type,
|
||||
required this.durationMinutes,
|
||||
required this.intensity,
|
||||
required this.notes,
|
||||
required this.exercises,
|
||||
});
|
||||
|
||||
final int week;
|
||||
final int day;
|
||||
final String title;
|
||||
final String type;
|
||||
final int durationMinutes;
|
||||
final String intensity;
|
||||
final String? notes;
|
||||
final List<TrainingExercise> exercises;
|
||||
|
||||
factory TrainingSession.fromJson(Map<String, dynamic> json) =>
|
||||
TrainingSession(
|
||||
week: _asInt(json['week']),
|
||||
day: _asInt(json['day']),
|
||||
title: json['title_ar'] as String? ?? 'جلسة تدريب',
|
||||
type: json['type'] as String? ?? 'rest',
|
||||
durationMinutes: _asInt(json['duration_minutes']),
|
||||
intensity: json['intensity'] as String? ?? 'easy',
|
||||
notes: json['notes_ar'] as String?,
|
||||
exercises: _mapList(json['exercises'])
|
||||
.map(TrainingExercise.fromJson)
|
||||
.toList(growable: false),
|
||||
);
|
||||
}
|
||||
|
||||
class TrainingExercise {
|
||||
const TrainingExercise({
|
||||
required this.uuid,
|
||||
required this.slug,
|
||||
required this.title,
|
||||
required this.instructions,
|
||||
required this.targetMuscles,
|
||||
required this.equipment,
|
||||
required this.gifUrl,
|
||||
required this.posterUrl,
|
||||
required this.durationSeconds,
|
||||
required this.repetitions,
|
||||
required this.safetyNotes,
|
||||
required this.alternativeUuid,
|
||||
required this.prescription,
|
||||
});
|
||||
|
||||
final String uuid;
|
||||
final String slug;
|
||||
final String title;
|
||||
final List<String> instructions;
|
||||
final List<String> targetMuscles;
|
||||
final List<String> equipment;
|
||||
final String? gifUrl;
|
||||
final String? posterUrl;
|
||||
final int? durationSeconds;
|
||||
final String? repetitions;
|
||||
final List<String> safetyNotes;
|
||||
final String? alternativeUuid;
|
||||
final ExercisePrescription prescription;
|
||||
|
||||
factory TrainingExercise.fromJson(Map<String, dynamic> json) {
|
||||
final prescription = json['prescription'];
|
||||
final prescriptionMap = prescription is Map<String, dynamic>
|
||||
? prescription
|
||||
: const <String, dynamic>{};
|
||||
return TrainingExercise(
|
||||
uuid: json['exercise_uuid'] as String? ?? '',
|
||||
slug: json['slug'] as String? ?? '',
|
||||
title: json['title_ar'] as String? ?? 'تمرين',
|
||||
instructions: _stringList(json['instructions_ar']),
|
||||
targetMuscles: _stringList(json['target_muscles']),
|
||||
equipment: _stringList(json['equipment']),
|
||||
gifUrl: json['gif_url'] as String?,
|
||||
posterUrl: json['gif_poster_url'] as String?,
|
||||
durationSeconds: _nullableInt(json['duration_seconds']),
|
||||
repetitions: json['repetitions'] as String?,
|
||||
safetyNotes: _stringList(json['safety_notes_ar']),
|
||||
alternativeUuid: json['alternative_exercise_uuid'] as String?,
|
||||
prescription: ExercisePrescription.fromJson(prescriptionMap),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class ExercisePrescription {
|
||||
const ExercisePrescription({
|
||||
this.sets,
|
||||
this.reps,
|
||||
this.durationSeconds,
|
||||
this.restSeconds = 0,
|
||||
});
|
||||
|
||||
final int? sets;
|
||||
final String? reps;
|
||||
final int? durationSeconds;
|
||||
final int restSeconds;
|
||||
|
||||
factory ExercisePrescription.fromJson(Map<String, dynamic> json) =>
|
||||
ExercisePrescription(
|
||||
sets: _nullableInt(json['sets']),
|
||||
reps: json['reps'] as String?,
|
||||
durationSeconds: _nullableInt(json['duration_seconds']),
|
||||
restSeconds: _asInt(json['rest_seconds']),
|
||||
);
|
||||
}
|
||||
|
||||
class TrainingCatalogResult {
|
||||
const TrainingCatalogResult({
|
||||
required this.plans,
|
||||
required this.fromCache,
|
||||
this.message,
|
||||
});
|
||||
|
||||
final List<TrainingPlan> plans;
|
||||
final bool fromCache;
|
||||
final String? message;
|
||||
}
|
||||
|
||||
List<Map<String, dynamic>> _mapList(dynamic value) {
|
||||
if (value is! List) return const [];
|
||||
return value.whereType<Map<String, dynamic>>().toList(growable: false);
|
||||
}
|
||||
|
||||
List<String> _stringList(dynamic value) {
|
||||
if (value is! List) return const [];
|
||||
return value.whereType<String>().toList(growable: false);
|
||||
}
|
||||
|
||||
int _asInt(dynamic value) => value is num ? value.toInt() : 0;
|
||||
|
||||
int? _nullableInt(dynamic value) => value is num ? value.toInt() : null;
|
||||
Reference in New Issue
Block a user