Initial commit: Penyerahan final Source code Tugas Akhir

This commit is contained in:
ferdiakhh
2025-07-10 19:15:14 +07:00
commit e1f2206b8a
687 changed files with 80132 additions and 0 deletions

View File

@ -0,0 +1,77 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_feather_icons/flutter_feather_icons.dart';
import 'package:initial_folder/providers/certificate_provider.dart';
import 'package:initial_folder/screens/certificate/component/just_certificate_count.dart';
import 'package:provider/provider.dart';
import '../../../size_config.dart';
import '../../../theme.dart';
class CertificateHeader extends StatelessWidget {
const CertificateHeader({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Consumer<CertificateProvider>(
builder: (context, value, _) {
return RefreshIndicator(
onRefresh: () async {
await Provider.of<CertificateProvider>(context, listen: false)
.getAllCertif();
},
child: const Column(
children: [
JustCertificateCount(),
// Visibility(
// visible: value.state != ResultState.Loading,
// child: Container(
// // decoration: BoxDecoration(
// // borderRadius: BorderRadius.circular(10),
// // color: Theme.of(context).brightness == Brightness.dark
// // ? seventeenColor
// // : secondaryColor.withOpacity(0.3),
// // ),
// height: 40,
// // child: TextField(
// // autofocus: false,
// // onSubmitted: (value) async {
// // if (value.trim().isNotEmpty) {
// // Provider.of<CertificateProvider>(context, listen: false)
// // .searchCertif(value);
// // }
// // },
// // style: primaryTextStyle.copyWith(
// // fontSize: getProportionateScreenWidth(14),
// // letterSpacing: 0.5,
// // ),
// // cursorColor: secondaryColor,
// // decoration: InputDecoration(
// // border: InputBorder.none,
// // errorBorder: OutlineInputBorder(
// // borderSide: BorderSide(color: sevenColor),
// // borderRadius: BorderRadius.circular(10)),
// // contentPadding: EdgeInsets.only(
// // top: getProportionateScreenHeight(3.5)),
// // prefixIcon: Icon(
// // FeatherIcons.search,
// // size: 20,
// // color: Colors.grey,
// // ),
// // hintText: 'Cari sertifikat kursus',
// // hintStyle: primaryTextStyle.copyWith(
// // fontSize: getProportionateScreenWidth(12),
// // color: secondaryColor,
// // letterSpacing: 0.5,
// // ),
// // ),
// // ),
// ),
// ),
],
),
);
},
);
}
}

View File

@ -0,0 +1,421 @@
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:initial_folder/models/my_certificate.dart';
import 'package:initial_folder/providers/certificate_provider.dart';
import 'package:initial_folder/screens/course/sertif.dart';
import 'package:initial_folder/screens/course/sertif_view.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:shimmer/shimmer.dart';
import 'package:initial_folder/screens/certificate/component/just_certificate_count.dart';
class CertificateItem extends StatefulWidget {
const CertificateItem({Key? key}) : super(key: key);
@override
State<CertificateItem> createState() => _CertificateItemState();
}
class _CertificateItemState extends State<CertificateItem> {
@override
Widget build(BuildContext context) {
return Consumer<CertificateProvider>(
builder: (context, value, child) {
return certificateCountComponent('assets/icons/gold-medal.png',
value.allCertificateCount.toString(), 'Jumlah Sertifikat', context);
},
);
}
Widget certificateCountComponent(
String icon,
String count,
String content,
BuildContext context,
) {
return ShaderMask(
shaderCallback: (Rect rect) {
return LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: [
Colors.black,
Colors.transparent,
Colors.transparent,
Colors.black
],
stops: [0.0, 0.02, 0.98, 1.0],
).createShader(rect);
},
blendMode: BlendMode.dstOut,
child: Consumer<CertificateProvider>(
builder: (context, state, _) {
if (state.state == ResultState.HasData) {
return Column(
children: [
SizedBox(height: getProportionateScreenHeight(10)),
Container(
padding:
EdgeInsets.only(top: getProportionateScreenHeight(10)),
height: getProportionateScreenWidth(550),
child: ListView.builder(
itemCount: state.allCertificate?.length,
itemBuilder: (context, index) {
return allCertificates(state, index, instructorProfile,
buttonOpacity, buttonActivator);
},
),
)
],
);
} else if (state.state == ResultState.Loading) {
return Shimmer.fromColors(
baseColor: Colors.grey,
highlightColor: Colors.white,
child: Column(
children: [
SizedBox(height: getProportionateScreenHeight(10)),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Row(
children: [
Container(
width: getProportionateScreenWidth(100),
height: getProportionateScreenHeight(20),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
color: Colors.white),
),
SizedBox(width: getProportionateScreenHeight(130)),
Container(
width: getProportionateScreenWidth(50),
height: getProportionateScreenHeight(20),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
color: Colors.white),
),
],
),
],
),
Container(
padding:
EdgeInsets.only(top: getProportionateScreenHeight(10)),
height: getProportionateScreenWidth(500),
child: ListView.builder(
itemCount: 5,
itemBuilder: (context, index) {
return Padding(
padding: EdgeInsets.only(
top: getProportionateScreenHeight(20)),
child: Container(
height: getProportionateScreenHeight(90),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
color: Colors.white),
),
);
},
),
)
],
),
);
} else if (state.state == ResultState.NoData) {
return Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
JustCertificateCount(),
],
),
Center(
child: Padding(
padding:
EdgeInsets.only(top: getProportionateScreenHeight(180)),
child: Text('Sertifikat Tidak Tersedia'),
),
)
],
);
} else if (state.state == ResultState.Error) {
return Center(
child: Text('Terjadi Kesalahan'),
);
} else {
return Center(
child: Text(''),
);
}
},
),
);
}
instructorProfile(DataMyCertificateModel certificate) {
if (certificate.fotoProfile == null) {
return Image.asset(
"assets/images/Profile Image.png",
width: getProportionateScreenWidth(21),
height: getProportionateScreenHeight(21),
);
} else
return CircleAvatar(
radius: getProportionateScreenWidth(10),
backgroundImage: NetworkImage(certificate.fotoProfile!),
);
}
buttonOpacity(int percentage) {
if (percentage == 100) {
return primaryColor;
} else {
return Color.fromRGBO(237, 169, 35, 0.5);
}
}
buttonActivator(int percentage, BuildContext context,
DataMyCertificateModel certificate) {
if (percentage == 100) {
return () {
Navigator.push(
context,
CustomNavigator(
child: Sertif(
idCourse: int.parse(certificate.courseId!),
totalProgress: certificate.progress,
),
),
);
};
} else {
return null;
}
}
buttonActivatorView(int percentage, BuildContext context,
DataMyCertificateModel certificate) {
if (percentage == 100) {
return () {
Navigator.push(
context,
CustomNavigator(
child: SertifView(
idCourse: int.parse(certificate.courseId!),
totalProgress: certificate.progress,
),
),
);
};
} else {
return null;
}
}
allCertificates(
state, index, instructorProfile, buttonOpacity, buttonActivator) {
return Padding(
padding: EdgeInsets.symmetric(vertical: getProportionateScreenHeight(8)),
child: Container(
height: getProportionateScreenHeight(120),
padding:
EdgeInsets.symmetric(horizontal: getProportionateScreenWidth(10)),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
color: Theme.of(context).colorScheme.primaryContainer,
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.1),
spreadRadius: 0,
blurRadius: 4,
offset: Offset(0, 4),
),
],
),
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Image.asset(
'assets/images/certificate.png',
width: getProportionateScreenWidth(45),
height: getProportionateScreenHeight(45),
),
SizedBox(
width: getProportionateScreenWidth(250),
child: Padding(
padding: EdgeInsets.symmetric(
vertical: getProportionateScreenHeight(13),
horizontal: getProportionateScreenWidth(3)),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
state.allCertificate![index]!.title!,
overflow: TextOverflow.ellipsis,
maxLines: 2,
style: TextStyle(
fontSize: getProportionateScreenWidth(13),
fontWeight: reguler),
),
SizedBox(height: getProportionateScreenHeight(10)),
Row(
children: [
instructorProfile(state.allCertificate![index]!),
SizedBox(width: getProportionateScreenWidth(5)),
Container(
width: getProportionateScreenHeight(100),
child: Text(
state.allCertificate![index]!.instructor!,
overflow: TextOverflow.ellipsis,
style: TextStyle(
fontSize: getProportionateScreenHeight(11)),
),
)
],
),
SizedBox(height: getProportionateScreenHeight(3)),
Row(
children: [
Stack(
children: [
Container(
width: (SizeConfig.screenWidth -
getProportionateScreenWidth(270)),
height: 10,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
color: Colors.grey),
),
Container(
width: (SizeConfig.screenWidth -
getProportionateScreenWidth(270)) *
state.allCertificate![index]!.progress! /
100,
height: 10,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
color: primaryColor),
),
],
),
Text(
" ${state.allCertificate![index]!.progress!.toString()}% ",
style: TextStyle(
fontSize: getProportionateScreenWidth(10),
fontWeight: bold),
),
ElevatedButton(
style: ElevatedButton.styleFrom(
minimumSize: Size(getProportionateScreenWidth(5),
getProportionateScreenHeight(5)),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(5),
),
backgroundColor: primaryColor,
disabledForegroundColor: Colors.grey,
disabledBackgroundColor: Colors.grey,
padding: EdgeInsets.symmetric(
horizontal: getProportionateScreenWidth(6)),
),
onPressed: buttonActivatorView(
state.allCertificate![index]!.progress!,
context,
state.allCertificate![index]!),
child: Row(
children: [
Padding(
padding: EdgeInsets.symmetric(
vertical: getProportionateScreenHeight(2)),
child: Text(
"Lihat\nSertifikat",
style: TextStyle(
fontSize: getProportionateScreenHeight(5),
color: baruTextutih),
),
),
SizedBox(width: getProportionateScreenWidth(5)),
SvgPicture.asset(
'assets/icons/eye.svg',
fit: BoxFit.fitWidth,
width: getProportionateScreenWidth(12),
)
],
),
),
SizedBox(width: getProportionateScreenWidth(7)),
ElevatedButton(
style: ElevatedButton.styleFrom(
minimumSize: Size(getProportionateScreenWidth(5),
getProportionateScreenHeight(5)),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(5),
),
backgroundColor: primaryColor,
disabledForegroundColor: Colors.grey,
disabledBackgroundColor: Colors.grey,
padding: EdgeInsets.symmetric(
horizontal: getProportionateScreenWidth(6)),
),
onPressed: buttonActivator(
state.allCertificate![index]!.progress!,
context,
state.allCertificate![index]!),
child: Row(
children: [
Padding(
padding: EdgeInsets.symmetric(
vertical: getProportionateScreenHeight(2)),
child: Text(
"Download\nSertifikat",
style: TextStyle(
fontSize: getProportionateScreenHeight(5),
color: baruTextutih),
),
),
SizedBox(width: getProportionateScreenWidth(5)),
SvgPicture.asset(
'assets/icons/download.svg',
fit: BoxFit.fitWidth,
width: getProportionateScreenWidth(12),
)
],
),
),
SizedBox(width: getProportionateScreenWidth(10)),
],
),
],
),
),
),
],
),
),
);
}
Widget certificateCountComponents(
String count,
BuildContext context,
) {
return Center(
child: ListView(
children: [
Container(
padding: const EdgeInsets.all(20.0),
constraints: BoxConstraints(
minHeight: MediaQuery.of(context).size.height / 1.5),
child: Center(
child: Text(count),
),
)
],
),
);
}
}

View File

@ -0,0 +1,380 @@
import 'package:flutter/material.dart';
import 'package:initial_folder/models/my_certificate.dart';
import 'package:initial_folder/providers/certificate_provider.dart';
import 'package:initial_folder/screens/certificate/component/all_certificate_header.dart';
import 'package:initial_folder/screens/course/sertif.dart';
import 'package:initial_folder/size_config.dart';
import 'package:initial_folder/theme.dart';
import 'package:provider/provider.dart';
import 'package:shimmer/shimmer.dart';
class JustCertificateCount extends StatefulWidget {
const JustCertificateCount({Key? key}) : super(key: key);
@override
State<JustCertificateCount> createState() => _JustCertificateCountState();
}
class _JustCertificateCountState extends State<JustCertificateCount> {
@override
Widget build(BuildContext context) {
return Consumer<CertificateProvider>(
builder: (context, value, child) {
return certificateCountComponent(
'assets/icons/gold-medal.png',
value.allCertificateCount.toString(),
'Jumlah Sertifikat Selesai',
context);
},
);
}
Widget certificateCountComponent(
String icon,
String count,
String content,
BuildContext context,
) {
return ShaderMask(
shaderCallback: (Rect rect) {
return LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: [
Colors.black,
Colors.transparent,
Colors.transparent,
Colors.black
],
stops: [0.0, 0.02, 0.98, 1.0],
).createShader(rect);
},
blendMode: BlendMode.dstOut,
child: Consumer<CertificateProvider>(
builder: (context, state, _) {
if (state.state == ResultState.HasData) {
return Column(
children: [
SizedBox(height: getProportionateScreenHeight(10)),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Row(
children: [
Image.asset(
icon,
width: getProportionateScreenWidth(18),
height: getProportionateScreenHeight(18),
),
SizedBox(width: getProportionateScreenWidth(8)),
Text(
content,
style: thirdTextStyle.copyWith(
letterSpacing: 0.42,
fontWeight: semiBold,
fontSize: getProportionateScreenWidth(12)),
),
SizedBox(width: getProportionateScreenWidth(4)),
Text(
count,
style: thirdTextStyle.copyWith(
letterSpacing: 0.42,
fontWeight: semiBold,
fontSize: getProportionateScreenWidth(17)),
),
],
),
],
),
SizedBox(height: getProportionateScreenHeight(5)),
],
);
} else if (state.state == ResultState.Loading) {
return Shimmer.fromColors(
baseColor: Colors.grey,
highlightColor: Colors.white,
child: Column(
children: [
SizedBox(height: getProportionateScreenHeight(10)),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Row(
children: [
Container(
width: getProportionateScreenWidth(100),
height: getProportionateScreenHeight(20),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
color: Colors.white),
),
SizedBox(width: getProportionateScreenHeight(130)),
Container(
width: getProportionateScreenWidth(50),
height: getProportionateScreenHeight(20),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
color: Colors.white),
),
],
),
],
),
Container(
padding:
EdgeInsets.only(top: getProportionateScreenHeight(10)),
height: getProportionateScreenWidth(500),
child: ListView.builder(
itemCount: 5,
itemBuilder: (context, index) {
return Padding(
padding: EdgeInsets.only(
top: getProportionateScreenHeight(20)),
child: Container(
height: getProportionateScreenHeight(90),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
color: Colors.white),
),
);
},
),
)
],
),
);
} else {
return Column(
children: [],
);
}
},
),
);
}
instructorProfile(DataMyCertificateModel certificate) {
if (certificate.fotoProfile == null) {
return Image.asset(
"assets/images/Profile Image.png",
scale: getProportionateScreenWidth(12),
);
} else
return CircleAvatar(
radius: getProportionateScreenWidth(8),
backgroundImage: NetworkImage(certificate.fotoProfile!),
);
}
buttonOpacity(int percentage) {
if (percentage == 100) {
return primaryColor;
} else {
return Color.fromRGBO(237, 169, 35, 0.5);
}
}
buttonActivator(int percentage, BuildContext context,
DataMyCertificateModel certificate) {
if (percentage == 100) {
return () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => Sertif(
idCourse: int.parse(certificate.courseId!),
totalProgress: certificate.progress,
),
),
);
};
} else {
return null;
}
}
allCertificates(
state, index, instructorProfile, buttonOpacity, buttonActivator) {
return Padding(
padding: EdgeInsets.symmetric(vertical: getProportionateScreenHeight(8)),
child: Container(
height: getProportionateScreenHeight(90),
padding:
EdgeInsets.symmetric(horizontal: getProportionateScreenWidth(8)),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
color: Theme.of(context).colorScheme.primaryContainer,
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.1),
spreadRadius: 0,
blurRadius: 4,
offset: Offset(0, 4),
),
],
),
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Padding(
padding: EdgeInsets.all(getProportionateScreenHeight(10)),
child: Image.asset(
'assets/icons/gold-medal.png',
fit: BoxFit.cover,
scale: getProportionateScreenWidth(2.2),
)),
Padding(
padding: EdgeInsets.symmetric(
vertical: getProportionateScreenHeight(5)),
child: Container(
height: double.infinity,
child:
VerticalDivider(color: Color.fromRGBO(52, 121, 148, 0.9)),
),
),
SizedBox(
width: getProportionateScreenWidth(150),
child: Padding(
padding: EdgeInsets.symmetric(
vertical: getProportionateScreenHeight(3),
horizontal: getProportionateScreenWidth(3)),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
state.allCertificate![index]!.title!,
overflow: TextOverflow.ellipsis,
maxLines: 2,
style: TextStyle(
fontSize: getProportionateScreenHeight(12),
fontWeight: reguler),
),
SizedBox(height: getProportionateScreenHeight(5)),
Row(
children: [
instructorProfile(state.allCertificate![index]!),
SizedBox(width: getProportionateScreenWidth(5)),
Container(
width: getProportionateScreenHeight(100),
child: Text(
state.allCertificate![index]!.instructor!,
overflow: TextOverflow.ellipsis,
style: TextStyle(
fontSize: getProportionateScreenHeight(10)),
),
)
],
),
SizedBox(height: getProportionateScreenHeight(5)),
Row(
children: [
Expanded(
child: Stack(
children: [
Container(
width: (SizeConfig.screenWidth -
getProportionateScreenWidth(245)),
height: 10,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
color: Colors.white),
),
Container(
width: (SizeConfig.screenWidth -
getProportionateScreenWidth(245)) *
state.allCertificate![index]!.progress! /
100,
height: 10,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
color: primaryColor),
),
],
),
),
Padding(
padding: EdgeInsets.symmetric(
horizontal: getProportionateScreenWidth(3)),
child: Container(
child: Align(
alignment: Alignment.center,
child: Text(
"${state.allCertificate![index]!.progress!.toString()}%",
style: TextStyle(
fontSize: 10,
color: Colors.white,
fontWeight: bold),
),
),
),
)
],
),
],
),
),
),
ElevatedButton(
style: ElevatedButton.styleFrom(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(5),
),
backgroundColor: Color.fromRGBO(45, 45, 45, 1),
disabledForegroundColor:
Color.fromRGBO(150, 150, 150, 1).withOpacity(0.38),
disabledBackgroundColor:
Color.fromRGBO(150, 150, 150, 1).withOpacity(0.12),
padding: EdgeInsets.symmetric(
vertical: 5, horizontal: getProportionateScreenWidth(5))),
onPressed: buttonActivator(
state.allCertificate![index]!.progress!,
context,
state.allCertificate![index]!),
child: Row(
children: [
Text(
"Download\nSertifikat",
style: TextStyle(
fontSize: getProportionateScreenHeight(8),
color: buttonOpacity(
state.allCertificate![index]!.progress!)),
),
SizedBox(width: getProportionateScreenWidth(5)),
Image.asset(
'assets/icons/left-arrow.png',
color:
buttonOpacity(state.allCertificate![index]!.progress!),
fit: BoxFit.fitWidth,
width: getProportionateScreenWidth(20),
)
],
),
)
],
),
),
);
}
Widget certificateCountComponents(
String count,
BuildContext context,
) {
return Center(
child: ListView(
children: [
Container(
padding: const EdgeInsets.all(20.0),
constraints: BoxConstraints(
minHeight: MediaQuery.of(context).size.height / 1.5),
child: Center(
child: Text(count),
),
)
],
),
);
}
}