import 'package:flutter/material.dart'; import 'package:initial_folder/get_it.dart'; import 'package:initial_folder/models/detail_course_model.dart'; import 'package:initial_folder/providers/detail_course_coupon_provider.dart'; import 'package:initial_folder/screens/checkout/detail_zero_payment.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 '../../providers/payments_provider.dart'; import 'components/course_list_coupon.dart'; import 'snap_payment_page.dart'; class CheckoutCouponPage extends StatefulWidget { final idCourse; final title; final discountPrice; final price; final instructor; final coupon; const CheckoutCouponPage( {Key? key, required this.idCourse, required this.instructor, required this.title, required this.price, required this.discountPrice, required this.coupon}) : super(key: key); @override State createState() => _CheckoutCouponPageState(); } class _CheckoutCouponPageState extends State { final controller = TextEditingController(); final provider = detailCouponGetIt(); 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, widget.coupon); return StreamBuilder( stream: provider.detailStream, builder: (context, AsyncSnapshot snapshot) { final detail = snapshot.data; if (snapshot.hasError) { return Center( child: Text( 'Terjadi Kesalahan', style: thirdTextStyle, ), ); } else { switch (snapshot.connectionState) { case ConnectionState.waiting: return Center( child: CircularProgressIndicator( color: primaryColor, strokeWidth: 2, ), ); case ConnectionState.none: return Center( child: Text( 'Tidak ada koneksi', style: thirdTextStyle, ), ); case ConnectionState.active: case ConnectionState.done: final detail = snapshot.data; return body( widget.idCourse, detail?.title ?? '', detail?.price ?? '0', detail?.discountPrice ?? '0', detail?.thumbnail ?? '', ); } } return Container(); }); } Widget bottomNav(String discountPrice, String price) { String total = discountPrice == '0' ? price : discountPrice; String totalPembayaran = 'Rp. ${NumberFormat.currency(locale: 'id', symbol: '', decimalDigits: 0).format(double.parse(price) - (double.parse(price) - double.parse(discountPrice)))}'; 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, ), Builder( builder: (BuildContext context) { double total = double.parse(price) - (double.parse(price) - double.parse(discountPrice)); if (total <= 50000) { total += 5000; } return Text( 'Rp. ${NumberFormat.currency(locale: 'id', symbol: '', decimalDigits: 0).format(total)}', style: primaryTextStyle.copyWith( fontSize: SizeConfig.blockVertical! * 2.5, letterSpacing: 0.23), ); }, ), SizedBox( height: getProportionateScreenHeight(2), ), ], ), Spacer(), GestureDetector( onTap: () async { if (totalPembayaran == 'Rp. 0') { // Jika total pembayaran adalah 0, arahkan ke halaman zero-payment Navigator.of(context).push( MaterialPageRoute( builder: (context) => DetailZeroPayment(), ), ); } else { // Dapatkan total harga dan id transaksi untuk Snap Midtrans String orderId = 'order-${DateTime.now().millisecondsSinceEpoch}'; int grossAmount = int.parse( totalPembayaran.replaceAll('Rp. ', '').replaceAll(',', '') ); // Persiapkan data_invoice untuk kursus yang dibeli List> dataInvoice = [ { 'id_kursus': widget.idCourse, 'title_kursus': widget.title, 'harga': grossAmount.toString(), 'qty': '1', } ]; // Panggil Snap melalui provider final paymentProvider = Provider.of(context, listen: false); Map? paymentResponse = await paymentProvider.startSnapPayment( orderId: orderId, grossAmount: grossAmount, dataInvoice: dataInvoice, ); if (paymentResponse != null) { // Jika Snap berhasil, tampilkan halaman WebView Snap Navigator.of(context).push( MaterialPageRoute( builder: (context) => SnapPaymentPage( transactionToken: paymentResponse['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) { 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), ), CourseListCoupon( 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(), 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), ), ), ], ), 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(), Builder( builder: (BuildContext context) { double total = double.parse(price) - (double.parse(price) - double.parse(discountPrice)); if (total <= 50000) { total += 5000; } else { total = total; } return Text( 'Rp. ${NumberFormat.currency(locale: 'id', symbol: '', decimalDigits: 0).format(total)}', style: secondaryTextStyle.copyWith( letterSpacing: 1, color: primaryColor, fontWeight: semiBold, fontSize: getProportionateScreenWidth(14), ), ); }, ), ], ), Row( children: [ Text(''), Spacer(), Builder( builder: (BuildContext context) { double total = double.parse(price) - (double.parse(price) - double.parse(discountPrice)); return total <= 50000 ? Text( '+ admin Rp 5000', style: secondaryTextStyle.copyWith( letterSpacing: 1, color: primaryColor, fontWeight: reguler, fontSize: getProportionateScreenWidth(10), ), ) : Container(); }, ), ], ), ], ), ), ), bottomNavigationBar: bottomNav(discountPrice, price), ); } @override void dispose() { controller.dispose(); super.dispose(); } }