Files
Vocasia-LMS-Mobile-apps--TA…/lib/widgets/my_course_list.dart

687 lines
38 KiB
Dart

import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_rating_bar/flutter_rating_bar.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:initial_folder/base_service.dart';
import 'package:initial_folder/models/my_course_model.dart';
import 'package:initial_folder/providers/current_lesson_provider.dart';
import 'package:initial_folder/providers/detail_course_provider.dart';
import 'package:initial_folder/providers/instructor_provider.dart';
import 'package:initial_folder/providers/lesson_course_provider.dart';
import 'package:initial_folder/providers/my_course_provider.dart';
import 'package:initial_folder/providers/theme_provider.dart';
import 'package:initial_folder/screens/course/play_course_page.dart';
import 'package:initial_folder/services/course_service.dart';
import 'package:initial_folder/services/instructor_service.dart';
import 'package:initial_folder/services/lesson_course_service.dart';
import 'package:initial_folder/size_config.dart';
import 'package:initial_folder/theme.dart';
import 'package:provider/provider.dart';
import 'package:shimmer/shimmer.dart';
import 'package:initial_folder/screens/detail_course/detail_course_screen.dart';
import 'package:initial_folder/providers/posting_review_provider.dart'
as postReviewProvider;
class MyCourseList extends StatefulWidget {
const MyCourseList({
Key? key,
required this.dataMyCourseModel,
this.onDialogClose,
}) : super(key: key);
final DataMyCourseModel dataMyCourseModel;
final VoidCallback? onDialogClose;
@override
State<MyCourseList> createState() => _MyCourseListState();
}
class _MyCourseListState extends State<MyCourseList> {
@override
void initState() {
super.initState();
SystemChrome.setPreferredOrientations([
DeviceOrientation.portraitUp,
]);
}
@override
Widget build(BuildContext context) {
final themeProvider = Provider.of<ThemeProvider>(context);
final Brightness brightnessValue =
MediaQuery.of(context).platformBrightness;
bool isDarkMode = brightnessValue == Brightness.dark;
double value = 0.0;
if (widget.dataMyCourseModel.rating.length != 0) {
value = double.parse(widget.dataMyCourseModel.rating[0].rating!);
}
TextEditingController _controller = TextEditingController(
text: (widget.dataMyCourseModel.rating.length == 0)
? ""
: widget.dataMyCourseModel.rating[0].review);
final _formKey = GlobalKey<FormState>();
return Column(
children: [
Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
color: Theme.of(context).colorScheme.primaryContainer,
boxShadow: [
BoxShadow(
color: isDarkMode ? Colors.black : Colors.grey,
spreadRadius: 0.01,
blurRadius: 2,
offset: Offset(0, 1),
),
],
),
margin: EdgeInsets.only(
left: getProportionateScreenWidth(20),
right: getProportionateScreenWidth(20),
top: getProportionateScreenWidth(10),
bottom: 5),
child: GestureDetector(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => DetailCourseScreen(
resoaktifitas: 'gada',
idcourse: widget.dataMyCourseModel.courseId ?? '1',
),
),
);
},
child: Padding(
padding: EdgeInsets.only(
right: getProportionateScreenWidth(10),
left: getProportionateScreenWidth(10),
top: getProportionateScreenHeight(10),
),
child: Column(
children: [
Padding(
padding: EdgeInsets.all(3),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Flexible(
flex: 10,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
Text(
widget.dataMyCourseModel.title ?? ' ',
style: secondaryTextStyle.copyWith(
letterSpacing: 1,
fontWeight: semiBold,
fontSize: SizeConfig.blockHorizontal! * 3.5,
),
maxLines: 2,
overflow: TextOverflow.ellipsis,
),
SizedBox(height: getProportionateScreenWidth(2)),
Text(
'${widget.dataMyCourseModel.instructor}',
style: thirdTextStyle.copyWith(
fontWeight: light,
color: Colors.grey.shade600,
fontSize: SizeConfig.blockHorizontal! * 3,
),
),
SizedBox(height: getProportionateScreenWidth(6)),
],
),
),
SizedBox(width: getProportionateScreenWidth(9)),
Flexible(
flex: 11,
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
CachedNetworkImage(
placeholder: (context, url) => Shimmer(
child: Container(
color: Colors.black,
),
gradient: LinearGradient(stops: [
0.2,
0.5,
0.6
], colors: [
ninthColor,
fourthColor,
ninthColor
])),
errorWidget: (context, url, error) =>
Icon(Icons.error),
imageBuilder: (context, imageUrl) => Container(
width: getProportionateScreenWidth(156),
height: getProportionateScreenWidth(88),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(5),
image: DecorationImage(
fit: BoxFit.fill,
image: imageUrl,
),
),
),
imageUrl: widget.dataMyCourseModel.thumbnail ??
'$baseUrl/uploads/courses_thumbnail/course_thumbnail_default_57.jpg',
),
SizedBox(
height: getProportionateScreenHeight(8),
),
],
),
),
],
),
),
Align(
alignment: Alignment.topRight,
child: Text(
'Progres ${widget.dataMyCourseModel.totalProgress}%',
style: thirdTextStyle.copyWith(
fontSize: SizeConfig.blockHorizontal! * 3.5,
color: Colors.grey.shade600,
letterSpacing: 0.2,
),
),
),
Stack(
children: [
Container(
width: double.infinity,
height: getProportionateScreenHeight(10),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
color: Colors.grey.shade300),
),
Container(
width: (SizeConfig.screenWidth -
getProportionateScreenWidth(32)) *
int.parse(widget.dataMyCourseModel.totalProgress
.toString()) /
100,
height: getProportionateScreenHeight(10),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
color: primaryColor,
),
),
],
),
SizedBox(height: getProportionateScreenWidth(10)),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Row(
children: [
RatingBarIndicator(
itemSize: SizeConfig.blockHorizontal! * 3.5,
rating: double.parse(widget
.dataMyCourseModel.rating.isEmpty
? '0'
: widget.dataMyCourseModel.rating[0].rating ??
'5'),
direction: Axis.horizontal,
itemCount: 5,
itemBuilder: (context, index) {
if (index <
double.parse(
widget.dataMyCourseModel.rating.isEmpty
? '0'
: widget.dataMyCourseModel.rating[0]
.rating ??
'5')) {
return FaIcon(
FontAwesomeIcons.solidStar,
color: primaryColor,
);
} else {
return FaIcon(
FontAwesomeIcons.star,
color: primaryColor,
);
}
},
),
SizedBox(width: getProportionateScreenWidth(5)),
InkWell(
onTap: () => showDialog(
context: context,
builder: (context) => MultiProvider(
providers: [
ChangeNotifierProvider(
create: (context) => postReviewProvider
.PostingReviewProvider(
courseService: CourseService(),
),
)
],
child: Consumer<
postReviewProvider.PostingReviewProvider>(
builder: (context, state, _) {
if (state.state ==
postReviewProvider
.ResultState.uninitilized) {
return AlertDialog(
surfaceTintColor: Colors.transparent,
shape: RoundedRectangleBorder(
borderRadius:
BorderRadius.circular(5)),
contentPadding: EdgeInsets.symmetric(
vertical: 10, horizontal: 10),
insetPadding: EdgeInsets.all(1),
backgroundColor: Theme.of(context)
.colorScheme
.background,
title: Center(
child: Text(
'Berikan Penilaian',
style: thirdTextStyle.copyWith(
fontSize: 15,
fontWeight: reguler,
letterSpacing: 0.2,
color: Theme.of(context)
.colorScheme
.background,
),
),
),
content: Container(
width:
getProportionateScreenWidth(300),
child: SingleChildScrollView(
scrollDirection: Axis.vertical,
child: Form(
key: _formKey,
child: Column(
children: [
Container(
width:
getProportionateScreenWidth(
170),
height:
getProportionateScreenWidth(
100),
decoration: BoxDecoration(
borderRadius:
BorderRadius.circular(
8),
image: DecorationImage(
fit: BoxFit.fill,
image: NetworkImage(widget
.dataMyCourseModel
.thumbnail ??
'$baseUrl/uploads/courses_thumbnail/course_thumbnail_default_57.jpg'),
),
),
),
SizedBox(
height:
getProportionateScreenWidth(
16)),
Text(
widget.dataMyCourseModel
.title ??
'',
style: thirdTextStyle
.copyWith(
letterSpacing: 1,
fontWeight:
reguler),
textAlign:
TextAlign.center),
SizedBox(
height:
getProportionateScreenWidth(
23),
),
RatingBar.builder(
minRating: 1,
itemPadding:
EdgeInsets.only(
left: 9),
initialRating: (widget
.dataMyCourseModel
.rating
.length ==
0)
? double.parse("0")
: double.parse(widget
.dataMyCourseModel
.rating[0]
.rating!),
itemSize: 25,
maxRating: 5,
itemBuilder:
(context, _) {
return FaIcon(
FontAwesomeIcons
.solidStar,
color: Colors
.orange[300]);
},
onRatingUpdate: (val) {
value = val;
}),
SizedBox(
height:
getProportionateScreenWidth(
16)),
SizedBox(
width:
getProportionateScreenWidth(
250),
child: TextFormField(
validator: (val) {
print(value);
if ((val == null ||
val.isEmpty) ||
value == 0.0) {
return 'Ulasan dan Rating tidak boleh kosong';
}
return null;
},
controller: _controller,
textInputAction:
TextInputAction.done,
cursorColor:
secondaryColor,
scrollPadding:
EdgeInsets.zero,
minLines: 2,
maxLines: null,
decoration:
InputDecoration(
filled: true,
fillColor: Theme.of(
context)
.brightness ==
Brightness.dark
? seventeenColor
: Colors.grey[200],
border:
OutlineInputBorder(
borderRadius:
BorderRadius
.circular(
10,
),
borderSide:
BorderSide
.none),
hintStyle:
secondaryTextStyle
.copyWith(
color: secondaryColor,
letterSpacing: 0.5,
fontSize:
getProportionateScreenWidth(
12),
),
hintText:
"Tulis Ulasan",
),
),
),
SizedBox(
height:
getProportionateScreenWidth(
10)),
ElevatedButton(
onPressed: () async {
if (_formKey.currentState!
.validate()) {
await state.postingReview(
_controller.text,
int.parse(widget
.dataMyCourseModel
.courseId
.toString()),
value.toInt());
await Provider.of<
MyCourseProvider>(
context,
listen: false)
.getMyCourse();
}
},
child: Text(
'Kirim Penilaian',
style: thirdTextStyle
.copyWith(
color:
Colors.white),
),
style: ElevatedButton
.styleFrom(
minimumSize: Size(
getProportionateScreenWidth(
150),
getProportionateScreenHeight(
33)),
backgroundColor:
primaryColor,
),
)
],
),
),
),
),
);
} else if (state.state ==
postReviewProvider
.ResultState.loading) {
return AlertDialog(
content: Container(
height:
getProportionateScreenHeight(40),
child: Center(
child: CircularProgressIndicator(
strokeWidth: 2,
color: primaryColor,
),
),
),
);
} else if (state.state ==
postReviewProvider
.ResultState.successUpdate) {
_controller.clear();
// widget.onDialogClose!();
return AlertDialog(
shape: RoundedRectangleBorder(
borderRadius:
BorderRadius.circular(10),
),
backgroundColor: Theme.of(context)
.colorScheme
.background,
surfaceTintColor: Colors.transparent,
contentPadding:
EdgeInsets.fromLTRB(12, 26, 22, 15),
content: Padding(
padding: EdgeInsets.only(
bottom:
getProportionateScreenHeight(
14)),
child: Container(
height:
getProportionateScreenHeight(
30),
child: Center(
child: Text(
'Berhasil mengedit ulasan',
style: primaryTextStyle.copyWith(
fontSize:
getProportionateScreenWidth(
12),
letterSpacing: 0.5),
),
),
),
),
);
} else if (state.state ==
postReviewProvider
.ResultState.successAdd) {
_controller.clear();
// widget.onDialogClose!();
return AlertDialog(
shape: RoundedRectangleBorder(
borderRadius:
BorderRadius.circular(10),
),
backgroundColor: Theme.of(context)
.colorScheme
.background,
surfaceTintColor: Colors.transparent,
contentPadding: EdgeInsets.fromLTRB(
12, 26, 22, 15),
content: Padding(
padding: EdgeInsets.only(
bottom:
getProportionateScreenHeight(
14)),
child: Container(
height:
getProportionateScreenHeight(
30),
child: Center(
child: Text(
'Berhasil memberikan ulasan',
style: primaryTextStyle.copyWith(
fontSize:
getProportionateScreenWidth(
12),
letterSpacing: 0.5),
),
),
),
));
} else if (state.state ==
postReviewProvider.ResultState.failed) {
return AlertDialog(
title: Text(
'Terjadi Kesalahan',
style: primaryTextStyle,
),
);
}
return AlertDialog(
title: Text(
'Terjadi Kesalahan',
style: primaryTextStyle,
),
);
},
),
),
),
child: widget.dataMyCourseModel.rating.isEmpty
? Text(
'Beri Penilaian',
style: thirdTextStyle.copyWith(
color: themeProvider.themeData == ThemeClass.darkmode
?primaryColor : primaryColorligtmode,
fontSize:
getProportionateScreenHeight(10),
),
)
: Text(
'Edit Penilaian',
style: thirdTextStyle.copyWith(
color: themeProvider.themeData == ThemeClass.darkmode
?primaryColor : primaryColorligtmode,
fontSize:
getProportionateScreenHeight(10),
),
),
)
],
),
SizedBox(),
ElevatedButton(
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => MultiProvider(
providers: [
ChangeNotifierProvider(
create: (context) =>
CurrentLessonProvider(),
),
ChangeNotifierProvider(
create: (context) => LessonCourseProvider(
lessonCourseService:
LessonCourseService(),
id: int.parse(
widget.dataMyCourseModel.courseId ??
'0'),
),
),
ChangeNotifierProvider(
create: (context) => DetailCourseProvider(
courseService: CourseService(),
id: widget.dataMyCourseModel.courseId ??
'1'),
),
ChangeNotifierProvider(
create: (context) => InstructorProvider(
instructorService: InstructorService(),
id: int.parse(widget
.dataMyCourseModel.instructorId!),
),
),
],
child: PlayCourse(
judul: widget.dataMyCourseModel.title ?? '',
instruktur:
widget.dataMyCourseModel.instructor ?? '',
thumbnail: widget
.dataMyCourseModel.thumbnail ??
'$baseUrl/uploads/courses_thumbnail/course_thumbnail_default_57.jpg',
courseeid:
widget.dataMyCourseModel.courseId ?? '',
),
),
),
);
},
child: Text(
'Mulai',
style: thirdTextStyle.copyWith(
color: baruTextutih,
),
),
style: ElevatedButton.styleFrom(
minimumSize: Size(getProportionateScreenWidth(100),
getProportionateScreenHeight(33)),
backgroundColor: themeProvider.themeData == ThemeClass.darkmode
?primaryColor : primaryColorligtmode,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10))),
),
],
),
SizedBox(height: getProportionateScreenHeight(10)),
],
),
),
),
),
],
);
}
}