1import 'package:fluentui_system_icons/fluentui_system_icons.dart';
2import 'package:flutter/material.dart';
3import 'package:flutter_bloc/flutter_bloc.dart';
4import 'package:flutter_screenutil/flutter_screenutil.dart';
5import 'package:go_router/go_router.dart';
7import '../../../../core/router/routes.dart';
8import '../../../../core/ui/theme/color_palette.dart';
9import '../../../../core/ui/widgets/custom_scaffold.dart';
10import '../../../../core/ui/widgets/faild_to_fetch_data_view.dart';
11import '../../domain/entities/course_entity.dart';
12import '../logic/cubit/elearning_v2_cubit.dart';
13import 'qcm_screen.dart';
20 required this.courseId,
24 State<CourseDetailScreen>
createState() => _CourseDetailScreenState();
27class _CourseDetailScreenState
extends State<CourseDetailScreen> {
35 context.read<ElearningV2Cubit>().loadCourseDetails(widget.courseId);
39 Widget
build(BuildContext context) {
40 return BlocBuilder<ElearningV2Cubit, ElearningV2State>(
41 builder: (context, state) {
42 return CustomScaffold(
44 ? state.course.title ??
'Course Details'
46 isLoading: state is LoadingCourseDetailsState,
47 isLeadingVisible:
true,
61 state.qcmList.isNotEmpty,
63 }
else if (state is CourseDetailsLoadingFailureState) {
64 return FailedToFetchDataView(
74 return SingleChildScrollView(
77 crossAxisAlignment: CrossAxisAlignment.start,
81 course.title ??
'Untitled Course',
82 style: Theme.of(context).textTheme.displayMedium,
87 style: Theme.of(context).textTheme.bodyMedium?.copyWith(
88 color: Theme.of(context).hintColor,
94 decoration: BoxDecoration(
95 color: Theme.of(context).colorScheme.surface,
96 borderRadius: BorderRadius.circular(16),
98 margin: EdgeInsets.symmetric(vertical: 16.sp),
101 crossAxisAlignment: CrossAxisAlignment.start,
105 Icon(FluentIcons.arrow_flow_diagonal_up_right_12_filled, size: 20),
109 style: Theme.of(context).textTheme.bodyLarge?.copyWith(
110 fontWeight: FontWeight.bold,
116 LinearProgressIndicator(
119 backgroundColor: mainColor.withValues(alpha: 0.11),
120 valueColor: AlwaysStoppedAnimation<Color>(
123 borderRadius: BorderRadius.circular(4.r),
128 alignment: Alignment.centerRight,
129 child:
Text(
'${(course.progress! * 100).toInt()}%',
130 style: Theme.of(context).textTheme.displaySmall?.copyWith(
142 style: Theme.of(context).textTheme.bodyLarge,
149 title:
'Step 1: Read the Material',
151 'Read through the PDF material to understand the concepts',
155 Routes.pdfViewerScreen.route,
157 'pdfPath': course.pdfPath,
158 'courseId': course.id,
159 'onComplete': (double progress) {
160 if (course.progress! < 0.5) {
161 context.read<ElearningV2Cubit>().updateProgress(
175 title:
'Step 2: Test Your Knowledge',
176 description:
'Complete the quiz to test your understanding',
178 course.progress! <= 0.5 ? 0.0 : (
course.progress! - 0.5) * 2,
179 isDisabled:
course.progress! < 0.5,
181 if (course.progress! >= 0.5) {
185 builder: (context) => QcmScreen(
186 courseId: course.id!,
187 currentProgress: course.progress!,
188 onComplete: (double quizScore) {
190 final newProgress = 0.5 + (quizScore * 0.5);
191 context.read<ElearningV2Cubit>().updateProgress(
209 required
String description,
211 required VoidCallback
onTap,
212 required Color
color,
213 bool isDisabled =
false,
215 return GestureDetector(
218 decoration: BoxDecoration(
219 color: Theme.of(context).colorScheme.surface,
220 borderRadius: BorderRadius.circular(16.r),
223 ? Theme.of(context).dividerColor
224 :
color.withValues(alpha: 0.3),
234 decoration: BoxDecoration(
236 ? Theme.of(context).disabledColor.withValues(alpha: 0.1)
237 :
color.withValues(alpha: 0.1),
238 shape: BoxShape.circle,
241 FluentIcons.document_100_16_regular,
242 color: isDisabled ? Theme.of(context).disabledColor :
color,
249 crossAxisAlignment: CrossAxisAlignment.start,
253 style: Theme.of(context).textTheme.titleMedium?.copyWith(
254 fontWeight: FontWeight.bold,
256 ? Theme.of(context).disabledColor
257 : Theme.of(context).textTheme.titleMedium?.color,
263 style: Theme.of(context).textTheme.bodyMedium?.copyWith(
265 ? Theme.of(context).hintColor.withValues(alpha: 0.3)
269 overflow: TextOverflow.ellipsis,
392 hexColor = hexColor.replaceAll(
'#',
'');
393 if (hexColor.length == 6) {
394 hexColor =
'FF$hexColor';
396 return Color(
int.parse(hexColor, radix: 16));
398 return Theme.of(context).colorScheme.primary;
override void initState()
class App extends StatefulWidget build(BuildContext context)
Widget _buildLearningStep({ required String title, required String description, required double progress, required VoidCallback onTap, required Color color, bool isDisabled=false, })
void _loadCourseDetails()
Widget _buildCourseDetails(CourseEntity course, String pdfPath, bool hasQcm)
Color _parseColor(String hexColor, BuildContext context)
const CourseDetailScreen({ super.key, required this.courseId, })
class CoursesLoadingFailureState extends ElearningV2State course
const CourseDetailsLoadedState(this.course, this.pdfPath, this.qcmList)
style Text( '${ 'scheduling.reference'.tr()}:${collection.internalCode}', style:Theme.of(context).textTheme.bodySmall,)
style SizedBox(height:2.h)
style Column(crossAxisAlignment:CrossAxisAlignment.end, children:[Container(padding:EdgeInsets.symmetric(horizontal:8.w, vertical:4.h), decoration:BoxDecoration(color:ColorPalette.tiffanyBlue.withValues(alpha:0.1), borderRadius:BorderRadius.circular(12),), child:Text(collection.type ?? '', style:Theme.of(context).textTheme.bodySmall?.copyWith(color:ColorPalette.tiffanyBlue, fontWeight:FontWeight.bold,),),),],)