Initial commit: Penyerahan final Source code Tugas Akhir
This commit is contained in:
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),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user