Files
Vocasia-LMS-Mobile-apps--TA…/lib/screens/checkout/checkout_coupon_page.dart

416 lines
14 KiB
Dart

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<CheckoutCouponPage> createState() => _CheckoutCouponPageState();
}
class _CheckoutCouponPageState extends State<CheckoutCouponPage> {
final controller = TextEditingController();
final provider = detailCouponGetIt<DetailCouponProvider>();
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<DataDetailCourseModel>(
stream: provider.detailStream,
builder: (context, AsyncSnapshot<DataDetailCourseModel> 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<Map<String, dynamic>> dataInvoice = [
{
'id_kursus': widget.idCourse,
'title_kursus': widget.title,
'harga': grossAmount.toString(),
'qty': '1',
}
];
// Panggil Snap melalui provider
final paymentProvider = Provider.of<PaymentsProvider>(context, listen: false);
Map<String, String>? 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();
}
}