import 'package:flutter/material.dart'; import 'package:initial_folder/get_it.dart'; import 'package:initial_folder/helper/user_info.dart'; import 'package:initial_folder/models/detail_course_model.dart'; import 'package:initial_folder/providers/detail_course_provider.dart'; import 'package:initial_folder/providers/total_price_provider.dart'; import 'package:initial_folder/screens/checkout/components/course_list.dart'; import 'package:initial_folder/screens/checkout/detail_zero_payment.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/size_config.dart'; import 'package:initial_folder/theme.dart'; import 'package:intl/intl.dart'; import 'package:provider/provider.dart'; import 'package:initial_folder/providers/payments_provider.dart' as paymentsProvider; import 'package:initial_folder/providers/my_course_provider.dart' as myCourseProvider; import '../../providers/payments_provider.dart'; import 'snap_payment_page.dart'; class CheckoutPage extends StatefulWidget { final idCourse; final title; final discountPrice; final price; final instructor; final thumbnail; const CheckoutPage({ Key? key, required this.idCourse, required this.instructor, required this.title, required this.price, required this.discountPrice, required this.thumbnail, }) : super(key: key); @override State createState() => _CheckoutPageState(); } class _CheckoutPageState extends State { final controller = TextEditingController(); final provider = detailGetIt(); Future _showMessage(String text) { return showDialog( context: context, builder: (context) => AlertDialog( contentPadding: EdgeInsets.fromLTRB(22, 30, 22, 30), content: Text( text, textAlign: TextAlign.center, style: primaryTextStyle.copyWith( fontSize: getProportionateScreenWidth(12), letterSpacing: 1), ), ), ); } @override Widget build(BuildContext context) { provider.getDetail(widget.idCourse); final selectedTotalPrice = Provider.of(context); // String? discountPrice; return StreamBuilder( stream: provider.detailStream, builder: (context, AsyncSnapshot snapshot) { final detail = snapshot.data?.data[0][0]; // discountPrice = detail?.discountPrice ?? '0'; if (snapshot.hasError) { return Center( child: Text( 'Terjadi Kesalahan', style: thirdTextStyle, ), ); } else { switch (snapshot.connectionState) { case ConnectionState.waiting: Center( child: CircularProgressIndicator( color: primaryColor, strokeWidth: 2, ), ); break; case ConnectionState.none: Center( child: Text( 'Tidak ada koneksi', style: thirdTextStyle, ), ); break; case ConnectionState.active: final detail = snapshot.data?.data[0][0]; // discountPrice = detail?.discountPrice ?? '0'; body(widget.idCourse, detail?.title ?? '', detail?.price ?? '0', detail?.discountPrice ?? '0', detail?.thumbnail ?? ''); break; case ConnectionState.done: final detail = snapshot.data?.data[0][0]; // discountPrice = detail?.discountPrice ?? '0'; body(widget.idCourse, detail?.title ?? '', detail?.price ?? '0', detail?.discountPrice ?? '0', detail?.thumbnail ?? ''); break; } } return body(widget.idCourse, detail?.title ?? '', detail?.price ?? '0', detail?.discountPrice ?? '0', detail?.thumbnail ?? ''); }, ); } Widget bottomNav(String discountPrice, String price) { String total = discountPrice == '0' ? price : discountPrice; paymentsProvider.PaymentsProvider pay = Provider.of(context); final selectedTotalPrice = Provider.of(context); hargaTotalNavBar() { String hargaTotal = 'Rp. ${NumberFormat.currency(locale: 'id', symbol: '', decimalDigits: 0).format(double.parse(price) - (double.parse(price) - double.parse(discountPrice)))}'; return hargaTotal; } showNotifDialog(BuildContext context) { showDialog( context: context, builder: (context) { return AlertDialog( content: Consumer( 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, ); } }, ), ); }, ); } 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 route) => false); }, child: Text( 'Login', style: primaryTextStyle.copyWith( fontSize: getProportionateScreenWidth(12), letterSpacing: 1, color: primaryColor), ), ), ], ), ); } handleNotLoginFree( String? id, String? title, String? thumb, String? instr, ) async { var token = await UsersInfo().getToken(); if (token != null || Condition.loginFirebase == true) { print("ini bisa ya"); if (await pay.freeCourse(int.parse(widget.idCourse))) { await Provider.of(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); } } int totalPrice; if (int.parse(discountPrice) != 0 && int.parse(discountPrice) < 50000) { totalPrice = int.parse(discountPrice) + 5000; } else { if (int.parse(price) < 50000) { totalPrice = int.parse(price) + 5000; } else { totalPrice = int.parse(price); } } return Container( width: double.infinity, height: getProportionateScreenHeight(64), decoration: BoxDecoration( border: Border(top: BorderSide(color: fourthColor)), boxShadow: [ BoxShadow( offset: Offset(0, -2), blurRadius: 50, color: fourthColor.withOpacity(0.15), ) ], ), child: Row( children: [ SizedBox(width: 13), Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ SizedBox(height: getProportionateScreenHeight(6)), Text( "Total", style: primaryTextStyle.copyWith( fontSize: getProportionateScreenHeight(12), letterSpacing: 1), ), SizedBox(height: 2), if (int.parse(price) < 50000 || int.parse(discountPrice) < 50000) Text( "Rp. ${NumberFormat.currency(locale: 'id', symbol: '', decimalDigits: 0).format(totalPrice)}", style: primaryTextStyle.copyWith( fontSize: SizeConfig.blockVertical! * 2.5, letterSpacing: 0.23), ) else Text( "Rp. ${NumberFormat.currency(locale: 'id', symbol: '', decimalDigits: 0).format(discountPrice == "0" ? double.parse(price) : double.parse(discountPrice))}", style: primaryTextStyle.copyWith( fontSize: SizeConfig.blockVertical! * 2.5, letterSpacing: 0.23), ), SizedBox(height: getProportionateScreenHeight(2)), ], ), Spacer(), GestureDetector( onTap: () async { selectedTotalPrice.selectedTotalPrice = totalPrice; if (price == "0") { Navigator.of(context).push( MaterialPageRoute( builder: (context) => DetailZeroPayment( discountPrice: discountPrice, price: price, ), ), ); } else { // Dapatkan total harga dan id transaksi untuk Snap Midtrans String orderId = 'order-${DateTime.now().millisecondsSinceEpoch}'; int grossAmount = int.parse(price); // Persiapkan data invoice berdasarkan pesanan List> dataInvoice = [ { 'id_kursus': widget.idCourse, 'title_kursus': widget.title, 'harga': price.toString(), 'qty': '1', } ]; // Panggil Snap melalui provider final paymentProvider = Provider.of(context, listen: false); bool success = (await paymentProvider.startSnapPayment( orderId: orderId, grossAmount: grossAmount, dataInvoice: dataInvoice, )) as bool; if (success) { // Jika Snap berhasil, tampilkan halaman WebView Snap Navigator.of(context).push( MaterialPageRoute( builder: (context) => SnapPaymentPage( transactionToken: '', orderId: orderId, grossAmount: grossAmount, courseTitle: '', courseThumbnail: '', courseInstructor: '', courseId: '', ), ), ); } else { print("Pembayaran gagal"); } } }, child: Container( margin: EdgeInsets.only(right: getProportionateScreenWidth(15)), width: getProportionateScreenWidth(188), height: getProportionateScreenHeight(41), decoration: BoxDecoration( color: primaryColor, borderRadius: BorderRadius.circular(5), ), child: Center( child: Text( 'Lengkapi Pembayaran', style: thirdTextStyle.copyWith( fontSize: SizeConfig.blockVertical! * 1.7, fontWeight: semiBold, letterSpacing: 0.32, color: Color(0xff050505), ), ), ), ), ) ], ), ); } Widget body(String idCourse, String title, String price, String discountPrice, String imageUrl) { int totalPrice; if (int.parse(discountPrice) != 0 && int.parse(discountPrice) < 50000) { totalPrice = int.parse(discountPrice) + 5000; } else { if (int.parse(price) < 50000) { totalPrice = int.parse(price) + 5000; } else { totalPrice = int.parse(price); } } return Scaffold( appBar: AppBar( title: Text( 'Checkout', style: secondaryTextStyle.copyWith( letterSpacing: 1, fontWeight: semiBold, fontSize: getProportionateScreenWidth(14)), ), ), body: SingleChildScrollView( child: Container( margin: EdgeInsets.symmetric(horizontal: getProportionateScreenWidth(16)), child: Column( children: [ Text( 'Detail Pesanan', style: secondaryTextStyle.copyWith( letterSpacing: 1, fontWeight: semiBold, fontSize: getProportionateScreenWidth(14), ), ), SizedBox(height: getProportionateScreenHeight(20)), CourseList( idCourse: idCourse, title: title, price: price, discountPrice: discountPrice, imageUrl: imageUrl), SizedBox(height: getProportionateScreenHeight(28)), Text( 'Rincian Harga', style: secondaryTextStyle.copyWith( letterSpacing: 1, fontWeight: semiBold, fontSize: getProportionateScreenWidth(14), ), ), SizedBox( height: getProportionateScreenHeight(15), ), Row( children: [ Text( 'Subtotal Harga Kursus', style: primaryTextStyle.copyWith( letterSpacing: 1, color: secondaryColor, fontWeight: reguler, fontSize: getProportionateScreenWidth(12), ), ), Spacer(), Text( 'Rp. ${NumberFormat.currency(locale: 'id', symbol: '', decimalDigits: 0).format(double.parse(price))}', style: primaryTextStyle.copyWith( letterSpacing: 0.5, color: tenthColor, fontWeight: reguler, fontSize: getProportionateScreenWidth(12), ), ), ], ), SizedBox(height: getProportionateScreenHeight(8)), Row( children: [ Text( 'Potongan Kupon', style: primaryTextStyle.copyWith( letterSpacing: 1, color: secondaryColor, fontWeight: reguler, fontSize: getProportionateScreenWidth(12), ), ), Spacer(), discountPrice != "0" ? Text( 'Rp. ${NumberFormat.currency(locale: 'id', symbol: '', decimalDigits: 0).format(double.parse(price) - double.parse(discountPrice))}', style: primaryTextStyle.copyWith( letterSpacing: 0.5, color: tenthColor, fontWeight: reguler, fontSize: getProportionateScreenWidth(12), ), ) : Text( 'Rp. 0', style: primaryTextStyle.copyWith( letterSpacing: 0.5, color: tenthColor, fontWeight: reguler, fontSize: getProportionateScreenWidth(12), ), ), ], ), SizedBox(height: getProportionateScreenHeight(5)), Divider( color: tenthColor, thickness: 0.5, ), SizedBox(height: getProportionateScreenHeight(5)), Row( children: [ Text( 'Total', style: secondaryTextStyle.copyWith( letterSpacing: 1, fontWeight: semiBold, fontSize: getProportionateScreenWidth(14), ), ), Spacer(), if (int.parse(price) < 50000 || int.parse(discountPrice) < 50000) Text( 'Rp. ${NumberFormat.currency(locale: 'id', symbol: '', decimalDigits: 0).format(totalPrice)}', style: secondaryTextStyle.copyWith( letterSpacing: 1, color: primaryColor, fontWeight: semiBold, fontSize: getProportionateScreenWidth(14), ), ) else Text( 'Rp. ${NumberFormat.currency(locale: 'id', symbol: '', decimalDigits: 0).format(discountPrice == "0" ? double.parse(price) : double.parse(discountPrice))}', style: secondaryTextStyle.copyWith( letterSpacing: 1, color: primaryColor, fontWeight: semiBold, fontSize: getProportionateScreenWidth(14), ), ), ], ), Row( children: [ Text(''), Spacer(), if (int.parse(price) < 50000 || int.parse(discountPrice) < 50000 && int.parse(discountPrice) != 0) Text( '+ admin Rp 5000', style: secondaryTextStyle.copyWith( letterSpacing: 1, color: primaryColor, fontWeight: reguler, fontSize: getProportionateScreenWidth(10), ), ) else SizedBox(), ], ), ], ), ), ), bottomNavigationBar: bottomNav(discountPrice, price), ); } @override void dispose() { controller.dispose(); super.dispose(); } }