Initial commit: Penyerahan final Source code Tugas Akhir
This commit is contained in:
482
lib/screens/detail_course/components/aktifitas.dart
Normal file
482
lib/screens/detail_course/components/aktifitas.dart
Normal file
@ -0,0 +1,482 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_html/flutter_html.dart';
|
||||
import 'package:initial_folder/providers/section_lesson_course_provider.dart';
|
||||
import 'package:initial_folder/screens/course/component/expansion_tile_copy.dart';
|
||||
import 'package:initial_folder/size_config.dart';
|
||||
import 'package:initial_folder/theme.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
class Aktifitas extends StatefulWidget {
|
||||
const Aktifitas({
|
||||
Key? key,
|
||||
required this.id,
|
||||
required this.totalDuration,
|
||||
this.resoaktifitas,
|
||||
}) : super(key: key);
|
||||
|
||||
final String id;
|
||||
final String totalDuration;
|
||||
final String? resoaktifitas;
|
||||
|
||||
@override
|
||||
_AktifitasState createState() => _AktifitasState();
|
||||
}
|
||||
|
||||
class _AktifitasState extends State<Aktifitas> {
|
||||
final _tileKeys = [];
|
||||
var _selectedIndex = -1;
|
||||
final List<ValueNotifier<bool>> _isExpanded = [];
|
||||
final ValueNotifier<int?> _selectedIndexNotifier = ValueNotifier<int?>(null);
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
for (int i = 0; i < 10; i++) {
|
||||
_isExpanded.add(ValueNotifier<bool>(false));
|
||||
}
|
||||
}
|
||||
|
||||
String formatDuration(String duration) {
|
||||
var parts = duration.split(':');
|
||||
String formattedDuration = '';
|
||||
|
||||
if (parts[0] != '00') {
|
||||
formattedDuration += '${parts[0]} jam ';
|
||||
}
|
||||
formattedDuration +=
|
||||
'${int.parse(parts[1])} menit ${int.parse(parts[2])} detik';
|
||||
|
||||
return '($formattedDuration)';
|
||||
}
|
||||
|
||||
String formatDurations(String duration) {
|
||||
if (duration == '') {
|
||||
String formattedDuration = '';
|
||||
|
||||
print('masuk sini');
|
||||
formattedDuration += '';
|
||||
return formattedDuration;
|
||||
}
|
||||
List<String> parts = duration.split(':');
|
||||
int hours = int.parse(parts[0]);
|
||||
int minutes = int.parse(parts[1]);
|
||||
|
||||
String formattedDuration = '';
|
||||
|
||||
if (hours != 0) {
|
||||
formattedDuration += '${hours}j';
|
||||
}
|
||||
|
||||
if (minutes != 0) {
|
||||
formattedDuration += '${int.parse(parts[1])}m';
|
||||
}
|
||||
|
||||
formattedDuration += '${int.parse(parts[2])}d';
|
||||
|
||||
return formattedDuration;
|
||||
}
|
||||
|
||||
void resetExpansionTileKeysAndSelectedIndex() {
|
||||
_tileKeys.clear();
|
||||
_selectedIndex = -1;
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
String _parseHtmlString(String htmlText) {
|
||||
RegExp exp = RegExp(r"<[^>]*>| |&|"",
|
||||
multiLine: true, caseSensitive: true);
|
||||
return htmlText.replaceAll(exp, '');
|
||||
}
|
||||
|
||||
resetExpansionTileKeysAndSelectedIndex();
|
||||
return Container(
|
||||
margin: EdgeInsets.only(
|
||||
left: getProportionateScreenWidth(15),
|
||||
right: getProportionateScreenWidth(15),
|
||||
top: getProportionateScreenHeight(20),
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
'Aktivitas',
|
||||
style: thirdTextStyle.copyWith(
|
||||
fontWeight: semiBold,
|
||||
fontSize: getProportionateScreenWidth(14),
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
height: 8,
|
||||
),
|
||||
Consumer<SectionLessonCourseProvider>(
|
||||
builder: (context, state, _) {
|
||||
if (state.state == ResultState.Loading) {
|
||||
return Center(
|
||||
child: CircularProgressIndicator(
|
||||
color: Colors.amber,
|
||||
strokeWidth: 2,
|
||||
),
|
||||
);
|
||||
} else if (state.state == ResultState.HasData) {
|
||||
_isExpanded.clear();
|
||||
for (int i = 0; i < state.result!.data![0].length; i++) {
|
||||
_isExpanded.add(ValueNotifier<bool>(false));
|
||||
}
|
||||
return Container(
|
||||
child: Column(
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Text(
|
||||
'${state.result!.data![0].length} Pelajaran',
|
||||
style: thirdTextStyle.copyWith(
|
||||
fontSize: getProportionateScreenWidth(11),
|
||||
fontWeight: light,
|
||||
),
|
||||
),
|
||||
SizedBox(width: getProportionateScreenWidth(6)),
|
||||
Text(
|
||||
formatDuration(widget.totalDuration == ""
|
||||
? "00:02:07"
|
||||
: widget.totalDuration),
|
||||
style: thirdTextStyle.copyWith(
|
||||
fontSize: getProportionateScreenWidth(11),
|
||||
fontWeight: light,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(height: getProportionateScreenHeight(5)),
|
||||
Container(
|
||||
height: widget.resoaktifitas == null
|
||||
? getProportionateScreenHeight(195)
|
||||
: getProportionateScreenHeight(195),
|
||||
width: SizeConfig.screenWidth,
|
||||
child: ListView.builder(
|
||||
itemCount: state.result!.data![0].length,
|
||||
itemBuilder: (context, index) {
|
||||
var chapter = state.result!.data![0][index];
|
||||
final tileKey = GlobalKey();
|
||||
_tileKeys.add(tileKey);
|
||||
return ValueListenableBuilder<bool>(
|
||||
valueListenable: _isExpanded[index],
|
||||
builder: (context, isExpanded, child) {
|
||||
return Theme(
|
||||
data: ThemeData.dark().copyWith(
|
||||
colorScheme: ColorScheme.dark(
|
||||
primary: secondaryColor),
|
||||
dividerColor: Colors.transparent,
|
||||
),
|
||||
child: Padding(
|
||||
padding: EdgeInsets.only(
|
||||
bottom:
|
||||
getProportionateScreenHeight(15)),
|
||||
child: Column(
|
||||
children: [
|
||||
ListTileTheme(
|
||||
dense: true,
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
color: Theme.of(context)
|
||||
.colorScheme
|
||||
.primaryContainer,
|
||||
borderRadius:
|
||||
BorderRadius.circular(5),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: baruTexthitam
|
||||
.withOpacity(0.1),
|
||||
blurRadius: 3,
|
||||
spreadRadius: 1,
|
||||
offset: Offset(0, 3),
|
||||
),
|
||||
],
|
||||
),
|
||||
child: ExpansionTileCopy(
|
||||
key: tileKey,
|
||||
onExpansionChanged:
|
||||
(bool expanding) {
|
||||
if (expanding) {
|
||||
if (_selectedIndexNotifier
|
||||
.value !=
|
||||
null &&
|
||||
_selectedIndexNotifier
|
||||
.value !=
|
||||
index &&
|
||||
_tileKeys[_selectedIndexNotifier
|
||||
.value!]
|
||||
.currentState !=
|
||||
null) {
|
||||
_tileKeys[
|
||||
_selectedIndexNotifier
|
||||
.value!]
|
||||
.currentState!
|
||||
.closeExpansion();
|
||||
}
|
||||
_selectedIndexNotifier
|
||||
.value = index;
|
||||
} else if (_selectedIndexNotifier
|
||||
.value ==
|
||||
index) {
|
||||
_selectedIndexNotifier
|
||||
.value = null;
|
||||
}
|
||||
},
|
||||
title: Text(
|
||||
'Bab ${index + 1}',
|
||||
style:
|
||||
thirdTextStyle.copyWith(
|
||||
fontWeight: semiBold,
|
||||
fontSize:
|
||||
getProportionateScreenWidth(
|
||||
11),
|
||||
color: Theme.of(context)
|
||||
.colorScheme
|
||||
.onBackground,
|
||||
),
|
||||
),
|
||||
subtitle: Html(
|
||||
shrinkWrap: true,
|
||||
data: chapter.title ?? '',
|
||||
style: {
|
||||
"body": Style(
|
||||
margin: Margins.zero,
|
||||
padding:
|
||||
HtmlPaddings.zero,
|
||||
fontSize: FontSize(
|
||||
getProportionateScreenWidth(
|
||||
12)),
|
||||
fontWeight: reguler,
|
||||
fontFamily: 'Poppins',
|
||||
color: Theme.of(context)
|
||||
.colorScheme
|
||||
.onBackground,
|
||||
),
|
||||
},
|
||||
),
|
||||
trailing:
|
||||
ValueListenableBuilder<
|
||||
int?>(
|
||||
valueListenable:
|
||||
_selectedIndexNotifier,
|
||||
builder:
|
||||
(context, value, child) {
|
||||
return Icon(
|
||||
value == index
|
||||
? Icons.remove
|
||||
: Icons.add,
|
||||
color: primaryColor,
|
||||
);
|
||||
},
|
||||
),
|
||||
children: chapter.dataLesson![0]
|
||||
.asMap()
|
||||
.entries
|
||||
.map(
|
||||
(e) => ListTile(
|
||||
minVerticalPadding: 15,
|
||||
leading: Text(
|
||||
'${e.key + 1}',
|
||||
style: thirdTextStyle
|
||||
.copyWith(
|
||||
color: Theme.of(
|
||||
context)
|
||||
.colorScheme
|
||||
.onBackground,
|
||||
),
|
||||
),
|
||||
minLeadingWidth: 15,
|
||||
title:
|
||||
Transform.translate(
|
||||
offset: Offset(0, 0),
|
||||
child: Text(
|
||||
_parseHtmlString(e
|
||||
.value
|
||||
.titleLesson ??
|
||||
''),
|
||||
style: TextStyle(
|
||||
fontSize:
|
||||
getProportionateScreenWidth(
|
||||
12),
|
||||
fontWeight:
|
||||
semiBold,
|
||||
fontFamily:
|
||||
'Poppins',
|
||||
color: Theme.of(
|
||||
context)
|
||||
.colorScheme
|
||||
.onBackground,
|
||||
),
|
||||
),
|
||||
),
|
||||
subtitle:
|
||||
Transform.translate(
|
||||
offset: Offset(0, 0),
|
||||
child: Text(
|
||||
(e.value.lessonType ==
|
||||
'video')
|
||||
? 'Video - ${formatDuration(e.value.duration.toString())}'
|
||||
: (e.value.lessonType ==
|
||||
'quiz')
|
||||
? 'Quiz'
|
||||
: (e.value
|
||||
.attachment
|
||||
.toString()
|
||||
.contains('.pdf'))
|
||||
? 'PDFs'
|
||||
: (e.value.attachment.toString().contains('.pptx'))
|
||||
? 'PPT'
|
||||
: (e.value.attachment.toString().contains('.rar'))
|
||||
? 'RAR'
|
||||
: (e.value.attachment.toString().contains('.zip'))
|
||||
? 'ZIP'
|
||||
: (e.value.attachment.toString().contains('.xlsx'))
|
||||
? 'Excel'
|
||||
: (e.value.attachment.toString().contains('.jpg') || e.value.attachment.toString().contains('.jpeg') || e.value.attachment.toString().contains('.png'))
|
||||
? 'Image'
|
||||
: (e.value.attachment.toString().contains('.docx'))
|
||||
? 'Document'
|
||||
: (e.value.attachment.toString().contains('.txt'))
|
||||
? 'Text'
|
||||
: 'Terjadi Kesalahan',
|
||||
style:
|
||||
thirdTextStyle
|
||||
.copyWith(
|
||||
color: Theme.of(
|
||||
context)
|
||||
.colorScheme
|
||||
.onBackground,
|
||||
fontSize:
|
||||
getProportionateScreenHeight(
|
||||
8),
|
||||
),
|
||||
),
|
||||
),
|
||||
trailing: (e.value
|
||||
.lessonType ==
|
||||
'video')
|
||||
? Image.asset(
|
||||
'assets/images/play_button_new.png',
|
||||
color: Theme.of(
|
||||
context)
|
||||
.colorScheme
|
||||
.onBackground,
|
||||
scale: 3,
|
||||
)
|
||||
: (e.value.lessonType ==
|
||||
'quiz')
|
||||
? Image.asset(
|
||||
'assets/icons/lms/ListNumbers.png',
|
||||
color: Theme.of(
|
||||
context)
|
||||
.colorScheme
|
||||
.onBackground,
|
||||
scale:
|
||||
getProportionateScreenWidth(
|
||||
1.3),
|
||||
)
|
||||
: (e.value
|
||||
.attachment
|
||||
.toString()
|
||||
.contains(
|
||||
'.pdf'))
|
||||
? Image
|
||||
.asset(
|
||||
'assets/icons/lms/FilePdf.png',
|
||||
color: Theme.of(context)
|
||||
.colorScheme
|
||||
.onBackground,
|
||||
scale: getProportionateScreenWidth(
|
||||
1.3),
|
||||
)
|
||||
: (e.value
|
||||
.attachment
|
||||
.toString()
|
||||
.contains(
|
||||
'.rar'))
|
||||
? Image
|
||||
.asset(
|
||||
'assets/icons/lms/FileArchive.png',
|
||||
color:
|
||||
Theme.of(context).colorScheme.onBackground,
|
||||
scale:
|
||||
getProportionateScreenWidth(1.3),
|
||||
)
|
||||
: (e.value.attachment.toString().contains('.zip'))
|
||||
? Image.asset(
|
||||
'assets/icons/lms/FileZip.png',
|
||||
color: Theme.of(context).colorScheme.onBackground,
|
||||
scale: getProportionateScreenWidth(1.3),
|
||||
)
|
||||
: (e.value.attachment.toString().contains('.pptx'))
|
||||
? Image.asset(
|
||||
'assets/icons/lms/FilePpt.png',
|
||||
color: Theme.of(context).colorScheme.onBackground,
|
||||
scale: getProportionateScreenWidth(1.3),
|
||||
)
|
||||
: (e.value.attachment.toString().contains('.xlsx'))
|
||||
? Image.asset(
|
||||
'assets/icons/lms/FileXls.png',
|
||||
color: Theme.of(context).colorScheme.onBackground,
|
||||
scale: getProportionateScreenWidth(1.3),
|
||||
)
|
||||
: (e.value.attachment.toString().contains('.jpg') || e.value.attachment.toString().contains('.jpeg') || e.value.attachment.toString().contains('.png'))
|
||||
? Image.asset(
|
||||
'assets/icons/lms/FileImage.png',
|
||||
color: Theme.of(context).colorScheme.onBackground,
|
||||
scale: getProportionateScreenWidth(1.3),
|
||||
)
|
||||
: (e.value.attachment.toString().contains('.txt'))
|
||||
? Image.asset(
|
||||
'assets/icons/lms/FileText.png',
|
||||
color: Theme.of(context).colorScheme.onBackground,
|
||||
scale: getProportionateScreenWidth(1.3),
|
||||
)
|
||||
: ((e.value.attachment.toString().contains('.docx')))
|
||||
? Image.asset(
|
||||
'assets/icons/lms/FileDoc.png',
|
||||
color: Theme.of(context).colorScheme.onBackground,
|
||||
scale: getProportionateScreenWidth(1.3),
|
||||
)
|
||||
: SizedBox(),
|
||||
),
|
||||
)
|
||||
.toList(),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
));
|
||||
},
|
||||
);
|
||||
},
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
);
|
||||
} else if (state.state == ResultState.NoData) {
|
||||
return Center(child: Text(state.message));
|
||||
} else if (state.state == ResultState.Error) {
|
||||
return Center(
|
||||
child: Padding(
|
||||
padding:
|
||||
EdgeInsets.only(top: getProportionateScreenHeight(30)),
|
||||
child: Text(
|
||||
'Kursus ini belum memiliki aktivitas',
|
||||
style: thirdTextStyle.copyWith(),
|
||||
),
|
||||
),
|
||||
);
|
||||
} else {
|
||||
return Center(child: Text(''));
|
||||
}
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
195
lib/screens/detail_course/components/app_bar.dart
Normal file
195
lib/screens/detail_course/components/app_bar.dart
Normal file
@ -0,0 +1,195 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
import 'package:initial_folder/providers/carts_provider.dart';
|
||||
import 'package:initial_folder/providers/notification_provider.dart';
|
||||
import 'package:initial_folder/screens/home/components/appBar/icon_btn_with_counter.dart';
|
||||
import 'package:initial_folder/screens/home/components/notification.dart';
|
||||
import 'package:initial_folder/screens/login/login_with_email/login_email_screen.dart';
|
||||
import 'package:initial_folder/size_config.dart';
|
||||
import 'package:initial_folder/theme.dart';
|
||||
import 'package:initial_folder/widgets/custom_navigator.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:initial_folder/helper/user_info.dart';
|
||||
import 'package:initial_folder/screens/cart/cart_page.dart';
|
||||
import 'package:initial_folder/screens/splash/splash_screen_login.dart';
|
||||
|
||||
class AppBarHeader extends StatelessWidget {
|
||||
const AppBarHeader({
|
||||
Key? key,
|
||||
this.idcourse,
|
||||
this.color,
|
||||
}) : super(key: key);
|
||||
|
||||
final String? idcourse;
|
||||
final Color? color;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
Future _showDialogNotLogin(String teks) {
|
||||
return showDialog(
|
||||
context: context,
|
||||
builder: (context) => AlertDialog(
|
||||
contentPadding: EdgeInsets.fromLTRB(12, 20, 12, 1),
|
||||
content: Text(
|
||||
'Mohon login terlebih dahulu sebelum $teks',
|
||||
style: primaryTextStyle.copyWith(
|
||||
fontSize: getProportionateScreenWidth(12), letterSpacing: 1),
|
||||
),
|
||||
actions: [
|
||||
GestureDetector(
|
||||
onTap: () {
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
child: Text(
|
||||
'Batal',
|
||||
style: primaryTextStyle.copyWith(
|
||||
fontSize: getProportionateScreenWidth(12),
|
||||
letterSpacing: 1,
|
||||
color: primaryColor,
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(width: getProportionateScreenWidth(5)),
|
||||
GestureDetector(
|
||||
onTap: () {
|
||||
Navigator.of(context).pushNamedAndRemoveUntil(
|
||||
LoginEmail.routeName, (Route<dynamic> route) => false);
|
||||
},
|
||||
child: Text(
|
||||
'Login',
|
||||
style: primaryTextStyle.copyWith(
|
||||
fontSize: getProportionateScreenWidth(12),
|
||||
letterSpacing: 1,
|
||||
color: primaryColor,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
handleNotLoginCart() async {
|
||||
var token = await UsersInfo().getToken();
|
||||
if (token != null || Condition.loginFirebase == true) {
|
||||
Navigator.of(context, rootNavigator: true).push(
|
||||
CustomNavigator(
|
||||
child: CartPage(),
|
||||
),
|
||||
);
|
||||
} else {
|
||||
String teks = 'dapat mengakses keranjang';
|
||||
return _showDialogNotLogin(teks);
|
||||
}
|
||||
}
|
||||
|
||||
handleNotLoginNotif() async {
|
||||
var token = await UsersInfo().getToken();
|
||||
if (token != null || Condition.loginFirebase == true) {
|
||||
Navigator.of(context, rootNavigator: true).push(
|
||||
CustomNavigator(
|
||||
child: Notifikasi(),
|
||||
),
|
||||
);
|
||||
} else {
|
||||
String teks = 'dapat mengakses notifikasi';
|
||||
return _showDialogNotLogin(teks);
|
||||
}
|
||||
}
|
||||
|
||||
return AnimatedContainer(
|
||||
duration: Duration(milliseconds: 500),
|
||||
curve: Curves.ease,
|
||||
color: color,
|
||||
width: SizeConfig.screenWidth,
|
||||
height: getProportionateScreenHeight(40),
|
||||
child: Padding(
|
||||
padding: EdgeInsets.only(
|
||||
right: getProportionateScreenWidth(10),
|
||||
left: getProportionateScreenWidth(5),
|
||||
),
|
||||
child: Row(
|
||||
children: [
|
||||
IconButton(
|
||||
alignment: Alignment.centerLeft,
|
||||
icon: Theme.of(context).brightness == Brightness.dark
|
||||
? SvgPicture.asset('assets/icons/arrow_back_dark.svg')
|
||||
: SvgPicture.asset('assets/icons/arrow_back.svg'),
|
||||
onPressed: () {
|
||||
Navigator.pop(context);
|
||||
},
|
||||
),
|
||||
Spacer(),
|
||||
Transform.scale(
|
||||
origin: Offset(-11, 0),
|
||||
scale: getProportionateScreenHeight(1),
|
||||
child: Container(
|
||||
padding: EdgeInsets.fromLTRB(getProportionateScreenHeight(3), 0,
|
||||
getProportionateScreenHeight(4), 0),
|
||||
child: Consumer<NotificationProvider>(
|
||||
builder: (context, value, child) {
|
||||
return IconBtnWithCounter(
|
||||
icon: Theme.of(context).brightness == Brightness.dark
|
||||
? SvgPicture.asset(
|
||||
"assets/icons/notification_dark.svg")
|
||||
: SvgPicture.asset("assets/icons/notification.svg"),
|
||||
numOfitem:
|
||||
(Condition.loginEmail || Condition.loginFirebase)
|
||||
? value.notificationCount
|
||||
: 0,
|
||||
press: () {
|
||||
handleNotLoginNotif();
|
||||
},
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
!Condition.loginEmail && !Condition.loginFirebase
|
||||
? Transform.scale(
|
||||
origin: Offset(0, 0),
|
||||
scale: getProportionateScreenHeight(1),
|
||||
child: Container(
|
||||
padding: EdgeInsets.fromLTRB(
|
||||
getProportionateScreenHeight(3),
|
||||
0,
|
||||
getProportionateScreenHeight(3),
|
||||
0),
|
||||
child: IconBtnWithCounter(
|
||||
numOfitem: 0,
|
||||
icon: Theme.of(context).brightness == Brightness.dark
|
||||
? SvgPicture.asset("assets/icons/cart_dark.svg")
|
||||
: SvgPicture.asset("assets/icons/cart.svg"),
|
||||
press: () => handleNotLoginCart(),
|
||||
),
|
||||
),
|
||||
)
|
||||
: Transform.scale(
|
||||
origin: Offset(0, 0),
|
||||
scale: getProportionateScreenHeight(1),
|
||||
child: Container(
|
||||
padding: EdgeInsets.fromLTRB(
|
||||
getProportionateScreenHeight(3),
|
||||
0,
|
||||
getProportionateScreenHeight(3),
|
||||
0),
|
||||
child: Consumer<CartsProvider>(
|
||||
builder: (context, state, _) {
|
||||
return IconBtnWithCounter(
|
||||
numOfitem: state.result == null ? 0 : state.lenght,
|
||||
icon: Theme.of(context).brightness ==
|
||||
Brightness.dark
|
||||
? SvgPicture.asset("assets/icons/cart_dark.svg")
|
||||
: SvgPicture.asset("assets/icons/cart.svg"),
|
||||
press: () => handleNotLoginCart(),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
124
lib/screens/detail_course/components/app_bar_filter.dart
Normal file
124
lib/screens/detail_course/components/app_bar_filter.dart
Normal file
@ -0,0 +1,124 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:initial_folder/screens/home/components/notification.dart';
|
||||
import 'package:initial_folder/screens/login/login_with_email/login_email_screen.dart';
|
||||
import 'package:initial_folder/screens/search_course/component/filter.dart';
|
||||
import 'package:initial_folder/size_config.dart';
|
||||
import 'package:initial_folder/theme.dart';
|
||||
import 'package:initial_folder/helper/user_info.dart';
|
||||
import 'package:initial_folder/screens/cart/cart_page.dart';
|
||||
import 'package:initial_folder/screens/splash/splash_screen_login.dart';
|
||||
import 'package:initial_folder/widgets/custom_navigator.dart';
|
||||
|
||||
class AppBarFilter extends StatelessWidget {
|
||||
const AppBarFilter({
|
||||
Key? key,
|
||||
this.idcourse,
|
||||
}) : super(key: key);
|
||||
|
||||
final String? idcourse;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
Future _showDialogNotLogin(String teks) {
|
||||
return showDialog(
|
||||
context: context,
|
||||
builder: (context) => AlertDialog(
|
||||
contentPadding: EdgeInsets.fromLTRB(12, 20, 12, 1),
|
||||
content: Text(
|
||||
'Mohon login terlebih dahulu sebelum $teks',
|
||||
style: primaryTextStyle.copyWith(
|
||||
fontSize: getProportionateScreenWidth(12), letterSpacing: 1),
|
||||
),
|
||||
actions: [
|
||||
GestureDetector(
|
||||
onTap: () {
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
child: Text('Batal',
|
||||
style: primaryTextStyle.copyWith(
|
||||
fontSize: getProportionateScreenWidth(12),
|
||||
letterSpacing: 1,
|
||||
color: primaryColor)),
|
||||
),
|
||||
SizedBox(
|
||||
width: getProportionateScreenWidth(5),
|
||||
),
|
||||
GestureDetector(
|
||||
onTap: () {
|
||||
Navigator.of(context).pushNamedAndRemoveUntil(
|
||||
LoginEmail.routeName, (Route<dynamic> route) => false);
|
||||
},
|
||||
child: Text('Login',
|
||||
style: primaryTextStyle.copyWith(
|
||||
fontSize: getProportionateScreenWidth(12),
|
||||
letterSpacing: 1,
|
||||
color: primaryColor)),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
handleNotLoginCart() async {
|
||||
var token = await UsersInfo().getToken();
|
||||
if (token != null || Condition.loginFirebase == true) {
|
||||
Navigator.of(context).push(
|
||||
CustomNavigator(
|
||||
child: CartPage(),
|
||||
),
|
||||
);
|
||||
} else {
|
||||
String teks = 'dapat mengakses keranjang';
|
||||
return _showDialogNotLogin(teks);
|
||||
}
|
||||
}
|
||||
|
||||
handleNotLoginNotif() async {
|
||||
var token = await UsersInfo().getToken();
|
||||
if (token != null || Condition.loginFirebase == true) {
|
||||
Navigator.push(
|
||||
context,
|
||||
CustomNavigator(
|
||||
child: Notifikasi(),
|
||||
),
|
||||
);
|
||||
} else {
|
||||
String teks = 'dapat mengakses notifikasi';
|
||||
return _showDialogNotLogin(teks);
|
||||
}
|
||||
}
|
||||
|
||||
return Container(
|
||||
margin: EdgeInsets.only(left: getProportionateScreenWidth(7)),
|
||||
width: SizeConfig.screenWidth,
|
||||
height: getProportionateScreenHeight(40),
|
||||
child: Row(
|
||||
children: [
|
||||
IconButton(
|
||||
alignment: Alignment.centerLeft,
|
||||
icon: Icon(
|
||||
Icons.arrow_back,
|
||||
size: getProportionateScreenHeight(18),
|
||||
color: Theme.of(context).brightness == Brightness.dark
|
||||
? tenthColor
|
||||
: ninthColor,
|
||||
),
|
||||
onPressed: () {
|
||||
Navigator.pop(context);
|
||||
},
|
||||
),
|
||||
Spacer(),
|
||||
// IconButton(
|
||||
// padding: EdgeInsets.zero,
|
||||
// onPressed: () => Navigator.of(context, rootNavigator: true).push(
|
||||
// CustomNavigator(
|
||||
// child: const Filter(isNotSearch: true),
|
||||
// ),
|
||||
// ),
|
||||
// icon: Icon(Icons.tune_rounded, color: primaryColor),
|
||||
// ),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
170
lib/screens/detail_course/components/custom_tab_bar.dart
Normal file
170
lib/screens/detail_course/components/custom_tab_bar.dart
Normal file
@ -0,0 +1,170 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:initial_folder/models/detail_course_model.dart';
|
||||
import 'package:initial_folder/providers/tab_provider.dart';
|
||||
import 'package:initial_folder/screens/detail_course/components/aktifitas.dart';
|
||||
import 'package:initial_folder/screens/detail_course/components/deskripsi.dart';
|
||||
import 'package:initial_folder/screens/detail_course/components/tab_bar_items.dart';
|
||||
import 'package:initial_folder/screens/detail_course/components/terkait.dart';
|
||||
import 'package:initial_folder/screens/detail_course/components/ulasan.dart';
|
||||
import 'package:initial_folder/size_config.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
class CustomTabBar extends StatefulWidget {
|
||||
const CustomTabBar({
|
||||
Key? key,
|
||||
required this.dataDetailCourseModel,
|
||||
this.totalDuration,
|
||||
this.bio,
|
||||
this.instructor,
|
||||
this.rating,
|
||||
this.review,
|
||||
this.totalLesson,
|
||||
this.totalStudent,
|
||||
this.fotoProfile,
|
||||
this.headline,
|
||||
this.resoaktifitas,
|
||||
this.idCategory,
|
||||
}) : super(key: key);
|
||||
final DataDetailCourseModel dataDetailCourseModel;
|
||||
final String? totalDuration,
|
||||
bio,
|
||||
instructor,
|
||||
review,
|
||||
totalLesson,
|
||||
totalStudent,
|
||||
fotoProfile,
|
||||
rating,
|
||||
headline,
|
||||
resoaktifitas,
|
||||
idCategory;
|
||||
|
||||
@override
|
||||
State<CustomTabBar> createState() => _CustomTabBarState();
|
||||
}
|
||||
|
||||
class _CustomTabBarState extends State<CustomTabBar> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
TabProvider tab = Provider.of<TabProvider>(context);
|
||||
|
||||
void _onHorizontalDragEnd(DragEndDetails details) {
|
||||
double velocity = details.primaryVelocity ?? 0.0;
|
||||
if (velocity < 0) {
|
||||
if (tab.currentIndex < 3) {
|
||||
tab.currentIndex++;
|
||||
}
|
||||
} else if (velocity > 0) {
|
||||
if (tab.currentIndex > 0) {
|
||||
tab.currentIndex--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Widget buildContent(int currentIndex) {
|
||||
switch (currentIndex) {
|
||||
case 0:
|
||||
return Desksripsi(
|
||||
dataDetailCourseModel: widget.dataDetailCourseModel,
|
||||
video: true,
|
||||
id: widget.dataDetailCourseModel.id,
|
||||
instructor: widget.instructor,
|
||||
bio: widget.bio,
|
||||
rating: widget.rating,
|
||||
fotoProfile: widget.fotoProfile,
|
||||
review: widget.review,
|
||||
totalLesson: widget.totalLesson,
|
||||
totalStudent: widget.totalStudent,
|
||||
headline: widget.headline,
|
||||
);
|
||||
case 1:
|
||||
return Aktifitas(
|
||||
id: widget.dataDetailCourseModel.id,
|
||||
totalDuration: widget.totalDuration ?? '',
|
||||
resoaktifitas: widget.resoaktifitas,
|
||||
);
|
||||
case 2:
|
||||
return Ulasan(
|
||||
id: widget.dataDetailCourseModel.id,
|
||||
);
|
||||
|
||||
case 3:
|
||||
return Terkait(
|
||||
idCategory: widget.idCategory,
|
||||
);
|
||||
default:
|
||||
return Desksripsi(
|
||||
dataDetailCourseModel: widget.dataDetailCourseModel,
|
||||
video: true,
|
||||
id: widget.dataDetailCourseModel.id,
|
||||
instructor: widget.instructor,
|
||||
bio: widget.bio,
|
||||
rating: widget.rating,
|
||||
fotoProfile: widget.fotoProfile,
|
||||
review: widget.review,
|
||||
totalLesson: widget.totalLesson,
|
||||
totalStudent: widget.totalStudent,
|
||||
headline: widget.headline,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return Column(
|
||||
children: [
|
||||
Container(
|
||||
width: SizeConfig.screenWidth,
|
||||
height: getProportionateScreenHeight(29),
|
||||
decoration: BoxDecoration(
|
||||
color: Theme.of(context).colorScheme.background,
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Colors.black.withOpacity(0.1),
|
||||
spreadRadius: -12,
|
||||
blurRadius: 8,
|
||||
offset: Offset(0, getProportionateScreenHeight(12)),
|
||||
),
|
||||
],
|
||||
),
|
||||
child: Center(
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||||
children: [
|
||||
GestureDetector(
|
||||
onTap: () => tab.currentIndex = 0,
|
||||
child: TabBarItems(
|
||||
index: 0,
|
||||
title: 'Deskripsi',
|
||||
),
|
||||
),
|
||||
GestureDetector(
|
||||
onTap: () => tab.currentIndex = 1,
|
||||
child: TabBarItems(
|
||||
index: 1,
|
||||
title: 'Aktivitas',
|
||||
),
|
||||
),
|
||||
GestureDetector(
|
||||
onTap: () => tab.currentIndex = 2,
|
||||
child: TabBarItems(
|
||||
index: 2,
|
||||
title: 'Ulasan',
|
||||
),
|
||||
),
|
||||
GestureDetector(
|
||||
onTap: () => tab.currentIndex = 3,
|
||||
child: TabBarItems(
|
||||
index: 3,
|
||||
title: 'Terkait',
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
GestureDetector(
|
||||
onHorizontalDragEnd: _onHorizontalDragEnd,
|
||||
child: buildContent(tab.currentIndex),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
557
lib/screens/detail_course/components/deskripsi.dart
Normal file
557
lib/screens/detail_course/components/deskripsi.dart
Normal file
@ -0,0 +1,557 @@
|
||||
import 'dart:convert';
|
||||
import 'package:expandable/expandable.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/gestures.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_html/flutter_html.dart';
|
||||
import 'package:initial_folder/models/detail_course_model.dart';
|
||||
import 'package:initial_folder/providers/description_provider.dart';
|
||||
import 'package:initial_folder/providers/theme_provider.dart';
|
||||
import 'package:initial_folder/screens/detail_course/components/kursus_include_item.dart';
|
||||
import 'package:initial_folder/size_config.dart';
|
||||
import 'package:initial_folder/theme.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
class Desksripsi extends StatefulWidget {
|
||||
const Desksripsi({
|
||||
Key? key,
|
||||
required this.dataDetailCourseModel,
|
||||
required this.id,
|
||||
this.instructor,
|
||||
this.bio,
|
||||
this.rating,
|
||||
this.review,
|
||||
this.totalStudent,
|
||||
this.totalLesson,
|
||||
this.video = false,
|
||||
this.fotoProfile,
|
||||
this.headline,
|
||||
}) : super(key: key);
|
||||
|
||||
final DataDetailCourseModel dataDetailCourseModel;
|
||||
final String id;
|
||||
final String? instructor;
|
||||
final String? bio;
|
||||
final String? rating;
|
||||
final String? review;
|
||||
final String? fotoProfile;
|
||||
final String? totalLesson;
|
||||
final String? totalStudent;
|
||||
final String? headline;
|
||||
final bool video;
|
||||
|
||||
@override
|
||||
State<Desksripsi> createState() => _DesksripsiState();
|
||||
}
|
||||
|
||||
class _DesksripsiState extends State<Desksripsi> {
|
||||
bool isExpanded = false;
|
||||
bool isExpanded2 = false;
|
||||
bool isExpanded3 = false;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final themeProvider = Provider.of<ThemeProvider>(context);
|
||||
DescriptionProvider descriptionProvider =
|
||||
Provider.of<DescriptionProvider>(context);
|
||||
final bool hasDescription =
|
||||
widget.dataDetailCourseModel.description!.isNotEmpty;
|
||||
String formatDuration(String duration) {
|
||||
var parts = duration.split(':');
|
||||
return '${int.parse(parts[0]).toString()} jam ${int.parse(parts[1]).toString()} menit ${int.parse(parts[2]).toString()} detik';
|
||||
}
|
||||
|
||||
List outcomes;
|
||||
try {
|
||||
outcomes = jsonDecode(widget.dataDetailCourseModel.outcome ?? '[]');
|
||||
} catch (e) {
|
||||
outcomes = [];
|
||||
}
|
||||
List requirement;
|
||||
try {
|
||||
requirement =
|
||||
jsonDecode(widget.dataDetailCourseModel.requirement ?? '[]');
|
||||
} catch (e) {
|
||||
requirement = [];
|
||||
}
|
||||
|
||||
Widget kemampuanDiraih(String title,
|
||||
{bool showToggle = false, bool isLast = false}) {
|
||||
return Container(
|
||||
margin: EdgeInsets.only(bottom: 6),
|
||||
child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
title.isNotEmpty
|
||||
? Icon(
|
||||
Icons.check,
|
||||
size: getProportionateScreenHeight(13),
|
||||
color: themeProvider.themeData == ThemeClass.darkmode
|
||||
?primaryColor : primaryColorligtmode,
|
||||
)
|
||||
: SizedBox.shrink(),
|
||||
SizedBox(width: getProportionateScreenWidth(9)),
|
||||
Flexible(
|
||||
child: RichText(
|
||||
text: TextSpan(
|
||||
text: title,
|
||||
style: thirdTextStyle.copyWith(
|
||||
fontSize: getProportionateScreenWidth(12),
|
||||
fontWeight: light,
|
||||
color: Theme.of(context).brightness == Brightness.dark
|
||||
? baruTextutih
|
||||
: baruTexthitam,
|
||||
),
|
||||
children: showToggle || isLast
|
||||
? [
|
||||
TextSpan(
|
||||
text:
|
||||
isExpanded ? ' Lihat Sedikit' : ' Lihat Semua',
|
||||
style: thirdTextStyle.copyWith(
|
||||
fontWeight: semiBold,
|
||||
fontSize: getProportionateScreenWidth(12),
|
||||
color: Theme.of(context).brightness ==
|
||||
Brightness.dark
|
||||
? baruTextutih
|
||||
: fourthColor,
|
||||
),
|
||||
recognizer: TapGestureRecognizer()
|
||||
..onTap = () {
|
||||
setState(() {
|
||||
isExpanded = !isExpanded;
|
||||
});
|
||||
},
|
||||
),
|
||||
]
|
||||
: [],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget persyaratan(String title,
|
||||
{bool showToggle = false, bool isLast = false}) {
|
||||
return Container(
|
||||
margin: EdgeInsets.only(bottom: 6),
|
||||
child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
title.isNotEmpty
|
||||
? Icon(
|
||||
Icons.brightness_1,
|
||||
size: getProportionateScreenHeight(13),
|
||||
color: themeProvider.themeData == ThemeClass.darkmode
|
||||
?primaryColor : primaryColorligtmode,
|
||||
)
|
||||
: SizedBox.shrink(),
|
||||
SizedBox(width: getProportionateScreenWidth(9)),
|
||||
Flexible(
|
||||
child: RichText(
|
||||
text: TextSpan(
|
||||
text: title,
|
||||
style: thirdTextStyle.copyWith(
|
||||
fontSize: getProportionateScreenWidth(12),
|
||||
fontWeight: light,
|
||||
color: Theme.of(context).brightness == Brightness.dark
|
||||
? baruTextutih
|
||||
: baruTexthitam,
|
||||
),
|
||||
children: showToggle || isLast
|
||||
? [
|
||||
TextSpan(
|
||||
text:
|
||||
isExpanded3 ? ' Lihat Sedikit' : ' Lihat Semua',
|
||||
style: thirdTextStyle.copyWith(
|
||||
fontWeight: semiBold,
|
||||
fontSize: getProportionateScreenWidth(12),
|
||||
color: Theme.of(context).brightness ==
|
||||
Brightness.dark
|
||||
? baruTextutih
|
||||
: fourthColor,
|
||||
),
|
||||
recognizer: TapGestureRecognizer()
|
||||
..onTap = () {
|
||||
setState(() {
|
||||
isExpanded3 = !isExpanded3;
|
||||
});
|
||||
},
|
||||
),
|
||||
]
|
||||
: [],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
List<Widget> kemampuanDiraihList() {
|
||||
List<Widget> items = outcomes
|
||||
.asMap()
|
||||
.entries
|
||||
.map((entry) => kemampuanDiraih(entry.value,
|
||||
showToggle: !isExpanded && entry.key == 2 && outcomes.length > 3,
|
||||
isLast: entry.key == outcomes.length - 1 && outcomes.length > 3))
|
||||
.toList();
|
||||
|
||||
if (!isExpanded && outcomes.length > 3) {
|
||||
items = items.take(3).toList();
|
||||
items.add(kemampuanDiraih("", isLast: false, showToggle: false));
|
||||
}
|
||||
|
||||
return items;
|
||||
}
|
||||
|
||||
List<Widget> persyaratanList() {
|
||||
List<Widget> items = requirement
|
||||
.asMap()
|
||||
.entries
|
||||
.map((entry) => persyaratan(entry.value,
|
||||
showToggle:
|
||||
!isExpanded3 && entry.key == 2 && requirement.length > 3,
|
||||
isLast: entry.key == requirement.length - 1 &&
|
||||
requirement.length > 3))
|
||||
.toList();
|
||||
|
||||
if (!isExpanded3 && requirement.length > 3) {
|
||||
items = items.take(3).toList();
|
||||
items.add(persyaratan("", isLast: false, showToggle: false));
|
||||
}
|
||||
|
||||
return items;
|
||||
}
|
||||
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
SizedBox(height: getProportionateScreenHeight(9)),
|
||||
Container(
|
||||
margin: EdgeInsets.only(
|
||||
left: getProportionateScreenWidth(16),
|
||||
top: getProportionateScreenHeight(10),
|
||||
),
|
||||
child: Text(
|
||||
'Kursus Ini Sudah Termasuk',
|
||||
style: thirdTextStyle.copyWith(
|
||||
fontWeight: semiBold,
|
||||
fontSize: getProportionateScreenWidth(14),
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(height: 10),
|
||||
KursusIncludeItems(
|
||||
svg: 'assets/icons/clock.svg',
|
||||
text:
|
||||
'${formatDuration(widget.dataDetailCourseModel.totalDuration!)} video pembelajaran'),
|
||||
KursusIncludeItems(
|
||||
svg: 'assets/icons/lesson.svg',
|
||||
text: '${widget.dataDetailCourseModel.totalLesson} pelajaran'),
|
||||
KursusIncludeItems(
|
||||
svg: 'assets/icons/calendar.svg',
|
||||
text: 'Akses full seumur hidup'),
|
||||
Padding(
|
||||
padding: EdgeInsets.only(left: getProportionateScreenWidth(1)),
|
||||
child: KursusIncludeItems(
|
||||
svg: 'assets/icons/phone.svg',
|
||||
text: ' Akses di ponsel dan TV '),
|
||||
),
|
||||
SizedBox(height: 10),
|
||||
],
|
||||
),
|
||||
SizedBox(height: getProportionateScreenHeight(5)),
|
||||
Column(
|
||||
children: [
|
||||
ExpandableNotifier(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Container(
|
||||
margin: EdgeInsets.only(
|
||||
left: getProportionateScreenWidth(10),
|
||||
right: getProportionateScreenWidth(106),
|
||||
bottom: getProportionateScreenWidth(8),
|
||||
),
|
||||
child: Text(
|
||||
'Kemampuan Yang Akan Diraih',
|
||||
style: thirdTextStyle.copyWith(
|
||||
fontWeight: semiBold,
|
||||
fontSize: getProportionateScreenWidth(14),
|
||||
),
|
||||
),
|
||||
),
|
||||
Container(
|
||||
margin: EdgeInsets.only(
|
||||
left: getProportionateScreenWidth(10),
|
||||
right: getProportionateScreenWidth(10),
|
||||
bottom: widget.dataDetailCourseModel.outcome == "[]" ||
|
||||
widget.dataDetailCourseModel.outcome!.isEmpty
|
||||
? getProportionateScreenHeight(20)
|
||||
: getProportionateScreenHeight(0),
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: kemampuanDiraihList(),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
Column(
|
||||
children: [
|
||||
ExpandableNotifier(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Container(
|
||||
margin: EdgeInsets.only(
|
||||
left: getProportionateScreenWidth(10),
|
||||
right: getProportionateScreenWidth(106),
|
||||
bottom: getProportionateScreenWidth(8),
|
||||
),
|
||||
child: Text(
|
||||
'Persyaratan',
|
||||
style: thirdTextStyle.copyWith(
|
||||
fontWeight: semiBold,
|
||||
fontSize: getProportionateScreenWidth(14),
|
||||
),
|
||||
),
|
||||
),
|
||||
Container(
|
||||
margin: EdgeInsets.only(
|
||||
left: getProportionateScreenWidth(10),
|
||||
right: getProportionateScreenWidth(10),
|
||||
bottom: widget.dataDetailCourseModel.requirement ==
|
||||
"[]" ||
|
||||
widget.dataDetailCourseModel.requirement!.isEmpty
|
||||
? getProportionateScreenHeight(20)
|
||||
: getProportionateScreenHeight(0),
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: persyaratanList(),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(height: getProportionateScreenHeight(5)),
|
||||
Column(
|
||||
children: [
|
||||
isExpanded
|
||||
? SizedBox(height: getProportionateScreenHeight(12))
|
||||
: SizedBox.shrink(),
|
||||
Align(
|
||||
alignment: Alignment.topLeft,
|
||||
child: Padding(
|
||||
padding: EdgeInsets.symmetric(
|
||||
horizontal: getProportionateScreenWidth(10)),
|
||||
child: Text(
|
||||
'Deskripsi',
|
||||
style: thirdTextStyle.copyWith(
|
||||
fontWeight: semiBold,
|
||||
fontSize: getProportionateScreenWidth(14),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
Padding(
|
||||
padding: EdgeInsets.symmetric(
|
||||
horizontal: getProportionateScreenWidth(5)),
|
||||
child: Container(
|
||||
height: descriptionProvider.isExpanded
|
||||
? getProportionateScreenHeight(53)
|
||||
: null,
|
||||
child: Html(
|
||||
data: widget.dataDetailCourseModel.description ?? "",
|
||||
style: {
|
||||
"p": Style(
|
||||
fontSize: FontSize(getProportionateScreenWidth(11)),
|
||||
fontWeight: light,
|
||||
margin: Margins.only(top: 0, bottom: 0),
|
||||
fontFamily: 'Poppins',
|
||||
color: Theme.of(context).colorScheme.onBackground),
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
if (hasDescription &&
|
||||
widget.dataDetailCourseModel.description!.length > 120)
|
||||
Container(
|
||||
child: Align(
|
||||
alignment: Alignment.topLeft,
|
||||
child: Padding(
|
||||
padding: EdgeInsets.symmetric(
|
||||
horizontal: getProportionateScreenWidth(10)),
|
||||
child: RichText(
|
||||
text: TextSpan(
|
||||
text: descriptionProvider.isExpanded
|
||||
? ' Lihat Semua'
|
||||
: ' Lihat Sedikit',
|
||||
style: thirdTextStyle.copyWith(
|
||||
fontWeight: semiBold,
|
||||
fontSize: getProportionateScreenWidth(12),
|
||||
color: Theme.of(context).brightness == Brightness.dark
|
||||
? baruTextutih
|
||||
: fourthColor,
|
||||
),
|
||||
recognizer: TapGestureRecognizer()
|
||||
..onTap = () {
|
||||
setState(() {
|
||||
descriptionProvider.isExpanded =
|
||||
!descriptionProvider.isExpanded;
|
||||
});
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
if (hasDescription &&
|
||||
widget.dataDetailCourseModel.description!.length > 120)
|
||||
SizedBox(height: getProportionateScreenHeight(10)),
|
||||
Padding(
|
||||
padding: EdgeInsets.symmetric(
|
||||
horizontal: getProportionateScreenWidth(10)),
|
||||
child: Row(
|
||||
children: [
|
||||
CircleAvatar(
|
||||
radius: 20,
|
||||
backgroundColor: primaryColor,
|
||||
backgroundImage: widget.fotoProfile == null
|
||||
? AssetImage("assets/images/Profile Image.png")
|
||||
: NetworkImage(widget.fotoProfile!) as ImageProvider,
|
||||
),
|
||||
SizedBox(width: getProportionateScreenWidth(10)),
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
widget.instructor ?? '',
|
||||
style: thirdTextStyle.copyWith(
|
||||
fontSize: getProportionateScreenWidth(12),
|
||||
fontWeight: bold,
|
||||
),
|
||||
),
|
||||
Row(
|
||||
children: [
|
||||
Text(
|
||||
'Instructor, ',
|
||||
style: thirdTextStyle.copyWith(
|
||||
fontSize: getProportionateScreenWidth(10),
|
||||
fontWeight: light,
|
||||
),
|
||||
),
|
||||
Text(
|
||||
'${widget.totalStudent ?? '0'} Murid, ',
|
||||
style: thirdTextStyle.copyWith(
|
||||
fontSize: getProportionateScreenWidth(10),
|
||||
fontWeight: light,
|
||||
),
|
||||
),
|
||||
Text(
|
||||
'${widget.totalLesson ?? ''} Kursus',
|
||||
style: thirdTextStyle.copyWith(
|
||||
fontSize: getProportionateScreenWidth(10),
|
||||
fontWeight: light,
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
if (widget.bio == null || widget.bio!.isEmpty)
|
||||
Padding(
|
||||
padding: EdgeInsets.only(
|
||||
left: getProportionateScreenHeight(10),
|
||||
right: getProportionateScreenHeight(10),
|
||||
bottom: getProportionateScreenHeight(10),
|
||||
),
|
||||
child: const SizedBox(height: 5)
|
||||
)
|
||||
else
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Padding(
|
||||
padding: EdgeInsets.only(
|
||||
left: getProportionateScreenWidth(5),
|
||||
right: getProportionateScreenWidth(10),
|
||||
),
|
||||
child: isExpanded2
|
||||
? Html(
|
||||
data: widget.bio,
|
||||
style: {
|
||||
"body": Style(
|
||||
fontSize:
|
||||
FontSize(getProportionateScreenWidth(11)),
|
||||
fontWeight: light,
|
||||
fontFamily: 'Poppins',
|
||||
),
|
||||
},
|
||||
)
|
||||
: Html(
|
||||
data: widget.bio != null && widget.bio!.length > 100
|
||||
? widget.bio!.substring(0, 100)
|
||||
: widget.bio!,
|
||||
style: {
|
||||
"body": Style(
|
||||
fontSize:
|
||||
FontSize(getProportionateScreenWidth(11)),
|
||||
fontWeight: light,
|
||||
fontFamily: 'Poppins',
|
||||
),
|
||||
},
|
||||
),
|
||||
),
|
||||
if (widget.bio!.isNotEmpty && widget.bio!.length > 100)
|
||||
Padding(
|
||||
padding: EdgeInsets.only(
|
||||
left: getProportionateScreenWidth(12),
|
||||
bottom: getProportionateScreenHeight(10),
|
||||
),
|
||||
child: GestureDetector(
|
||||
onTap: () {
|
||||
setState(() {
|
||||
isExpanded2 = !isExpanded2;
|
||||
});
|
||||
},
|
||||
child: Text(
|
||||
isExpanded2 ? 'Lihat Sedikit' : 'Lihat Semua',
|
||||
style: thirdTextStyle.copyWith(
|
||||
fontWeight: semiBold,
|
||||
color:
|
||||
Theme.of(context).brightness == Brightness.dark
|
||||
? baruTextutih
|
||||
: fourthColor,
|
||||
fontSize: getProportionateScreenWidth(12),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
75
lib/screens/detail_course/components/detail_list_ulasan.dart
Normal file
75
lib/screens/detail_course/components/detail_list_ulasan.dart
Normal file
@ -0,0 +1,75 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_rating_bar/flutter_rating_bar.dart';
|
||||
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||
import 'package:initial_folder/helper/validator.dart';
|
||||
|
||||
import '../../../size_config.dart';
|
||||
import '../../../theme.dart';
|
||||
|
||||
class DetailListUlasan extends StatelessWidget {
|
||||
const DetailListUlasan({
|
||||
Key? key,
|
||||
required this.name,
|
||||
required this.starRating,
|
||||
required this.review,
|
||||
required this.date,
|
||||
}) : super(key: key);
|
||||
final String name;
|
||||
final double starRating;
|
||||
final String review;
|
||||
final String date;
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
SizedBox(height: getProportionateScreenHeight(5)),
|
||||
Text(
|
||||
name,
|
||||
style: thirdTextStyle.copyWith(
|
||||
fontWeight: semiBold,
|
||||
fontSize: getProportionateScreenWidth(14),
|
||||
),
|
||||
),
|
||||
SizedBox(height: getProportionateScreenHeight(5)),
|
||||
Row(
|
||||
children: [
|
||||
RatingBarIndicator(
|
||||
itemSize: getProportionateScreenWidth(11),
|
||||
rating: starRating,
|
||||
direction: Axis.horizontal,
|
||||
itemCount: 5,
|
||||
itemPadding: EdgeInsets.symmetric(
|
||||
horizontal: getProportionateScreenWidth(1)),
|
||||
//itemPadding: EdgeInsets.symmetric(horizontal: 4.0),
|
||||
itemBuilder: (context, _) =>
|
||||
FaIcon(FontAwesomeIcons.solidStar, color: thirteenColor),
|
||||
),
|
||||
SizedBox(width: getProportionateScreenWidth(5)),
|
||||
Text(
|
||||
dateFormatUlasan(date),
|
||||
style: thirdTextStyle.copyWith(
|
||||
fontSize: getProportionateScreenWidth(10),
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
Container(
|
||||
child: Text(
|
||||
review,
|
||||
style: thirdTextStyle.copyWith(
|
||||
fontSize: getProportionateScreenWidth(12),
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(height: getProportionateScreenHeight(7)),
|
||||
Divider(
|
||||
color: Color(0xff2D2D2D),
|
||||
thickness: 1,
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
1535
lib/screens/detail_course/components/header.dart
Normal file
1535
lib/screens/detail_course/components/header.dart
Normal file
File diff suppressed because it is too large
Load Diff
604
lib/screens/detail_course/components/header_coupon.dart
Normal file
604
lib/screens/detail_course/components/header_coupon.dart
Normal file
@ -0,0 +1,604 @@
|
||||
import 'package:cached_network_image/cached_network_image.dart';
|
||||
import 'package:connectivity_plus/connectivity_plus.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:initial_folder/base_service.dart';
|
||||
import 'package:initial_folder/helper/user_info.dart';
|
||||
import 'package:initial_folder/models/detail_course_model.dart';
|
||||
import 'package:initial_folder/providers/cart_provider.dart';
|
||||
import 'package:initial_folder/providers/carts_provider.dart';
|
||||
import 'package:initial_folder/providers/detail_course_provider.dart'
|
||||
as detailCourseProv;
|
||||
import 'package:initial_folder/providers/radeem_voucher_provider.dart';
|
||||
import 'package:initial_folder/providers/whislist_provider.dart'
|
||||
as wishlistProvider;
|
||||
import 'package:initial_folder/providers/whislist_provider.dart';
|
||||
import 'package:initial_folder/providers/wishlist_post_provider.dart';
|
||||
import 'package:initial_folder/screens/cart/cart_page.dart';
|
||||
import 'package:initial_folder/screens/checkout/components/field_kupon.dart';
|
||||
import 'package:initial_folder/screens/detail_course/components/murid_and_rating.dart';
|
||||
import 'package:initial_folder/screens/login/login_screen.dart';
|
||||
import 'package:initial_folder/screens/login/login_with_email/login_email_screen.dart';
|
||||
import 'package:initial_folder/screens/splash/splash_screen_login.dart';
|
||||
import 'package:initial_folder/size_config.dart';
|
||||
import 'package:initial_folder/theme.dart';
|
||||
import 'package:initial_folder/widgets/login_regist/default_button.dart';
|
||||
import 'package:initial_folder/widgets/login_regist/loading_button.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:shimmer/shimmer.dart';
|
||||
|
||||
class HeaderCoupon extends StatelessWidget {
|
||||
const HeaderCoupon({
|
||||
Key? key,
|
||||
required this.dataDetailCourseModel,
|
||||
}) : super(key: key);
|
||||
|
||||
final DataDetailCourseModel dataDetailCourseModel;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
WishlistPostProvider wishlistPostProvider =
|
||||
Provider.of<WishlistPostProvider>(context);
|
||||
// var finalRating =
|
||||
// double.parse((course.specificRating![0] / 20).toStringAsFixed(2));
|
||||
|
||||
final kuponController = TextEditingController();
|
||||
bool isLoading = false;
|
||||
|
||||
Future _showDialogNotLogin() {
|
||||
return showDialog(
|
||||
context: context,
|
||||
builder: (context) => AlertDialog(
|
||||
contentPadding: EdgeInsets.fromLTRB(12, 20, 12, 1),
|
||||
content: Text(
|
||||
'Mohon login terlebih dahulu sebelum menambahkan ke wishlist',
|
||||
style: primaryTextStyle.copyWith(
|
||||
fontSize: getProportionateScreenWidth(12), letterSpacing: 1),
|
||||
),
|
||||
actions: [
|
||||
GestureDetector(
|
||||
onTap: () {
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
child: Text('Batal',
|
||||
style: primaryTextStyle.copyWith(
|
||||
fontSize: getProportionateScreenWidth(12),
|
||||
letterSpacing: 1,
|
||||
color: primaryColor)),
|
||||
),
|
||||
SizedBox(
|
||||
width: getProportionateScreenWidth(5),
|
||||
),
|
||||
GestureDetector(
|
||||
onTap: () => Navigator.of(context).pushNamedAndRemoveUntil(
|
||||
LoginEmail.routeName, (Route<dynamic> route) => false),
|
||||
child: Text('Login',
|
||||
style: primaryTextStyle.copyWith(
|
||||
fontSize: getProportionateScreenWidth(12),
|
||||
letterSpacing: 1,
|
||||
color: primaryColor)),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Future _showDialogNotLoginKupon() {
|
||||
return showDialog(
|
||||
context: context,
|
||||
builder: (context) => AlertDialog(
|
||||
contentPadding: EdgeInsets.fromLTRB(12, 20, 12, 1),
|
||||
content: Text(
|
||||
'Mohon login terlebih dahulu sebelum tukar kupon',
|
||||
style: primaryTextStyle.copyWith(
|
||||
fontSize: getProportionateScreenWidth(12), letterSpacing: 1),
|
||||
),
|
||||
actions: [
|
||||
GestureDetector(
|
||||
onTap: () {
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
child: Text('Batal',
|
||||
style: primaryTextStyle.copyWith(
|
||||
fontSize: getProportionateScreenWidth(12),
|
||||
letterSpacing: 1,
|
||||
color: primaryColor)),
|
||||
),
|
||||
SizedBox(
|
||||
width: getProportionateScreenWidth(5),
|
||||
),
|
||||
GestureDetector(
|
||||
onTap: () => Navigator.of(context).pushNamedAndRemoveUntil(
|
||||
LoginEmail.routeName, (Route<dynamic> route) => false),
|
||||
child: Text('Login',
|
||||
style: primaryTextStyle.copyWith(
|
||||
fontSize: getProportionateScreenWidth(12),
|
||||
letterSpacing: 1,
|
||||
color: primaryColor)),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
addWishlist() async {
|
||||
var connectivityResult = await (Connectivity().checkConnectivity());
|
||||
if (connectivityResult == ConnectivityResult.none) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
duration: Duration(seconds: 1),
|
||||
backgroundColor: Colors.red[600],
|
||||
content: Text(
|
||||
'No Internet Connections',
|
||||
textAlign: TextAlign.center,
|
||||
style: primaryTextStyle.copyWith(color: Colors.white),
|
||||
),
|
||||
behavior: SnackBarBehavior.floating,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(5),
|
||||
),
|
||||
),
|
||||
);
|
||||
} else {
|
||||
await wishlistPostProvider
|
||||
.addWishlist(int.parse(dataDetailCourseModel.id));
|
||||
await Provider.of<wishlistProvider.WishlistProvider>(context,
|
||||
listen: false)
|
||||
.getWishlist();
|
||||
await Provider.of<CartProvider>(context, listen: false)
|
||||
.addCart(dataDetailCourseModel.id);
|
||||
await Provider.of<CartsProvider>(context, listen: false).getCarts();
|
||||
}
|
||||
}
|
||||
|
||||
addWishlistNotExist() async {
|
||||
var connectivityResult = await (Connectivity().checkConnectivity());
|
||||
if (connectivityResult == ConnectivityResult.none) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
duration: Duration(seconds: 1),
|
||||
backgroundColor: Colors.red[600],
|
||||
content: Text(
|
||||
'No Internet Connections',
|
||||
textAlign: TextAlign.center,
|
||||
style: primaryTextStyle.copyWith(color: Colors.white),
|
||||
),
|
||||
behavior: SnackBarBehavior.floating,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(5),
|
||||
),
|
||||
),
|
||||
);
|
||||
} else {
|
||||
await wishlistPostProvider
|
||||
.addWishlist(int.parse(dataDetailCourseModel.id));
|
||||
await Provider.of<wishlistProvider.WishlistProvider>(context,
|
||||
listen: false)
|
||||
.getWishlist();
|
||||
}
|
||||
}
|
||||
|
||||
checkUser() async {
|
||||
var token = await UsersInfo().getToken();
|
||||
if (token != null || Condition.loginFirebase == true) {
|
||||
addWishlist();
|
||||
} else {
|
||||
return _showDialogNotLogin();
|
||||
}
|
||||
}
|
||||
|
||||
wishlistExist() async {
|
||||
var token = await UsersInfo().getToken();
|
||||
if (token != null || Condition.loginFirebase == true) {
|
||||
addWishlistNotExist();
|
||||
} else {
|
||||
return _showDialogNotLogin();
|
||||
}
|
||||
}
|
||||
|
||||
Future _showKupon() {
|
||||
return showDialog(
|
||||
context: context,
|
||||
builder: (context) => AlertDialog(
|
||||
contentPadding: EdgeInsets.fromLTRB(3, 1, 6, 30),
|
||||
content: SingleChildScrollView(
|
||||
child: Container(
|
||||
width: getProportionateScreenWidth(400),
|
||||
height: getProportionateScreenHeight(400),
|
||||
child: Column(
|
||||
children: [
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
children: [
|
||||
IconButton(
|
||||
icon: Icon(Icons.cancel_rounded),
|
||||
onPressed: () {
|
||||
Navigator.pop(context);
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
Center(
|
||||
child: Column(
|
||||
children: [
|
||||
SizedBox(
|
||||
height: getProportionateScreenHeight(30),
|
||||
),
|
||||
Image.asset('assets/images/discount_coupon.png'),
|
||||
SizedBox(
|
||||
height: getProportionateScreenHeight(26),
|
||||
),
|
||||
Text(
|
||||
'Tukarkan Voucher',
|
||||
style: thirdTextStyle.copyWith(
|
||||
letterSpacing: 1,
|
||||
fontWeight: semiBold,
|
||||
fontSize: getProportionateScreenWidth(14)),
|
||||
),
|
||||
SizedBox(
|
||||
height: getProportionateScreenHeight(16),
|
||||
),
|
||||
Text(
|
||||
'Masukkan kode kupon untuk klaim\npromo menarik Vocasia',
|
||||
textAlign: TextAlign.center,
|
||||
style: primaryTextStyle.copyWith(
|
||||
fontWeight: reguler,
|
||||
fontSize: getProportionateScreenWidth(12)),
|
||||
),
|
||||
SizedBox(
|
||||
height: getProportionateScreenHeight(30),
|
||||
),
|
||||
Padding(
|
||||
padding: EdgeInsets.symmetric(
|
||||
horizontal: getProportionateScreenWidth(16)),
|
||||
child: FieldKupon(
|
||||
controler: kuponController,
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
height: getProportionateScreenHeight(7),
|
||||
),
|
||||
Padding(
|
||||
padding: EdgeInsets.symmetric(
|
||||
horizontal: getProportionateScreenWidth(15)),
|
||||
child: isLoading
|
||||
? LoadingButton(
|
||||
backgroundButtonColor: primaryColor,
|
||||
textButtonColor: Color(0xff050505),
|
||||
)
|
||||
: DefaultButton(
|
||||
text: 'Tukarkan',
|
||||
press: () async {
|
||||
final voucher = kuponController.text;
|
||||
if (await Provider.of<
|
||||
RadeemVoucherProvider>(context,
|
||||
listen: false)
|
||||
.radeemVoucher(
|
||||
int.parse(dataDetailCourseModel.id),
|
||||
voucher)) {
|
||||
await Provider.of<CartsProvider>(context,
|
||||
listen: false)
|
||||
.getCarts();
|
||||
Navigator.of(context).push(
|
||||
MaterialPageRoute(
|
||||
builder: (context) => CartPage(
|
||||
idcourse: dataDetailCourseModel.id,
|
||||
isiVoucher: voucher,
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
kuponController.clear();
|
||||
|
||||
// _showMessage('Voucher Berhasil Digunakan');
|
||||
} else {
|
||||
ScaffoldMessenger.of(context)
|
||||
.showSnackBar(SnackBar(
|
||||
content: Text(
|
||||
"Kursus sudah di keranjang\natau kupon tidak valid"),
|
||||
duration: Duration(seconds: 4),
|
||||
));
|
||||
}
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget imageCourse() {
|
||||
return Container(
|
||||
margin: EdgeInsets.only(
|
||||
left: getProportionateScreenWidth(2),
|
||||
right: getProportionateScreenWidth(2)),
|
||||
width: double.infinity,
|
||||
height: getProportionateScreenWidth(178),
|
||||
child: Column(
|
||||
children: [
|
||||
Container(
|
||||
width: double.infinity,
|
||||
height: getProportionateScreenWidth(178),
|
||||
child: CachedNetworkImage(
|
||||
imageUrl: dataDetailCourseModel.thumbnail ??
|
||||
'$baseUrl/uploads/courses_thumbnail/course_thumbnail_default_57.jpg',
|
||||
imageBuilder: (context, imageProvider) => Container(
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.vertical(
|
||||
top: Radius.circular(5), bottom: Radius.circular(5)),
|
||||
image: DecorationImage(
|
||||
image: imageProvider,
|
||||
fit: BoxFit.fill,
|
||||
),
|
||||
),
|
||||
),
|
||||
placeholder: (context, url) => Shimmer(
|
||||
child: Container(
|
||||
color: thirdColor,
|
||||
),
|
||||
gradient: LinearGradient(
|
||||
stops: [0.4, 0.5, 0.6],
|
||||
colors: [secondaryColor, thirdColor, secondaryColor])),
|
||||
errorWidget: (context, url, error) => Icon(Icons.error),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget buttonKuponWishlist() {
|
||||
return Row(
|
||||
children: [
|
||||
// Consumer<detailCourseProv.DetailCourseProvider>(
|
||||
// builder: (context, state, _) {
|
||||
// if (state.state == detailCourseProv.ResultState.HasData) {
|
||||
// var detailCourse = state.result!.data[0][0];
|
||||
// if (detailCourse.isFreeCourse == '1') {
|
||||
// return SizedBox(width: 60);
|
||||
// } else {
|
||||
// return Container(
|
||||
// margin:
|
||||
// EdgeInsets.only(left: getProportionateScreenWidth(2)),
|
||||
// child: ElevatedButton(
|
||||
// style: ElevatedButton.styleFrom(
|
||||
// primary: Color(0xFF2D2D2D),
|
||||
// shape: RoundedRectangleBorder(
|
||||
// borderRadius: BorderRadius.circular(6))),
|
||||
// onPressed: () {
|
||||
// (Condition.loginEmail || Condition.loginFirebase)
|
||||
// ? _showKupon()
|
||||
// : _showDialogNotLoginKupon();
|
||||
// },
|
||||
// child: Padding(
|
||||
// padding: EdgeInsets.symmetric(
|
||||
// horizontal: getProportionateScreenWidth(3),
|
||||
// vertical: getProportionateScreenHeight(6)),
|
||||
// child: Row(
|
||||
// crossAxisAlignment: CrossAxisAlignment.center,
|
||||
// mainAxisAlignment: MainAxisAlignment.start,
|
||||
// children: [
|
||||
// Image.asset(
|
||||
// "assets/images/home_coupon.png",
|
||||
// color: Colors.white,
|
||||
// ),
|
||||
// SizedBox(
|
||||
// width: getProportionateScreenWidth(10),
|
||||
// ),
|
||||
// Text(
|
||||
// 'Tukar Kupon',
|
||||
// textAlign: TextAlign.start,
|
||||
// style: thirdTextStyle.copyWith(
|
||||
// color: Colors.white,
|
||||
// fontSize: getProportionateScreenWidth(12),
|
||||
// fontWeight: reguler),
|
||||
// ),
|
||||
// ],
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
// );
|
||||
// }
|
||||
// } else {
|
||||
// return Container();
|
||||
// }
|
||||
// },
|
||||
// ),
|
||||
|
||||
SizedBox(width: 60),
|
||||
SizedBox(
|
||||
width: getProportionateScreenWidth(16),
|
||||
),
|
||||
// Consumer<WishlistProvider>(builder: (context, state, _) {
|
||||
// return Text(state.data.contains(dataDetailCourseModel.id)
|
||||
// ? 'ada di wishlist'
|
||||
// : 'ga ada');
|
||||
// }),
|
||||
Container(
|
||||
width: getProportionateScreenWidth(173),
|
||||
height: getProportionateScreenHeight(28),
|
||||
padding: EdgeInsets.symmetric(
|
||||
horizontal: getProportionateScreenWidth(12),
|
||||
vertical: getProportionateScreenHeight(6)),
|
||||
// color: Color(0xFF2D2D2D),
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(6),
|
||||
color: Color(0xFF2D2D2D)),
|
||||
child: GestureDetector(
|
||||
onTap: Provider.of<CartsProvider>(context)
|
||||
.data
|
||||
.contains(dataDetailCourseModel.id)
|
||||
? checkUser
|
||||
: wishlistExist,
|
||||
child: !Condition.loginEmail && !Condition.loginFirebase
|
||||
? Row(
|
||||
children: [
|
||||
Icon(
|
||||
Icons.favorite_border,
|
||||
color: Colors.white,
|
||||
size: getProportionateScreenWidth(18),
|
||||
),
|
||||
SizedBox(
|
||||
width: getProportionateScreenWidth(6),
|
||||
),
|
||||
Text(
|
||||
'Tambah ke Wishlist',
|
||||
style: primaryTextStyle.copyWith(
|
||||
fontSize: getProportionateScreenWidth(12),
|
||||
letterSpacing: 0.2),
|
||||
),
|
||||
],
|
||||
)
|
||||
: Row(
|
||||
children: [
|
||||
Consumer<wishlistProvider.WishlistProvider>(
|
||||
builder: (context, state, _) {
|
||||
if (state.state ==
|
||||
wishlistProvider.ResultState.Loading) {
|
||||
return Center(
|
||||
child: CircularProgressIndicator(
|
||||
color: secondaryColor,
|
||||
strokeWidth: 1,
|
||||
),
|
||||
);
|
||||
}
|
||||
return Icon(
|
||||
state.data.contains(dataDetailCourseModel.id)
|
||||
? Icons.favorite_outlined
|
||||
: Icons.favorite_border,
|
||||
color:
|
||||
state.data.contains(dataDetailCourseModel.id)
|
||||
? Color(0xffCD2228)
|
||||
: Colors.white,
|
||||
size: getProportionateScreenWidth(18),
|
||||
);
|
||||
},
|
||||
),
|
||||
SizedBox(
|
||||
width: getProportionateScreenWidth(6),
|
||||
),
|
||||
Consumer<wishlistProvider.WishlistProvider>(
|
||||
builder: (contex, state, _) {
|
||||
if (state.state ==
|
||||
wishlistProvider.ResultState.Loading) {
|
||||
return Text('');
|
||||
}
|
||||
return Text(
|
||||
state.data.contains(dataDetailCourseModel.id)
|
||||
? 'Sudah dalam wihslist'
|
||||
: 'Tambah ke Wishlist',
|
||||
style: primaryTextStyle.copyWith(
|
||||
fontSize: getProportionateScreenWidth(12),
|
||||
letterSpacing: 0.2),
|
||||
);
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
return Container(
|
||||
margin: EdgeInsets.only(
|
||||
left: getProportionateScreenWidth(15),
|
||||
right: getProportionateScreenWidth(15)),
|
||||
width: SizeConfig.screenWidth,
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Container(
|
||||
width: getProportionateScreenWidth(232),
|
||||
child: Text(dataDetailCourseModel.title ?? ' ',
|
||||
style: primaryTextStyle.copyWith(
|
||||
letterSpacing: 0.1,
|
||||
fontSize: getProportionateScreenHeight(14)),
|
||||
maxLines: 3,
|
||||
overflow: TextOverflow.ellipsis),
|
||||
),
|
||||
SizedBox(
|
||||
height: getProportionateScreenHeight(13),
|
||||
),
|
||||
// Row(
|
||||
// // crossAxisAlignment: CrossAxisAlignment.start,
|
||||
// children: [
|
||||
// RatingBarIndicator(
|
||||
// itemSize: getProportionateScreenWidth(10),
|
||||
// rating: double.parse(
|
||||
// dataDetailCourseModel.rating[0].avgRating != null
|
||||
// ? '${dataDetailCourseModel.rating[0].avgRating}'
|
||||
// : '5.0'),
|
||||
// direction: Axis.horizontal,
|
||||
// itemCount: 5,
|
||||
// //itemPadding: EdgeInsets.symmetric(horizontal: 4.0),
|
||||
// itemBuilder: (context, _) =>
|
||||
// FaIcon(FontAwesomeIcons.solidStar, color: primaryColor)),
|
||||
// SizedBox(
|
||||
// width: getProportionateScreenWidth(4),
|
||||
// ),
|
||||
// Text(
|
||||
// double.parse(dataDetailCourseModel.rating[0].avgRating != null
|
||||
// ? '${dataDetailCourseModel.rating[0].avgRating}'
|
||||
// : '5.0')
|
||||
// .toString(),
|
||||
// style: primaryTextStyle.copyWith(
|
||||
// fontSize: getProportionateScreenWidth(10),
|
||||
// color: secondaryColor,
|
||||
// fontWeight: reguler),
|
||||
// ),
|
||||
// SizedBox(
|
||||
// width: getProportionateScreenWidth(4),
|
||||
// ),
|
||||
// Text(
|
||||
// // '(${course.numberOfRatings.toString()})',
|
||||
// '(${dataDetailCourseModel.rating[0].totalReview})',
|
||||
// style: primaryTextStyle.copyWith(
|
||||
// fontSize: getProportionateScreenWidth(10),
|
||||
// color: secondaryColor,
|
||||
// fontWeight: reguler),
|
||||
// ),
|
||||
// ],
|
||||
// ),
|
||||
SizedBox(
|
||||
height: getProportionateScreenHeight(9),
|
||||
),
|
||||
MuridAndRating(
|
||||
dataDetailCourseModel: dataDetailCourseModel,
|
||||
),
|
||||
SizedBox(
|
||||
height: getProportionateScreenHeight(16),
|
||||
),
|
||||
imageCourse(),
|
||||
SizedBox(
|
||||
height: getProportionateScreenHeight(11),
|
||||
),
|
||||
// Consumer<detailCourseProv.DetailCourseProvider>(
|
||||
// builder: (context, state, _) {
|
||||
// if (state.state == detailCourseProv.ResultState.HasData) {
|
||||
// var detailCourse = state.result!.data[0][0];
|
||||
// if (detailCourse.isMine == 1) {
|
||||
// return Container();
|
||||
// } else {
|
||||
// return buttonKuponWishlist();
|
||||
// }
|
||||
// } else {
|
||||
// return Container();
|
||||
// }
|
||||
// },
|
||||
// ),
|
||||
buttonKuponWishlist(),
|
||||
SizedBox(
|
||||
height: getProportionateScreenHeight(11),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
1
lib/screens/detail_course/components/image_course.dart
Normal file
1
lib/screens/detail_course/components/image_course.dart
Normal file
@ -0,0 +1 @@
|
||||
|
@ -0,0 +1,30 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import '../../../size_config.dart';
|
||||
import '../../../theme.dart';
|
||||
|
||||
class InstructorStudentsCourses extends StatelessWidget {
|
||||
const InstructorStudentsCourses(
|
||||
{Key? key, required this.course, required this.murid})
|
||||
: super(key: key);
|
||||
final String murid;
|
||||
final String course;
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Row(
|
||||
children: [
|
||||
Text(
|
||||
' $murid Murid',
|
||||
style: primaryTextStyle.copyWith(
|
||||
fontSize: getProportionateScreenWidth(10), letterSpacing: 0.5),
|
||||
),
|
||||
SizedBox(width: getProportionateScreenWidth(10)),
|
||||
Text(
|
||||
' $course Kursus',
|
||||
style: primaryTextStyle.copyWith(
|
||||
fontSize: getProportionateScreenWidth(10), letterSpacing: 0.5),
|
||||
)
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
229
lib/screens/detail_course/components/instruktur.dart
Normal file
229
lib/screens/detail_course/components/instruktur.dart
Normal file
@ -0,0 +1,229 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_html/flutter_html.dart';
|
||||
import 'package:flutter_rating_bar/flutter_rating_bar.dart';
|
||||
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||
import 'package:initial_folder/size_config.dart';
|
||||
import 'package:initial_folder/theme.dart';
|
||||
|
||||
class Instruktur extends StatefulWidget {
|
||||
const Instruktur({
|
||||
Key? key,
|
||||
required this.id,
|
||||
this.instructor,
|
||||
this.bio,
|
||||
this.rating,
|
||||
this.review,
|
||||
this.totalStudent,
|
||||
this.totalLesson,
|
||||
this.video = false,
|
||||
this.fotoProfile,
|
||||
this.headline,
|
||||
}) : super(key: key);
|
||||
final String id;
|
||||
final String? instructor;
|
||||
final String? bio;
|
||||
final String? rating;
|
||||
final String? review;
|
||||
final String? fotoProfile;
|
||||
final String? totalLesson;
|
||||
final String? totalStudent;
|
||||
final String? headline;
|
||||
final bool video;
|
||||
|
||||
@override
|
||||
State<Instruktur> createState() => _InstrukturState();
|
||||
}
|
||||
|
||||
class _InstrukturState extends State<Instruktur> {
|
||||
bool isExpanded = false;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
margin: EdgeInsets.symmetric(horizontal: 10, vertical: 10),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
'Instruktur Kursus',
|
||||
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 16),
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
Container(
|
||||
decoration: BoxDecoration(
|
||||
color: const Color(0xFF212121),
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
const SizedBox(height: 16),
|
||||
Container(
|
||||
margin: EdgeInsets.only(left: 10),
|
||||
child: CircleAvatar(
|
||||
radius: 40,
|
||||
backgroundColor: Colors.amber,
|
||||
backgroundImage: widget.fotoProfile == null
|
||||
? AssetImage("assets/images/Profile Image.png")
|
||||
: NetworkImage(widget.fotoProfile!)
|
||||
as ImageProvider,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
Container(
|
||||
margin: EdgeInsets.only(left: 10),
|
||||
child: Text(
|
||||
widget.instructor ?? '',
|
||||
style: TextStyle(fontSize: 15),
|
||||
),
|
||||
),
|
||||
SizedBox(height: 2),
|
||||
widget.headline != null
|
||||
? Container(
|
||||
margin: EdgeInsets.only(left: 10),
|
||||
child: Text(
|
||||
widget.headline!,
|
||||
style: TextStyle(fontSize: 13),
|
||||
),
|
||||
)
|
||||
: const SizedBox(),
|
||||
SizedBox(height: 10),
|
||||
Container(
|
||||
margin: EdgeInsets.only(left: 10),
|
||||
child: Row(
|
||||
children: [
|
||||
RatingBarIndicator(
|
||||
itemSize: 11,
|
||||
rating: double.parse(widget.rating ?? '0'),
|
||||
direction: Axis.horizontal,
|
||||
itemCount: 5,
|
||||
itemBuilder: (context, _) => const FaIcon(
|
||||
FontAwesomeIcons.solidStar,
|
||||
color: Colors.amber,
|
||||
),
|
||||
),
|
||||
SizedBox(width: 4),
|
||||
Text(
|
||||
double.parse(widget.rating ?? '0').toString(),
|
||||
style: TextStyle(fontSize: 10),
|
||||
),
|
||||
SizedBox(width: 4),
|
||||
Text(
|
||||
'(${widget.review ?? '0'})',
|
||||
style: TextStyle(fontSize: 10),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Container(
|
||||
height: 40,
|
||||
margin: EdgeInsets.only(left: 10, top: 1),
|
||||
child: Row(
|
||||
children: [
|
||||
Text(
|
||||
'${widget.totalStudent ?? '0'} Murid',
|
||||
style: primaryTextStyle.copyWith(
|
||||
color: secondaryColor,
|
||||
fontSize: getProportionateScreenWidth(10),
|
||||
letterSpacing: 0.5),
|
||||
),
|
||||
SizedBox(width: 10),
|
||||
Text(
|
||||
'${widget.totalLesson ?? ''} Pelajaran',
|
||||
style: primaryTextStyle.copyWith(
|
||||
color: secondaryColor,
|
||||
fontSize: getProportionateScreenWidth(10),
|
||||
letterSpacing: 0.5),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
if (widget.bio == null || widget.bio!.isEmpty)
|
||||
Padding(
|
||||
padding: EdgeInsets.only(
|
||||
left: getProportionateScreenHeight(10),
|
||||
right: getProportionateScreenHeight(10),
|
||||
bottom: getProportionateScreenHeight(10)),
|
||||
child: Text(
|
||||
'*Instruktur belum mencantumkan profil*',
|
||||
style: TextStyle(
|
||||
fontSize: getProportionateScreenWidth(10),
|
||||
fontWeight: reguler,
|
||||
fontFamily: 'Noto Sans',
|
||||
color: secondaryColor,
|
||||
),
|
||||
),
|
||||
)
|
||||
else
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Padding(
|
||||
padding: EdgeInsets.only(
|
||||
left: getProportionateScreenHeight(5),
|
||||
right: getProportionateScreenHeight(10)),
|
||||
child: isExpanded
|
||||
? Html(
|
||||
data: widget.bio,
|
||||
style: {
|
||||
"body": Style(
|
||||
fontSize: FontSize(12),
|
||||
fontWeight: reguler,
|
||||
fontFamily: 'Noto Sans',
|
||||
color: secondaryColor),
|
||||
},
|
||||
)
|
||||
: Html(
|
||||
data: widget.bio != null &&
|
||||
widget.bio!.length > 200
|
||||
? widget.bio!.substring(0, 200)
|
||||
: widget.bio!,
|
||||
style: {
|
||||
"body": Style(
|
||||
fontSize: FontSize(12),
|
||||
fontWeight: reguler,
|
||||
fontFamily: 'Noto Sans',
|
||||
color: secondaryColor),
|
||||
},
|
||||
),
|
||||
),
|
||||
if (widget.bio!.isNotEmpty &&
|
||||
(widget.bio!.length > 70 ||
|
||||
widget.bio!.length > 200))
|
||||
Padding(
|
||||
padding: EdgeInsets.only(
|
||||
left: getProportionateScreenHeight(7)),
|
||||
child: TextButton(
|
||||
onPressed: () {
|
||||
setState(() {
|
||||
isExpanded = !isExpanded;
|
||||
});
|
||||
},
|
||||
child: Text(
|
||||
isExpanded
|
||||
? 'Tampilkan Lebih Sedikit'
|
||||
: 'Tampilkan Lebih Banyak',
|
||||
style: primaryTextStyle.copyWith(
|
||||
fontWeight: semiBold,
|
||||
color: primaryColor,
|
||||
fontSize: getProportionateScreenWidth(12),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 30)
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
@ -0,0 +1,40 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:initial_folder/size_config.dart';
|
||||
import 'package:initial_folder/theme.dart';
|
||||
|
||||
class KemampuainDiraihList extends StatelessWidget {
|
||||
const KemampuainDiraihList({
|
||||
Key? key,
|
||||
required this.title,
|
||||
}) : super(key: key);
|
||||
final String title;
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
margin: EdgeInsets.only(bottom: 6),
|
||||
child: Row(
|
||||
children: [
|
||||
Icon(Icons.check,
|
||||
size: getProportionateScreenHeight(13), color: thirdColor),
|
||||
SizedBox(
|
||||
width: 10,
|
||||
),
|
||||
Expanded(
|
||||
child: Align(
|
||||
alignment: Alignment.topLeft,
|
||||
// TODO : saat teks menjadi 2 baris menjadi tidak sejajar perlu dirapihkan
|
||||
child: Text(
|
||||
// TODO : MAX 75 Chareacters
|
||||
title,
|
||||
style: primaryTextStyle.copyWith(
|
||||
color: secondaryColor,
|
||||
fontSize: getProportionateScreenWidth(12),
|
||||
letterSpacing: 0.5),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
@ -0,0 +1,45 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
import 'package:initial_folder/size_config.dart';
|
||||
import 'package:initial_folder/theme.dart';
|
||||
|
||||
class KursusIncludeItems extends StatelessWidget {
|
||||
const KursusIncludeItems({Key? key, this.svg, required this.text})
|
||||
: super(key: key);
|
||||
|
||||
final String? svg;
|
||||
final String text;
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
margin: EdgeInsets.only(left: getProportionateScreenWidth(16)),
|
||||
child: Column(
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
SvgPicture.asset(
|
||||
svg!,
|
||||
width: getProportionateScreenWidth(13),
|
||||
height: getProportionateScreenHeight(13),
|
||||
color: Theme.of(context).brightness == Brightness.dark
|
||||
? baruTextutih
|
||||
: fourthColor,
|
||||
),
|
||||
SizedBox(width: getProportionateScreenWidth(9)),
|
||||
Expanded(
|
||||
child: Text(
|
||||
text,
|
||||
style: thirdTextStyle.copyWith(
|
||||
fontSize: getProportionateScreenWidth(12),
|
||||
fontWeight: light,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(height: getProportionateScreenHeight(6)),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
262
lib/screens/detail_course/components/murid_and_rating.dart
Normal file
262
lib/screens/detail_course/components/murid_and_rating.dart
Normal file
@ -0,0 +1,262 @@
|
||||
import 'package:connectivity_plus/connectivity_plus.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_rating_bar/flutter_rating_bar.dart';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
import 'package:initial_folder/helper/user_info.dart';
|
||||
import 'package:initial_folder/models/detail_course_model.dart';
|
||||
import 'package:initial_folder/providers/cart_provider.dart';
|
||||
import 'package:initial_folder/providers/carts_provider.dart';
|
||||
import 'package:initial_folder/providers/posting_review_provider.dart';
|
||||
import 'package:initial_folder/providers/whislist_provider.dart'
|
||||
as wishlistProvider;
|
||||
import 'package:initial_folder/providers/wishlist_post_provider.dart';
|
||||
import 'package:initial_folder/screens/login/login_screen.dart';
|
||||
import 'package:initial_folder/screens/login/login_with_email/login_email_screen.dart';
|
||||
import 'package:initial_folder/screens/splash/splash_screen_login.dart';
|
||||
import 'package:initial_folder/size_config.dart';
|
||||
import 'package:initial_folder/theme.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||
|
||||
class MuridAndRating extends StatelessWidget {
|
||||
const MuridAndRating({Key? key, required this.dataDetailCourseModel})
|
||||
: super(key: key);
|
||||
final DataDetailCourseModel dataDetailCourseModel;
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
WishlistPostProvider wishlistPostProvider =
|
||||
Provider.of<WishlistPostProvider>(context);
|
||||
Future _showDialogNotLogin() {
|
||||
return showDialog(
|
||||
context: context,
|
||||
builder: (context) => AlertDialog(
|
||||
contentPadding: EdgeInsets.fromLTRB(12, 20, 12, 1),
|
||||
content: Text(
|
||||
'Mohon login terlebih dahulu sebelum menambahkan ke wishlist',
|
||||
style: primaryTextStyle.copyWith(
|
||||
fontSize: getProportionateScreenWidth(12), letterSpacing: 1),
|
||||
),
|
||||
actions: [
|
||||
GestureDetector(
|
||||
onTap: () {
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
child: Text('Batal',
|
||||
style: primaryTextStyle.copyWith(
|
||||
fontSize: getProportionateScreenWidth(12),
|
||||
letterSpacing: 1,
|
||||
color: primaryColor)),
|
||||
),
|
||||
SizedBox(
|
||||
width: getProportionateScreenWidth(5),
|
||||
),
|
||||
GestureDetector(
|
||||
onTap: () => Navigator.of(context).pushNamedAndRemoveUntil(
|
||||
LoginEmail.routeName, (Route<dynamic> route) => false),
|
||||
child: Text('Login',
|
||||
style: primaryTextStyle.copyWith(
|
||||
fontSize: getProportionateScreenWidth(12),
|
||||
letterSpacing: 1,
|
||||
color: primaryColor)),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
// Future _showMessage() {
|
||||
// return showDialog(
|
||||
// context: context,
|
||||
// builder: (context) => AlertDialog(
|
||||
// contentPadding: EdgeInsets.fromLTRB(22, 30, 22, 30),
|
||||
// content: Text(
|
||||
// 'Berhasil menambahkan kursus ke wishlist',
|
||||
// textAlign: TextAlign.center,
|
||||
// style: primaryTextStyle.copyWith(
|
||||
// fontSize: getProportionateScreenWidth(12), letterSpacing: 1),
|
||||
// ),
|
||||
// ),
|
||||
// );
|
||||
// }
|
||||
|
||||
addWishlist() async {
|
||||
var connectivityResult = await (Connectivity().checkConnectivity());
|
||||
if (connectivityResult == ConnectivityResult.none) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
duration: Duration(seconds: 1),
|
||||
backgroundColor: Colors.red[600],
|
||||
content: Text(
|
||||
'No Internet Connections',
|
||||
textAlign: TextAlign.center,
|
||||
style: primaryTextStyle.copyWith(color: Colors.white),
|
||||
),
|
||||
behavior: SnackBarBehavior.floating,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(5),
|
||||
),
|
||||
),
|
||||
);
|
||||
} else {
|
||||
await wishlistPostProvider
|
||||
.addWishlist(int.parse(dataDetailCourseModel.id));
|
||||
await Provider.of<wishlistProvider.WishlistProvider>(context,
|
||||
listen: false)
|
||||
.getWishlist();
|
||||
await Provider.of<CartProvider>(context, listen: false)
|
||||
.addCart(dataDetailCourseModel.id);
|
||||
await Provider.of<CartsProvider>(context, listen: false).getCarts();
|
||||
}
|
||||
}
|
||||
|
||||
addWishlistNotExist() async {
|
||||
var connectivityResult = await (Connectivity().checkConnectivity());
|
||||
if (connectivityResult == ConnectivityResult.none) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
duration: Duration(seconds: 1),
|
||||
backgroundColor: Colors.red[600],
|
||||
content: Text(
|
||||
'No Internet Connections',
|
||||
textAlign: TextAlign.center,
|
||||
style: primaryTextStyle.copyWith(color: Colors.white),
|
||||
),
|
||||
behavior: SnackBarBehavior.floating,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(5),
|
||||
),
|
||||
),
|
||||
);
|
||||
} else {
|
||||
await wishlistPostProvider
|
||||
.addWishlist(int.parse(dataDetailCourseModel.id));
|
||||
await Provider.of<wishlistProvider.WishlistProvider>(context,
|
||||
listen: false)
|
||||
.getWishlist();
|
||||
}
|
||||
}
|
||||
|
||||
// deleteWishlist() async {
|
||||
// var connectivityResult = await (Connectivity().checkConnectivity());
|
||||
// if (connectivityResult == ConnectivityResult.none) {
|
||||
// ScaffoldMessenger.of(context).showSnackBar(
|
||||
// SnackBar(
|
||||
// duration: Duration(seconds: 1),
|
||||
// backgroundColor: Colors.red[600],
|
||||
// content: Text(
|
||||
// 'No Internet Connections',
|
||||
// textAlign: TextAlign.center,
|
||||
// style: primaryTextStyle.copyWith(color: Colors.white),
|
||||
// ),
|
||||
// behavior: SnackBarBehavior.floating,
|
||||
// shape: RoundedRectangleBorder(
|
||||
// borderRadius: BorderRadius.circular(5),
|
||||
// ),
|
||||
// ),
|
||||
// );
|
||||
// } else {
|
||||
// await wishlistPostProvider
|
||||
// .addWishlist(int.parse(dataDetailCourseModel.id));
|
||||
// }
|
||||
// }
|
||||
|
||||
checkUser() async {
|
||||
var token = await UsersInfo().getToken();
|
||||
if (token != null || Condition.loginFirebase == true) {
|
||||
addWishlist();
|
||||
} else {
|
||||
return _showDialogNotLogin();
|
||||
}
|
||||
}
|
||||
|
||||
wishlistExist() async {
|
||||
var token = await UsersInfo().getToken();
|
||||
if (token != null || Condition.loginFirebase == true) {
|
||||
addWishlistNotExist();
|
||||
} else {
|
||||
return _showDialogNotLogin();
|
||||
}
|
||||
}
|
||||
|
||||
return Padding(
|
||||
padding:
|
||||
EdgeInsets.symmetric(horizontal: getProportionateScreenWidth(15)),
|
||||
child: Container(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
SvgPicture.asset(
|
||||
"assets/icons/student.svg",
|
||||
width: getProportionateScreenWidth(17),
|
||||
height: getProportionateScreenHeight(17),
|
||||
color: Theme.of(context).brightness == Brightness.dark
|
||||
? baruTextutih
|
||||
: fourthColor,
|
||||
),
|
||||
SizedBox(width: getProportionateScreenWidth(4)),
|
||||
Text(
|
||||
' ${dataDetailCourseModel.totalStudents != null ? dataDetailCourseModel.totalStudents : "0"} Murid',
|
||||
style: thirdTextStyle.copyWith(
|
||||
fontSize: getProportionateScreenWidth(10),
|
||||
fontWeight: medium,
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
SizedBox(height: getProportionateScreenHeight(8)),
|
||||
Row(
|
||||
children: [
|
||||
dataDetailCourseModel.rating[0].avgRating != null &&
|
||||
dataDetailCourseModel.rating[0].avgRating != 0
|
||||
? Text(
|
||||
double.parse('${dataDetailCourseModel.rating[0].avgRating}')
|
||||
.toString(),
|
||||
style: thirdTextStyle.copyWith(
|
||||
fontSize: getProportionateScreenWidth(11),
|
||||
fontWeight: medium,
|
||||
),
|
||||
)
|
||||
: SizedBox.shrink(),
|
||||
|
||||
SizedBox(width: getProportionateScreenWidth(4)),
|
||||
RatingBarIndicator(
|
||||
itemPadding: EdgeInsets.symmetric(
|
||||
horizontal: getProportionateScreenWidth(2)),
|
||||
itemSize: getProportionateScreenWidth(13),
|
||||
rating: dataDetailCourseModel.rating[0].avgRating != null &&
|
||||
dataDetailCourseModel.rating[0].avgRating != 0
|
||||
? double.parse('${dataDetailCourseModel.rating[0].avgRating}')
|
||||
: 5.0,
|
||||
direction: Axis.horizontal,
|
||||
itemCount: 5,
|
||||
itemBuilder: (context, _) => FaIcon(
|
||||
FontAwesomeIcons.solidStar,
|
||||
color: thirteenColor,
|
||||
),
|
||||
),
|
||||
if (dataDetailCourseModel.rating[0].totalReview != null &&
|
||||
int.tryParse('${dataDetailCourseModel.rating[0].totalReview}') != null &&
|
||||
int.parse('${dataDetailCourseModel.rating[0].totalReview}') > 0)
|
||||
...[
|
||||
SizedBox(width: getProportionateScreenWidth(4)),
|
||||
Text(
|
||||
'(${dataDetailCourseModel.rating[0].totalReview} Reviews)',
|
||||
style: thirdTextStyle.copyWith(
|
||||
fontSize: getProportionateScreenWidth(10),
|
||||
fontWeight: medium,
|
||||
),
|
||||
),
|
||||
]
|
||||
else
|
||||
SizedBox.shrink(),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
283
lib/screens/detail_course/components/murid_and_whislist.dart
Normal file
283
lib/screens/detail_course/components/murid_and_whislist.dart
Normal file
@ -0,0 +1,283 @@
|
||||
import 'package:connectivity_plus/connectivity_plus.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:initial_folder/helper/user_info.dart';
|
||||
import 'package:initial_folder/models/detail_course_model.dart';
|
||||
import 'package:initial_folder/providers/cart_provider.dart';
|
||||
import 'package:initial_folder/providers/carts_provider.dart';
|
||||
import 'package:initial_folder/providers/posting_review_provider.dart';
|
||||
import 'package:initial_folder/providers/whislist_provider.dart'
|
||||
as wishlistProvider;
|
||||
import 'package:initial_folder/providers/wishlist_post_provider.dart';
|
||||
import 'package:initial_folder/screens/login/login_screen.dart';
|
||||
import 'package:initial_folder/screens/login/login_with_email/login_email_screen.dart';
|
||||
import 'package:initial_folder/screens/splash/splash_screen_login.dart';
|
||||
import 'package:initial_folder/size_config.dart';
|
||||
import 'package:initial_folder/theme.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
class MuridAndWhislist extends StatelessWidget {
|
||||
const MuridAndWhislist({Key? key, required this.dataDetailCourseModel})
|
||||
: super(key: key);
|
||||
final DataDetailCourseModel dataDetailCourseModel;
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
WishlistPostProvider wishlistPostProvider =
|
||||
Provider.of<WishlistPostProvider>(context);
|
||||
Future _showDialogNotLogin() {
|
||||
return showDialog(
|
||||
context: context,
|
||||
builder: (context) => AlertDialog(
|
||||
contentPadding: EdgeInsets.fromLTRB(12, 20, 12, 1),
|
||||
content: Text(
|
||||
'Mohon login terlebih dahulu sebelum menambahkan ke wishlist',
|
||||
style: primaryTextStyle.copyWith(
|
||||
fontSize: getProportionateScreenWidth(12), letterSpacing: 1),
|
||||
),
|
||||
actions: [
|
||||
GestureDetector(
|
||||
onTap: () {
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
child: Text('Batal',
|
||||
style: primaryTextStyle.copyWith(
|
||||
fontSize: getProportionateScreenWidth(12),
|
||||
letterSpacing: 1,
|
||||
color: primaryColor)),
|
||||
),
|
||||
SizedBox(
|
||||
width: getProportionateScreenWidth(5),
|
||||
),
|
||||
GestureDetector(
|
||||
onTap: () => Navigator.of(context).pushNamedAndRemoveUntil(
|
||||
LoginEmail.routeName, (Route<dynamic> route) => false),
|
||||
child: Text('Login',
|
||||
style: primaryTextStyle.copyWith(
|
||||
fontSize: getProportionateScreenWidth(12),
|
||||
letterSpacing: 1,
|
||||
color: primaryColor)),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
// Future _showMessage() {
|
||||
// return showDialog(
|
||||
// context: context,
|
||||
// builder: (context) => AlertDialog(
|
||||
// contentPadding: EdgeInsets.fromLTRB(22, 30, 22, 30),
|
||||
// content: Text(
|
||||
// 'Berhasil menambahkan kursus ke wishlist',
|
||||
// textAlign: TextAlign.center,
|
||||
// style: primaryTextStyle.copyWith(
|
||||
// fontSize: getProportionateScreenWidth(12), letterSpacing: 1),
|
||||
// ),
|
||||
// ),
|
||||
// );
|
||||
// }
|
||||
|
||||
addWishlist() async {
|
||||
var connectivityResult = await (Connectivity().checkConnectivity());
|
||||
if (connectivityResult == ConnectivityResult.none) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
duration: Duration(seconds: 1),
|
||||
backgroundColor: Colors.red[600],
|
||||
content: Text(
|
||||
'No Internet Connections',
|
||||
textAlign: TextAlign.center,
|
||||
style: primaryTextStyle.copyWith(color: Colors.white),
|
||||
),
|
||||
behavior: SnackBarBehavior.floating,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(5),
|
||||
),
|
||||
),
|
||||
);
|
||||
} else {
|
||||
await wishlistPostProvider
|
||||
.addWishlist(int.parse(dataDetailCourseModel.id));
|
||||
await Provider.of<wishlistProvider.WishlistProvider>(context,
|
||||
listen: false)
|
||||
.getWishlist();
|
||||
await Provider.of<CartProvider>(context, listen: false)
|
||||
.addCart(dataDetailCourseModel.id);
|
||||
await Provider.of<CartsProvider>(context, listen: false).getCarts();
|
||||
}
|
||||
}
|
||||
|
||||
addWishlistNotExist() async {
|
||||
var connectivityResult = await (Connectivity().checkConnectivity());
|
||||
if (connectivityResult == ConnectivityResult.none) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
duration: Duration(seconds: 1),
|
||||
backgroundColor: Colors.red[600],
|
||||
content: Text(
|
||||
'No Internet Connections',
|
||||
textAlign: TextAlign.center,
|
||||
style: primaryTextStyle.copyWith(color: Colors.white),
|
||||
),
|
||||
behavior: SnackBarBehavior.floating,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(5),
|
||||
),
|
||||
),
|
||||
);
|
||||
} else {
|
||||
await wishlistPostProvider
|
||||
.addWishlist(int.parse(dataDetailCourseModel.id));
|
||||
await Provider.of<wishlistProvider.WishlistProvider>(context,
|
||||
listen: false)
|
||||
.getWishlist();
|
||||
}
|
||||
}
|
||||
|
||||
// deleteWishlist() async {
|
||||
// var connectivityResult = await (Connectivity().checkConnectivity());
|
||||
// if (connectivityResult == ConnectivityResult.none) {
|
||||
// ScaffoldMessenger.of(context).showSnackBar(
|
||||
// SnackBar(
|
||||
// duration: Duration(seconds: 1),
|
||||
// backgroundColor: Colors.red[600],
|
||||
// content: Text(
|
||||
// 'No Internet Connections',
|
||||
// textAlign: TextAlign.center,
|
||||
// style: primaryTextStyle.copyWith(color: Colors.white),
|
||||
// ),
|
||||
// behavior: SnackBarBehavior.floating,
|
||||
// shape: RoundedRectangleBorder(
|
||||
// borderRadius: BorderRadius.circular(5),
|
||||
// ),
|
||||
// ),
|
||||
// );
|
||||
// } else {
|
||||
// await wishlistPostProvider
|
||||
// .addWishlist(int.parse(dataDetailCourseModel.id));
|
||||
// }
|
||||
// }
|
||||
|
||||
checkUser() async {
|
||||
var token = await UsersInfo().getToken();
|
||||
if (token != null || Condition.loginFirebase == true) {
|
||||
addWishlist();
|
||||
} else {
|
||||
return _showDialogNotLogin();
|
||||
}
|
||||
}
|
||||
|
||||
wishlistExist() async {
|
||||
var token = await UsersInfo().getToken();
|
||||
if (token != null || Condition.loginFirebase == true) {
|
||||
addWishlistNotExist();
|
||||
} else {
|
||||
return _showDialogNotLogin();
|
||||
}
|
||||
}
|
||||
|
||||
return Container(
|
||||
child: Row(
|
||||
children: [
|
||||
Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Icon(
|
||||
Icons.people_outline,
|
||||
color: Colors.white,
|
||||
size: getProportionateScreenWidth(22),
|
||||
),
|
||||
SizedBox(width: getProportionateScreenWidth(4)),
|
||||
Text(
|
||||
' ${dataDetailCourseModel.totalStudents} Murid',
|
||||
style: primaryTextStyle.copyWith(
|
||||
fontSize: getProportionateScreenWidth(10),
|
||||
letterSpacing: 0.5),
|
||||
)
|
||||
],
|
||||
),
|
||||
SizedBox(
|
||||
width: getProportionateScreenWidth(15),
|
||||
),
|
||||
// Consumer<WishlistProvider>(builder: (context, state, _) {
|
||||
// return Text(state.data.contains(dataDetailCourseModel.id)
|
||||
// ? 'ada di wishlist'
|
||||
// : 'ga ada');
|
||||
// }),
|
||||
GestureDetector(
|
||||
onTap: Provider.of<CartsProvider>(context)
|
||||
.data
|
||||
.contains(dataDetailCourseModel.id)
|
||||
? checkUser
|
||||
: wishlistExist,
|
||||
child: !Condition.loginEmail
|
||||
? Row(
|
||||
children: [
|
||||
Icon(
|
||||
Icons.favorite_border,
|
||||
color: Colors.white,
|
||||
size: getProportionateScreenWidth(22),
|
||||
),
|
||||
SizedBox(
|
||||
width: getProportionateScreenWidth(4),
|
||||
),
|
||||
Text(
|
||||
'Tambah ke wishlist',
|
||||
style: primaryTextStyle.copyWith(
|
||||
fontSize: getProportionateScreenWidth(10),
|
||||
letterSpacing: 0.2),
|
||||
),
|
||||
],
|
||||
)
|
||||
: Row(
|
||||
children: [
|
||||
Consumer<wishlistProvider.WishlistProvider>(
|
||||
builder: (context, state, _) {
|
||||
if (state.state ==
|
||||
wishlistProvider.ResultState.Loading) {
|
||||
return Container(
|
||||
height: 15,
|
||||
width: 15,
|
||||
child: CircularProgressIndicator(
|
||||
color: secondaryColor,
|
||||
strokeWidth: 1,
|
||||
),
|
||||
);
|
||||
}
|
||||
return Icon(
|
||||
state.data.contains(dataDetailCourseModel.id)
|
||||
? Icons.favorite_outlined
|
||||
: Icons.favorite_border,
|
||||
color: state.data.contains(dataDetailCourseModel.id)
|
||||
? Color(0xffCD2228)
|
||||
: Colors.white,
|
||||
size: getProportionateScreenWidth(22),
|
||||
);
|
||||
},
|
||||
),
|
||||
SizedBox(
|
||||
width: getProportionateScreenWidth(4),
|
||||
),
|
||||
Consumer<wishlistProvider.WishlistProvider>(
|
||||
builder: (contex, state, _) {
|
||||
if (state.state ==
|
||||
wishlistProvider.ResultState.Loading) {
|
||||
return Text('');
|
||||
}
|
||||
return Text(
|
||||
state.data.contains(dataDetailCourseModel.id)
|
||||
? 'Sudah dalam wihslist'
|
||||
: 'Tambah ke wishlist',
|
||||
style: primaryTextStyle.copyWith(
|
||||
fontSize: getProportionateScreenWidth(10),
|
||||
letterSpacing: 0.2),
|
||||
);
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
59
lib/screens/detail_course/components/tab_bar_items.dart
Normal file
59
lib/screens/detail_course/components/tab_bar_items.dart
Normal file
@ -0,0 +1,59 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:initial_folder/providers/tab_provider.dart';
|
||||
import 'package:initial_folder/size_config.dart';
|
||||
import 'package:initial_folder/theme.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
class TabBarItems extends StatelessWidget {
|
||||
final int index;
|
||||
final String title;
|
||||
|
||||
const TabBarItems({
|
||||
Key? key,
|
||||
required this.index,
|
||||
required this.title,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
TabProvider tab = Provider.of<TabProvider>(context, listen: false);
|
||||
|
||||
return GestureDetector(
|
||||
onTap: () {
|
||||
tab.currentIndex = index;
|
||||
},
|
||||
child: Container(
|
||||
child: Column(
|
||||
children: [
|
||||
Text(
|
||||
title,
|
||||
style: thirdTextStyle.copyWith(
|
||||
color: tab.currentIndex == index
|
||||
? Theme.of(context).brightness == Brightness.light
|
||||
? primaryColorligtmode
|
||||
: primaryColor
|
||||
: fifteenColor,
|
||||
fontSize: getProportionateScreenWidth(12),
|
||||
fontWeight: semiBold,
|
||||
),
|
||||
),
|
||||
SizedBox(height: getProportionateScreenHeight(2)),
|
||||
Container(
|
||||
width: getProportionateScreenWidth(58),
|
||||
height: getProportionateScreenHeight(2),
|
||||
decoration: BoxDecoration(
|
||||
color: tab.currentIndex == index
|
||||
? Theme.of(context).brightness == Brightness.light
|
||||
? primaryColorligtmode
|
||||
: primaryColor
|
||||
: Colors.transparent,
|
||||
borderRadius:
|
||||
BorderRadius.circular(getProportionateScreenHeight(19)),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
36
lib/screens/detail_course/components/terkait.dart
Normal file
36
lib/screens/detail_course/components/terkait.dart
Normal file
@ -0,0 +1,36 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:initial_folder/screens/home/components/body_comp/course_terkait.dart';
|
||||
import 'package:initial_folder/size_config.dart';
|
||||
|
||||
class Terkait extends StatelessWidget {
|
||||
const Terkait({
|
||||
Key? key,
|
||||
this.idCategory,
|
||||
}) : super(key: key);
|
||||
|
||||
final String? idCategory;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Padding(
|
||||
padding: EdgeInsets.only(
|
||||
top: getProportionateScreenHeight(20),
|
||||
left: getProportionateScreenWidth(10),
|
||||
),
|
||||
child: Container(
|
||||
height: getProportionateScreenHeight(240),
|
||||
child: Column(
|
||||
children: [
|
||||
Expanded(
|
||||
child: CourseTerkait(
|
||||
name: "",
|
||||
categoryId: idCategory ?? "",
|
||||
subId: "",
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
430
lib/screens/detail_course/components/ulasan.dart
Normal file
430
lib/screens/detail_course/components/ulasan.dart
Normal file
@ -0,0 +1,430 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_rating_bar/flutter_rating_bar.dart';
|
||||
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||
import 'package:initial_folder/helper/validator.dart';
|
||||
import 'package:initial_folder/models/detail_rating_course_model.dart';
|
||||
import 'package:initial_folder/providers/detail_rating_course_provider.dart';
|
||||
import 'package:initial_folder/screens/detail_course/components/detail_list_ulasan.dart';
|
||||
import 'package:initial_folder/size_config.dart';
|
||||
import 'package:initial_folder/theme.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
class Ulasan extends StatefulWidget {
|
||||
const Ulasan({
|
||||
Key? key,
|
||||
required this.id,
|
||||
}) : super(key: key);
|
||||
final String id;
|
||||
|
||||
@override
|
||||
_UlasanState createState() => _UlasanState();
|
||||
}
|
||||
|
||||
class _UlasanState extends State<Ulasan> {
|
||||
int _currentPage = 1;
|
||||
int _totalPages = 1;
|
||||
List<DataReview> _filteredReviews = []; // Menyimpan review yang sudah difilter
|
||||
|
||||
// Fungsi untuk membatasi ulasan per halaman
|
||||
List<DataReview> _getPaginatedReviews(List<DataReview> reviews) {
|
||||
int startIndex = (_currentPage - 1) * 5;
|
||||
int endIndex = startIndex + 5;
|
||||
return reviews.sublist(startIndex, endIndex.clamp(0, reviews.length));
|
||||
}
|
||||
|
||||
void _filterReviews(int rating, List<DataReview> allReviews) {
|
||||
setState(() {
|
||||
_filteredReviews = allReviews.where((review) => double.parse(review.rating ?? '0') == rating).toList();
|
||||
_totalPages = (_filteredReviews.length / 5).ceil();
|
||||
_currentPage = 1; // Reset ke halaman pertama saat filter diubah
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final listChoices = <ItemChoice>[
|
||||
ItemChoice(0, 0, 'Semua '),
|
||||
ItemChoice(5, 1, '5'),
|
||||
ItemChoice(4, 1, '4'),
|
||||
ItemChoice(3, 1, '3'),
|
||||
ItemChoice(2, 1, '2'),
|
||||
ItemChoice(1, 1, '1'),
|
||||
];
|
||||
|
||||
return SingleChildScrollView(
|
||||
child: Column(
|
||||
children: [
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Container(
|
||||
margin: EdgeInsets.only(
|
||||
left: getProportionateScreenWidth(10),
|
||||
right: getProportionateScreenWidth(10),
|
||||
),
|
||||
child: Consumer<DetailRatingCourseProvider>(
|
||||
builder: (context, state, _) {
|
||||
if (state.state == ResultState.Loading) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: Center(
|
||||
child: CircularProgressIndicator(
|
||||
color: primaryColor,
|
||||
strokeWidth: 2,
|
||||
),
|
||||
),
|
||||
);
|
||||
} else if (state.state == ResultState.HasData) {
|
||||
var ulasan = state.result;
|
||||
|
||||
// Hitung total halaman berdasarkan jumlah ulasan jika semua ulasan ditampilkan
|
||||
if (state.currentIndex == 0) {
|
||||
_filteredReviews = ulasan!.dataReview;
|
||||
_totalPages = (_filteredReviews.length / 5).ceil();
|
||||
}
|
||||
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
SizedBox(height: getProportionateScreenHeight(20)),
|
||||
Text(
|
||||
'Ulasan Kursus',
|
||||
style: thirdTextStyle.copyWith(
|
||||
fontWeight: semiBold,
|
||||
fontSize: getProportionateScreenWidth(15),
|
||||
),
|
||||
),
|
||||
Row(
|
||||
children: [
|
||||
Text(
|
||||
ulasan!.data.avgRating is List<dynamic>
|
||||
? '0'
|
||||
: double.parse(ulasan.data.avgRating)
|
||||
.toStringAsFixed(1)
|
||||
.replaceAll('.', ','),
|
||||
style: thirdTextStyle.copyWith(
|
||||
fontSize: getProportionateScreenWidth(29),
|
||||
),
|
||||
),
|
||||
SizedBox(width: getProportionateScreenWidth(8)),
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
SizedBox(
|
||||
height: getProportionateScreenHeight(2)),
|
||||
RatingBarIndicator(
|
||||
itemSize: getProportionateScreenWidth(10),
|
||||
rating: ulasan.data.avgRating is List<dynamic>
|
||||
? 5.0
|
||||
: double.parse(ulasan.data.avgRating),
|
||||
direction: Axis.horizontal,
|
||||
itemCount: 5,
|
||||
itemBuilder: (context, _) => FaIcon(
|
||||
FontAwesomeIcons.solidStar,
|
||||
color: thirteenColor,
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
height: getProportionateScreenHeight(2)),
|
||||
Text(
|
||||
'(${ulasan.dataReview.length} Ulasan)',
|
||||
style: thirdTextStyle.copyWith(
|
||||
fontSize: getProportionateScreenWidth(12),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(height: getProportionateScreenHeight(11)),
|
||||
VerticalRatingBar(
|
||||
lebar: ulasan.data.precentageRating.rating5.toString(),
|
||||
text: '5.0',
|
||||
total: (ulasan.data.precentageRating.rating5.runtimeType == String)
|
||||
? '${persentaseUlasan(ulasan.data.precentageRating.rating5)}'
|
||||
: '${ulasan.data.precentageRating.rating5}'),
|
||||
VerticalRatingBar(
|
||||
lebar: ulasan.data.precentageRating.rating4.toString(),
|
||||
text: '4.0',
|
||||
total: (ulasan.data.precentageRating.rating4.runtimeType == String)
|
||||
? '${persentaseUlasan(ulasan.data.precentageRating.rating4)}'
|
||||
: '${ulasan.data.precentageRating.rating4}'),
|
||||
VerticalRatingBar(
|
||||
lebar: ulasan.data.precentageRating.rating3.toString(),
|
||||
text: '3.0',
|
||||
total: (ulasan.data.precentageRating.rating3.runtimeType == String)
|
||||
? '${persentaseUlasan(ulasan.data.precentageRating.rating3)}'
|
||||
: '${ulasan.data.precentageRating.rating3}'),
|
||||
VerticalRatingBar(
|
||||
lebar: ulasan.data.precentageRating.rating2.toString(),
|
||||
text: '2.0',
|
||||
total: (ulasan.data.precentageRating.rating2.runtimeType == String)
|
||||
? '${persentaseUlasan(ulasan.data.precentageRating.rating2)}'
|
||||
: '${ulasan.data.precentageRating.rating2}'),
|
||||
VerticalRatingBar(
|
||||
lebar: ulasan.data.precentageRating.rating1.toString(),
|
||||
text: '1.0',
|
||||
total: (ulasan.data.precentageRating.rating1.runtimeType == String)
|
||||
? '${persentaseUlasan(ulasan.data.precentageRating.rating1)}'
|
||||
: '${ulasan.data.precentageRating.rating1}'),
|
||||
],
|
||||
);
|
||||
}
|
||||
return Text(
|
||||
'Terjadi Kesalan ',
|
||||
style: primaryTextStyle,
|
||||
);
|
||||
}),
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(height: getProportionateScreenHeight(11)),
|
||||
Consumer<DetailRatingCourseProvider>(
|
||||
builder: (context, state, _) {
|
||||
if (state.state == ResultState.HasData) {
|
||||
var ulasan = state.result;
|
||||
return Column(
|
||||
children: [
|
||||
SizedBox(height: getProportionateScreenHeight(8)),
|
||||
Wrap(
|
||||
spacing: 6,
|
||||
runSpacing: 3,
|
||||
children: listChoices
|
||||
.map(
|
||||
(e) => InkWell(
|
||||
onTap: () {
|
||||
state.currentIndex = e.id;
|
||||
if (state.currentIndex == 0) {
|
||||
// Reset ke semua review jika memilih filter "Semua"
|
||||
Provider.of<DetailRatingCourseProvider>(context, listen: false)
|
||||
.getDetailCourse();
|
||||
_filteredReviews = ulasan!.dataReview;
|
||||
_totalPages = (_filteredReviews.length / 5).ceil();
|
||||
_currentPage = 1;
|
||||
} else {
|
||||
// Filter sesuai dengan rating yang dipilih
|
||||
_filterReviews(e.id, ulasan!.dataReview);
|
||||
}
|
||||
},
|
||||
child: Container(
|
||||
padding: EdgeInsets.symmetric(horizontal: 5),
|
||||
decoration: BoxDecoration(
|
||||
color: state.currentIndex == e.id
|
||||
? Theme.of(context)
|
||||
.colorScheme
|
||||
.onBackground
|
||||
: Theme.of(context)
|
||||
.colorScheme
|
||||
.primaryContainer,
|
||||
border: Border.all(
|
||||
color: Theme.of(context)
|
||||
.colorScheme
|
||||
.brightness ==
|
||||
Brightness.dark
|
||||
? seventeenColor
|
||||
: secondaryColor,
|
||||
),
|
||||
borderRadius: BorderRadius.circular(20),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: baruTexthitam.withOpacity(0.2),
|
||||
blurRadius: 2,
|
||||
spreadRadius: 1,
|
||||
offset: Offset(0, 2),
|
||||
)
|
||||
],
|
||||
),
|
||||
child: Padding(
|
||||
padding: EdgeInsets.symmetric(
|
||||
horizontal: getProportionateScreenWidth(5),
|
||||
vertical: getProportionateScreenHeight(5),
|
||||
),
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
(e.icon == 0)
|
||||
? Text('')
|
||||
: FaIcon(
|
||||
FontAwesomeIcons.solidStar,
|
||||
color: thirteenColor,
|
||||
size: getProportionateScreenWidth(11),
|
||||
),
|
||||
SizedBox(width: getProportionateScreenWidth(3)),
|
||||
Text(
|
||||
e.label,
|
||||
style: thirdTextStyle.copyWith(
|
||||
color: state.currentIndex == e.id
|
||||
? Theme.of(context)
|
||||
.colorScheme
|
||||
.background
|
||||
: e.label == "Semua "
|
||||
? primaryColor
|
||||
: Theme.of(context)
|
||||
.colorScheme
|
||||
.onBackground,
|
||||
fontSize: getProportionateScreenWidth(12),
|
||||
fontWeight: reguler,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
.toList(),
|
||||
),
|
||||
SizedBox(height: getProportionateScreenHeight(17)),
|
||||
Container(
|
||||
margin: EdgeInsets.only(
|
||||
left: getProportionateScreenWidth(15),
|
||||
right: getProportionateScreenWidth(10),
|
||||
),
|
||||
child: (_filteredReviews.isEmpty)
|
||||
? SizedBox(height: getProportionateScreenHeight(15))
|
||||
: Column(
|
||||
children: _getPaginatedReviews(_filteredReviews)
|
||||
.map(
|
||||
(e) => DetailListUlasan(
|
||||
review: e.review ?? '',
|
||||
date: e.date ?? '-',
|
||||
name: e.name ?? '',
|
||||
starRating: double.parse(e.rating ?? '5'),
|
||||
),
|
||||
)
|
||||
.toList()),
|
||||
),
|
||||
// Navigasi Pagination
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
if (_filteredReviews.isEmpty)
|
||||
Text(
|
||||
'Belum ada rating untuk kategori bintang ini',
|
||||
style: thirdTextStyle.copyWith(
|
||||
fontSize: getProportionateScreenWidth(12),
|
||||
),
|
||||
)
|
||||
else ...[
|
||||
if (_currentPage > 1)
|
||||
IconButton(
|
||||
onPressed: () {
|
||||
setState(() {
|
||||
_currentPage--;
|
||||
});
|
||||
},
|
||||
icon: Icon(Icons.arrow_back),
|
||||
),
|
||||
Text('$_currentPage of $_totalPages'),
|
||||
if (_currentPage < _totalPages)
|
||||
IconButton(
|
||||
onPressed: () {
|
||||
setState(() {
|
||||
_currentPage++;
|
||||
});
|
||||
},
|
||||
icon: Icon(Icons.arrow_forward),
|
||||
),
|
||||
]
|
||||
],
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
return Text('');
|
||||
},
|
||||
),
|
||||
SizedBox(
|
||||
height: 30,
|
||||
)
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class VerticalRatingBar extends StatelessWidget {
|
||||
const VerticalRatingBar({
|
||||
Key? key,
|
||||
required this.text,
|
||||
this.lebar = '0',
|
||||
required this.total,
|
||||
}) : super(key: key);
|
||||
final String text;
|
||||
final String total;
|
||||
final String lebar;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
margin: EdgeInsets.only(bottom: getProportionateScreenWidth(8)),
|
||||
child: Column(
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
FaIcon(
|
||||
FontAwesomeIcons.solidStar,
|
||||
color: thirteenColor,
|
||||
size: getProportionateScreenWidth(11),
|
||||
),
|
||||
SizedBox(width: getProportionateScreenWidth(4)),
|
||||
Text(
|
||||
text,
|
||||
style: thirdTextStyle.copyWith(
|
||||
fontSize: getProportionateScreenWidth(10),
|
||||
),
|
||||
),
|
||||
SizedBox(width: getProportionateScreenWidth(6)),
|
||||
Expanded(
|
||||
child: Column(
|
||||
children: [
|
||||
Stack(
|
||||
children: [
|
||||
Container(
|
||||
height: getProportionateScreenWidth(4),
|
||||
decoration: BoxDecoration(
|
||||
color: fourthColor,
|
||||
borderRadius: BorderRadius.circular(10)),
|
||||
),
|
||||
Container(
|
||||
width: (SizeConfig.screenWidth -
|
||||
getProportionateScreenWidth(110)) *
|
||||
double.parse(persentaseUlasan(lebar)
|
||||
.replaceAll(',', '.')) /
|
||||
100,
|
||||
height: getProportionateScreenWidth(4),
|
||||
decoration: BoxDecoration(
|
||||
color: thirteenColor,
|
||||
borderRadius: BorderRadius.circular(10)),
|
||||
)
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
SizedBox(width: getProportionateScreenWidth(8)),
|
||||
Container(
|
||||
width: getProportionateScreenWidth(30),
|
||||
child: Text(
|
||||
total,
|
||||
style: thirdTextStyle.copyWith(
|
||||
fontSize: getProportionateScreenWidth(10),
|
||||
),
|
||||
textAlign: TextAlign.start,
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class ItemChoice {
|
||||
final int id;
|
||||
final int icon;
|
||||
final String label;
|
||||
|
||||
ItemChoice(this.id, this.icon, this.label);
|
||||
}
|
770
lib/screens/detail_course/detail_course_coupon_screen.dart
Normal file
770
lib/screens/detail_course/detail_course_coupon_screen.dart
Normal file
@ -0,0 +1,770 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_feather_icons/flutter_feather_icons.dart';
|
||||
import 'package:initial_folder/base_service.dart';
|
||||
import 'package:initial_folder/helper/user_info.dart';
|
||||
import 'package:initial_folder/helper/validator.dart';
|
||||
|
||||
import 'package:initial_folder/providers/cart_provider.dart' as cartProvider;
|
||||
import 'package:initial_folder/providers/carts_provider.dart' as cartsProvider;
|
||||
import 'package:initial_folder/providers/detail_course_coupon_provider.dart';
|
||||
|
||||
import 'package:initial_folder/providers/detail_rating_course_provider.dart'
|
||||
as detailRatingCourseProvider;
|
||||
import 'package:initial_folder/providers/instructor_provider.dart'
|
||||
as instructorProvider;
|
||||
import 'package:initial_folder/providers/lesson_course_provider.dart'
|
||||
as lessonCourseProvider;
|
||||
import 'package:initial_folder/providers/my_course_provider.dart'
|
||||
as myCourseProvider;
|
||||
import 'package:initial_folder/providers/order_provider.dart' as orderProvider;
|
||||
import 'package:initial_folder/providers/payments_provider.dart'
|
||||
as paymentsProvider;
|
||||
import 'package:initial_folder/providers/section_lesson_course_provider.dart'
|
||||
as sectionLessonCourseProvider;
|
||||
import 'package:initial_folder/providers/tab_provider.dart';
|
||||
import 'package:initial_folder/providers/total_price_provider.dart';
|
||||
import 'package:initial_folder/providers/whislist_provider.dart'
|
||||
as wishlistProvider;
|
||||
import 'package:initial_folder/providers/wishlist_post_provider.dart';
|
||||
import 'package:initial_folder/screens/cart/cart_page.dart';
|
||||
import 'package:initial_folder/screens/checkout/checkout_coupon_page.dart';
|
||||
import 'package:initial_folder/screens/checkout/checkout_page.dart';
|
||||
import 'package:initial_folder/screens/course/play_course_page.dart';
|
||||
import 'package:initial_folder/screens/detail_course/components/header_coupon.dart';
|
||||
import 'package:initial_folder/screens/login/login_screen.dart';
|
||||
import 'package:initial_folder/screens/login/login_with_email/login_email_screen.dart';
|
||||
import 'package:initial_folder/screens/my_course/success_free_course.dart';
|
||||
import 'package:initial_folder/screens/splash/splash_screen_login.dart';
|
||||
import 'package:initial_folder/screens/detail_course/components/app_bar.dart';
|
||||
import 'package:initial_folder/screens/detail_course/components/custom_tab_bar.dart';
|
||||
import 'package:initial_folder/screens/detail_course/components/header.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/services/section_lesson_service.dart';
|
||||
import 'package:initial_folder/size_config.dart';
|
||||
import 'package:initial_folder/theme.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
class DetailCourseCouponScreen extends StatelessWidget {
|
||||
const DetailCourseCouponScreen(
|
||||
{Key? key, required this.idcourse, required this.coupon})
|
||||
: super(key: key);
|
||||
final String idcourse;
|
||||
final String coupon;
|
||||
|
||||
static String routeName = "/course_detail";
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final typeCoupon = Provider.of<TotalPriceProvider>(context).typeCoupon;
|
||||
final selected = Provider.of<TotalPriceProvider>(context);
|
||||
// Provider.of<orderProvider.OrderProvider>(context).clearOrder();
|
||||
// Provider.of<orderProvider.OrderProvider>(context).clearInvoice();
|
||||
paymentsProvider.PaymentsProvider pay =
|
||||
Provider.of<paymentsProvider.PaymentsProvider>(context);
|
||||
SizeConfig().init(context);
|
||||
showNotifDialog(BuildContext context) {
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (context) {
|
||||
return AlertDialog(
|
||||
content: Consumer<paymentsProvider.PaymentsProvider>(
|
||||
builder: (context, state, child) {
|
||||
if (state.state == paymentsProvider.ResultState.gagal) {
|
||||
return Container(
|
||||
height: getProportionateScreenHeight(40),
|
||||
width: getProportionateScreenWidth(15),
|
||||
child: Center(
|
||||
child: Text(
|
||||
'Anda sudah memiliki kursus ini',
|
||||
style: primaryTextStyle.copyWith(fontSize: 12),
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
),
|
||||
);
|
||||
} else {
|
||||
return Text(
|
||||
'Erorr lain',
|
||||
style: thirdTextStyle,
|
||||
);
|
||||
}
|
||||
},
|
||||
),
|
||||
);
|
||||
},
|
||||
// barrierDismissible: false,
|
||||
);
|
||||
}
|
||||
|
||||
Future _showDialogNotLogin(String teks) {
|
||||
return showDialog(
|
||||
context: context,
|
||||
builder: (context) => AlertDialog(
|
||||
contentPadding: EdgeInsets.fromLTRB(12, 20, 12, 1),
|
||||
content: Text(
|
||||
'Mohon login terlebih dahulu sebelum $teks',
|
||||
style: primaryTextStyle.copyWith(
|
||||
fontSize: getProportionateScreenWidth(12), letterSpacing: 1),
|
||||
),
|
||||
actions: [
|
||||
GestureDetector(
|
||||
onTap: () {
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
child: Text('Batal',
|
||||
style: primaryTextStyle.copyWith(
|
||||
fontSize: getProportionateScreenWidth(12),
|
||||
letterSpacing: 1,
|
||||
color: primaryColor)),
|
||||
),
|
||||
SizedBox(
|
||||
width: getProportionateScreenWidth(5),
|
||||
),
|
||||
GestureDetector(
|
||||
onTap: () {
|
||||
Navigator.of(context).pushNamedAndRemoveUntil(
|
||||
LoginEmail.routeName, (Route<dynamic> route) => false);
|
||||
},
|
||||
child: Text('Login',
|
||||
style: primaryTextStyle.copyWith(
|
||||
fontSize: getProportionateScreenWidth(12),
|
||||
letterSpacing: 1,
|
||||
color: primaryColor)),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> _showMessage() {
|
||||
return showModalBottomSheet<void>(
|
||||
context: context,
|
||||
builder: (BuildContext context) {
|
||||
return Consumer<cartProvider.CartProvider>(
|
||||
builder: (context, state, _) {
|
||||
if (state.state == cartProvider.ResultState.loading) {
|
||||
return Container(
|
||||
decoration: BoxDecoration(
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
blurRadius: 10,
|
||||
offset: Offset(0, -1),
|
||||
)
|
||||
],
|
||||
borderRadius: BorderRadius.vertical(
|
||||
top: Radius.circular(10),
|
||||
),
|
||||
color: Color(0xff242424),
|
||||
),
|
||||
height: getProportionateScreenHeight(200),
|
||||
child: Center(
|
||||
child: CircularProgressIndicator(
|
||||
strokeWidth: 1,
|
||||
color: primaryColor,
|
||||
),
|
||||
));
|
||||
} else if (state.state == cartProvider.ResultState.succes) {
|
||||
return Container(
|
||||
decoration: BoxDecoration(
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
blurRadius: 10,
|
||||
offset: Offset(0, -1),
|
||||
)
|
||||
],
|
||||
borderRadius: BorderRadius.vertical(
|
||||
top: Radius.circular(10),
|
||||
),
|
||||
color: Color(0xff242424),
|
||||
),
|
||||
height: getProportionateScreenHeight(200),
|
||||
child: Column(
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
IconButton(
|
||||
onPressed: () {
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
icon: Icon(
|
||||
Icons.close,
|
||||
color: secondaryColor,
|
||||
size: 15,
|
||||
)),
|
||||
],
|
||||
),
|
||||
Icon(
|
||||
Icons.check_rounded,
|
||||
size: 40,
|
||||
color: eightColor,
|
||||
),
|
||||
SizedBox(
|
||||
height: getProportionateScreenWidth(15),
|
||||
),
|
||||
Text(
|
||||
'Berhasil menambahkan kursus ke keranjang',
|
||||
textAlign: TextAlign.center,
|
||||
style: primaryTextStyle.copyWith(
|
||||
fontSize: SizeConfig.blockHorizontal! * 4,
|
||||
letterSpacing: 0.5),
|
||||
),
|
||||
SizedBox(
|
||||
height: getProportionateScreenWidth(4),
|
||||
),
|
||||
TextButton(
|
||||
style: ButtonStyle(
|
||||
overlayColor: MaterialStateProperty.all(sixColor),
|
||||
padding: MaterialStateProperty.all(
|
||||
EdgeInsets.symmetric(vertical: 1, horizontal: 1),
|
||||
),
|
||||
),
|
||||
onPressed: () {
|
||||
Navigator.of(context).push(MaterialPageRoute(
|
||||
builder: (context) => CartPage(
|
||||
idcourse: idcourse,
|
||||
)));
|
||||
},
|
||||
child: Text(
|
||||
'Lihat keranjang',
|
||||
style: thirdTextStyle.copyWith(
|
||||
fontSize: getProportionateScreenWidth(13),
|
||||
letterSpacing: 0.5,
|
||||
color: primaryColor),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
} else if (state.state == cartProvider.ResultState.failed) {
|
||||
return Container(
|
||||
decoration: BoxDecoration(
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
blurRadius: 10,
|
||||
offset: Offset(0, -1),
|
||||
)
|
||||
],
|
||||
borderRadius: BorderRadius.vertical(
|
||||
top: Radius.circular(10),
|
||||
),
|
||||
color: Color(0xff242424),
|
||||
),
|
||||
height: getProportionateScreenHeight(200),
|
||||
child: Column(
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
IconButton(
|
||||
onPressed: () {
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
icon: Icon(
|
||||
Icons.close,
|
||||
color: secondaryColor,
|
||||
size: 15,
|
||||
)),
|
||||
],
|
||||
),
|
||||
Icon(
|
||||
Icons.check_rounded,
|
||||
size: 40,
|
||||
color: eightColor,
|
||||
),
|
||||
SizedBox(
|
||||
height: getProportionateScreenWidth(15),
|
||||
),
|
||||
Text(
|
||||
'Berhasil menghapus kursus dari keranjang',
|
||||
textAlign: TextAlign.center,
|
||||
style: primaryTextStyle.copyWith(
|
||||
fontSize: SizeConfig.blockHorizontal! * 4,
|
||||
letterSpacing: 0.5),
|
||||
),
|
||||
SizedBox(
|
||||
height: getProportionateScreenWidth(4),
|
||||
),
|
||||
TextButton(
|
||||
style: ButtonStyle(
|
||||
overlayColor: MaterialStateProperty.all(sixColor),
|
||||
padding: MaterialStateProperty.all(
|
||||
EdgeInsets.symmetric(vertical: 1, horizontal: 1),
|
||||
),
|
||||
),
|
||||
onPressed: () {
|
||||
Navigator.of(context).push(MaterialPageRoute(
|
||||
builder: (context) => CartPage(
|
||||
idcourse: idcourse,
|
||||
)));
|
||||
},
|
||||
child: Text(
|
||||
'Lihat keranjang',
|
||||
style: thirdTextStyle.copyWith(
|
||||
fontSize: getProportionateScreenWidth(13),
|
||||
letterSpacing: 0.5,
|
||||
color: primaryColor),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
} else {
|
||||
return Container(
|
||||
decoration: BoxDecoration(
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
blurRadius: 10,
|
||||
offset: Offset(0, -1),
|
||||
)
|
||||
],
|
||||
borderRadius: BorderRadius.vertical(
|
||||
top: Radius.circular(10),
|
||||
),
|
||||
color: Color(0xff242424),
|
||||
),
|
||||
height: getProportionateScreenHeight(200),
|
||||
child: Center(
|
||||
child: Text('Terjadi Kesalahan'),
|
||||
));
|
||||
}
|
||||
});
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
handleNotLogin() async {
|
||||
var token = await UsersInfo().getToken();
|
||||
if (token != null || Condition.loginFirebase == true) {
|
||||
_showMessage();
|
||||
await Provider.of<cartProvider.CartProvider>(context, listen: false)
|
||||
.addCart(int.parse(idcourse));
|
||||
await Provider.of<cartsProvider.CartsProvider>(context, listen: false)
|
||||
.getCarts();
|
||||
await Provider.of<WishlistPostProvider>(context, listen: false)
|
||||
.addWishlist(int.parse(idcourse));
|
||||
await Provider.of<wishlistProvider.WishlistProvider>(context,
|
||||
listen: false)
|
||||
.getWishlist();
|
||||
// cartsDatabaseProvider.setCarts(id);
|
||||
} else {
|
||||
String teks = 'menambahkan ke keranjang';
|
||||
return _showDialogNotLogin(teks);
|
||||
}
|
||||
}
|
||||
|
||||
handleNotLoginWishlistNotExist() async {
|
||||
var token = await UsersInfo().getToken();
|
||||
if (token != null || Condition.loginFirebase == true) {
|
||||
_showMessage();
|
||||
await Provider.of<cartProvider.CartProvider>(context, listen: false)
|
||||
.addCart(int.parse(idcourse));
|
||||
await Provider.of<cartsProvider.CartsProvider>(context, listen: false)
|
||||
.getCarts();
|
||||
} else {
|
||||
String teks = 'menambahkan ke keranjang';
|
||||
return _showDialogNotLogin(teks);
|
||||
}
|
||||
}
|
||||
|
||||
handleNotLoginBuy(
|
||||
{required String title,
|
||||
required String price,
|
||||
required String discountPrice,
|
||||
required String instructor,
|
||||
required String imageUrl}) async {
|
||||
var token = await UsersInfo().getToken();
|
||||
if (token != null || Condition.loginFirebase == true) {
|
||||
Provider.of<orderProvider.OrderProvider>(context, listen: false)
|
||||
.clear();
|
||||
Provider.of<orderProvider.OrderProvider>(context, listen: false)
|
||||
.addOrder(
|
||||
id: idcourse,
|
||||
title: title,
|
||||
price: price,
|
||||
discountPrice: discountPrice,
|
||||
imageUrl: imageUrl,
|
||||
instructor: instructor,
|
||||
);
|
||||
Provider.of<orderProvider.OrderProvider>(context, listen: false)
|
||||
.getTotalPrice(discountPrice);
|
||||
Navigator.of(context).push(MaterialPageRoute(
|
||||
builder: (context) => CheckoutCouponPage(
|
||||
discountPrice: discountPrice,
|
||||
idCourse: idcourse,
|
||||
instructor: instructor,
|
||||
title: title,
|
||||
price: price,
|
||||
coupon: coupon,
|
||||
)));
|
||||
} else {
|
||||
String teks = 'membeli kursus';
|
||||
return _showDialogNotLogin(teks);
|
||||
}
|
||||
}
|
||||
|
||||
handleNotLoginFree(
|
||||
String? id,
|
||||
String? title,
|
||||
String? thumb,
|
||||
String? instr,
|
||||
) async {
|
||||
var token = await UsersInfo().getToken();
|
||||
if (token != null || Condition.loginFirebase == true) {
|
||||
if (await pay.freeCourse(int.parse(idcourse))) {
|
||||
await Provider.of<myCourseProvider.MyCourseProvider>(context,
|
||||
listen: false)
|
||||
.getMyCourse();
|
||||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) => SuccessFreeCourse(
|
||||
id: id,
|
||||
thumbnail: thumb,
|
||||
title: title,
|
||||
instructor: instr,
|
||||
)));
|
||||
} else {
|
||||
showNotifDialog(context);
|
||||
}
|
||||
} else {
|
||||
String teks = 'memiliki kursus ini';
|
||||
return _showDialogNotLogin(teks);
|
||||
}
|
||||
}
|
||||
|
||||
Widget freeBottomNav(String? courseId, String? instructor,
|
||||
String? thumbnail, String? title) {
|
||||
return Container(
|
||||
width: double.infinity,
|
||||
height: getProportionateScreenHeight(60),
|
||||
decoration: BoxDecoration(
|
||||
border:
|
||||
Border.symmetric(horizontal: BorderSide(color: fourthColor)),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
offset: Offset(0, -2),
|
||||
blurRadius: 50,
|
||||
color: fourthColor.withOpacity(0.15))
|
||||
]),
|
||||
child: Row(
|
||||
children: [
|
||||
SizedBox(
|
||||
width: 13,
|
||||
),
|
||||
Text(
|
||||
'Gratis',
|
||||
style: primaryTextStyle.copyWith(
|
||||
fontSize: getProportionateScreenHeight(20),
|
||||
letterSpacing: 0.23),
|
||||
),
|
||||
Spacer(),
|
||||
GestureDetector(
|
||||
onTap: () =>
|
||||
handleNotLoginFree(courseId, title, thumbnail, instructor),
|
||||
child: Container(
|
||||
margin: EdgeInsets.only(right: getProportionateScreenWidth(15)),
|
||||
width: getProportionateScreenWidth(123),
|
||||
height: getProportionateScreenHeight(33),
|
||||
decoration: BoxDecoration(
|
||||
color: primaryColor,
|
||||
borderRadius: BorderRadius.circular(5)),
|
||||
child: Center(
|
||||
child: Consumer<paymentsProvider.PaymentsProvider>(
|
||||
builder: (context, state, _) {
|
||||
if (state.stateProcess ==
|
||||
paymentsProvider.Process.uninitialized) {
|
||||
return Text(
|
||||
'Miliki sekarang',
|
||||
style: thirdTextStyle.copyWith(
|
||||
fontSize: SizeConfig.blockHorizontal! * 3.5,
|
||||
letterSpacing: 0.085,
|
||||
color: Color(0xff181818),
|
||||
),
|
||||
);
|
||||
} else if (state.stateProcess ==
|
||||
paymentsProvider.Process.loading) {
|
||||
return Container(
|
||||
width: 20,
|
||||
height: 20,
|
||||
child: CircularProgressIndicator(
|
||||
color: eightColor,
|
||||
strokeWidth: 2,
|
||||
),
|
||||
);
|
||||
}
|
||||
return Text(
|
||||
'Miliki sekarang',
|
||||
style: thirdTextStyle.copyWith(
|
||||
fontSize: SizeConfig.blockHorizontal! * 3.5,
|
||||
letterSpacing: 0.085,
|
||||
color: Color(0xff181818),
|
||||
),
|
||||
);
|
||||
}),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget playCourseNav(String? courseId, String? instructor,
|
||||
String? thumbnail, String? title) {
|
||||
return Container(
|
||||
width: double.infinity,
|
||||
height: getProportionateScreenHeight(60),
|
||||
decoration: BoxDecoration(
|
||||
border:
|
||||
Border.symmetric(horizontal: BorderSide(color: fourthColor)),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
offset: Offset(0, -2),
|
||||
blurRadius: 50,
|
||||
color: fourthColor.withOpacity(0.15))
|
||||
]),
|
||||
child: Center(
|
||||
child: ElevatedButton(
|
||||
style: ElevatedButton.styleFrom(
|
||||
minimumSize: Size(getProportionateScreenWidth(90),
|
||||
getProportionateScreenHeight(33)),
|
||||
backgroundColor: primaryColor,
|
||||
),
|
||||
onPressed: () {
|
||||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) => MultiProvider(
|
||||
providers: [
|
||||
ChangeNotifierProvider(
|
||||
create: (context) =>
|
||||
lessonCourseProvider.LessonCourseProvider(
|
||||
lessonCourseService: LessonCourseService(),
|
||||
id: int.parse(courseId ?? '0'),
|
||||
),
|
||||
),
|
||||
ChangeNotifierProvider(
|
||||
create: (context) => DetailCourseCouponProvider(
|
||||
courseService: CourseService(),
|
||||
id: courseId ?? '1',
|
||||
coupon: coupon))
|
||||
],
|
||||
child: PlayCourse(
|
||||
judul: title ?? '',
|
||||
instruktur: instructor ?? '',
|
||||
thumbnail: thumbnail ??
|
||||
'$baseUrl/uploads/courses_thumbnail/course_thumbnail_default_57.jpg',
|
||||
courseeid: idcourse,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
child: Text(
|
||||
'Lanjutkan Belajar',
|
||||
style: thirdTextStyle.copyWith(color: Colors.black),
|
||||
),
|
||||
),
|
||||
));
|
||||
}
|
||||
|
||||
Widget bottomNav(
|
||||
{required String discountPrice,
|
||||
required String idCourse,
|
||||
required String title,
|
||||
required String price,
|
||||
required String instructor,
|
||||
required String imageUrl}) {
|
||||
return Container(
|
||||
width: double.infinity,
|
||||
height: getProportionateScreenHeight(60),
|
||||
decoration: BoxDecoration(
|
||||
border:
|
||||
Border.symmetric(horizontal: BorderSide(color: fourthColor)),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
offset: Offset(0, -2),
|
||||
blurRadius: 50,
|
||||
color: fourthColor.withOpacity(0.15))
|
||||
]),
|
||||
child: Row(
|
||||
children: [
|
||||
SizedBox(
|
||||
width: 13,
|
||||
),
|
||||
Text(
|
||||
numberFormat(discountPrice.toString().replaceAll('.', '')),
|
||||
style: primaryTextStyle.copyWith(
|
||||
fontSize: getProportionateScreenHeight(20),
|
||||
letterSpacing: 0.23),
|
||||
),
|
||||
Spacer(),
|
||||
Container(
|
||||
width: getProportionateScreenWidth(39),
|
||||
height: getProportionateScreenHeight(34),
|
||||
decoration: BoxDecoration(
|
||||
border: Border.all(color: primaryColor),
|
||||
borderRadius: BorderRadius.circular(5),
|
||||
),
|
||||
child: Consumer<wishlistProvider.WishlistProvider>(
|
||||
builder: (context, state, _) {
|
||||
return IconButton(
|
||||
padding: EdgeInsets.zero,
|
||||
splashRadius: 17,
|
||||
onPressed: () => state.data.contains(idcourse)
|
||||
? handleNotLogin()
|
||||
: handleNotLoginWishlistNotExist(),
|
||||
icon: Icon(FeatherIcons.shoppingCart,
|
||||
color: primaryColor, size: 20),
|
||||
);
|
||||
}),
|
||||
),
|
||||
// ),
|
||||
SizedBox(
|
||||
width: getProportionateScreenWidth(12),
|
||||
),
|
||||
GestureDetector(
|
||||
onTap: () {
|
||||
int total = int.parse(discountPrice);
|
||||
selected.selectedTotalPrice =
|
||||
total <= 50000 ? total + 5000 : total;
|
||||
print("Ini total price buat ke va ${selected.totalPrice}");
|
||||
handleNotLoginBuy(
|
||||
title: title,
|
||||
discountPrice: discountPrice,
|
||||
imageUrl: imageUrl,
|
||||
price: price,
|
||||
instructor: instructor);
|
||||
},
|
||||
child: Container(
|
||||
margin: EdgeInsets.only(right: getProportionateScreenWidth(15)),
|
||||
width: getProportionateScreenWidth(113),
|
||||
height: getProportionateScreenHeight(33),
|
||||
decoration: BoxDecoration(
|
||||
color: primaryColor,
|
||||
borderRadius: BorderRadius.circular(5)),
|
||||
child: Center(
|
||||
child: Text(
|
||||
'Beli sekarang',
|
||||
style: thirdTextStyle.copyWith(
|
||||
fontSize: SizeConfig.blockHorizontal! * 3.5,
|
||||
letterSpacing: 0.085,
|
||||
color: Color(0xff181818),
|
||||
),
|
||||
)),
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
return SafeArea(
|
||||
child: MultiProvider(
|
||||
providers: [
|
||||
ChangeNotifierProvider(
|
||||
create: (context) => DetailCourseCouponProvider(
|
||||
courseService: CourseService(), id: idcourse, coupon: coupon),
|
||||
),
|
||||
ChangeNotifierProvider(
|
||||
create: (context) =>
|
||||
detailRatingCourseProvider.DetailRatingCourseProvider(
|
||||
courseService: CourseService(), id: idcourse),
|
||||
),
|
||||
ChangeNotifierProvider(
|
||||
create: (context) =>
|
||||
sectionLessonCourseProvider.SectionLessonCourseProvider(
|
||||
id: idcourse, sectionLessonService: SectionLessonService()),
|
||||
),
|
||||
],
|
||||
child: Consumer<DetailCourseCouponProvider>(
|
||||
builder: (context, state, _) {
|
||||
if (state.state == ResultState.Loading) {
|
||||
return Center(
|
||||
child: CircularProgressIndicator(
|
||||
color: secondaryColor,
|
||||
strokeWidth: 2,
|
||||
),
|
||||
);
|
||||
} else if (state.state == ResultState.HasData) {
|
||||
var detailCourse = state.result!;
|
||||
|
||||
return Scaffold(
|
||||
body: ListView(
|
||||
physics: ScrollPhysics(),
|
||||
shrinkWrap: true,
|
||||
children: [
|
||||
AppBarHeader(
|
||||
idcourse: idcourse,
|
||||
),
|
||||
HeaderCoupon(
|
||||
dataDetailCourseModel: detailCourse,
|
||||
),
|
||||
MultiProvider(
|
||||
providers: [
|
||||
ChangeNotifierProvider(
|
||||
create: (context) =>
|
||||
instructorProvider.InstructorProvider(
|
||||
instructorService: InstructorService(),
|
||||
id: int.parse(detailCourse.instructorId!)),
|
||||
),
|
||||
ChangeNotifierProvider(
|
||||
create: (context) => TabProvider()),
|
||||
],
|
||||
child: CustomTabBar(
|
||||
dataDetailCourseModel: detailCourse,
|
||||
totalDuration: detailCourse.totalDuration,
|
||||
bio: detailCourse.bio,
|
||||
instructor: detailCourse.instructor,
|
||||
rating: detailCourse.rating[0].avgRating.toString(),
|
||||
review: detailCourse.rating[0].totalReview,
|
||||
totalLesson: detailCourse.totalLesson,
|
||||
totalStudent: detailCourse.totalStudents,
|
||||
),
|
||||
),
|
||||
]
|
||||
// var finalRating = double.parse(
|
||||
|
||||
),
|
||||
bottomNavigationBar: (detailCourse.isMine == 1)
|
||||
? playCourseNav(
|
||||
detailCourse.id,
|
||||
detailCourse.instructor,
|
||||
detailCourse.thumbnail,
|
||||
detailCourse.title,
|
||||
)
|
||||
: (detailCourse.isFreeCourse == '1' || typeCoupon == '1')
|
||||
? freeBottomNav(
|
||||
detailCourse.id,
|
||||
detailCourse.instructor,
|
||||
detailCourse.thumbnail,
|
||||
detailCourse.title,
|
||||
)
|
||||
: bottomNav(
|
||||
discountPrice: detailCourse.discountPrice ?? ' ',
|
||||
idCourse: detailCourse.id,
|
||||
instructor: detailCourse.instructor ?? '',
|
||||
price: detailCourse.price ?? '',
|
||||
title: detailCourse.title ?? '',
|
||||
imageUrl: detailCourse.thumbnail ??
|
||||
'$baseUrl/uploads/courses_thumbnail/course_thumbnail_default_57.jpg'),
|
||||
);
|
||||
} else if (state.state == ResultState.NoData) {
|
||||
return Center(child: Text(state.message));
|
||||
} else if (state.state == ResultState.Error) {
|
||||
return Center(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
Text('Server internal Error'),
|
||||
],
|
||||
),
|
||||
);
|
||||
} else {
|
||||
return Center(child: Text(''));
|
||||
}
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
2000
lib/screens/detail_course/detail_course_screen.dart
Normal file
2000
lib/screens/detail_course/detail_course_screen.dart
Normal file
File diff suppressed because it is too large
Load Diff
1592
lib/screens/detail_course/detail_course_voucher_screen.dart
Normal file
1592
lib/screens/detail_course/detail_course_voucher_screen.dart
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user