import 'dart:async'; import 'package:flutter/cupertino.dart'; import 'package:flutter/rendering.dart'; import 'package:flutter/services.dart'; import 'package:flutter/material.dart'; import 'package:flutter/widgets.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:initial_folder/services/all_certificate_service.dart'; import 'package:initial_folder/size_config.dart'; import 'package:initial_folder/theme.dart'; import 'package:intl/intl.dart'; import 'package:provider/provider.dart'; import 'package:initial_folder/providers/certificate_provider.dart' as certifProvider; import 'package:qr_flutter/qr_flutter.dart'; class Sertif extends StatefulWidget { Sertif({ Key? key, this.totalProgress, this.idCourse, this.idPayment, this.finishDate, this.text, this.pdfBytes, this.saving, }) : super(key: key); static String routeName = "/sertif"; final int? totalProgress; final int? idCourse; final String? idPayment; final String? text; final dynamic finishDate; bool? saving = false; final Uint8List? pdfBytes; @override State createState() => _SertifState(); } class _SertifState extends State { final _globalKeySertif = GlobalKey(); bool _isLoading = false; @override Widget build(BuildContext context) { Future.delayed(Duration(seconds: 0), () { if (widget.text == null) { Provider.of(context, listen: false) .getCertif(widget.idCourse.toString()); } else { Provider.of(context, listen: false) .checkSertif(widget.text!); } }); certifProvider.CertificateProvider? certifProv = Provider.of(context, listen: false); Widget notFinish() { return SafeArea( child: Scaffold( appBar: AppBar( centerTitle: true, ), body: Center( child: Container( height: getProportionateScreenHeight(270), decoration: BoxDecoration( color: Theme.of(context).colorScheme.primaryContainer, borderRadius: BorderRadius.circular(15), boxShadow: [ BoxShadow( color: Theme.of(context).brightness == Brightness.dark ? Colors.black : Colors.grey, blurRadius: 2, spreadRadius: 1, offset: Offset(0, 3)) ]), margin: EdgeInsets.only( left: getProportionateScreenWidth(16), right: getProportionateScreenWidth(16), ), child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Text( 'Sertifikat', textAlign: TextAlign.center, style: thirdTextStyle.copyWith( letterSpacing: -0.5, color: Theme.of(context).colorScheme.onBackground, fontWeight: reguler, fontSize: getProportionateScreenWidth(28), ), ), Text( 'Belum Tersedia', textAlign: TextAlign.center, style: thirdTextStyle.copyWith( letterSpacing: -0.5, color: Theme.of(context).colorScheme.onBackground, fontWeight: reguler, fontSize: getProportionateScreenWidth(28), ), ), SizedBox(height: getProportionateScreenHeight(24)), Padding( padding: EdgeInsets.symmetric(horizontal: 15), child: Stack( children: [ Container( width: double.infinity, height: getProportionateScreenWidth(20), decoration: BoxDecoration( borderRadius: BorderRadius.circular(10), color: Colors.grey[300], ), ), Container( width: (SizeConfig.screenWidth - getProportionateScreenWidth(32)) * (widget.totalProgress ?? 0) / 100, height: getProportionateScreenWidth(20), decoration: BoxDecoration( borderRadius: BorderRadius.circular(10), color: primaryColor, ), child: Text( '${widget.totalProgress ?? 0}%', textAlign: TextAlign.center, style: primaryTextStyle.copyWith( fontSize: getProportionateScreenWidth(12), fontWeight: reguler, color: Colors.white, letterSpacing: 0.5, ), ), ), ], ), ), SizedBox(height: getProportionateScreenHeight(16)), Text( 'Anda baru menyelesaikan ${widget.totalProgress ?? 0}% kursus', textAlign: TextAlign.center, style: thirdTextStyle.copyWith( letterSpacing: 0.5, color: Theme.of(context).colorScheme.onBackground, fontWeight: reguler, fontSize: getProportionateScreenWidth(13), ), ), SizedBox(height: getProportionateScreenHeight(16)), Text( 'Anda belum memenuhi persyaratan untuk mendapatkan sertfikat. Selesaikan kursus anda untuk mendapatkan sertifikat penyelesaian kursus.', textAlign: TextAlign.center, style: primaryTextStyle.copyWith( letterSpacing: 0.5, color: Theme.of(context).colorScheme.onBackground, fontWeight: reguler, fontSize: getProportionateScreenWidth(13), ), ), ], ), ), ), ), ); } Widget checkCertificateFinish() { return SafeArea( child: Scaffold( appBar: AppBar( centerTitle: true, title: Text( 'Sertifikat', style: thirdTextStyle.copyWith( letterSpacing: 0.23, fontWeight: semiBold, fontSize: getProportionateScreenWidth(14), ), )), body: Center( child: Container( margin: EdgeInsets.only( left: getProportionateScreenWidth(16), right: getProportionateScreenWidth(16), ), child: Consumer( builder: (context, state, _) { if (state.state == certifProvider.ResultState.Loading) { return Center( child: CircularProgressIndicator( strokeWidth: 2, color: primaryColor, ), ); } else if (state.state == certifProvider.ResultState.HasData) { return Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Container( margin: EdgeInsets.all(15), width: double.infinity, height: 280, child: LayoutBuilder( builder: (context, constraint) { return Stack( alignment: Alignment.center, children: [ Image.asset( 'assets/images/certif_template_new.png'), Positioned( top: constraint.maxHeight / 2.55, left: 0, right: 0, child: Padding( padding: const EdgeInsets.symmetric( horizontal: 25), child: Text( certifProv.name!, textAlign: TextAlign.center, style: primaryTextStyle.copyWith( fontWeight: FontWeight.bold, fontSize: 14, color: Color(0xff575553)), ), ), ), Positioned( top: constraint.maxHeight / 1.9, left: 0, right: 0, child: Padding( padding: const EdgeInsets.symmetric( horizontal: 33), child: Text('"${certifProv.title}"', style: primaryTextStyle.copyWith( fontWeight: FontWeight.bold, fontSize: (certifProv.title!.length > 20) ? 9 : 12, color: Color(0xff575553)), textAlign: TextAlign.center), ), ), Positioned( top: constraint.maxHeight / 1.6, left: 0, right: 0, child: Center( child: Text( '${DateFormat('dd MMMM yyyy ').format(DateTime.fromMillisecondsSinceEpoch(certifProv.finishDate * 1000))}', style: primaryTextStyle.copyWith( fontWeight: FontWeight.normal, fontSize: 8, color: Color(0xff575553)), ), ), ), Positioned( bottom: constraint.maxHeight / 5.6, left: constraint.maxWidth / 10, child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( 'Certificate no : ${certifProv.certificateNo}', style: primaryTextStyle.copyWith( fontWeight: FontWeight.normal, fontSize: 4, color: Color(0xff575553), ), ), Text( 'Certificate URL : https://vocasia-v4-develop.vercel.app/certificate/${certifProv.certificateNo}', style: primaryTextStyle.copyWith( fontWeight: FontWeight.normal, fontSize: 4, color: Color(0xff575553), ), ), ], ), ) ], ); }, ), ), ], ); } else if (state.state == certifProvider.ResultState.Error) { return Center( child: Column( children: [ Text( 'Terjadi Kesalahan Coba Lagi', style: thirdTextStyle, ), ], ), ); } else { return Center( child: Text( 'Terjadi kesalahan', style: thirdTextStyle, ), ); } }, ), ), ), ), ); } Widget checkCertificateNotFinished() { return SafeArea( child: Scaffold( appBar: AppBar( centerTitle: true, title: Text( 'Sertifikat', style: thirdTextStyle.copyWith( letterSpacing: 0.23, fontWeight: semiBold, fontSize: getProportionateScreenWidth(14), ), ), ), body: Center( child: Text( 'Sertifikat Belum Diterbitkan', textAlign: TextAlign.center, style: primaryTextStyle.copyWith( letterSpacing: 0.5, color: Theme.of(context).colorScheme.onBackground, fontWeight: reguler, fontSize: getProportionateScreenWidth(20), ), ), ), ), ); } Widget buildCertificate() { return Container( color: Colors.red, margin: EdgeInsets.all(15), width: double.infinity, height: 300, child: Stack( alignment: Alignment.center, children: [ Image.asset('assets/certif_template_new.png'), Positioned( top: 120, left: 0, right: 0, child: Padding( padding: EdgeInsets.symmetric( horizontal: getProportionateScreenHeight(25)), child: Text( 'Safinatun Najah Unju', textAlign: TextAlign.center, style: TextStyle( fontWeight: FontWeight.bold, fontSize: getProportionateScreenWidth(14)), ), ), ), Positioned( top: 155, left: 0, right: 0, child: Padding( padding: EdgeInsets.symmetric( horizontal: getProportionateScreenHeight(33)), child: Column( children: [ Text( '"Basic Excel Trainig For Professional Employees & Recruitment Selection Candidates"', style: TextStyle( fontWeight: FontWeight.w600, fontSize: 12), textAlign: TextAlign.center), SizedBox(height: getProportionateScreenHeight(10)), Text( 'Jakarta, 24 October 2021', style: TextStyle( fontWeight: FontWeight.normal, fontSize: getProportionateScreenWidth(8)), ) ], ), ), ), Positioned( bottom: getProportionateScreenHeight(50), left: (65 / 640) * MediaQuery.of(context).size.width, child: Column( children: [ Text( 'Certificate no : 257911829183', style: TextStyle( fontWeight: FontWeight.normal, fontSize: getProportionateScreenWidth(6)), ), Text( 'Certificate no : 257911829183', style: TextStyle( fontWeight: FontWeight.normal, fontSize: getProportionateScreenWidth(6)), ), ], ), ) ], ), ); } Widget finish() { return SafeArea( child: Scaffold( appBar: AppBar( backgroundColor: Theme.of(context).colorScheme.background, centerTitle: true, title: Text( 'Sertifikat', style: thirdTextStyle.copyWith( letterSpacing: 0.23, fontWeight: semiBold, fontSize: getProportionateScreenWidth(14)), ), ), body: Center( child: Container( child: Consumer( builder: (context, state, _) { if (state.state == certifProvider.ResultState.Loading) { return Center( child: CircularProgressIndicator( color: primaryColor, strokeWidth: 2, ), ); } else if (state.state == certifProvider.ResultState.HasData) { return Column( mainAxisAlignment: MainAxisAlignment.center, children: [ InteractiveViewer( child: RepaintBoundary( key: _globalKeySertif, child: Container( width: getProportionateScreenWidth(300), height: getProportionateScreenHeight(173), child: LayoutBuilder( builder: (context, constraint) { return Stack( alignment: Alignment.center, children: [ Image.asset( 'assets/images/certif_template_new.png'), Positioned.fill( child: FractionallySizedBox( alignment: Alignment.center, widthFactor: 1.0, heightFactor: 0.6, child: Padding( padding: EdgeInsets.only( left: getProportionateScreenWidth(28.5), right: getProportionateScreenWidth(240), top: getProportionateScreenHeight(10), bottom: getProportionateScreenHeight(90) ), child: Text( certifProv.certificateNo!.toUpperCase(), textAlign: TextAlign.left, style: primaryTextStyle.copyWith( fontFamily: 'Arial', fontWeight: FontWeight.w500, fontSize: getProportionateScreenWidth( 4), color: Color.fromARGB(255, 255, 255, 255), ), ), ), ), ), Positioned.fill( child: FractionallySizedBox( alignment: Alignment.center, widthFactor: 1.0, heightFactor: 0.3, child: Padding( padding: EdgeInsets.only( left: getProportionateScreenWidth(27.5), right: getProportionateScreenHeight( 80), top: getProportionateScreenHeight( 6), ), child: Text( certifProv.name!.toUpperCase(), textAlign: TextAlign.left, style: primaryTextStyle.copyWith( fontFamily: 'Arial', fontWeight: FontWeight.bold, fontSize: getProportionateScreenWidth( 9), color: Color.fromARGB(255, 248, 124, 0), ), ), ), ), ), Positioned.fill( child: FractionallySizedBox( alignment: Alignment.bottomCenter, widthFactor: 1.0, heightFactor: 0.5, child: Padding( padding: EdgeInsets.only( right: getProportionateScreenWidth( 85), left: 27.5), child: Text('"${certifProv.title}"', style: primaryTextStyle.copyWith( fontFamily: 'Arial', fontWeight: FontWeight.bold, fontSize: certifProv .title!.length > 40 ? getProportionateScreenWidth( 9) : getProportionateScreenWidth( 11), color: Color.fromARGB(255, 248, 124, 0)), textAlign: TextAlign.left, ), ), ), ), Positioned.fill( child: FractionallySizedBox( alignment: Alignment.bottomLeft, widthFactor: 0.299, heightFactor: 0.62, child: Center( child: Padding( padding: EdgeInsets.only( bottom: getProportionateScreenHeight( 2), left: 5), child: Text( 'Jakarta, ${DateFormat('dd MMMM yyyy ').format(DateTime.fromMillisecondsSinceEpoch(certifProv.finishDate * 1000))}', style: primaryTextStyle.copyWith( fontWeight: FontWeight.normal, fontSize: getProportionateScreenWidth( 4), color: Color.fromARGB(255, 0, 0, 0)), ), ), ), ), ), Positioned.fill( child: FractionallySizedBox( alignment: Alignment.bottomRight, // widthFactor heightFactor: 0.495, child: Padding( padding: EdgeInsets.only( right: 19 ), child: Column( crossAxisAlignment: CrossAxisAlignment.end, children: [ QrImageView( data: "https://vocasia.id/?no-certificate=${certifProv.certificateNo}", version: QrVersions.auto, size: getProportionateScreenHeight(48), gapless: false,), ], ), ), ), ), Positioned.fill( child: FractionallySizedBox( alignment: Alignment.bottomRight, // widthFactor heightFactor: 0.18, child: Padding( padding: EdgeInsets.only( right: 25 ), child: Column( crossAxisAlignment: CrossAxisAlignment.end, children: [ RichText( text: TextSpan( text: 'Issued : ${DateFormat('dd MMMM yyyy ').format(DateTime.fromMillisecondsSinceEpoch(certifProv.finishDate * 1000))}', style: primaryTextStyle .copyWith( fontWeight: FontWeight.normal, fontSize: getProportionateScreenWidth( 3), color: Color(0xff575553), ), ), ) ], ), ), ), ), ], ); }, ), ), ), ), SizedBox(height: getProportionateScreenHeight(10)), Padding( padding: EdgeInsets.symmetric( horizontal: getProportionateScreenWidth(70)), child: ElevatedButton( style: ElevatedButton.styleFrom( shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(8), ), minimumSize: Size(double.infinity, getProportionateScreenHeight(40)), backgroundColor: primaryColor, ), onPressed: _isLoading ? null : () async { setState(() { _isLoading = true; }); try { await AllCertificateServices() .convertAndUpload(_globalKeySertif, certifProv.idPayment!); ScaffoldMessenger.of(context) .showSnackBar( SnackBar( duration: Duration(seconds: 2), backgroundColor: primaryColor, content: Text( 'Cek email anda!', textAlign: TextAlign.center, style: primaryTextStyle.copyWith( color: baruTextutih), ), behavior: SnackBarBehavior.floating, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(5), ), ), ); } catch (e) { print('Error: $e'); ScaffoldMessenger.of(context) .showSnackBar( SnackBar( content: Text( 'Gagal mengunduh sertifikat')), ); } finally { setState(() { _isLoading = false; }); } }, child: _isLoading ? CircularProgressIndicator(color: baruTextutih) : Row( mainAxisAlignment: MainAxisAlignment.center, children: [ SvgPicture.asset( 'assets/icons/download.svg', color: baruTextutih, width: 18, height: 18, ), Text( 'Download Sertifikat', style: thirdTextStyle.copyWith( color: baruTextutih, fontSize: getProportionateScreenWidth(12), ), ), ], ), ), ) ], ); } else if (state.state == certifProvider.ResultState.Error) { return Center( child: Column( children: [ Text( 'Terjadi Kesalahan Coba Lagi', style: thirdTextStyle, ), ], ), ); } else { return Center( child: Text( 'Terjadi kesalahan', style: thirdTextStyle, ), ); } }, ), ), ), ), ); } if (widget.totalProgress == 100 && widget.idCourse != null) { return finish(); } else if (widget.totalProgress != 100 && widget.idCourse != null) { return notFinish(); } else if (widget.finishDate != false) { return checkCertificateFinish(); } else { return checkCertificateNotFinished(); } } }