Compare commits
No commits in common. 'Courses-CR#-7150' and 'master' have entirely different histories.
Courses-CR
...
master
@ -1,8 +0,0 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" width="19.5" height="19.5" viewBox="0 0 19.5 19.5">
|
|
||||||
<g id="graduation-cap" transform="translate(0)">
|
|
||||||
<path id="cap-top" d="M9.75,4.5L3.5,7.5L9.75,10.5L16,7.5L9.75,4.5Z" fill="#2e303a"/>
|
|
||||||
<path id="cap-body" d="M4.5,8.5V13.5C4.5,14.5,6.5,16.5,9.75,16.5C13,16.5,15,14.5,15,13.5V8.5L9.75,11.5L4.5,8.5Z" fill="#2e303a"/>
|
|
||||||
<path id="tassel" d="M16,8V12.5L16.5,13L17,12.5V8H16Z" fill="#2e303a"/>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
|
|
||||||
|
Before Width: | Height: | Size: 457 B |
@ -1,6 +0,0 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" width="32.774" height="32.788" viewBox="0 0 32.774 32.788">
|
|
||||||
<g id="park-tickets-couple" transform="translate(-0.205 0.001)">
|
|
||||||
<path id="Path_4724" data-name="Path 4724" d="M68.36,485.746a1.657,1.657,0,0,1-1.581,1.3.539.539,0,0,0-.206,1.025,1.656,1.656,0,0,1,.955,1.814l-.14.7a1.744,1.744,0,0,1-2.093,1.278c-.25-.06-.506-.106-.759-.156-.373-.073-.745-.15-1.118-.223-.493-.1-.985-.2-1.477-.3l-1.76-.353c-.655-.133-1.311-.263-1.967-.4-.7-.14-1.4-.279-2.1-.423-.719-.143-1.438-.289-2.153-.433l-2.133-.429-2.036-.409c-.622-.123-1.241-.25-1.863-.373-.539-.107-1.078-.216-1.614-.323l-1.291-.26-.888-.18c-.136-.027-.273-.057-.409-.083-.007,0-.013,0-.02,0a1.686,1.686,0,0,1-.12,1.062,1.705,1.705,0,0,1-1.87.958.5.5,0,0,0-.562.246l-.3.649a.5.5,0,0,0,.176.589c.033.027,24.018,11.084,24.058,11.094a.5.5,0,0,0,.562-.246l.3-.649a.5.5,0,0,0-.176-.589,1.7,1.7,0,0,1,1.388-3,.5.5,0,0,0,.562-.246l.3-.649a.5.5,0,0,0-.176-.589,1.7,1.7,0,0,1,1.388-3,.5.5,0,0,0,.562-.246l.3-.649a.5.5,0,0,0-.176-.589,1.7,1.7,0,0,1,1.388-3,.5.5,0,0,0,.562-.246l.329-.719a.41.41,0,0,0-.2-.546L68.416,485.5Z" transform="translate(-39.26 -469.349)" fill="#2bb8a6"/>
|
|
||||||
<path id="Path_4725" data-name="Path 4725" d="M.519,16.168c.04.02,25.932,5.214,25.975,5.214a.5.5,0,0,0,.489-.369l.14-.7a.5.5,0,0,0-.309-.532,1.7,1.7,0,0,1,.652-3.244.5.5,0,0,0,.489-.369l.1-.512.037-.19a.5.5,0,0,0-.309-.532,1.7,1.7,0,0,1,.652-3.244.5.5,0,0,0,.489-.369l.14-.7a.5.5,0,0,0-.309-.532,1.7,1.7,0,0,1,.652-3.244.5.5,0,0,0,.489-.369l.156-.775a.41.41,0,0,0-.323-.482S3.714,0,3.687,0a.412.412,0,0,0-.4.329L3.128,1.1a.5.5,0,0,0,.309.532A1.7,1.7,0,0,1,2.786,4.88.5.5,0,0,0,2.3,5.25l-.14.7a.5.5,0,0,0,.309.532,1.7,1.7,0,0,1-.652,3.244.5.5,0,0,0-.489.369l-.14.7a.5.5,0,0,0,.309.532A1.7,1.7,0,0,1,.842,14.57a.5.5,0,0,0-.489.369l-.14.7A.494.494,0,0,0,.519,16.168ZM22.7,7.639a.831.831,0,1,1,1.631.326l-1.1,5.464L22.555,16.8a.832.832,0,0,1-.815.669.9.9,0,0,1-.163-.017.833.833,0,0,1-.652-.978l.755-3.757ZM7.7,4.628a.831.831,0,0,1,1.631.326L8.948,6.84,8.519,8.98,8.173,10.7l-.616,3.081a.832.832,0,0,1-.815.669.9.9,0,0,1-.163-.017.4.4,0,0,1-.067-.017.829.829,0,0,1-.582-.962l.123-.622.323-1.611Z" fill="#125765"/>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 2.1 KiB |
@ -1,16 +0,0 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" width="23.959" height="37.006" viewBox="0 0 23.959 37.006">
|
|
||||||
<g id="Layer_x0020_1" transform="translate(-300.998)">
|
|
||||||
<g id="_411123120" transform="translate(301)">
|
|
||||||
<g id="Group_8657" data-name="Group 8657" transform="translate(3.252)">
|
|
||||||
<path id="Path_13674" data-name="Path 13674" d="M612.691,6.612H619.8V1.691h-7.111ZM620.669,8.3h-8.823A.833.833,0,0,1,611,7.458V.845A.847.847,0,0,1,611.846,0h8.823a.861.861,0,0,1,.845.845V7.458A.847.847,0,0,1,620.669,8.3Z" transform="translate(-607.531)" fill="#2bb8a6"/>
|
|
||||||
<path id="Path_13675" data-name="Path 13675" d="M466.845,305h15.089a.833.833,0,0,1,.845.845,5.44,5.44,0,0,1-5.42,5.441h-5.918A5.478,5.478,0,0,1,466,305.845.847.847,0,0,1,466.845,305Z" transform="translate(-465.675 -298.388)" fill="#2bb8a6"/>
|
|
||||||
<path id="Path_13676" data-name="Path 13676" d="M527.845,0A.861.861,0,0,0,527,.845a.847.847,0,0,0,.846.845h12.444a.851.851,0,0,0,.867-.845A.865.865,0,0,0,540.289,0Z" transform="translate(-525.352)" fill="#2bb8a6"/>
|
|
||||||
<g id="Group_8656" data-name="Group 8656" transform="translate(0 33.863)">
|
|
||||||
<path id="Path_13677" data-name="Path 13677" d="M455.553,1562v.867a2.276,2.276,0,1,1-4.553,0V1562h4.553Z" transform="translate(-451 -1562)" fill="#2bb8a6"/>
|
|
||||||
<path id="Path_13678" data-name="Path 13678" d="M1050.553,1562v.867a2.276,2.276,0,0,1-4.553,0V1562h4.553Z" transform="translate(-1033.101 -1562)" fill="#2bb8a6"/>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<path id="Subtraction_59" data-name="Subtraction 59" d="M20570.063,22681.4h-16.975a.817.817,0,0,1-.238-.023,3.388,3.388,0,0,1-2.236-1.018,3.476,3.476,0,0,1-1.02-2.471v-19.4a3.557,3.557,0,0,1,1.02-2.475,3.457,3.457,0,0,1,1.906-.975,1.745,1.745,0,0,0-.193.8,6.288,6.288,0,0,0,6.289,6.285h5.92a6.288,6.288,0,0,0,6.285-6.285,1.692,1.692,0,0,0-.217-.8,3.472,3.472,0,0,1,2.949,3.449v19.4a3.476,3.476,0,0,1-1.02,2.471,3.383,3.383,0,0,1-2.236,1.018A.879.879,0,0,1,20570.063,22681.4Zm-10.756-7.187a2.114,2.114,0,1,0,1.494.619A2.1,2.1,0,0,0,20559.307,22674.211Zm4.027.732-.613.621.961.939-.961.943.613.621.963-.949v0l.973.949.609-.621-.961-.943.961-.939-.609-.621-.973.951Zm-4.025-6.031a2.112,2.112,0,0,0-.807,4.063,2.071,2.071,0,0,0,.809.164,2.113,2.113,0,0,0,0-4.227Zm3.543,1.406-.645.584,1.531,1.7,2.637-2.6-.609-.619-1.992,1.963Zm-3.539-6.709a2.158,2.158,0,0,0-.486.059,2.111,2.111,0,1,0,.969,4.109,2.123,2.123,0,0,0,1.57-2.545A2.1,2.1,0,0,0,20559.313,22663.609Zm3.539,1.266-.645.58,1.531,1.7,2.637-2.6-.609-.619-1.992,1.963Z" transform="translate(-20549.596 -22648.381)" fill="#125765"/>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 2.5 KiB |
@ -1 +0,0 @@
|
|||||||
<?xml version="1.0" ?><svg id="Outline" viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg"><defs><style>.cls-1{fill:#ffffff;}</style></defs><path style="fill: #FFF" class="cls-1" d="M376,170a11.34,11.34,0,0,0-16,.15L215.28,317.64l-64-65.22a11.34,11.34,0,0,0-16.18,15.88l72.16,73.58a11.35,11.35,0,0,0,16,.15,12,12,0,0,0,1.43-1.7l.4-.37,151-154A11.33,11.33,0,0,0,376,170Z"/><path style="fill: #FFF" class="cls-1" d="M256,58.65c-108.38,0-196.56,88.18-196.56,196.56S147.62,451.77,256,451.77,452.56,363.6,452.56,255.21,364.38,58.65,256,58.65Zm0,370.45c-95.88,0-173.88-78-173.88-173.89S160.12,81.33,256,81.33s173.88,78,173.88,173.88S351.88,429.1,256,429.1Z"/></svg>
|
|
||||||
|
Before Width: | Height: | Size: 665 B |
@ -1 +0,0 @@
|
|||||||
<?xml version="1.0" ?><svg data-name="Livello 1" id="Livello_1" viewBox="0 0 128 128" xmlns="http://www.w3.org/2000/svg"><title/><path style="fill: #fff;" d="M64,0a64,64,0,1,0,64,64A64.07,64.07,0,0,0,64,0Zm0,122a58,58,0,1,1,58-58A58.07,58.07,0,0,1,64,122Z"/><path style="fill: #fff;" d="M92.12,35.79a3,3,0,0,0-4.24,0L64,59.75l-23.87-24A3,3,0,0,0,35.88,40L59.76,64,35.88,88a3,3,0,0,0,4.25,4.24L64,68.25l23.88,24A3,3,0,0,0,92.13,88L68.24,64,92.13,40A3,3,0,0,0,92.12,35.79Z"/></svg>
|
|
||||||
|
Before Width: | Height: | Size: 479 B |
@ -1,91 +0,0 @@
|
|||||||
class CoursesResponseModel {
|
|
||||||
bool? success;
|
|
||||||
int? status;
|
|
||||||
String? username;
|
|
||||||
List<CourseStatus>? coursesStatus;
|
|
||||||
int? totalCourses;
|
|
||||||
|
|
||||||
CoursesResponseModel({
|
|
||||||
this.success,
|
|
||||||
this.status,
|
|
||||||
this.username,
|
|
||||||
this.coursesStatus,
|
|
||||||
this.totalCourses,
|
|
||||||
});
|
|
||||||
|
|
||||||
CoursesResponseModel.fromJson(Map<String, dynamic> json) {
|
|
||||||
success = json['success'];
|
|
||||||
status = json['status'];
|
|
||||||
username = json['username'];
|
|
||||||
if (json['courses_status'] != null) {
|
|
||||||
coursesStatus = <CourseStatus>[];
|
|
||||||
json['courses_status'].forEach((v) {
|
|
||||||
coursesStatus!.add(CourseStatus.fromJson(v));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
totalCourses = json['total_courses'];
|
|
||||||
}
|
|
||||||
|
|
||||||
Map<String, dynamic> toJson() {
|
|
||||||
Map<String, dynamic> data = <String, dynamic>{};
|
|
||||||
data['success'] = success;
|
|
||||||
data['status'] = status;
|
|
||||||
data['username'] = username;
|
|
||||||
if (coursesStatus != null) {
|
|
||||||
data['courses_status'] = coursesStatus!.map((v) => v.toJson()).toList();
|
|
||||||
}
|
|
||||||
data['total_courses'] = totalCourses;
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class CourseStatus {
|
|
||||||
String? cId;
|
|
||||||
String? cFullname;
|
|
||||||
String? cNameAr;
|
|
||||||
String? cShortname;
|
|
||||||
String? cStatus;
|
|
||||||
String? cIsMohemmAffective;
|
|
||||||
String? cStartdate;
|
|
||||||
String? cEnddate;
|
|
||||||
String? cUrl;
|
|
||||||
|
|
||||||
CourseStatus({
|
|
||||||
this.cId,
|
|
||||||
this.cFullname,
|
|
||||||
this.cNameAr,
|
|
||||||
this.cShortname,
|
|
||||||
this.cStatus,
|
|
||||||
this.cIsMohemmAffective,
|
|
||||||
this.cStartdate,
|
|
||||||
this.cEnddate,
|
|
||||||
this.cUrl,
|
|
||||||
});
|
|
||||||
|
|
||||||
CourseStatus.fromJson(Map<String, dynamic> json) {
|
|
||||||
cId = json['c_id'];
|
|
||||||
cFullname = json['c_fullname'];
|
|
||||||
cNameAr = json['c_name_ar'];
|
|
||||||
cShortname = json['c_shortname'];
|
|
||||||
cStatus = json['c_status'];
|
|
||||||
cIsMohemmAffective = json['c_is_mohemm_affective'];
|
|
||||||
cStartdate = json['c_startdate'];
|
|
||||||
cEnddate = json['c_enddate'];
|
|
||||||
cUrl = json['c_url'];
|
|
||||||
}
|
|
||||||
|
|
||||||
Map<String, dynamic> toJson() {
|
|
||||||
Map<String, dynamic> data = <String, dynamic>{};
|
|
||||||
data['c_id'] = cId;
|
|
||||||
data['c_fullname'] = cFullname;
|
|
||||||
data['c_name_ar'] = cNameAr;
|
|
||||||
data['c_shortname'] = cShortname;
|
|
||||||
data['c_status'] = cStatus;
|
|
||||||
data['c_is_mohemm_affective'] = cIsMohemmAffective;
|
|
||||||
data['c_startdate'] = cStartdate;
|
|
||||||
data['c_enddate'] = cEnddate;
|
|
||||||
data['c_url'] = cUrl;
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@ -1,328 +0,0 @@
|
|||||||
import 'package:easy_localization/easy_localization.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
|
|
||||||
import 'package:flutter_svg/flutter_svg.dart';
|
|
||||||
import 'package:mohem_flutter_app/app_state/app_state.dart';
|
|
||||||
import 'package:mohem_flutter_app/classes/colors.dart';
|
|
||||||
import 'package:mohem_flutter_app/classes/inAppWebView.dart';
|
|
||||||
import 'package:mohem_flutter_app/classes/utils.dart';
|
|
||||||
import 'package:mohem_flutter_app/extensions/int_extensions.dart';
|
|
||||||
import 'package:mohem_flutter_app/extensions/string_extensions.dart';
|
|
||||||
import 'package:mohem_flutter_app/extensions/widget_extensions.dart';
|
|
||||||
import 'package:mohem_flutter_app/generated/locale_keys.g.dart';
|
|
||||||
import 'package:mohem_flutter_app/models/dashboard/courses_response_model.dart';
|
|
||||||
import 'package:mohem_flutter_app/provider/dashboard_provider_model.dart';
|
|
||||||
import 'package:mohem_flutter_app/theme/colors.dart' as theme_colors;
|
|
||||||
import 'package:mohem_flutter_app/widgets/app_bar_widget.dart';
|
|
||||||
import 'package:provider/provider.dart';
|
|
||||||
import 'package:pull_to_refresh/pull_to_refresh.dart';
|
|
||||||
|
|
||||||
class CoursesScreen extends StatefulWidget {
|
|
||||||
const CoursesScreen({Key? key}) : super(key: key);
|
|
||||||
|
|
||||||
@override
|
|
||||||
_CoursesScreenState createState() => _CoursesScreenState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class _CoursesScreenState extends State<CoursesScreen> {
|
|
||||||
late DashboardProviderModel data;
|
|
||||||
final RefreshController _refreshController = RefreshController(initialRefresh: false);
|
|
||||||
|
|
||||||
@override
|
|
||||||
void initState() {
|
|
||||||
super.initState();
|
|
||||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
|
||||||
data = Provider.of<DashboardProviderModel>(context, listen: false);
|
|
||||||
_onRefresh();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
void _onRefresh() async {
|
|
||||||
await data.fetchCourses(context);
|
|
||||||
_refreshController.refreshCompleted();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return Scaffold(
|
|
||||||
appBar: AppBarWidget(
|
|
||||||
context,
|
|
||||||
title: LocaleKeys.courses.tr(),
|
|
||||||
),
|
|
||||||
body: Consumer<DashboardProviderModel>(
|
|
||||||
builder: (context, provider, child) {
|
|
||||||
return SmartRefresher(
|
|
||||||
enablePullDown: true,
|
|
||||||
enablePullUp: false,
|
|
||||||
controller: _refreshController,
|
|
||||||
onRefresh: _onRefresh,
|
|
||||||
child: provider.isCoursesLoading
|
|
||||||
? _buildShimmerLoading()
|
|
||||||
: provider.coursesList.isEmpty
|
|
||||||
? _buildEmptyState()
|
|
||||||
: _buildCoursesList(provider.coursesList),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget _buildShimmerLoading() {
|
|
||||||
return ListView.builder(
|
|
||||||
padding: const EdgeInsets.all(21),
|
|
||||||
itemCount: 5,
|
|
||||||
itemBuilder: (context, index) {
|
|
||||||
return Container(
|
|
||||||
margin: const EdgeInsets.only(bottom: 12),
|
|
||||||
height: 150,
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
color: Colors.white,
|
|
||||||
borderRadius: BorderRadius.circular(15),
|
|
||||||
boxShadow: [
|
|
||||||
BoxShadow(
|
|
||||||
color: const Color(0xff000000).withOpacity(.05),
|
|
||||||
blurRadius: 26,
|
|
||||||
offset: const Offset(0, -3),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
child: Column(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
|
||||||
children: [
|
|
||||||
Container(
|
|
||||||
height: 20,
|
|
||||||
width: 200,
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
color: Colors.grey[300],
|
|
||||||
borderRadius: BorderRadius.circular(4),
|
|
||||||
),
|
|
||||||
).toShimmer(),
|
|
||||||
12.height,
|
|
||||||
Container(
|
|
||||||
height: 14,
|
|
||||||
width: 100,
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
color: Colors.grey[300],
|
|
||||||
borderRadius: BorderRadius.circular(4),
|
|
||||||
),
|
|
||||||
).toShimmer(),
|
|
||||||
const Spacer(),
|
|
||||||
Container(
|
|
||||||
height: 40,
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
color: Colors.grey[300],
|
|
||||||
borderRadius: BorderRadius.circular(6),
|
|
||||||
),
|
|
||||||
).toShimmer(),
|
|
||||||
],
|
|
||||||
).paddingAll(14),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget _buildEmptyState() {
|
|
||||||
return Utils.getNoDataWidget(context);
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget _buildCoursesList(List<CourseStatus> courses) {
|
|
||||||
return ListView.separated(
|
|
||||||
physics: const BouncingScrollPhysics(),
|
|
||||||
shrinkWrap: true,
|
|
||||||
padding: const EdgeInsets.all(21),
|
|
||||||
itemBuilder: (BuildContext context, int index) {
|
|
||||||
return _buildCourseCard(courses[index]);
|
|
||||||
},
|
|
||||||
separatorBuilder: (BuildContext context, int index) => 12.height,
|
|
||||||
itemCount: courses.length,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget _buildCourseCard(CourseStatus course) {
|
|
||||||
bool isArabic = AppState().isArabic(context);
|
|
||||||
String courseName = isArabic && course.cNameAr != null && course.cNameAr!.isNotEmpty
|
|
||||||
? course.cNameAr!
|
|
||||||
: course.cFullname ?? '';
|
|
||||||
|
|
||||||
String status = course.cStatus ?? 'Unknown';
|
|
||||||
Color statusColor = _getStatusColor(status);
|
|
||||||
|
|
||||||
return InkWell(
|
|
||||||
onTap: () => _openCourse(course.cUrl ?? ''),
|
|
||||||
child: Column(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
|
||||||
children: [
|
|
||||||
// Course Title
|
|
||||||
Row(
|
|
||||||
children: [
|
|
||||||
Container(
|
|
||||||
padding: const EdgeInsets.all(8),
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
color: MyColors.lightGreyEFColor,
|
|
||||||
borderRadius: BorderRadius.circular(8),
|
|
||||||
),
|
|
||||||
child: const Icon(
|
|
||||||
Icons.school_rounded,
|
|
||||||
color: MyColors.gradiantStartColor,
|
|
||||||
size: 20,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
12.width,
|
|
||||||
Expanded(
|
|
||||||
child: courseName.toText14(isBold: true, color: MyColors.darkTextColor),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
12.height,
|
|
||||||
// Status Badge
|
|
||||||
Row(
|
|
||||||
children: [
|
|
||||||
Icon(
|
|
||||||
_getStatusIcon(status),
|
|
||||||
size: 16,
|
|
||||||
color: statusColor,
|
|
||||||
),
|
|
||||||
6.width,
|
|
||||||
LocaleKeys.status.tr().toText11(color: MyColors.grey98Color),
|
|
||||||
8.width,
|
|
||||||
Container(
|
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 4),
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
color: statusColor.withOpacity(0.1),
|
|
||||||
borderRadius: BorderRadius.circular(12),
|
|
||||||
border: Border.all(
|
|
||||||
color: statusColor.withOpacity(0.3),
|
|
||||||
width: 1,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
child: status.toText10(color: statusColor, isBold: true),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
10.height,
|
|
||||||
// Start Date
|
|
||||||
if (course.cEnddate != null && course.cEnddate!.isNotEmpty)
|
|
||||||
Row(
|
|
||||||
children: [
|
|
||||||
const Icon(
|
|
||||||
Icons.calendar_month_rounded,
|
|
||||||
size: 16,
|
|
||||||
color: MyColors.darkIconColor,
|
|
||||||
),
|
|
||||||
6.width,
|
|
||||||
LocaleKeys.endDateT.tr().toText11(color: MyColors.grey98Color),
|
|
||||||
8.width,
|
|
||||||
Expanded(
|
|
||||||
child: _formatDate(course.cEnddate!).toText11(
|
|
||||||
color: MyColors.darkTextColor,
|
|
||||||
isBold: true,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
if (course.cStartdate != null && course.cStartdate!.isNotEmpty) 14.height,
|
|
||||||
// Open Button
|
|
||||||
Row(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.end,
|
|
||||||
children: [
|
|
||||||
LocaleKeys.open.tr().toText12(color: MyColors.gradiantStartColor, isUnderLine: true),
|
|
||||||
6.width,
|
|
||||||
RotatedBox(
|
|
||||||
quarterTurns: AppState().isArabic(context) ? 2 : 4,
|
|
||||||
child: SvgPicture.asset(
|
|
||||||
"assets/images/arrow_next.svg",
|
|
||||||
color: MyColors.gradiantStartColor,
|
|
||||||
width: 16,
|
|
||||||
height: 16,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
],
|
|
||||||
).objectContainerView(),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
IconData _getStatusIcon(String status) {
|
|
||||||
if (status.toLowerCase().contains('passed')) {
|
|
||||||
return Icons.check_circle_rounded;
|
|
||||||
} else if (status.toLowerCase().contains('not passed') || status.toLowerCase().contains('failed')) {
|
|
||||||
return Icons.cancel_rounded;
|
|
||||||
} else if (status.toLowerCase().contains('in progress')) {
|
|
||||||
return Icons.pending_rounded;
|
|
||||||
} else {
|
|
||||||
return Icons.info_rounded;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Color _getStatusColor(String status) {
|
|
||||||
if (status.toLowerCase().contains('passed') && !status.toLowerCase().contains('not passed')) {
|
|
||||||
return Colors.green;
|
|
||||||
} else if (status.toLowerCase().contains('not passed') || status.toLowerCase().contains('failed')) {
|
|
||||||
return Colors.red;
|
|
||||||
} else if (status.toLowerCase().contains('in progress')) {
|
|
||||||
return Colors.yellow[700]!;
|
|
||||||
} else {
|
|
||||||
return MyColors.grey98Color;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
DateTime? _parseDate(String? date) {
|
|
||||||
if (date == null || date.isEmpty) return null;
|
|
||||||
try {
|
|
||||||
return DateTime.parse(date.replaceAll(' ', 'T'));
|
|
||||||
} catch (e) {
|
|
||||||
try {
|
|
||||||
DateFormat format = DateFormat('yyyy-MM-dd HH:mm:ss');
|
|
||||||
return format.parse(date);
|
|
||||||
} catch (e) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
String _formatDate(String date) {
|
|
||||||
DateTime? dateTime = _parseDate(date);
|
|
||||||
if (dateTime == null) return date;
|
|
||||||
|
|
||||||
bool isArabic = AppState().isArabic(context);
|
|
||||||
DateFormat format = DateFormat('dd MMM yyyy, hh:mm a', isArabic ? 'ar' : 'en');
|
|
||||||
return format.format(dateTime);
|
|
||||||
}
|
|
||||||
|
|
||||||
void _openCourse(String url) {
|
|
||||||
if (url.isEmpty) {
|
|
||||||
Utils.showToast(LocaleKeys.courseUrlNotAvailable.tr());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
MyInAppBrowser browser = MyInAppBrowser(
|
|
||||||
onExitCallback: () {},
|
|
||||||
onLoadStartCallback: (String url) {},
|
|
||||||
);
|
|
||||||
|
|
||||||
var settings = InAppBrowserClassSettings(
|
|
||||||
webViewSettings: InAppWebViewSettings(
|
|
||||||
useShouldOverrideUrlLoading: false,
|
|
||||||
transparentBackground: false,
|
|
||||||
),
|
|
||||||
browserSettings: InAppBrowserSettings(
|
|
||||||
hideUrlBar: true,
|
|
||||||
hideTitleBar: false,
|
|
||||||
toolbarTopBackgroundColor: theme_colors.primaryColor,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
|
|
||||||
browser.openUrlRequest(
|
|
||||||
urlRequest: URLRequest(url: WebUri(url)),
|
|
||||||
settings: settings,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
void dispose() {
|
|
||||||
_refreshController.dispose();
|
|
||||||
super.dispose();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Loading…
Reference in New Issue