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 createState() => _DesksripsiState(); } class _DesksripsiState extends State { bool isExpanded = false; bool isExpanded2 = false; bool isExpanded3 = false; @override Widget build(BuildContext context) { final themeProvider = Provider.of(context); DescriptionProvider descriptionProvider = Provider.of(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 kemampuanDiraihList() { List 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 persyaratanList() { List 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), ), ), ), ), ], ), ], ), ], ); } }