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

560 lines
20 KiB
Dart

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<CheckoutPage> createState() => _CheckoutPageState();
}
class _CheckoutPageState extends State<CheckoutPage> {
final controller = TextEditingController();
final provider = detailGetIt<DetailProvider>();
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<TotalPriceProvider>(context);
// String? discountPrice;
return StreamBuilder<DetailCourseModel>(
stream: provider.detailStream,
builder: (context, AsyncSnapshot<DetailCourseModel> 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<paymentsProvider.PaymentsProvider>(context);
final selectedTotalPrice = Provider.of<TotalPriceProvider>(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<paymentsProvider.PaymentsProvider>(
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<dynamic> 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<myCourseProvider.MyCourseProvider>(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<Map<String, dynamic>> dataInvoice = [
{
'id_kursus': widget.idCourse,
'title_kursus': widget.title,
'harga': price.toString(),
'qty': '1',
}
];
// Panggil Snap melalui provider
final paymentProvider = Provider.of<PaymentsProvider>(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();
}
}