Aidra Driver 1.3.5+68
Aidra Driver - Your path to green energy
Loading...
Searching...
No Matches
elearning_v2_local_data_source_impl.dart
Go to the documentation of this file.
1import 'dart:convert';
2import 'package:flutter/services.dart';
3import 'package:shared_preferences/shared_preferences.dart';
4
5import '../models/course_model.dart';
6import '../models/qcm_model.dart';
7import '../../domain/entities/course_entity.dart';
8import '../../domain/entities/qcm_entity.dart';
9import 'elearning_v2_local_data_source.dart';
10
11class ElearningV2LocalDataSourceImpl implements ElearningV2LocalDataSource {
12 final SharedPreferences sharedPreferences;
13 static const String _progressKeyPrefix = 'course_progress_';
14
15 ElearningV2LocalDataSourceImpl({required this.sharedPreferences});
16
17 @override
18 Future<List<CourseEntity>> getCourses() async {
19 try {
20 // Load courses from a local JSON file
21 final String response =
22 await rootBundle.loadString('assets/data/courses.json');
23 final data = await json.decode(response) as List;
24 List<CourseModel> courses =
25 data.map((course) => CourseModel.fromJson(course)).toList();
26
27 // Update progress for each course from SharedPreferences
28 for (var i = 0; i < courses.length; i++) {
30 .getDouble('$_progressKeyPrefix${courses[i].id}') ??
31 0.0;
32 // Create a new CourseModel with updated progress
33 courses[i] = CourseModel(
34 id: courses[i].id,
36 description: courses[i].description,
37 imageUrl: courses[i].imageUrl,
39 qcmPath: courses[i].qcmPath,
40 durationMinutes: courses[i].durationMinutes,
42 iconColor: courses[i].iconColor,
43 createdAt: courses[i].createdAt,
44 );
45 }
46
47 return courses;
48 } catch (e) {
49 throw Exception('Failed to load courses: $e');
50 }
51 }
52
53 @override
54 Future<CourseEntity> getCourseDetails(int courseId) async {
55 try {
56 // Load course details
57 final String coursesResponse =
58 await rootBundle.loadString('assets/data/courses.json');
59 final coursesData = await json.decode(coursesResponse) as List;
60 final courseData = coursesData.firstWhere(
61 (course) => course['id'] == courseId,
62 orElse: () => throw Exception('Course not found with ID: $courseId'),
63 );
64 final CourseModel course = CourseModel.fromJson(courseData);
65
66 // Get progress from SharedPreferences
67 final progress =
68 sharedPreferences.getDouble('$_progressKeyPrefix$courseId') ?? 0.0;
69
70 // Return course with updated progress
71 return CourseModel(
72 id: course.id,
73 title: course.title,
74 description: course.description,
75 imageUrl: course.imageUrl,
76 pdfPath: course.pdfPath,
77 qcmPath: course.qcmPath,
78 durationMinutes: course.durationMinutes,
80 iconColor: course.iconColor,
81 createdAt: course.createdAt,
82 );
83 } catch (e) {
84 throw Exception('Failed to load course details: $e');
85 }
86 }
87
88 @override
89 Future<List<QcmEntity>> getQcmForCourse(int courseId) async {
90 try {
91 // Load QCM questions for this course
92 final String qcmResponse =
93 await rootBundle.loadString('assets/data/qcm.json');
94 final qcmData = await json.decode(qcmResponse) as List;
95 final courseQcm = qcmData
96 .where((qcm) => qcm['courseId'] == courseId)
97 .map((qcm) => QcmModel.fromJson(qcm))
98 .toList();
99
100 if (courseQcm.isEmpty) {
101 // No QCM questions found for this course
102 return [];
103 }
104
105 return courseQcm;
106 } catch (e) {
107 throw Exception('Failed to load QCM questions: $e');
108 }
109 }
110
111 @override
112 Future<String> getPdfPathForCourse(int courseId) async {
113 try {
114 // Load course details to get PDF path
115 final String coursesResponse =
116 await rootBundle.loadString('assets/data/courses.json');
117 final coursesData = await json.decode(coursesResponse) as List;
118 final courseData = coursesData.firstWhere(
119 (course) => course['id'] == courseId,
120 orElse: () => throw Exception('Course not found with ID: $courseId'),
121 );
122 final CourseModel course = CourseModel.fromJson(courseData);
123
124 if (course.pdfPath == null || course.pdfPath!.isEmpty) {
125 throw Exception('No PDF available for this course');
126 }
127
128 // Return PDF path
129 return 'assets/fonts/${course.pdfPath}';
130 } catch (e) {
131 throw Exception('Failed to get PDF path: $e');
132 }
133 }
134
135 @override
136 Future<bool> updateCourseProgress(int courseId, double progress) async {
137 try {
138 // Validate progress value
140 throw Exception('Progress must be between 0.0 and 1.0');
141 }
142
143 // Save progress to SharedPreferences
144 await sharedPreferences.setDouble(
145 '$_progressKeyPrefix$courseId', progress);
146 return true;
147 } catch (e) {
148 throw Exception('Failed to update progress: $e');
149 }
150 }
151}
override Future< String > getPdfPathForCourse(int courseId) async
override Future< List< QcmEntity > > getQcmForCourse(int courseId) async
override Future< bool > updateCourseProgress(int courseId, double progress) async
override Future< CourseEntity > getCourseDetails(int courseId) async
override Future< List< CourseEntity > > getCourses() async
ElearningV2LocalDataSourceImpl({required this.sharedPreferences})
class Partner String
final String pdfPath
class CoursesLoadingFailureState extends ElearningV2State course
abstract class ElearningV2State extends Equatable courses
class GetPdfPathUseCase implements UseCase< String, PdfParams > courseId
final String title
final double progress