Initial commit: Penyerahan final Source code Tugas Akhir
This commit is contained in:
782
lib/screens/checkout/batas_bayar.dart
Normal file
782
lib/screens/checkout/batas_bayar.dart
Normal file
@ -0,0 +1,782 @@
|
||||
import 'dart:async';
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:initial_folder/helper/user_info.dart';
|
||||
import 'package:initial_folder/models/detail_order_model.dart';
|
||||
import 'package:initial_folder/models/history_transaction_model.dart';
|
||||
import 'package:initial_folder/providers/cart_provider.dart';
|
||||
import 'package:initial_folder/providers/carts_provider.dart';
|
||||
import 'package:initial_folder/providers/order_provider.dart';
|
||||
import 'package:initial_folder/providers/page_provider.dart';
|
||||
import 'package:initial_folder/screens/checkout/components/bar_batas_bayar.dart';
|
||||
import 'package:initial_folder/screens/checkout/components/bottom_sheet_detail.dart';
|
||||
import 'package:initial_folder/screens/checkout/components/tab_bar_batas_bayar.dart';
|
||||
import 'package:initial_folder/screens/home/home_screen.dart';
|
||||
import 'package:initial_folder/screens/profile/account_sign_in/riwayat_transaksi_pending.dart';
|
||||
import 'package:initial_folder/size_config.dart';
|
||||
import 'package:initial_folder/theme.dart';
|
||||
import 'package:initial_folder/widgets/custom_navigator_pop.dart';
|
||||
import 'package:initial_folder/widgets/login_regist/default_button.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:pusher_client/pusher_client.dart';
|
||||
import 'package:shimmer/shimmer.dart';
|
||||
import 'package:initial_folder/screens/checkout/success_paid_course.dart';
|
||||
import 'package:initial_folder/providers/payments_provider.dart' as payProv;
|
||||
|
||||
class BatasBayar extends StatefulWidget {
|
||||
BatasBayar({
|
||||
this.historyTransactionModel,
|
||||
this.isFromHistory,
|
||||
this.idCart,
|
||||
});
|
||||
|
||||
final HistoryTransactionModel? historyTransactionModel;
|
||||
final bool? isFromHistory;
|
||||
final List<String>? idCart;
|
||||
|
||||
@override
|
||||
State<BatasBayar> createState() => _BatasBayarState();
|
||||
}
|
||||
|
||||
class _BatasBayarState extends State<BatasBayar> {
|
||||
Channel? _channel;
|
||||
String? statusTransaction;
|
||||
String? statusMessage;
|
||||
PusherClient? pusher;
|
||||
String capitalize(String s) =>
|
||||
s[0].toUpperCase() + s.substring(1).toLowerCase();
|
||||
|
||||
Future<void> deleteCourse() async {
|
||||
List<String> idCarts = widget.idCart!;
|
||||
|
||||
for (var element in idCarts) {
|
||||
await Provider.of<CartProvider>(context, listen: false)
|
||||
.deleteCart(element);
|
||||
await Provider.of<CartsProvider>(context, listen: false).getCarts();
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> initPusher() async {
|
||||
int? idUser = await UsersInfo().getIdUser();
|
||||
PusherClient pusher = PusherClient(
|
||||
'92060797e94ac7033edb', PusherOptions(cluster: 'ap1'),
|
||||
autoConnect: false);
|
||||
|
||||
pusher.connect();
|
||||
|
||||
pusher.onConnectionStateChange((state) {
|
||||
print(state!.currentState);
|
||||
});
|
||||
|
||||
pusher.onConnectionError((error) {
|
||||
print(error);
|
||||
});
|
||||
|
||||
_channel = pusher.subscribe('payment-channel');
|
||||
|
||||
_channel!.bind(
|
||||
'paid-event-$idUser',
|
||||
(event) async {
|
||||
print("Event? ini apaan dah ${event!.data!}");
|
||||
if (mounted) {
|
||||
final status = jsonDecode(event.data!);
|
||||
final newStatusTransaction = status['status_code'];
|
||||
final newStatusMessage = status['message'];
|
||||
|
||||
if (newStatusMessage.contains("Berhasil !") &&
|
||||
newStatusTransaction == '200') {
|
||||
await deleteCourse();
|
||||
if (mounted) {
|
||||
setState(() {
|
||||
statusTransaction = newStatusTransaction;
|
||||
statusMessage = newStatusMessage;
|
||||
});
|
||||
Navigator.of(context).pushAndRemoveUntil(
|
||||
MaterialPageRoute(
|
||||
builder: (context) => SuccessPaidCourse(),
|
||||
),
|
||||
(route) => false,
|
||||
);
|
||||
}
|
||||
} else if (newStatusMessage.contains("Dibatalkan") &&
|
||||
newStatusTransaction == '200') {
|
||||
await deleteCourse();
|
||||
|
||||
if (mounted) {
|
||||
setState(() {
|
||||
statusTransaction = newStatusTransaction;
|
||||
statusMessage = newStatusMessage;
|
||||
});
|
||||
Navigator.pop(context);
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (context) => AlertDialog(
|
||||
backgroundColor: Theme.of(context).colorScheme.background,
|
||||
elevation: 0.0,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
),
|
||||
contentPadding: EdgeInsets.fromLTRB(12, 26, 22, 15),
|
||||
content: Padding(
|
||||
padding: EdgeInsets.only(
|
||||
bottom: getProportionateScreenHeight(14)),
|
||||
child: Text(
|
||||
textAlign: TextAlign.center,
|
||||
"Transaksi berhasil dibatalkan",
|
||||
style: thirdTextStyle.copyWith(
|
||||
fontSize: getProportionateScreenWidth(12),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
initPusher();
|
||||
super.initState();
|
||||
}
|
||||
|
||||
Widget _buildBatasBayarHistory() {
|
||||
List<DetailOrderModel> detailOrder =
|
||||
Provider.of<payProv.PaymentsProvider>(context).detailOrder;
|
||||
var orders = Provider.of<OrderProvider>(context, listen: false).orders;
|
||||
var selectedOrder =
|
||||
Provider.of<payProv.PaymentsProvider>(context, listen: false);
|
||||
var selected = Provider.of<OrderProvider>(context);
|
||||
selected.selectedThumbnail = orders[0].imageUrl;
|
||||
selected.selectedTitle = orders[0].title;
|
||||
selected.selectedInstructor = orders[0].instructor;
|
||||
PageProvider pageProviders = Provider.of<PageProvider>(context);
|
||||
pageProviders.remove();
|
||||
|
||||
Widget mandiriPay() {
|
||||
return detailOrder[0].bankName == 'mandiri'
|
||||
? Column(
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Text(
|
||||
detailOrder[0].billerCode.toString(),
|
||||
style: thirdTextStyle.copyWith(
|
||||
letterSpacing: 1,
|
||||
fontWeight: semiBold,
|
||||
fontSize: getProportionateScreenWidth(14),
|
||||
),
|
||||
),
|
||||
Spacer(),
|
||||
GestureDetector(
|
||||
onTap: () {
|
||||
Clipboard.setData(ClipboardData(
|
||||
text: detailOrder[0].billerCode.toString()))
|
||||
.then(
|
||||
(_) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
content:
|
||||
Text('Berhasil Menyalin Kode Pembayaran'),
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
child: Text(
|
||||
"Salin",
|
||||
style: primaryTextStyle.copyWith(
|
||||
letterSpacing: 0.5,
|
||||
color: primaryColor,
|
||||
fontSize: getProportionateScreenWidth(10),
|
||||
fontWeight: reguler),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
)
|
||||
: Row();
|
||||
}
|
||||
|
||||
Widget indomartPay() {
|
||||
return detailOrder[0].bankName == 'indomaret'
|
||||
? Column(
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Text(
|
||||
detailOrder[0].merchantId!,
|
||||
style: thirdTextStyle.copyWith(
|
||||
letterSpacing: 1,
|
||||
fontWeight: semiBold,
|
||||
fontSize: getProportionateScreenWidth(14),
|
||||
),
|
||||
),
|
||||
Spacer(),
|
||||
GestureDetector(
|
||||
onTap: () {
|
||||
Clipboard.setData(
|
||||
ClipboardData(text: detailOrder[0].merchantId!))
|
||||
.then(
|
||||
(_) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
content:
|
||||
Text('Berhasil Menyalin Kode Merchant'),
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
child: Text(
|
||||
"Salin",
|
||||
style: primaryTextStyle.copyWith(
|
||||
letterSpacing: 0.5,
|
||||
color: primaryColor,
|
||||
fontSize: getProportionateScreenWidth(10),
|
||||
fontWeight: reguler,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
)
|
||||
: Row();
|
||||
}
|
||||
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
scrolledUnderElevation: 0.0,
|
||||
backgroundColor: Theme.of(context).colorScheme.background,
|
||||
title: Text(
|
||||
'Selesaikan Pembayaran',
|
||||
style: secondaryTextStyle.copyWith(
|
||||
letterSpacing: 1,
|
||||
fontWeight: semiBold,
|
||||
fontSize: getProportionateScreenWidth(14)),
|
||||
),
|
||||
leading: IconButton(
|
||||
icon: Icon(
|
||||
Icons.arrow_back_ios,
|
||||
size: getProportionateScreenWidth(17),
|
||||
),
|
||||
onPressed: () {
|
||||
selectedOrder.selectedIdOrders = '';
|
||||
Navigator.pop(context);
|
||||
},
|
||||
),
|
||||
),
|
||||
body: SingleChildScrollView(
|
||||
child: Consumer<payProv.PaymentsProvider>(
|
||||
builder: (context, state, _) {
|
||||
if (state.stateProcess == payProv.Process.loading) {
|
||||
return Padding(
|
||||
padding: EdgeInsets.only(
|
||||
left: getProportionateScreenWidth(20),
|
||||
bottom: getProportionateScreenHeight(20),
|
||||
right: getProportionateScreenWidth(20),
|
||||
),
|
||||
child: Shimmer.fromColors(
|
||||
baseColor: Colors.white,
|
||||
highlightColor: Colors.grey,
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
Container(
|
||||
width: getProportionateScreenWidth(140),
|
||||
height: getProportionateScreenHeight(7),
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
color: Colors.white,
|
||||
),
|
||||
),
|
||||
SizedBox(height: getProportionateScreenHeight(10)),
|
||||
Container(
|
||||
width: getProportionateScreenWidth(110),
|
||||
height: getProportionateScreenHeight(9),
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
color: Colors.white,
|
||||
),
|
||||
),
|
||||
SizedBox(height: getProportionateScreenHeight(10)),
|
||||
Container(
|
||||
width: getProportionateScreenWidth(220),
|
||||
height: getProportionateScreenHeight(7),
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
color: Colors.white,
|
||||
),
|
||||
),
|
||||
SizedBox(height: getProportionateScreenHeight(40)),
|
||||
Container(
|
||||
width: double.infinity,
|
||||
height: getProportionateScreenHeight(250),
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
color: Colors.white,
|
||||
),
|
||||
),
|
||||
SizedBox(height: getProportionateScreenHeight(20)),
|
||||
Container(
|
||||
width: double.infinity,
|
||||
height: getProportionateScreenHeight(40),
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
color: Colors.white,
|
||||
),
|
||||
),
|
||||
SizedBox(height: getProportionateScreenHeight(30)),
|
||||
Container(
|
||||
width: double.infinity,
|
||||
height: getProportionateScreenHeight(170),
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
color: Colors.white,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
} else if (state.state == payProv.ResultState.gagal &&
|
||||
state.stateProcess == payProv.Process.uninitialized) {
|
||||
return Center(
|
||||
child: Text('Gagal Mengambil Pesanan'),
|
||||
);
|
||||
} else if (state.state == payProv.ResultState.success &&
|
||||
state.stateProcess == payProv.Process.uninitialized) {
|
||||
return Container(
|
||||
margin: EdgeInsets.symmetric(
|
||||
horizontal: getProportionateScreenWidth(16)),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: <Widget>[
|
||||
SizedBox(height: getProportionateScreenHeight(10)),
|
||||
Center(
|
||||
child: Column(
|
||||
children: [
|
||||
Text(
|
||||
'Batas akhir pembayaran sampai',
|
||||
style: thirdTextStyle.copyWith(
|
||||
letterSpacing: 0.5,
|
||||
fontWeight: reguler,
|
||||
fontSize: getProportionateScreenWidth(10),
|
||||
),
|
||||
),
|
||||
SizedBox(height: getProportionateScreenHeight(5)),
|
||||
Text(
|
||||
DateFormat('E, d MMM y (H:m)')
|
||||
.format(detailOrder[0].transactionTimeLimit),
|
||||
style: thirdTextStyle.copyWith(
|
||||
letterSpacing: 1,
|
||||
fontWeight: semiBold,
|
||||
fontSize: SizeConfig.blockHorizontal! * 3,
|
||||
),
|
||||
),
|
||||
SizedBox(height: getProportionateScreenHeight(5)),
|
||||
Text(
|
||||
'Mohon melakukan pembayaran sebelum batas',
|
||||
style: thirdTextStyle.copyWith(
|
||||
letterSpacing: 0.5,
|
||||
fontWeight: reguler,
|
||||
fontSize: getProportionateScreenWidth(10),
|
||||
),
|
||||
),
|
||||
Text(
|
||||
'tanggal yang ditetapkan atau pesanan',
|
||||
style: thirdTextStyle.copyWith(
|
||||
letterSpacing: 0.5,
|
||||
fontWeight: reguler,
|
||||
fontSize: getProportionateScreenWidth(10),
|
||||
),
|
||||
),
|
||||
Text(
|
||||
'akan otomatis dibatalkan',
|
||||
style: thirdTextStyle.copyWith(
|
||||
letterSpacing: 0.5,
|
||||
fontWeight: reguler,
|
||||
fontSize: getProportionateScreenWidth(10),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
SizedBox(height: getProportionateScreenHeight(25)),
|
||||
Container(
|
||||
decoration: BoxDecoration(
|
||||
color: Theme.of(context).colorScheme.primaryContainer,
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Colors.black.withOpacity(0.1),
|
||||
spreadRadius: 0,
|
||||
blurRadius: 4,
|
||||
offset: Offset(0, 4),
|
||||
),
|
||||
],
|
||||
),
|
||||
margin: EdgeInsets.only(
|
||||
left: getProportionateScreenWidth(2),
|
||||
right: getProportionateScreenWidth(2)),
|
||||
child: Container(
|
||||
padding: EdgeInsets.symmetric(
|
||||
vertical: 16,
|
||||
horizontal: getProportionateScreenWidth(10)),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
'Metode Pembayaran',
|
||||
style: thirdTextStyle.copyWith(
|
||||
letterSpacing: 0.5,
|
||||
fontWeight: reguler,
|
||||
fontSize: getProportionateScreenWidth(10),
|
||||
),
|
||||
),
|
||||
SizedBox(height: getProportionateScreenHeight(8)),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(
|
||||
detailOrder[0].bankName == 'mandiri'
|
||||
? 'Mandiri Virtual Account'
|
||||
: detailOrder[0].bankName == 'permata'
|
||||
? 'Permata Virtual Account'
|
||||
: detailOrder[0].bankName == 'bni'
|
||||
? 'BNI Virtual Account'
|
||||
: detailOrder[0].bankName == 'bca'
|
||||
? 'BCA Virtual Account'
|
||||
: detailOrder[0].bankName ==
|
||||
'indomaret'
|
||||
? 'Indomaret'
|
||||
: 'Alfamart',
|
||||
style: thirdTextStyle.copyWith(
|
||||
letterSpacing: 1,
|
||||
fontWeight: semiBold,
|
||||
fontSize: getProportionateScreenWidth(13),
|
||||
),
|
||||
),
|
||||
Container(
|
||||
width: getProportionateScreenWidth(50),
|
||||
height: getProportionateScreenWidth(17),
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(2),
|
||||
image: DecorationImage(
|
||||
fit: BoxFit.fill,
|
||||
image: detailOrder[0].bankName ==
|
||||
'mandiri'
|
||||
? AssetImage(
|
||||
"assets/images/mandiri.png")
|
||||
: detailOrder[0].bankName == 'permata'
|
||||
? AssetImage(
|
||||
"assets/images/permata.png")
|
||||
: detailOrder[0].bankName == 'bni'
|
||||
? AssetImage(
|
||||
"assets/images/bni.png")
|
||||
: detailOrder[0].bankName ==
|
||||
'bca'
|
||||
? AssetImage(
|
||||
"assets/images/bca.png")
|
||||
: detailOrder[0]
|
||||
.bankName ==
|
||||
'alfamart'
|
||||
? AssetImage(
|
||||
"assets/images/alfamart.png")
|
||||
: AssetImage(
|
||||
"assets/images/indomaret.png"),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(height: getProportionateScreenHeight(16)),
|
||||
Text(
|
||||
detailOrder[0].bankName == 'alfamart' ||
|
||||
detailOrder[0].bankName == 'indomaret'
|
||||
? 'Nomor Pesanan'
|
||||
: 'Nomor Virtual Akun',
|
||||
style: thirdTextStyle.copyWith(
|
||||
letterSpacing: 0.5,
|
||||
fontWeight: reguler,
|
||||
fontSize: getProportionateScreenWidth(10),
|
||||
),
|
||||
),
|
||||
SizedBox(height: getProportionateScreenHeight(8)),
|
||||
Row(
|
||||
children: [
|
||||
Text(
|
||||
detailOrder[0].virtualNumber ?? 'ABCD',
|
||||
style: thirdTextStyle.copyWith(
|
||||
letterSpacing: 1,
|
||||
fontWeight: semiBold,
|
||||
fontSize: getProportionateScreenWidth(14),
|
||||
),
|
||||
),
|
||||
Spacer(),
|
||||
GestureDetector(
|
||||
onTap: () {
|
||||
Clipboard.setData(ClipboardData(
|
||||
text:
|
||||
detailOrder[0].virtualNumber!))
|
||||
.then(
|
||||
(_) {
|
||||
ScaffoldMessenger.of(context)
|
||||
.showSnackBar(
|
||||
SnackBar(
|
||||
content: Text(detailOrder[0]
|
||||
.bankName ==
|
||||
'alfamart' ||
|
||||
detailOrder[0].bankName ==
|
||||
'indomaret'
|
||||
? 'Berhasil Menyalin Nomor Pesanan'
|
||||
: 'Berhasil Menyalin Nomor Virtual Akun'),
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
child: Text(
|
||||
"Salin",
|
||||
style: thirdTextStyle.copyWith(
|
||||
letterSpacing: 0.5,
|
||||
color: primaryColor,
|
||||
fontSize:
|
||||
getProportionateScreenWidth(10),
|
||||
fontWeight: reguler),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
detailOrder[0].bankName == 'indomaret'
|
||||
? Padding(
|
||||
padding: EdgeInsets.only(
|
||||
top: getProportionateScreenHeight(16),
|
||||
bottom: getProportionateScreenHeight(8),
|
||||
),
|
||||
child: Text(
|
||||
'Kode Merchant',
|
||||
style: thirdTextStyle.copyWith(
|
||||
letterSpacing: 0.5,
|
||||
fontWeight: reguler,
|
||||
fontSize:
|
||||
getProportionateScreenWidth(10),
|
||||
),
|
||||
),
|
||||
)
|
||||
: SizedBox.shrink(),
|
||||
detailOrder[0].bankName == 'mandiri'
|
||||
? Padding(
|
||||
padding: EdgeInsets.only(
|
||||
top: getProportionateScreenHeight(16),
|
||||
bottom: getProportionateScreenHeight(8),
|
||||
),
|
||||
child: Text(
|
||||
'Kode Pembayaran',
|
||||
style: thirdTextStyle.copyWith(
|
||||
letterSpacing: 0.5,
|
||||
fontWeight: reguler,
|
||||
fontSize:
|
||||
getProportionateScreenWidth(10),
|
||||
),
|
||||
),
|
||||
)
|
||||
: SizedBox.shrink(),
|
||||
indomartPay(),
|
||||
mandiriPay(),
|
||||
SizedBox(height: getProportionateScreenHeight(16)),
|
||||
Text(
|
||||
'Total Pembayaran',
|
||||
style: thirdTextStyle.copyWith(
|
||||
letterSpacing: 0.5,
|
||||
fontWeight: reguler,
|
||||
fontSize: getProportionateScreenWidth(10),
|
||||
),
|
||||
),
|
||||
SizedBox(height: getProportionateScreenHeight(8)),
|
||||
Row(
|
||||
children: [
|
||||
Text(
|
||||
'Rp. ${NumberFormat.currency(locale: 'id', symbol: '', decimalDigits: 0).format(double.parse(detailOrder[0].totalPayment))}',
|
||||
style: thirdTextStyle.copyWith(
|
||||
letterSpacing: 1,
|
||||
fontWeight: semiBold,
|
||||
fontSize: getProportionateScreenWidth(14),
|
||||
),
|
||||
),
|
||||
Spacer(),
|
||||
GestureDetector(
|
||||
onTap: () {
|
||||
showModalBottomSheet(
|
||||
context: context,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.vertical(
|
||||
top: Radius.circular(20),
|
||||
),
|
||||
),
|
||||
builder: (context) {
|
||||
return BottomSheetDetail();
|
||||
},
|
||||
);
|
||||
},
|
||||
child: Text(
|
||||
"Detail Pembayaran",
|
||||
style: thirdTextStyle.copyWith(
|
||||
letterSpacing: 0.5,
|
||||
color: primaryColor,
|
||||
fontSize:
|
||||
getProportionateScreenWidth(10),
|
||||
fontWeight: reguler),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(height: getProportionateScreenHeight(16)),
|
||||
Text(
|
||||
'Status Pembayaran',
|
||||
style: thirdTextStyle.copyWith(
|
||||
letterSpacing: 0.5,
|
||||
fontWeight: reguler,
|
||||
fontSize: getProportionateScreenWidth(10),
|
||||
),
|
||||
),
|
||||
SizedBox(height: getProportionateScreenHeight(8)),
|
||||
Text(
|
||||
capitalize(
|
||||
detailOrder[0].transactionStatus!.toString()),
|
||||
style: thirdTextStyle.copyWith(
|
||||
color: primaryColor,
|
||||
letterSpacing: 1,
|
||||
fontWeight: medium,
|
||||
fontSize: getProportionateScreenWidth(12),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(height: getProportionateScreenHeight(24)),
|
||||
DefaultButton(
|
||||
text: 'Belanja kursus lainnya',
|
||||
weight: semiBold,
|
||||
press: () {
|
||||
pageProviders.currentIndex == 0;
|
||||
Navigator.pushAndRemoveUntil(
|
||||
context,
|
||||
CustomNavigatorPop(child: HomeScreen()),
|
||||
(route) => false,
|
||||
);
|
||||
},
|
||||
),
|
||||
SizedBox(height: getProportionateScreenHeight(12)),
|
||||
SizedBox(
|
||||
width: getProportionateScreenWidth(300),
|
||||
height: getProportionateScreenHeight(38),
|
||||
child: TextButton(
|
||||
onPressed: () {
|
||||
Navigator.pushReplacement(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) => RiwayatTransaksiPending(),
|
||||
),
|
||||
);
|
||||
},
|
||||
child: Text(
|
||||
"Cek Status Transaksi",
|
||||
style: thirdTextStyle.copyWith(
|
||||
fontSize: getProportionateScreenWidth(12),
|
||||
fontWeight: semiBold,
|
||||
color: primaryColor,
|
||||
letterSpacing: 0.5,
|
||||
),
|
||||
),
|
||||
style: TextButton.styleFrom(
|
||||
foregroundColor:
|
||||
Theme.of(context).colorScheme.background,
|
||||
shape: RoundedRectangleBorder(
|
||||
side: BorderSide(color: primaryColor),
|
||||
borderRadius: BorderRadius.circular(
|
||||
getProportionateScreenWidth(10)),
|
||||
),
|
||||
backgroundColor: Colors.transparent,
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(height: getProportionateScreenHeight(32)),
|
||||
Container(
|
||||
decoration: BoxDecoration(
|
||||
color: Theme.of(context).colorScheme.primaryContainer,
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Colors.black.withOpacity(0.1),
|
||||
spreadRadius: 0,
|
||||
blurRadius: 4,
|
||||
offset: Offset(0, 4),
|
||||
),
|
||||
],
|
||||
),
|
||||
margin: EdgeInsets.only(
|
||||
left: getProportionateScreenWidth(2),
|
||||
right: getProportionateScreenWidth(2)),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Container(
|
||||
padding: EdgeInsets.symmetric(
|
||||
vertical: 16,
|
||||
horizontal: getProportionateScreenWidth(16)),
|
||||
child: Text(
|
||||
'Cara Pembayaran',
|
||||
style: thirdTextStyle.copyWith(
|
||||
letterSpacing: 1,
|
||||
fontWeight: semiBold,
|
||||
fontSize: getProportionateScreenWidth(14),
|
||||
),
|
||||
),
|
||||
),
|
||||
Divider(
|
||||
color: Color(0xff2D2D2D),
|
||||
thickness: 0.5,
|
||||
height: 0.5,
|
||||
),
|
||||
Container(
|
||||
padding: EdgeInsets.symmetric(
|
||||
vertical: 16,
|
||||
horizontal: getProportionateScreenWidth(16)),
|
||||
child: detailOrder[0].bankName == 'indomaret' ||
|
||||
detailOrder[0].bankName == 'alfamart'
|
||||
? BarBatasBayar(detailOrder[0].bankName!)
|
||||
: TabBarBatasBayar()),
|
||||
],
|
||||
),
|
||||
),
|
||||
SizedBox(height: getProportionateScreenHeight(30)),
|
||||
],
|
||||
),
|
||||
);
|
||||
} else {
|
||||
return Center(
|
||||
child: Text('Terjadi Kesalahan'),
|
||||
);
|
||||
}
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return _buildBatasBayarHistory();
|
||||
}
|
||||
}
|
991
lib/screens/checkout/batas_bayar_bank.dart
Normal file
991
lib/screens/checkout/batas_bayar_bank.dart
Normal file
@ -0,0 +1,991 @@
|
||||
import 'dart:async';
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:flutter_countdown_timer/current_remaining_time.dart';
|
||||
import 'package:flutter_countdown_timer/flutter_countdown_timer.dart';
|
||||
import 'package:initial_folder/base_service.dart';
|
||||
import 'package:initial_folder/helper/user_info.dart';
|
||||
import 'package:initial_folder/models/detail_order_model.dart';
|
||||
import 'package:initial_folder/models/history_transaction_model.dart';
|
||||
import 'package:initial_folder/providers/cart_provider.dart';
|
||||
import 'package:initial_folder/providers/carts_provider.dart';
|
||||
import 'package:initial_folder/providers/order_provider.dart';
|
||||
import 'package:initial_folder/providers/page_provider.dart';
|
||||
import 'package:initial_folder/screens/checkout/components/bar_batas_bayar.dart';
|
||||
import 'package:initial_folder/screens/checkout/components/bottom_sheet_detail.dart';
|
||||
import 'package:initial_folder/screens/checkout/components/tab_bar_batas_bayar.dart';
|
||||
import 'package:initial_folder/screens/home/home_screen.dart';
|
||||
import 'package:initial_folder/services/cancel_payment_service.dart';
|
||||
import 'package:initial_folder/size_config.dart';
|
||||
import 'package:initial_folder/theme.dart';
|
||||
import 'package:initial_folder/widgets/custom_navigator_pop.dart';
|
||||
import 'package:initial_folder/widgets/login_regist/default_button_payment.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:pusher_client/pusher_client.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
import 'package:shimmer/shimmer.dart';
|
||||
import 'package:initial_folder/screens/checkout/success_paid_course.dart';
|
||||
import 'package:initial_folder/providers/payments_provider.dart' as payProv;
|
||||
|
||||
class BatasBayarBank extends StatefulWidget {
|
||||
BatasBayarBank({
|
||||
this.historyTransactionModel,
|
||||
this.isFromHistory,
|
||||
this.idCart,
|
||||
});
|
||||
|
||||
final HistoryTransactionModel? historyTransactionModel;
|
||||
final bool? isFromHistory;
|
||||
final List<String>? idCart;
|
||||
|
||||
@override
|
||||
State<BatasBayarBank> createState() => _BatasBayarBankState();
|
||||
}
|
||||
|
||||
class _BatasBayarBankState extends State<BatasBayarBank> {
|
||||
Channel? _channel;
|
||||
String? statusTransaction;
|
||||
String? statusMessage;
|
||||
bool isLoading = false;
|
||||
PusherClient? pusher;
|
||||
Duration? remainingTime;
|
||||
String capitalize(String s) =>
|
||||
s[0].toUpperCase() + s.substring(1).toLowerCase();
|
||||
|
||||
Future<void> saveRemainingTime(Duration remainingTime) async {
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
prefs.setInt('remainingTime', remainingTime.inSeconds);
|
||||
}
|
||||
|
||||
Future<void> deleteCourse() async {
|
||||
List<String> idCarts = widget.idCart!;
|
||||
|
||||
for (var element in idCarts) {
|
||||
await Provider.of<CartProvider>(context, listen: false)
|
||||
.deleteCart(element);
|
||||
await Provider.of<CartsProvider>(context, listen: false).getCarts();
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> initPusher() async {
|
||||
int? idUser = await UsersInfo().getIdUser();
|
||||
PusherClient pusher = PusherClient(
|
||||
'92060797e94ac7033edb', PusherOptions(cluster: 'ap1'),
|
||||
autoConnect: false);
|
||||
|
||||
pusher.connect();
|
||||
|
||||
pusher.onConnectionStateChange((state) {
|
||||
print(state!.currentState);
|
||||
});
|
||||
|
||||
pusher.onConnectionError((error) {
|
||||
print(error);
|
||||
});
|
||||
|
||||
_channel = pusher.subscribe('payment-channel');
|
||||
|
||||
_channel!.bind(
|
||||
'paid-event-$idUser',
|
||||
(event) async {
|
||||
print("Event? ini apaan dah ${event!.data!}");
|
||||
if (mounted) {
|
||||
final status = jsonDecode(event.data!);
|
||||
final newStatusTransaction = status['status_code'];
|
||||
final newStatusMessage = status['message'];
|
||||
|
||||
if (newStatusMessage.contains("Berhasil !") &&
|
||||
newStatusTransaction == '200') {
|
||||
await deleteCourse();
|
||||
if (mounted) {
|
||||
setState(() {
|
||||
statusTransaction = newStatusTransaction;
|
||||
statusMessage = newStatusMessage;
|
||||
});
|
||||
Navigator.of(context).pushAndRemoveUntil(
|
||||
MaterialPageRoute(
|
||||
builder: (context) => SuccessPaidCourse(),
|
||||
),
|
||||
(route) => false,
|
||||
);
|
||||
}
|
||||
} else if (newStatusMessage.contains("Dibatalkan") &&
|
||||
newStatusTransaction == '200') {
|
||||
await deleteCourse();
|
||||
|
||||
if (mounted) {
|
||||
setState(() {
|
||||
statusTransaction = newStatusTransaction;
|
||||
statusMessage = newStatusMessage;
|
||||
});
|
||||
Navigator.pop(context);
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (context) => AlertDialog(
|
||||
backgroundColor: Theme.of(context).colorScheme.background,
|
||||
elevation: 0.0,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
),
|
||||
contentPadding: EdgeInsets.fromLTRB(12, 26, 22, 15),
|
||||
content: Padding(
|
||||
padding: EdgeInsets.only(
|
||||
bottom: getProportionateScreenHeight(14)),
|
||||
child: Text(
|
||||
textAlign: TextAlign.center,
|
||||
"Transaksi berhasil dibatalkan",
|
||||
style: thirdTextStyle.copyWith(
|
||||
fontSize: getProportionateScreenWidth(12),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
initPusher();
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
if (remainingTime != null) {
|
||||
saveRemainingTime(remainingTime!);
|
||||
}
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
Widget _buildBatasBayarHistory() {
|
||||
List<DetailOrderModel> detailOrder =
|
||||
Provider.of<payProv.PaymentsProvider>(context).detailOrder;
|
||||
var orders = Provider.of<OrderProvider>(context, listen: false).orders;
|
||||
var selected = Provider.of<OrderProvider>(context);
|
||||
selected.selectedThumbnail = orders[0].imageUrl;
|
||||
selected.selectedTitle = orders[0].title;
|
||||
selected.selectedInstructor = orders[0].instructor;
|
||||
PageProvider pageProvider = Provider.of<PageProvider>(context);
|
||||
|
||||
Widget mandiriPay() {
|
||||
return detailOrder[0].bankName == 'mandiri'
|
||||
? Column(
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Text(
|
||||
detailOrder[0].billerCode.toString(),
|
||||
style: thirdTextStyle.copyWith(
|
||||
letterSpacing: 1,
|
||||
fontWeight: semiBold,
|
||||
fontSize: getProportionateScreenWidth(14),
|
||||
),
|
||||
),
|
||||
Spacer(),
|
||||
GestureDetector(
|
||||
onTap: () {
|
||||
Clipboard.setData(ClipboardData(
|
||||
text: detailOrder[0].billerCode.toString()))
|
||||
.then(
|
||||
(_) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
content:
|
||||
Text('Berhasil Menyalin Kode Pembayaran'),
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
child: Text(
|
||||
"Salin",
|
||||
style: primaryTextStyle.copyWith(
|
||||
letterSpacing: 0.5,
|
||||
color: primaryColor,
|
||||
fontSize: getProportionateScreenWidth(10),
|
||||
fontWeight: reguler),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
)
|
||||
: Row();
|
||||
}
|
||||
|
||||
Widget indomartPay() {
|
||||
return detailOrder[0].bankName == 'indomaret'
|
||||
? Column(
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Text(
|
||||
detailOrder[0].merchantId!,
|
||||
style: thirdTextStyle.copyWith(
|
||||
letterSpacing: 1,
|
||||
fontWeight: semiBold,
|
||||
fontSize: getProportionateScreenWidth(14),
|
||||
),
|
||||
),
|
||||
Spacer(),
|
||||
GestureDetector(
|
||||
onTap: () {
|
||||
Clipboard.setData(
|
||||
ClipboardData(text: detailOrder[0].merchantId!))
|
||||
.then(
|
||||
(_) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
content:
|
||||
Text('Berhasil Menyalin Kode Merchant'),
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
child: Text(
|
||||
"Salin",
|
||||
style: primaryTextStyle.copyWith(
|
||||
letterSpacing: 0.5,
|
||||
color: primaryColor,
|
||||
fontSize: getProportionateScreenWidth(10),
|
||||
fontWeight: reguler,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
)
|
||||
: Row();
|
||||
}
|
||||
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
scrolledUnderElevation: 0.0,
|
||||
centerTitle: true,
|
||||
backgroundColor: Theme.of(context).colorScheme.background,
|
||||
title: Text(
|
||||
'Menunggu Pembayaran',
|
||||
style: thirdTextStyle.copyWith(
|
||||
fontWeight: semiBold,
|
||||
fontSize: getProportionateScreenWidth(14),
|
||||
),
|
||||
),
|
||||
leading: IconButton(
|
||||
icon: Icon(
|
||||
Icons.arrow_back_ios,
|
||||
color: Theme.of(context).colorScheme.onBackground,
|
||||
size: getProportionateScreenWidth(17),
|
||||
),
|
||||
onPressed: () {
|
||||
pageProvider.currentIndex == 0;
|
||||
Navigator.pushAndRemoveUntil(
|
||||
context,
|
||||
CustomNavigatorPop(child: HomeScreen()),
|
||||
(route) => false,
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
body: SingleChildScrollView(
|
||||
child: Consumer<payProv.PaymentsProvider>(
|
||||
builder: (context, state, _) {
|
||||
if (state.stateProcess == payProv.Process.loading) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.all(20),
|
||||
child: Shimmer.fromColors(
|
||||
baseColor: Colors.white,
|
||||
highlightColor: Colors.grey,
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
SizedBox(height: getProportionateScreenHeight(40)),
|
||||
Container(
|
||||
width: double.infinity,
|
||||
height: getProportionateScreenHeight(250),
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
color: Colors.white,
|
||||
),
|
||||
),
|
||||
SizedBox(height: getProportionateScreenHeight(20)),
|
||||
Container(
|
||||
width: double.infinity,
|
||||
height: getProportionateScreenHeight(40),
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
color: Colors.white,
|
||||
),
|
||||
),
|
||||
SizedBox(height: getProportionateScreenHeight(30)),
|
||||
Container(
|
||||
width: double.infinity,
|
||||
height: getProportionateScreenHeight(170),
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
color: Colors.white,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
} else if (state.state == payProv.ResultState.gagal &&
|
||||
state.stateProcess == payProv.Process.uninitialized) {
|
||||
return Center(
|
||||
child: Text('Gagal Mengambil Pesanan'),
|
||||
);
|
||||
} else if (state.state == payProv.ResultState.success &&
|
||||
state.stateProcess == payProv.Process.uninitialized) {
|
||||
return Container(
|
||||
margin: EdgeInsets.symmetric(
|
||||
horizontal: getProportionateScreenWidth(8)),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: <Widget>[
|
||||
SizedBox(height: getProportionateScreenHeight(10)),
|
||||
Center(
|
||||
child: Container(
|
||||
width: double.infinity,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(4),
|
||||
color: Theme.of(context).colorScheme.primaryContainer,
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: secondaryColor.withOpacity(0.2),
|
||||
spreadRadius: 1,
|
||||
blurRadius: 2,
|
||||
offset:
|
||||
Offset(0, getProportionateScreenHeight(4)),
|
||||
),
|
||||
],
|
||||
),
|
||||
padding: EdgeInsets.symmetric(
|
||||
horizontal: getProportionateScreenWidth(10),
|
||||
vertical: getProportionateScreenHeight(15),
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
'Batas Waktu Pembayaran',
|
||||
style: thirdTextStyle.copyWith(
|
||||
fontFamily: "Poppins",
|
||||
fontSize: getProportionateScreenWidth(11),
|
||||
),
|
||||
),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(
|
||||
DateFormat('E, d MMM y H:m WIB').format(
|
||||
detailOrder[0].transactionTimeLimit),
|
||||
style: thirdTextStyle.copyWith(
|
||||
fontWeight: semiBold,
|
||||
fontSize: SizeConfig.blockHorizontal! * 3,
|
||||
),
|
||||
),
|
||||
Container(
|
||||
decoration: BoxDecoration(
|
||||
color: sevenColor,
|
||||
borderRadius: BorderRadius.circular(4),
|
||||
),
|
||||
padding: EdgeInsets.symmetric(
|
||||
horizontal: getProportionateScreenWidth(3),
|
||||
vertical: getProportionateScreenHeight(2),
|
||||
),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
children: [
|
||||
Icon(
|
||||
Icons.access_time,
|
||||
color: baruTextutih,
|
||||
size: getProportionateScreenWidth(14),
|
||||
),
|
||||
SizedBox(
|
||||
width:
|
||||
getProportionateScreenWidth(2)),
|
||||
CountdownTimer(
|
||||
endTime: DateTime.now()
|
||||
.add(Duration(hours: 24))
|
||||
.millisecondsSinceEpoch,
|
||||
widgetBuilder:
|
||||
(_, CurrentRemainingTime? time) {
|
||||
if (time == null) {
|
||||
return Text(
|
||||
'00:00:00',
|
||||
style: thirdTextStyle.copyWith(
|
||||
fontWeight: semiBold,
|
||||
letterSpacing: 1,
|
||||
fontSize:
|
||||
getProportionateScreenWidth(
|
||||
10),
|
||||
color: baruTextutih,
|
||||
),
|
||||
);
|
||||
} else {
|
||||
remainingTime = Duration(
|
||||
hours: time.hours ?? 0,
|
||||
minutes: time.min ?? 0,
|
||||
seconds: time.sec ?? 0,
|
||||
);
|
||||
return Text(
|
||||
'${time.hours}:${time.min}:${time.sec}',
|
||||
style: thirdTextStyle.copyWith(
|
||||
fontWeight: semiBold,
|
||||
letterSpacing: 1,
|
||||
fontSize:
|
||||
getProportionateScreenWidth(
|
||||
10),
|
||||
color: baruTextutih,
|
||||
),
|
||||
);
|
||||
}
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(height: getProportionateScreenHeight(10)),
|
||||
Text(
|
||||
"Kursus",
|
||||
style: thirdTextStyle.copyWith(
|
||||
fontFamily: "Poppins",
|
||||
fontSize: getProportionateScreenWidth(11),
|
||||
),
|
||||
),
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: orders.map((e) {
|
||||
return listCourse(
|
||||
imageUrl: e.imageUrl,
|
||||
instructor: e.instructor,
|
||||
title: e.title,
|
||||
price: e.price,
|
||||
discountPrice: e.discountPrice,
|
||||
);
|
||||
}).toList(),
|
||||
),
|
||||
Text(
|
||||
'Metode Pembayaran',
|
||||
style: thirdTextStyle.copyWith(
|
||||
letterSpacing: 0.5,
|
||||
fontWeight: reguler,
|
||||
fontSize: getProportionateScreenWidth(10),
|
||||
),
|
||||
),
|
||||
SizedBox(height: getProportionateScreenHeight(8)),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(
|
||||
detailOrder[0].bankName == 'mandiri'
|
||||
? 'Mandiri Virtual Account'
|
||||
: detailOrder[0].bankName == 'permata'
|
||||
? 'Permata Virtual Account'
|
||||
: detailOrder[0].bankName == 'bni'
|
||||
? 'BNI Virtual Account'
|
||||
: detailOrder[0].bankName == 'bca'
|
||||
? 'BCA Virtual Account'
|
||||
: detailOrder[0].bankName ==
|
||||
'indomaret'
|
||||
? 'Indomaret'
|
||||
: 'Alfamart',
|
||||
style: thirdTextStyle.copyWith(
|
||||
letterSpacing: 1,
|
||||
fontWeight: semiBold,
|
||||
fontSize: getProportionateScreenWidth(13),
|
||||
),
|
||||
),
|
||||
Container(
|
||||
width: getProportionateScreenWidth(50),
|
||||
height: getProportionateScreenWidth(17),
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(2),
|
||||
image: DecorationImage(
|
||||
fit: BoxFit.fill,
|
||||
image: detailOrder[0].bankName ==
|
||||
'mandiri'
|
||||
? AssetImage(
|
||||
"assets/images/mandiri.png")
|
||||
: detailOrder[0].bankName == 'permata'
|
||||
? AssetImage(
|
||||
"assets/images/permata.png")
|
||||
: detailOrder[0].bankName == 'bni'
|
||||
? AssetImage(
|
||||
"assets/images/bni.png")
|
||||
: detailOrder[0].bankName ==
|
||||
'bca'
|
||||
? AssetImage(
|
||||
"assets/images/bca.png")
|
||||
: detailOrder[0]
|
||||
.bankName ==
|
||||
'alfamart'
|
||||
? AssetImage(
|
||||
"assets/images/alfamart.png")
|
||||
: AssetImage(
|
||||
"assets/images/indomaret.png"),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(height: getProportionateScreenHeight(16)),
|
||||
Text(
|
||||
detailOrder[0].bankName == 'alfamart' ||
|
||||
detailOrder[0].bankName == 'indomaret'
|
||||
? 'Nomor Pesanan'
|
||||
: 'Nomor Virtual Akun',
|
||||
style: thirdTextStyle.copyWith(
|
||||
letterSpacing: 0.5,
|
||||
fontWeight: reguler,
|
||||
fontSize: getProportionateScreenWidth(10),
|
||||
),
|
||||
),
|
||||
SizedBox(height: getProportionateScreenHeight(8)),
|
||||
Row(
|
||||
children: [
|
||||
Text(
|
||||
detailOrder[0].virtualNumber ?? 'ABCD',
|
||||
style: thirdTextStyle.copyWith(
|
||||
letterSpacing: 1,
|
||||
fontWeight: semiBold,
|
||||
fontSize: getProportionateScreenWidth(14),
|
||||
),
|
||||
),
|
||||
Spacer(),
|
||||
GestureDetector(
|
||||
onTap: () {
|
||||
Clipboard.setData(ClipboardData(
|
||||
text:
|
||||
detailOrder[0].virtualNumber!))
|
||||
.then(
|
||||
(_) {
|
||||
ScaffoldMessenger.of(context)
|
||||
.showSnackBar(
|
||||
SnackBar(
|
||||
content: Text(detailOrder[0]
|
||||
.bankName ==
|
||||
'alfamart' ||
|
||||
detailOrder[0].bankName ==
|
||||
'indomaret'
|
||||
? 'Berhasil Menyalin Nomor Pesanan'
|
||||
: 'Berhasil Menyalin Nomor Virtual Akun'),
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
child: Text(
|
||||
"Salin",
|
||||
style: thirdTextStyle.copyWith(
|
||||
letterSpacing: 0.5,
|
||||
color: primaryColor,
|
||||
fontSize:
|
||||
getProportionateScreenWidth(10),
|
||||
fontWeight: reguler),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
detailOrder[0].bankName == 'indomaret'
|
||||
? Padding(
|
||||
padding: EdgeInsets.only(
|
||||
top: getProportionateScreenHeight(16),
|
||||
bottom: getProportionateScreenHeight(8),
|
||||
),
|
||||
child: Text(
|
||||
'Kode Merchant',
|
||||
style: thirdTextStyle.copyWith(
|
||||
letterSpacing: 0.5,
|
||||
fontWeight: reguler,
|
||||
fontSize:
|
||||
getProportionateScreenWidth(10),
|
||||
),
|
||||
),
|
||||
)
|
||||
: SizedBox.shrink(),
|
||||
detailOrder[0].bankName == 'mandiri'
|
||||
? Padding(
|
||||
padding: EdgeInsets.only(
|
||||
top: getProportionateScreenHeight(16),
|
||||
bottom: getProportionateScreenHeight(8),
|
||||
),
|
||||
child: Text(
|
||||
'Kode Pembayaran',
|
||||
style: thirdTextStyle.copyWith(
|
||||
letterSpacing: 0.5,
|
||||
fontWeight: reguler,
|
||||
fontSize:
|
||||
getProportionateScreenWidth(10),
|
||||
),
|
||||
),
|
||||
)
|
||||
: SizedBox.shrink(),
|
||||
indomartPay(),
|
||||
mandiriPay(),
|
||||
SizedBox(height: getProportionateScreenHeight(16)),
|
||||
Text(
|
||||
'Total Pembayaran',
|
||||
style: thirdTextStyle.copyWith(
|
||||
letterSpacing: 0.5,
|
||||
fontWeight: reguler,
|
||||
fontSize: getProportionateScreenWidth(10),
|
||||
),
|
||||
),
|
||||
SizedBox(height: getProportionateScreenHeight(8)),
|
||||
Row(
|
||||
children: [
|
||||
Text(
|
||||
'Rp. ${NumberFormat.currency(locale: 'id', symbol: '', decimalDigits: 0).format(double.parse(detailOrder[0].totalPayment))}',
|
||||
style: thirdTextStyle.copyWith(
|
||||
letterSpacing: 1,
|
||||
fontWeight: semiBold,
|
||||
fontSize: getProportionateScreenWidth(14),
|
||||
),
|
||||
),
|
||||
Spacer(),
|
||||
GestureDetector(
|
||||
onTap: () {
|
||||
showModalBottomSheet(
|
||||
backgroundColor: Theme.of(context)
|
||||
.colorScheme
|
||||
.background,
|
||||
elevation: 0.0,
|
||||
context: context,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.vertical(
|
||||
top: Radius.circular(20),
|
||||
),
|
||||
),
|
||||
builder: (context) {
|
||||
return BottomSheetDetail();
|
||||
},
|
||||
);
|
||||
},
|
||||
child: Text(
|
||||
"Detail Pembayaran",
|
||||
style: thirdTextStyle.copyWith(
|
||||
letterSpacing: 0.5,
|
||||
color: primaryColor,
|
||||
fontSize:
|
||||
getProportionateScreenWidth(10),
|
||||
fontWeight: reguler),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Column(
|
||||
children: [
|
||||
SizedBox(
|
||||
height:
|
||||
getProportionateScreenHeight(24)),
|
||||
DefaultButtonPayment(
|
||||
text: 'Ubah Metode Pembayaran',
|
||||
weight: semiBold,
|
||||
press: () {
|
||||
state.selectedIdOrders = "";
|
||||
Navigator.pop(context);
|
||||
},
|
||||
width: 320,
|
||||
height: 44,
|
||||
),
|
||||
SizedBox(
|
||||
height:
|
||||
getProportionateScreenHeight(12)),
|
||||
SizedBox(
|
||||
width: getProportionateScreenWidth(320),
|
||||
height: getProportionateScreenHeight(38),
|
||||
child: TextButton(
|
||||
onPressed: () async {
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (BuildContext context) {
|
||||
return AlertDialog(
|
||||
elevation: 0.0,
|
||||
backgroundColor:
|
||||
Theme.of(context)
|
||||
.colorScheme
|
||||
.background,
|
||||
contentPadding:
|
||||
EdgeInsets.symmetric(
|
||||
vertical:
|
||||
getProportionateScreenHeight(
|
||||
20),
|
||||
horizontal:
|
||||
getProportionateScreenWidth(
|
||||
10),
|
||||
),
|
||||
actionsPadding: EdgeInsets.only(
|
||||
right:
|
||||
getProportionateScreenWidth(
|
||||
10),
|
||||
bottom:
|
||||
getProportionateScreenHeight(
|
||||
12),
|
||||
),
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius:
|
||||
BorderRadius.circular(
|
||||
getProportionateScreenWidth(
|
||||
4)),
|
||||
),
|
||||
content: Text(
|
||||
'Apakah Anda yakin ingin membatalkan transaksi?'),
|
||||
actions: [
|
||||
GestureDetector(
|
||||
child: Text(
|
||||
'Ya',
|
||||
style: TextStyle(
|
||||
color: primaryColor,
|
||||
fontSize:
|
||||
getProportionateScreenWidth(
|
||||
11),
|
||||
),
|
||||
),
|
||||
onTap: () async {
|
||||
state.selectedIdOrders =
|
||||
"";
|
||||
Navigator.of(context)
|
||||
.pop();
|
||||
CancelPaymentService
|
||||
cancelPaymentService =
|
||||
CancelPaymentService();
|
||||
|
||||
setState(() {
|
||||
isLoading = true;
|
||||
});
|
||||
|
||||
await cancelPaymentService
|
||||
.cancelPayment(
|
||||
detailOrder[0]
|
||||
.idOrder
|
||||
.toString());
|
||||
|
||||
await Future.delayed(
|
||||
Duration(seconds: 2));
|
||||
|
||||
setState(() {
|
||||
isLoading = false;
|
||||
});
|
||||
},
|
||||
),
|
||||
SizedBox(
|
||||
width:
|
||||
getProportionateScreenWidth(
|
||||
5)),
|
||||
GestureDetector(
|
||||
child: Text(
|
||||
'Tidak',
|
||||
style: TextStyle(
|
||||
color: primaryColor,
|
||||
fontSize:
|
||||
getProportionateScreenWidth(
|
||||
11),
|
||||
),
|
||||
),
|
||||
onTap: () {
|
||||
Navigator.of(context)
|
||||
.pop();
|
||||
},
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
child: isLoading
|
||||
? Container(
|
||||
width:
|
||||
getProportionateScreenWidth(
|
||||
15),
|
||||
height:
|
||||
getProportionateScreenHeight(
|
||||
13),
|
||||
child:
|
||||
CircularProgressIndicator(
|
||||
color: primaryColor,
|
||||
),
|
||||
)
|
||||
: Text(
|
||||
"Batalkan Transaksi",
|
||||
style: thirdTextStyle.copyWith(
|
||||
fontSize:
|
||||
getProportionateScreenWidth(
|
||||
12),
|
||||
fontWeight: semiBold,
|
||||
color: primaryColor,
|
||||
letterSpacing: 0.5,
|
||||
),
|
||||
),
|
||||
style: TextButton.styleFrom(
|
||||
foregroundColor: Theme.of(context)
|
||||
.colorScheme
|
||||
.background,
|
||||
shape: RoundedRectangleBorder(
|
||||
side:
|
||||
BorderSide(color: primaryColor),
|
||||
borderRadius: BorderRadius.circular(
|
||||
getProportionateScreenWidth(5),
|
||||
),
|
||||
),
|
||||
backgroundColor: Colors.transparent,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(height: getProportionateScreenHeight(20)),
|
||||
Container(
|
||||
decoration: BoxDecoration(
|
||||
color: Theme.of(context).colorScheme.primaryContainer,
|
||||
borderRadius: BorderRadius.circular(4),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Colors.black.withOpacity(0.1),
|
||||
spreadRadius: 0,
|
||||
blurRadius: 4,
|
||||
offset: Offset(0, 4),
|
||||
),
|
||||
],
|
||||
),
|
||||
margin: EdgeInsets.only(
|
||||
left: getProportionateScreenWidth(2),
|
||||
right: getProportionateScreenWidth(2)),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Container(
|
||||
width: double.infinity,
|
||||
padding: EdgeInsets.only(
|
||||
top: getProportionateScreenHeight(15),
|
||||
bottom: getProportionateScreenHeight(7),
|
||||
left: getProportionateScreenWidth(18),
|
||||
),
|
||||
decoration: BoxDecoration(
|
||||
color: Theme.of(context)
|
||||
.colorScheme
|
||||
.primaryContainer,
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: secondaryColor.withOpacity(0.2),
|
||||
spreadRadius: 0,
|
||||
blurRadius: 2,
|
||||
offset: Offset(
|
||||
0, getProportionateScreenHeight(4)),
|
||||
),
|
||||
],
|
||||
),
|
||||
child: Text(
|
||||
'Cara Pembayaran',
|
||||
style: thirdTextStyle.copyWith(
|
||||
letterSpacing: 1,
|
||||
fontWeight: semiBold,
|
||||
fontSize: getProportionateScreenWidth(14),
|
||||
),
|
||||
),
|
||||
),
|
||||
Container(
|
||||
padding: EdgeInsets.symmetric(
|
||||
horizontal: getProportionateScreenWidth(5),
|
||||
),
|
||||
child: detailOrder[0].bankName == 'indomaret' ||
|
||||
detailOrder[0].bankName == 'alfamart'
|
||||
? BarBatasBayar(detailOrder[0].bankName!)
|
||||
: TabBarBatasBayar(),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
SizedBox(height: getProportionateScreenHeight(30)),
|
||||
],
|
||||
),
|
||||
);
|
||||
} else {
|
||||
return Center(
|
||||
child: Text('Terjadi Kesalahan'),
|
||||
);
|
||||
}
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return _buildBatasBayarHistory();
|
||||
}
|
||||
|
||||
Widget listCourse({
|
||||
String? imageUrl,
|
||||
String? title,
|
||||
String? instructor,
|
||||
String? price,
|
||||
String? discountPrice,
|
||||
int? totalPrices,
|
||||
}) {
|
||||
return Container(
|
||||
padding: EdgeInsets.symmetric(vertical: getProportionateScreenHeight(9)),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
Container(
|
||||
width: getProportionateScreenWidth(60),
|
||||
height: getProportionateScreenHeight(30),
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(2),
|
||||
image: DecorationImage(
|
||||
image: NetworkImage(imageUrl ??
|
||||
'$baseUrl/uploads/courses_thumbnail/course_thumbnail_default_57.jpg'),
|
||||
fit: BoxFit.cover,
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(width: getProportionateScreenWidth(10)),
|
||||
Flexible(
|
||||
flex: 7,
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
title!,
|
||||
maxLines: 2,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: thirdTextStyle.copyWith(
|
||||
letterSpacing: 0.5,
|
||||
fontWeight: reguler,
|
||||
fontSize: getProportionateScreenWidth(11),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
384
lib/screens/checkout/checkout_cart_coupon_page.dart
Normal file
384
lib/screens/checkout/checkout_cart_coupon_page.dart
Normal file
@ -0,0 +1,384 @@
|
||||
import 'package:flutter/material.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/size_config.dart';
|
||||
import 'package:initial_folder/theme.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:initial_folder/providers/order_provider.dart' as provOrder;
|
||||
|
||||
import '../../providers/payments_provider.dart';
|
||||
import 'snap_payment_page.dart';
|
||||
|
||||
class CheckoutCartCouponPage extends StatefulWidget {
|
||||
CheckoutCartCouponPage({
|
||||
Key? key,
|
||||
required this.idCart,
|
||||
this.potonganKupon,
|
||||
this.discountHarga,
|
||||
this.isKupon,
|
||||
}) : super(key: key);
|
||||
|
||||
final List<String> idCart;
|
||||
final int? potonganKupon;
|
||||
final int? discountHarga;
|
||||
final bool? isKupon;
|
||||
|
||||
@override
|
||||
State<CheckoutCartCouponPage> createState() => _CheckoutCartCouponPageState();
|
||||
}
|
||||
|
||||
class _CheckoutCartCouponPageState extends State<CheckoutCartCouponPage> {
|
||||
final controller = TextEditingController();
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final priceCoupon = Provider.of<TotalPriceProvider>(context).priceCoupon;
|
||||
final totalPrice2 = Provider.of<TotalPriceProvider>(context).totalPrice;
|
||||
final totalPrice3 = Provider.of<TotalPriceProvider>(context).totalPrices;
|
||||
final typeCoupon = Provider.of<TotalPriceProvider>(context).typeCoupon;
|
||||
final finalPriceCoupon =
|
||||
Provider.of<TotalPriceProvider>(context).finalPriceCoupon;
|
||||
final potonganKupon2 =
|
||||
Provider.of<TotalPriceProvider>(context).potonganKupon;
|
||||
|
||||
Widget bottomNav(String totalPrice) {
|
||||
String totalHarga =
|
||||
"Rp. ${NumberFormat.currency(locale: 'id', symbol: '', decimalDigits: 0).format(totalPrice == '0' ? widget.discountHarga : double.parse(totalPrice))}";
|
||||
|
||||
return Container(
|
||||
width: double.infinity,
|
||||
height: getProportionateScreenHeight(64),
|
||||
decoration: BoxDecoration(
|
||||
color: Theme.of(context).colorScheme.background,
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Theme.of(context).colorScheme.onPrimary.withOpacity(0.1),
|
||||
spreadRadius: 4,
|
||||
blurRadius: 15,
|
||||
offset: Offset(0, 4),
|
||||
),
|
||||
],
|
||||
),
|
||||
child: Row(
|
||||
children: [
|
||||
SizedBox(width: 13),
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
SizedBox(height: getProportionateScreenHeight(6)),
|
||||
Text(
|
||||
"Total",
|
||||
style: thirdTextStyle.copyWith(
|
||||
fontSize: getProportionateScreenHeight(12),
|
||||
fontWeight: semiBold,
|
||||
),
|
||||
),
|
||||
SizedBox(height: getProportionateScreenHeight(2)),
|
||||
if (widget.isKupon == null)
|
||||
Text(
|
||||
'Rp. ${NumberFormat.currency(locale: 'id', symbol: '', decimalDigits: 0).format(finalPriceCoupon! < 50000 ? finalPriceCoupon + 5000 : finalPriceCoupon)}',
|
||||
style: thirdTextStyle.copyWith(
|
||||
fontSize: SizeConfig.blockVertical! * 2.5,
|
||||
letterSpacing: 0.23,
|
||||
),
|
||||
),
|
||||
if (widget.isKupon == true)
|
||||
Text(
|
||||
'Rp. ${NumberFormat.currency(locale: 'id', symbol: '', decimalDigits: 0).format(widget.discountHarga! < 50000 ? widget.discountHarga! + 5000 : widget.discountHarga)}',
|
||||
style: thirdTextStyle.copyWith(
|
||||
fontSize: SizeConfig.blockVertical! * 2.5,
|
||||
letterSpacing: 0.23,
|
||||
),
|
||||
),
|
||||
SizedBox(height: getProportionateScreenHeight(2)),
|
||||
],
|
||||
),
|
||||
Spacer(),
|
||||
GestureDetector(
|
||||
onTap: () async {
|
||||
print("Ini id cart? ${widget.idCart}");
|
||||
|
||||
if (totalHarga == 'Rp. 0') {
|
||||
// Jika harga total adalah 0, arahkan ke halaman zero-payment
|
||||
Navigator.of(context).push(
|
||||
MaterialPageRoute(
|
||||
builder: (context) => DetailZeroPayment(idCart: widget.idCart),
|
||||
),
|
||||
);
|
||||
} else {
|
||||
// harga dan id transaksi untuk Snap Midtrans
|
||||
String orderId = 'order-${DateTime.now().millisecondsSinceEpoch}';
|
||||
int grossAmount = int.parse(totalHarga.replaceAll('Rp. ', '').replaceAll(',', ''));
|
||||
|
||||
// Persiapkan data_invoice berdasarkan pesanan
|
||||
List<Map<String, dynamic>> dataInvoice = widget.idCart.map((id) {
|
||||
return {
|
||||
'id_kursus': id,
|
||||
'title_kursus': 'Nama Kursus',
|
||||
'harga': grossAmount.toString(),
|
||||
'qty': '1',
|
||||
};
|
||||
}).toList();
|
||||
|
||||
// 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(135),
|
||||
height: getProportionateScreenHeight(35),
|
||||
decoration: BoxDecoration(
|
||||
color: primaryColor,
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
),
|
||||
child: Center(
|
||||
child: Text(
|
||||
'Pilih Pembayaran',
|
||||
style: thirdTextStyle.copyWith(
|
||||
fontSize: SizeConfig.blockVertical! * 1.7,
|
||||
fontWeight: semiBold,
|
||||
letterSpacing: 0.5,
|
||||
color: baruTextutih,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
backgroundColor: Theme.of(context).colorScheme.background,
|
||||
centerTitle: true,
|
||||
title: Text(
|
||||
'Checkout',
|
||||
style: thirdTextStyle.copyWith(
|
||||
letterSpacing: 1,
|
||||
fontWeight: semiBold,
|
||||
fontSize: getProportionateScreenWidth(14)),
|
||||
),
|
||||
),
|
||||
body: SingleChildScrollView(
|
||||
child: Container(
|
||||
margin:
|
||||
EdgeInsets.symmetric(horizontal: getProportionateScreenWidth(16)),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
'Detail Pesanan',
|
||||
style: thirdTextStyle.copyWith(
|
||||
letterSpacing: 1,
|
||||
fontWeight: semiBold,
|
||||
fontSize: getProportionateScreenWidth(14),
|
||||
),
|
||||
),
|
||||
SizedBox(height: getProportionateScreenHeight(20)),
|
||||
Consumer<provOrder.OrderProvider>(
|
||||
builder: (context, state, _) {
|
||||
print(state.orders.map((e) => e.idCourse));
|
||||
return Column(
|
||||
children: [
|
||||
...state.orders.map(
|
||||
(order) => CourseList(
|
||||
idCourse: order.idCourse,
|
||||
title: order.title,
|
||||
price: widget.isKupon == null
|
||||
? finalPriceCoupon.toString()
|
||||
: (potonganKupon2 == 0
|
||||
? priceCoupon.toString()
|
||||
: (potonganKupon2! > totalPrice2!
|
||||
? finalPriceCoupon.toString()
|
||||
: totalPrice3.toString())),
|
||||
discountPrice: order.discountPrice,
|
||||
imageUrl: order.imageUrl,
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
),
|
||||
SizedBox(height: getProportionateScreenHeight(5)),
|
||||
Text(
|
||||
'Rincian Harga',
|
||||
style: thirdTextStyle.copyWith(
|
||||
letterSpacing: 1,
|
||||
fontWeight: semiBold,
|
||||
fontSize: getProportionateScreenWidth(14),
|
||||
),
|
||||
),
|
||||
SizedBox(height: getProportionateScreenHeight(10)),
|
||||
Row(
|
||||
children: [
|
||||
Text(
|
||||
'Subtotal Harga Kursus',
|
||||
style: thirdTextStyle.copyWith(
|
||||
fontWeight: reguler,
|
||||
fontSize: getProportionateScreenWidth(10),
|
||||
),
|
||||
),
|
||||
Spacer(),
|
||||
if (widget.isKupon == null)
|
||||
Text(
|
||||
'Rp. ${NumberFormat.currency(locale: 'id', symbol: '', decimalDigits: 0).format(priceCoupon!)}',
|
||||
style: thirdTextStyle.copyWith(
|
||||
letterSpacing: 0.5,
|
||||
fontWeight: reguler,
|
||||
fontSize: getProportionateScreenWidth(12),
|
||||
),
|
||||
),
|
||||
if (widget.isKupon == true)
|
||||
Text(
|
||||
'Rp. ${NumberFormat.currency(locale: 'id', symbol: '', decimalDigits: 0).format(finalPriceCoupon == 0 ? priceCoupon : (potonganKupon2! > totalPrice2! ? finalPriceCoupon : totalPrice3))}',
|
||||
style: thirdTextStyle.copyWith(
|
||||
letterSpacing: 0.5,
|
||||
fontWeight: reguler,
|
||||
fontSize: getProportionateScreenWidth(12),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(height: getProportionateScreenHeight(5)),
|
||||
Row(
|
||||
children: [
|
||||
Text(
|
||||
'Biaya Layanan',
|
||||
style: thirdTextStyle.copyWith(
|
||||
fontWeight: reguler,
|
||||
fontSize: getProportionateScreenWidth(10),
|
||||
),
|
||||
),
|
||||
Spacer(),
|
||||
Text(
|
||||
'Rp ${NumberFormat.currency(locale: 'id', symbol: '', decimalDigits: 0).format(double.parse(finalPriceCoupon! < 5000 ? "5000" : "0"))}',
|
||||
style: thirdTextStyle.copyWith(
|
||||
fontWeight: reguler,
|
||||
fontSize: getProportionateScreenWidth(12),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(height: getProportionateScreenHeight(5)),
|
||||
Row(
|
||||
children: [
|
||||
Text(
|
||||
'Potongan Kupon',
|
||||
style: primaryTextStyle.copyWith(
|
||||
fontWeight: reguler,
|
||||
fontSize: getProportionateScreenWidth(10),
|
||||
),
|
||||
),
|
||||
Spacer(),
|
||||
Text(
|
||||
'Rp ${NumberFormat.currency(locale: 'id', symbol: '', decimalDigits: 0).format(double.parse(typeCoupon != "3" ? widget.potonganKupon.toString() : (priceCoupon! - widget.potonganKupon!).toString()))}',
|
||||
style: primaryTextStyle.copyWith(
|
||||
fontWeight: reguler,
|
||||
fontSize: getProportionateScreenWidth(12),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(height: getProportionateScreenHeight(8)),
|
||||
Row(
|
||||
children: [
|
||||
Text(
|
||||
'Total Bayar',
|
||||
style: thirdTextStyle.copyWith(
|
||||
fontWeight: reguler,
|
||||
fontSize: getProportionateScreenWidth(14),
|
||||
),
|
||||
),
|
||||
Spacer(),
|
||||
if (widget.isKupon == null)
|
||||
Text(
|
||||
'Rp. ${NumberFormat.currency(locale: 'id', symbol: '', decimalDigits: 0).format(finalPriceCoupon! < 50000 ? finalPriceCoupon + 5000 : finalPriceCoupon)}',
|
||||
style: thirdTextStyle.copyWith(
|
||||
fontWeight: semiBold,
|
||||
fontSize: getProportionateScreenWidth(14),
|
||||
),
|
||||
),
|
||||
if (widget.isKupon == true)
|
||||
Text(
|
||||
'Rp. ${NumberFormat.currency(locale: 'id', symbol: '', decimalDigits: 0).format(widget.discountHarga! < 50000 ? widget.discountHarga! + 5000 : widget.discountHarga)}',
|
||||
style: thirdTextStyle.copyWith(
|
||||
fontWeight: semiBold,
|
||||
fontSize: getProportionateScreenWidth(14),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
Row(
|
||||
children: [
|
||||
Text(''),
|
||||
Spacer(),
|
||||
if (widget.isKupon == null)
|
||||
Text(
|
||||
(int.parse(Provider.of<provOrder.OrderProvider>(context)
|
||||
.totalPrice!) !=
|
||||
0 &&
|
||||
int.parse(
|
||||
Provider.of<provOrder.OrderProvider>(context).totalPrice!) < 50000) ||
|
||||
finalPriceCoupon! < 50000
|
||||
? "+ admin Rp 5000"
|
||||
: "",
|
||||
style: secondaryTextStyle.copyWith(
|
||||
letterSpacing: 1,
|
||||
fontWeight: reguler,
|
||||
fontSize: getProportionateScreenWidth(10),
|
||||
),
|
||||
),
|
||||
if (widget.isKupon != null)
|
||||
Text(
|
||||
(widget.discountHarga != 0 && widget.discountHarga! < 50000)
|
||||
? "+ admin Rp 5000"
|
||||
: "",
|
||||
style: secondaryTextStyle.copyWith(
|
||||
letterSpacing: 1,
|
||||
fontWeight: reguler,
|
||||
fontSize: getProportionateScreenWidth(10),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
bottomNavigationBar: bottomNav(
|
||||
(int.parse(Provider.of<provOrder.OrderProvider>(context).totalPrice as String)).toString(),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
controller.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
}
|
296
lib/screens/checkout/checkout_cart_page.dart
Normal file
296
lib/screens/checkout/checkout_cart_page.dart
Normal file
@ -0,0 +1,296 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:initial_folder/providers/order_provider.dart' as provOrder;
|
||||
import 'package:initial_folder/providers/theme_provider.dart';
|
||||
import 'package:initial_folder/providers/total_price_provider.dart';
|
||||
import 'package:initial_folder/providers/payments_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/checkout/snap_payment_page.dart'; // Import SnapPaymentPage
|
||||
import 'package:initial_folder/size_config.dart';
|
||||
import 'package:initial_folder/theme.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
class CheckoutCartPage extends StatefulWidget {
|
||||
CheckoutCartPage({
|
||||
Key? key,
|
||||
required this.idCart,
|
||||
this.potonganKupon,
|
||||
this.discountHarga,
|
||||
this.isCart,
|
||||
this.isDetailCourse,
|
||||
}) : super(key: key);
|
||||
|
||||
final List<String> idCart;
|
||||
final int? potonganKupon;
|
||||
final int? discountHarga;
|
||||
final bool? isCart;
|
||||
final bool? isDetailCourse;
|
||||
|
||||
@override
|
||||
State<CheckoutCartPage> createState() => _CheckoutCartPageState();
|
||||
}
|
||||
|
||||
class _CheckoutCartPageState extends State<CheckoutCartPage> {
|
||||
final controller = TextEditingController();
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final subTotal = Provider.of<TotalPriceProvider>(context).subTotal;
|
||||
final paymentProvider = Provider.of<PaymentsProvider>(context, listen: false);
|
||||
final themeProvider = Provider.of<ThemeProvider>(context);
|
||||
|
||||
Widget bottomNav(String totalPrice) {
|
||||
String totalHarga =
|
||||
"Rp ${NumberFormat.currency(locale: 'id', symbol: '', decimalDigits: 0).format(totalPrice == '0' ? widget.discountHarga : double.parse(totalPrice))}";
|
||||
|
||||
return Container(
|
||||
width: double.infinity,
|
||||
height: getProportionateScreenHeight(64),
|
||||
decoration: BoxDecoration(
|
||||
color: Theme.of(context).colorScheme.background,
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Theme.of(context).colorScheme.onPrimary.withOpacity(0.1),
|
||||
spreadRadius: 4,
|
||||
blurRadius: 15,
|
||||
offset: Offset(0, 4),
|
||||
),
|
||||
],
|
||||
),
|
||||
child: Row(
|
||||
children: [
|
||||
SizedBox(width: 13),
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
SizedBox(height: getProportionateScreenHeight(6)),
|
||||
Text(
|
||||
"Total",
|
||||
style: thirdTextStyle.copyWith(
|
||||
fontSize: getProportionateScreenHeight(12),
|
||||
fontWeight: semiBold,
|
||||
),
|
||||
),
|
||||
SizedBox(height: getProportionateScreenHeight(2)),
|
||||
Text(
|
||||
'Rp. ${NumberFormat.currency(locale: 'id', symbol: '', decimalDigits: 0).format(Provider.of<provOrder.OrderProvider>(context).totalPrice as String == "0" ? (widget.discountHarga! < 50000 ? widget.discountHarga! + 5000 : widget.discountHarga) : (int.parse(Provider.of<provOrder.OrderProvider>(context).totalPrice!) == widget.discountHarga ? (int.parse(Provider.of<provOrder.OrderProvider>(context).totalPrice!) < 50000 ? int.parse(Provider.of<provOrder.OrderProvider>(context).totalPrice!) + 5000 : int.parse(Provider.of<provOrder.OrderProvider>(context).totalPrice as String)) : int.parse(Provider.of<provOrder.OrderProvider>(context).totalPrice as String)))}',
|
||||
style: primaryTextStyle.copyWith(
|
||||
fontSize: SizeConfig.blockVertical! * 2.5,
|
||||
fontWeight: bold,
|
||||
),
|
||||
),
|
||||
SizedBox(height: getProportionateScreenHeight(2)),
|
||||
],
|
||||
),
|
||||
Spacer(),
|
||||
GestureDetector(
|
||||
onTap: () async {
|
||||
String orderId = 'order-${DateTime.now().millisecondsSinceEpoch}';
|
||||
int grossAmount = Provider.of<provOrder.OrderProvider>(context, listen: false)
|
||||
.orders
|
||||
.fold(0, (sum, order) {
|
||||
// Gunakan harga diskon jika tersedia, jika tidak ada gunakan harga asli
|
||||
int harga = (order.discountPrice != null && order.discountPrice != "0")
|
||||
? int.parse(order.discountPrice)
|
||||
: int.parse(order.price);
|
||||
|
||||
// Tambahkan biaya admin jika harga di bawah 50.000
|
||||
return sum + (harga < 50000 ? harga + 5000 : harga);
|
||||
});
|
||||
|
||||
// Persiapkan data_invoice berdasarkan kursus yang ada di keranjang
|
||||
List<Map<String, dynamic>> dataInvoice = [];
|
||||
Provider.of<provOrder.OrderProvider>(context, listen: false).orders.forEach((order) {
|
||||
dataInvoice.add({
|
||||
'id_kursus': order.idCourse.toString(),
|
||||
'title_kursus': order.title,
|
||||
// Gunakan harga diskon jika tersedia, jika tidak gunakan harga asli
|
||||
'harga': (order.discountPrice != null && order.discountPrice != "0")
|
||||
? order.discountPrice.toString()
|
||||
: order.price.toString(),
|
||||
'qty': '1',
|
||||
});
|
||||
});
|
||||
|
||||
// Panggil Snap melalui provider
|
||||
Map<String, String>? paymentResponse = await paymentProvider.startSnapPayment(
|
||||
orderId: orderId,
|
||||
grossAmount: grossAmount,
|
||||
dataInvoice: dataInvoice,
|
||||
);
|
||||
|
||||
if (paymentResponse != null) {
|
||||
// Snap berhasil dibuka, navigasi ke SnapPaymentPage untuk menampilkan WebView
|
||||
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(135),
|
||||
height: getProportionateScreenHeight(35),
|
||||
decoration: BoxDecoration(
|
||||
color: themeProvider.themeData == ThemeClass.darkmode
|
||||
?primaryColor : primaryColorligtmode,
|
||||
borderRadius: BorderRadius.circular(10)),
|
||||
child: Center(
|
||||
child: Text(
|
||||
'Pilih Pembayaran',
|
||||
style: thirdTextStyle.copyWith(
|
||||
fontSize: SizeConfig.blockVertical! * 1.7,
|
||||
fontWeight: semiBold,
|
||||
letterSpacing: 0.5,
|
||||
color: baruTextutih,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
backgroundColor: Theme.of(context).colorScheme.background,
|
||||
centerTitle: true,
|
||||
title: Text(
|
||||
'Checkout',
|
||||
style: thirdTextStyle.copyWith(
|
||||
letterSpacing: 1,
|
||||
fontWeight: semiBold,
|
||||
fontSize: getProportionateScreenWidth(14)),
|
||||
),
|
||||
),
|
||||
body: SingleChildScrollView(
|
||||
child: Container(
|
||||
margin: EdgeInsets.symmetric(horizontal: getProportionateScreenWidth(16)),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
'Detail Pesanan',
|
||||
style: thirdTextStyle.copyWith(
|
||||
letterSpacing: 1,
|
||||
fontWeight: semiBold,
|
||||
fontSize: getProportionateScreenWidth(14),
|
||||
),
|
||||
),
|
||||
SizedBox(height: getProportionateScreenHeight(20)),
|
||||
Consumer<provOrder.OrderProvider>(
|
||||
builder: (context, state, _) {
|
||||
return Column(
|
||||
children: [
|
||||
...state.orders.map(
|
||||
(order) => widget.isDetailCourse != null
|
||||
? CourseList(
|
||||
idCourse: order.idCourse,
|
||||
title: order.title,
|
||||
price: widget.isCart == null
|
||||
? order.price
|
||||
: (order.discountPrice != null
|
||||
? order.discountPrice
|
||||
: order.price),
|
||||
discountPrice: order.discountPrice == null
|
||||
? order.discountPrice
|
||||
: order.price,
|
||||
imageUrl: order.imageUrl,
|
||||
isDetailCourse: true,
|
||||
)
|
||||
: CourseList(
|
||||
idCourse: order.idCourse,
|
||||
title: order.title,
|
||||
price: widget.isCart == null
|
||||
? order.price
|
||||
: (order.discountPrice != null
|
||||
? order.discountPrice
|
||||
: order.price),
|
||||
discountPrice: order.discountPrice == null
|
||||
? order.discountPrice
|
||||
: order.price,
|
||||
imageUrl: order.imageUrl,
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
),
|
||||
SizedBox(height: getProportionateScreenHeight(5)),
|
||||
Text(
|
||||
'Rincian Harga',
|
||||
style: thirdTextStyle.copyWith(
|
||||
letterSpacing: 1,
|
||||
fontWeight: semiBold,
|
||||
fontSize: getProportionateScreenWidth(14),
|
||||
),
|
||||
),
|
||||
SizedBox(height: getProportionateScreenHeight(10)),
|
||||
Row(
|
||||
children: [
|
||||
Text(
|
||||
'Subtotal Harga Kursus',
|
||||
style: thirdTextStyle.copyWith(
|
||||
fontWeight: reguler,
|
||||
fontSize: getProportionateScreenWidth(10),
|
||||
),
|
||||
),
|
||||
Spacer(),
|
||||
RichText(
|
||||
text: TextSpan(
|
||||
children: [
|
||||
if (widget.discountHarga.toString() != subTotal)
|
||||
TextSpan(
|
||||
text:
|
||||
'Rp ${NumberFormat.currency(locale: 'id', symbol: '', decimalDigits: 0).format(int.parse(subTotal!))}',
|
||||
style: thirdTextStyle.copyWith(
|
||||
decoration: TextDecoration.lineThrough,
|
||||
color: fourthColor,
|
||||
fontWeight: reguler,
|
||||
fontSize: SizeConfig.blockHorizontal! * 2.8,
|
||||
),
|
||||
),
|
||||
WidgetSpan(
|
||||
child: SizedBox(
|
||||
width: getProportionateScreenWidth(8))),
|
||||
TextSpan(
|
||||
text:
|
||||
'Rp ${NumberFormat.currency(locale: 'id', symbol: '', decimalDigits: 0).format(Provider.of<provOrder.OrderProvider>(context).totalPrice as String == "0" ? (widget.discountHarga! < 50000 ? widget.discountHarga! + 5000 : widget.discountHarga) : int.parse(Provider.of<provOrder.OrderProvider>(context).totalPrice as String))}',
|
||||
style: thirdTextStyle.copyWith(
|
||||
color: Theme.of(context).colorScheme.onPrimary,
|
||||
fontWeight: reguler,
|
||||
fontSize: getProportionateScreenWidth(12),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
bottomNavigationBar: bottomNav(
|
||||
(int.parse(Provider.of<provOrder.OrderProvider>(context).totalPrice as String)).toString(),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
controller.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
}
|
415
lib/screens/checkout/checkout_coupon_page.dart
Normal file
415
lib/screens/checkout/checkout_coupon_page.dart
Normal file
@ -0,0 +1,415 @@
|
||||
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();
|
||||
}
|
||||
}
|
391
lib/screens/checkout/checkout_detail_coupon.dart
Normal file
391
lib/screens/checkout/checkout_detail_coupon.dart
Normal file
@ -0,0 +1,391 @@
|
||||
import 'package:flutter/material.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/size_config.dart';
|
||||
import 'package:initial_folder/theme.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:initial_folder/providers/order_provider.dart' as provOrder;
|
||||
|
||||
import '../../providers/payments_provider.dart';
|
||||
import 'snap_payment_page.dart';
|
||||
|
||||
class CheckoutDetailCoupon extends StatefulWidget {
|
||||
CheckoutDetailCoupon({
|
||||
Key? key,
|
||||
required this.idCart,
|
||||
this.potonganKupon,
|
||||
this.discountHarga,
|
||||
this.isKupon,
|
||||
}) : super(key: key);
|
||||
|
||||
final List<String> idCart;
|
||||
final int? potonganKupon;
|
||||
final int? discountHarga;
|
||||
final bool? isKupon;
|
||||
|
||||
@override
|
||||
State<CheckoutDetailCoupon> createState() => _CheckoutDetailCouponState();
|
||||
}
|
||||
|
||||
class _CheckoutDetailCouponState extends State<CheckoutDetailCoupon> {
|
||||
final controller = TextEditingController();
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final priceCoupon = Provider.of<TotalPriceProvider>(context).priceCoupon;
|
||||
final totalPrice2 = Provider.of<TotalPriceProvider>(context).totalPrice;
|
||||
final totalPrice3 = Provider.of<TotalPriceProvider>(context).totalPrices;
|
||||
final typeCoupon = Provider.of<TotalPriceProvider>(context).typeCoupon;
|
||||
final finalPriceCoupon =
|
||||
Provider.of<TotalPriceProvider>(context).finalPriceCoupon;
|
||||
final potonganKupon2 =
|
||||
Provider.of<TotalPriceProvider>(context).potonganKupon;
|
||||
|
||||
Widget bottomNav(String totalPrice) {
|
||||
String totalHarga =
|
||||
"Rp. ${NumberFormat.currency(locale: 'id', symbol: '', decimalDigits: 0).format(totalPrice == '0' ? widget.discountHarga : double.parse(totalPrice))}";
|
||||
|
||||
return Container(
|
||||
width: double.infinity,
|
||||
height: getProportionateScreenHeight(64),
|
||||
decoration: BoxDecoration(
|
||||
color: Theme.of(context).colorScheme.background,
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Theme.of(context).colorScheme.onPrimary.withOpacity(0.1),
|
||||
spreadRadius: 4,
|
||||
blurRadius: 15,
|
||||
offset: Offset(0, 4),
|
||||
),
|
||||
],
|
||||
),
|
||||
child: Row(
|
||||
children: [
|
||||
SizedBox(width: 13),
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
SizedBox(height: getProportionateScreenHeight(6)),
|
||||
Text(
|
||||
"Total",
|
||||
style: thirdTextStyle.copyWith(
|
||||
fontSize: getProportionateScreenHeight(12),
|
||||
fontWeight: semiBold,
|
||||
),
|
||||
),
|
||||
SizedBox(height: getProportionateScreenHeight(2)),
|
||||
if (widget.isKupon == null)
|
||||
Text(
|
||||
'Rp. ${NumberFormat.currency(locale: 'id', symbol: '', decimalDigits: 0).format(finalPriceCoupon! < 50000 ? finalPriceCoupon + 5000 : finalPriceCoupon)}',
|
||||
style: thirdTextStyle.copyWith(
|
||||
fontSize: SizeConfig.blockVertical! * 2.5,
|
||||
letterSpacing: 0.23,
|
||||
),
|
||||
),
|
||||
if (widget.isKupon == true)
|
||||
Text(
|
||||
'Rp. ${NumberFormat.currency(locale: 'id', symbol: '', decimalDigits: 0).format(widget.discountHarga! < 50000 ? widget.discountHarga! + 5000 : widget.discountHarga)}',
|
||||
style: thirdTextStyle.copyWith(
|
||||
fontSize: SizeConfig.blockVertical! * 2.5,
|
||||
letterSpacing: 0.23,
|
||||
),
|
||||
),
|
||||
SizedBox(height: getProportionateScreenHeight(2)),
|
||||
],
|
||||
),
|
||||
Spacer(),
|
||||
GestureDetector(
|
||||
onTap: () async {
|
||||
print("Ini id cart? ${widget.idCart}");
|
||||
|
||||
if (totalHarga == 'Rp. 0') {
|
||||
// Jika total harga adalah 0, arahkan ke halaman zero-payment
|
||||
Navigator.of(context).push(
|
||||
MaterialPageRoute(
|
||||
builder: (context) => DetailZeroPayment(idCart: widget.idCart),
|
||||
),
|
||||
);
|
||||
} else {
|
||||
// Dapatkan total harga dan id transaksi untuk Snap Midtrans
|
||||
String orderId = 'order-${DateTime.now().millisecondsSinceEpoch}';
|
||||
int grossAmount = int.parse(
|
||||
totalHarga.replaceAll('Rp. ', '').replaceAll(',', '')
|
||||
);
|
||||
|
||||
// Persiapkan data_invoice berdasarkan kursus yang dibeli
|
||||
List<Map<String, dynamic>> dataInvoice = [];
|
||||
widget.idCart.forEach((cartId) {
|
||||
dataInvoice.add({
|
||||
'id_kursus': cartId, // Sesuaikan dengan data yang relevan
|
||||
'title_kursus': 'Nama Kursus', // Nama kursus yang sesuai
|
||||
'harga': grossAmount.toString(),
|
||||
'qty': '1', // Sesuaikan jumlah jika diperlukan
|
||||
});
|
||||
});
|
||||
|
||||
// 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) {
|
||||
// Snap berhasil dibuka, arahkan ke halaman WebView Snap
|
||||
Navigator.of(context).push(
|
||||
MaterialPageRoute(
|
||||
builder: (context) => SnapPaymentPage(
|
||||
transactionToken: paymentResponse[''] ?? '',
|
||||
orderId: orderId,
|
||||
grossAmount: grossAmount, courseTitle: '', courseThumbnail: '', courseInstructor: '', courseId: '',
|
||||
),
|
||||
),
|
||||
);
|
||||
} else {
|
||||
// Jika Snap gagal dibuka
|
||||
print("Pembayaran gagal");
|
||||
}
|
||||
}
|
||||
},
|
||||
child: Container(
|
||||
margin: EdgeInsets.only(right: getProportionateScreenWidth(15)),
|
||||
width: getProportionateScreenWidth(135),
|
||||
height: getProportionateScreenHeight(35),
|
||||
decoration: BoxDecoration(
|
||||
color: primaryColor,
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
),
|
||||
child: Center(
|
||||
child: Text(
|
||||
'Pilih Pembayaran',
|
||||
style: thirdTextStyle.copyWith(
|
||||
fontSize: SizeConfig.blockVertical! * 1.7,
|
||||
fontWeight: semiBold,
|
||||
letterSpacing: 0.5,
|
||||
color: baruTextutih,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
backgroundColor: Theme.of(context).colorScheme.background,
|
||||
centerTitle: true,
|
||||
title: Text(
|
||||
'Checkout',
|
||||
style: thirdTextStyle.copyWith(
|
||||
letterSpacing: 1,
|
||||
fontWeight: semiBold,
|
||||
fontSize: getProportionateScreenWidth(14)),
|
||||
),
|
||||
),
|
||||
body: SingleChildScrollView(
|
||||
child: Container(
|
||||
margin: EdgeInsets.symmetric(horizontal: getProportionateScreenWidth(16)),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
'Detail Pesanan',
|
||||
style: thirdTextStyle.copyWith(
|
||||
letterSpacing: 1,
|
||||
fontWeight: semiBold,
|
||||
fontSize: getProportionateScreenWidth(14),
|
||||
),
|
||||
),
|
||||
SizedBox(height: getProportionateScreenHeight(20)),
|
||||
Consumer<provOrder.OrderProvider>(
|
||||
builder: (context, state, _) {
|
||||
return Column(
|
||||
children: [
|
||||
...state.orders.map(
|
||||
(order) => CourseList(
|
||||
idCourse: order.idCourse,
|
||||
title: order.title,
|
||||
price: widget.isKupon == null
|
||||
? finalPriceCoupon.toString()
|
||||
: (potonganKupon2 == 0
|
||||
? finalPriceCoupon.toString()
|
||||
: (potonganKupon2! > totalPrice2!
|
||||
? finalPriceCoupon.toString()
|
||||
: totalPrice3.toString())),
|
||||
discountPrice: priceCoupon.toString(),
|
||||
imageUrl: order.imageUrl,
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
),
|
||||
SizedBox(height: getProportionateScreenHeight(5)),
|
||||
Text(
|
||||
'Rincian Harga',
|
||||
style: thirdTextStyle.copyWith(
|
||||
letterSpacing: 1,
|
||||
fontWeight: semiBold,
|
||||
fontSize: getProportionateScreenWidth(14),
|
||||
),
|
||||
),
|
||||
SizedBox(height: getProportionateScreenHeight(10)),
|
||||
Row(
|
||||
children: [
|
||||
Text(
|
||||
'Subtotal Harga Kursus',
|
||||
style: thirdTextStyle.copyWith(
|
||||
fontWeight: reguler,
|
||||
fontSize: getProportionateScreenWidth(10),
|
||||
),
|
||||
),
|
||||
Spacer(),
|
||||
if (widget.isKupon == null)
|
||||
Text(
|
||||
'Rp. ${NumberFormat.currency(locale: 'id', symbol: '', decimalDigits: 0).format(priceCoupon!)}',
|
||||
style: thirdTextStyle.copyWith(
|
||||
letterSpacing: 0.5,
|
||||
fontWeight: reguler,
|
||||
fontSize: getProportionateScreenWidth(12),
|
||||
),
|
||||
),
|
||||
if (widget.isKupon == true)
|
||||
Text(
|
||||
'Rp. ${NumberFormat.currency(locale: 'id', symbol: '', decimalDigits: 0).format(finalPriceCoupon == 0 ? priceCoupon : (potonganKupon2! > totalPrice2! ? finalPriceCoupon : totalPrice3))}',
|
||||
style: thirdTextStyle.copyWith(
|
||||
letterSpacing: 0.5,
|
||||
fontWeight: reguler,
|
||||
fontSize: getProportionateScreenWidth(12),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(height: getProportionateScreenHeight(5)),
|
||||
Row(
|
||||
children: [
|
||||
Text(
|
||||
'Biaya Layanan',
|
||||
style: thirdTextStyle.copyWith(
|
||||
fontWeight: reguler,
|
||||
fontSize: getProportionateScreenWidth(10),
|
||||
),
|
||||
),
|
||||
Spacer(),
|
||||
Text(
|
||||
'Rp ${NumberFormat.currency(locale: 'id', symbol: '', decimalDigits: 0).format(double.parse(finalPriceCoupon! < 5000 ? "5000" : "0"))}',
|
||||
style: thirdTextStyle.copyWith(
|
||||
fontWeight: reguler,
|
||||
fontSize: getProportionateScreenWidth(12),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(height: getProportionateScreenHeight(5)),
|
||||
Row(
|
||||
children: [
|
||||
Text(
|
||||
'Potongan Kupon',
|
||||
style: primaryTextStyle.copyWith(
|
||||
fontWeight: reguler,
|
||||
fontSize: getProportionateScreenWidth(10),
|
||||
),
|
||||
),
|
||||
Spacer(),
|
||||
Text(
|
||||
'Rp ${NumberFormat.currency(locale: 'id', symbol: '', decimalDigits: 0).format(double.parse(typeCoupon != "3" ? widget.potonganKupon.toString() : (priceCoupon! - finalPriceCoupon).toString()))}',
|
||||
style: primaryTextStyle.copyWith(
|
||||
fontWeight: reguler,
|
||||
fontSize: getProportionateScreenWidth(12),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(height: getProportionateScreenHeight(8)),
|
||||
Row(
|
||||
children: [
|
||||
Text(
|
||||
'Total Bayar',
|
||||
style: thirdTextStyle.copyWith(
|
||||
fontWeight: reguler,
|
||||
fontSize: getProportionateScreenWidth(14),
|
||||
),
|
||||
),
|
||||
Spacer(),
|
||||
if (widget.isKupon == null)
|
||||
Text(
|
||||
'Rp. ${NumberFormat.currency(locale: 'id', symbol: '', decimalDigits: 0).format(finalPriceCoupon! < 50000 ? finalPriceCoupon + 5000 : finalPriceCoupon)}',
|
||||
style: thirdTextStyle.copyWith(
|
||||
fontWeight: semiBold,
|
||||
fontSize: getProportionateScreenWidth(14),
|
||||
),
|
||||
),
|
||||
if (widget.isKupon == true)
|
||||
Text(
|
||||
'Rp. ${NumberFormat.currency(locale: 'id', symbol: '', decimalDigits: 0).format(widget.discountHarga! < 50000 ? widget.discountHarga! + 5000 : widget.discountHarga)}',
|
||||
style: thirdTextStyle.copyWith(
|
||||
fontWeight: semiBold,
|
||||
fontSize: getProportionateScreenWidth(14),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
Row(
|
||||
children: [
|
||||
Text(''),
|
||||
Spacer(),
|
||||
if (widget.isKupon == null)
|
||||
Text(
|
||||
(int.parse(Provider.of<provOrder.OrderProvider>(context)
|
||||
.totalPrice!) !=
|
||||
0 &&
|
||||
int.parse(
|
||||
Provider.of<provOrder.OrderProvider>(context)
|
||||
.totalPrice!) < 50000) ||
|
||||
finalPriceCoupon! < 50000
|
||||
? "+ admin Rp 5000"
|
||||
: "",
|
||||
style: secondaryTextStyle.copyWith(
|
||||
letterSpacing: 1,
|
||||
fontWeight: reguler,
|
||||
fontSize: getProportionateScreenWidth(10),
|
||||
),
|
||||
),
|
||||
if (widget.isKupon != null)
|
||||
Text(
|
||||
(widget.discountHarga != 0 &&
|
||||
widget.discountHarga! < 50000)
|
||||
? "+ admin Rp 5000"
|
||||
: "",
|
||||
style: secondaryTextStyle.copyWith(
|
||||
letterSpacing: 1,
|
||||
fontWeight: reguler,
|
||||
fontSize: getProportionateScreenWidth(10),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
bottomNavigationBar: bottomNav(
|
||||
(int.parse(Provider.of<provOrder.OrderProvider>(context).totalPrice
|
||||
as String))
|
||||
.toString(),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
controller.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
}
|
559
lib/screens/checkout/checkout_page.dart
Normal file
559
lib/screens/checkout/checkout_page.dart
Normal file
@ -0,0 +1,559 @@
|
||||
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();
|
||||
}
|
||||
}
|
317
lib/screens/checkout/components/atm.dart
Normal file
317
lib/screens/checkout/components/atm.dart
Normal file
@ -0,0 +1,317 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:initial_folder/size_config.dart';
|
||||
import 'package:initial_folder/theme.dart';
|
||||
import 'package:styled_text/styled_text.dart';
|
||||
|
||||
class ATMBNI extends StatelessWidget {
|
||||
final TextStyle baris = thirdTextStyle.copyWith(
|
||||
fontWeight: reguler,
|
||||
fontSize: getProportionateScreenWidth(14),
|
||||
letterSpacing: 0.5,
|
||||
);
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Padding(
|
||||
padding:
|
||||
EdgeInsets.symmetric(horizontal: getProportionateScreenWidth(12)),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
StyledText(
|
||||
// text: '1. Open the <bold>BNI Mobile Banking</bold> app and login',
|
||||
text: '1. Masukkan kartu anda',
|
||||
style: baris,
|
||||
tags: {
|
||||
'bold': StyledTextTag(style: TextStyle(fontWeight: bold)),
|
||||
},
|
||||
),
|
||||
Divider(color: Color(0xff2D2D2D), thickness: 0.5, height: 35),
|
||||
StyledText(
|
||||
// text: '2. Choose menu <bold>Transfer</bold>',
|
||||
text: '2. Pilih Bahasa',
|
||||
style: baris,
|
||||
tags: {
|
||||
'bold': StyledTextTag(style: TextStyle(fontWeight: bold)),
|
||||
},
|
||||
),
|
||||
Divider(color: Color(0xff2D2D2D), thickness: 0.5, height: 35),
|
||||
StyledText(
|
||||
// text: '3. Choose menu <bold>Virtual Account Billing</bold>',
|
||||
text: '3. Masukkan <bold>PIN ATM</bold> Anda',
|
||||
style: baris,
|
||||
tags: {
|
||||
'bold': StyledTextTag(style: TextStyle(fontWeight: bold)),
|
||||
},
|
||||
),
|
||||
Divider(color: Color(0xff2D2D2D), thickness: 0.5, height: 35),
|
||||
StyledText(
|
||||
// text: '4. Choose the bank account you want to use',
|
||||
text: "4. Pilih \"Menu Lainnya\"",
|
||||
style: baris,
|
||||
tags: {
|
||||
'bold': StyledTextTag(style: TextStyle(fontWeight: bold)),
|
||||
},
|
||||
),
|
||||
Divider(color: Color(0xff2D2D2D), thickness: 0.5, height: 35),
|
||||
StyledText(
|
||||
// text: '5. Enter the 16 digits <bold>virtual account number</bold>',
|
||||
text: "5. Pilih \"Transfer\"",
|
||||
style: baris,
|
||||
tags: {
|
||||
'bold': StyledTextTag(style: TextStyle(fontWeight: bold)),
|
||||
},
|
||||
),
|
||||
Divider(color: Color(0xff2D2D2D), thickness: 0.5, height: 35),
|
||||
StyledText(
|
||||
text:
|
||||
// '6. The billing information will appear on the payment validation page',
|
||||
'6. Pilih Jenis rekening yang akan Anda gunakan',
|
||||
style: baris,
|
||||
tags: {
|
||||
'bold': StyledTextTag(style: TextStyle(fontWeight: bold)),
|
||||
},
|
||||
),
|
||||
Divider(color: Color(0xff2D2D2D), thickness: 0.5, height: 35),
|
||||
StyledText(
|
||||
text:
|
||||
// '7. If the information is correct, enter your password to proceed the payment',
|
||||
'7. Pilih \"Virtual Account Billing\"',
|
||||
style: baris,
|
||||
tags: {
|
||||
'bold': StyledTextTag(style: TextStyle(fontWeight: bold)),
|
||||
},
|
||||
),
|
||||
Divider(color: Color(0xff2D2D2D), thickness: 0.5, height: 35),
|
||||
StyledText(
|
||||
// text: '8. Your transaction will be processed',
|
||||
text: '8. Masukkan nomor Virtual Account Anda',
|
||||
style: baris,
|
||||
tags: {
|
||||
'bold': StyledTextTag(style: TextStyle(fontWeight: bold)),
|
||||
},
|
||||
),
|
||||
SizedBox(height: getProportionateScreenHeight(10)),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class ATMBCA extends StatelessWidget {
|
||||
final TextStyle baris = thirdTextStyle.copyWith(
|
||||
fontWeight: reguler,
|
||||
fontSize: getProportionateScreenWidth(14),
|
||||
letterSpacing: 0.5,
|
||||
);
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Padding(
|
||||
padding:
|
||||
EdgeInsets.symmetric(horizontal: getProportionateScreenWidth(12)),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
StyledText(
|
||||
// text: '1. Open the <bold>BNI Mobile Banking</bold> app and login',
|
||||
text: '1. Masukkan kartu anda ATM dan PIN BCA anda',
|
||||
style: baris,
|
||||
tags: {
|
||||
'bold': StyledTextTag(style: TextStyle(fontWeight: bold)),
|
||||
},
|
||||
),
|
||||
Divider(color: Color(0xff2D2D2D), thickness: 0.5, height: 35),
|
||||
StyledText(
|
||||
// text: '2. Choose menu <bold>Transfer</bold>',
|
||||
text: "2. Pada menu utama, pilih menu \"Transaksi lainnya\" ",
|
||||
style: baris,
|
||||
tags: {
|
||||
'bold': StyledTextTag(style: TextStyle(fontWeight: bold)),
|
||||
},
|
||||
),
|
||||
Divider(color: Color(0xff2D2D2D), thickness: 0.5, height: 35),
|
||||
StyledText(
|
||||
// text: '3. Choose menu <bold>Virtual Account Billing</bold>',
|
||||
text:
|
||||
"3. Pilih menu \"Transfer\" dan kemudian pilih \"BCA Virtual Account\" ",
|
||||
style: baris,
|
||||
tags: {
|
||||
'bold': StyledTextTag(style: TextStyle(fontWeight: bold)),
|
||||
},
|
||||
),
|
||||
Divider(color: Color(0xff2D2D2D), thickness: 0.5, height: 35),
|
||||
StyledText(
|
||||
// text: '4. Choose the bank account you want to use',
|
||||
text: "4. Masukkan no. BCA Virtual Account & klik \"Lanjutkan\" ",
|
||||
style: baris,
|
||||
tags: {
|
||||
'bold': StyledTextTag(style: TextStyle(fontWeight: bold)),
|
||||
},
|
||||
),
|
||||
Divider(color: Color(0xff2D2D2D), thickness: 0.5, height: 35),
|
||||
StyledText(
|
||||
// text: '5. Enter the 16 digits <bold>virtual account number</bold>',
|
||||
text: "5. Periksa kembali rincian pembayaran anda, lalu pilih Ya",
|
||||
style: baris,
|
||||
tags: {
|
||||
'bold': StyledTextTag(style: TextStyle(fontWeight: bold)),
|
||||
},
|
||||
),
|
||||
SizedBox(height: getProportionateScreenHeight(10)),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class AtmMandiri extends StatelessWidget {
|
||||
final TextStyle baris = thirdTextStyle.copyWith(
|
||||
fontWeight: reguler,
|
||||
fontSize: getProportionateScreenWidth(14),
|
||||
letterSpacing: 0.5,
|
||||
);
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Padding(
|
||||
padding:
|
||||
EdgeInsets.symmetric(horizontal: getProportionateScreenWidth(12)),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
StyledText(
|
||||
// text: '1. Open the <bold>BNI Mobile Banking</bold> app and login',
|
||||
text: '1. Masukkan kartu anda ATM dan PIN anda',
|
||||
style: baris,
|
||||
tags: {
|
||||
'bold': StyledTextTag(style: TextStyle(fontWeight: bold)),
|
||||
},
|
||||
),
|
||||
Divider(color: Color(0xff2D2D2D), thickness: 0.5, height: 35),
|
||||
StyledText(
|
||||
// text: '2. Choose menu <bold>Transfer</bold>',
|
||||
text: "2. Pada menu utama, pilih menu \"Bayar/Beli\" ",
|
||||
style: baris,
|
||||
tags: {
|
||||
'bold': StyledTextTag(style: TextStyle(fontWeight: bold)),
|
||||
},
|
||||
),
|
||||
Divider(color: Color(0xff2D2D2D), thickness: 0.5, height: 35),
|
||||
StyledText(
|
||||
// text: '3. Choose menu <bold>Virtual Account Billing</bold>',
|
||||
text:
|
||||
"3. Pilih menu \"Multi Payment\" (jika di layar belum tersedia tekan menu \"Lainnya\" dan pilih \"Multi Payment\") ",
|
||||
style: baris,
|
||||
tags: {
|
||||
'bold': StyledTextTag(style: TextStyle(fontWeight: bold)),
|
||||
},
|
||||
),
|
||||
Divider(color: Color(0xff2D2D2D), thickness: 0.5, height: 35),
|
||||
StyledText(
|
||||
// text: '4. Choose the bank account you want to use',
|
||||
text:
|
||||
"4. Masukkan nomor Biller Code pada kode perusahaan & klik \"Benar\" ",
|
||||
style: baris,
|
||||
tags: {
|
||||
'bold': StyledTextTag(style: TextStyle(fontWeight: bold)),
|
||||
},
|
||||
),
|
||||
Divider(color: Color(0xff2D2D2D), thickness: 0.5, height: 35),
|
||||
StyledText(
|
||||
// text: '5. Enter the 16 digits <bold>virtual account number</bold>',
|
||||
text:
|
||||
"5. Masukkan kode pembayaran (kode pembayaran Mandiri billpayment anda)",
|
||||
style: baris,
|
||||
tags: {
|
||||
'bold': StyledTextTag(style: TextStyle(fontWeight: bold)),
|
||||
},
|
||||
),
|
||||
StyledText(
|
||||
// text: '5. Enter the 16 digits <bold>virtual account number</bold>',
|
||||
text:
|
||||
"6. Periksa kembali data transaksi anda dan selesaikan proses pembayaran.",
|
||||
style: baris,
|
||||
tags: {
|
||||
'bold': StyledTextTag(style: TextStyle(fontWeight: bold)),
|
||||
},
|
||||
),
|
||||
SizedBox(height: getProportionateScreenHeight(10)),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class AtmPermata extends StatelessWidget {
|
||||
final TextStyle baris = thirdTextStyle.copyWith(
|
||||
fontWeight: reguler,
|
||||
fontSize: getProportionateScreenWidth(14),
|
||||
letterSpacing: 0.5,
|
||||
);
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Padding(
|
||||
padding:
|
||||
EdgeInsets.symmetric(horizontal: getProportionateScreenWidth(12)),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
StyledText(
|
||||
// text: '1. Open the <bold>BNI Mobile Banking</bold> app and login',
|
||||
text: '1. Masukkan kartu ATM dan PIN anda',
|
||||
style: baris,
|
||||
tags: {
|
||||
'bold': StyledTextTag(style: TextStyle(fontWeight: bold)),
|
||||
},
|
||||
),
|
||||
Divider(color: Color(0xff2D2D2D), thickness: 0.5, height: 35),
|
||||
StyledText(
|
||||
// text: '2. Choose menu <bold>Transfer</bold>',
|
||||
text: "2. Pada menu \"Transaksi Lainnya\" ",
|
||||
style: baris,
|
||||
tags: {
|
||||
'bold': StyledTextTag(style: TextStyle(fontWeight: bold)),
|
||||
},
|
||||
),
|
||||
Divider(color: Color(0xff2D2D2D), thickness: 0.5, height: 35),
|
||||
StyledText(
|
||||
// text: '3. Choose menu <bold>Virtual Account Billing</bold>',
|
||||
text:
|
||||
"3. Pilih menu \"Pembayaran\" kemudian Pilih \"Menu Pembayaran Lainnya\" ",
|
||||
style: baris,
|
||||
tags: {
|
||||
'bold': StyledTextTag(style: TextStyle(fontWeight: bold)),
|
||||
},
|
||||
),
|
||||
Divider(color: Color(0xff2D2D2D), thickness: 0.5, height: 35),
|
||||
StyledText(
|
||||
// text: '4. Choose the bank account you want to use',
|
||||
text: "4. Pilih menu \"VIRTUAL ACCOUNT\" ",
|
||||
style: baris,
|
||||
tags: {
|
||||
'bold': StyledTextTag(style: TextStyle(fontWeight: bold)),
|
||||
},
|
||||
),
|
||||
Divider(color: Color(0xff2D2D2D), thickness: 0.5, height: 35),
|
||||
StyledText(
|
||||
// text: '5. Enter the 16 digits <bold>virtual account number</bold>',
|
||||
text: "5. Masukkan nomor \"VIRTUAL ACCOUNT\", dan tekan \"BENAR\" ",
|
||||
style: baris,
|
||||
tags: {
|
||||
'bold': StyledTextTag(style: TextStyle(fontWeight: bold)),
|
||||
},
|
||||
),
|
||||
Divider(color: Color(0xff2D2D2D), thickness: 0.5, height: 35),
|
||||
StyledText(
|
||||
// text: '5. Enter the 16 digits <bold>virtual account number</bold>',
|
||||
text:
|
||||
"6. Pilih rekening yang menjadi sumber dana yang akan didebet, lalu tekan YA untuk konfirmasi transaksi",
|
||||
style: baris,
|
||||
tags: {
|
||||
'bold': StyledTextTag(style: TextStyle(fontWeight: bold)),
|
||||
},
|
||||
),
|
||||
SizedBox(height: getProportionateScreenHeight(10)),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
61
lib/screens/checkout/components/bar_batas_bayar.dart
Normal file
61
lib/screens/checkout/components/bar_batas_bayar.dart
Normal file
@ -0,0 +1,61 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:initial_folder/size_config.dart';
|
||||
import 'package:initial_folder/theme.dart';
|
||||
import 'package:styled_text/styled_text.dart';
|
||||
|
||||
class BarBatasBayar extends StatelessWidget {
|
||||
String storeName;
|
||||
BarBatasBayar(this.storeName);
|
||||
final TextStyle baris = thirdTextStyle.copyWith(
|
||||
fontFamily: "Poppins",
|
||||
fontSize: getProportionateScreenWidth(13),
|
||||
);
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
String store = storeName == 'indomaret' ? 'Indomaret' : 'Alfamart';
|
||||
return Padding(
|
||||
padding: EdgeInsets.symmetric(
|
||||
horizontal: getProportionateScreenWidth(12),
|
||||
vertical: getProportionateScreenHeight(12),
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
StyledText(
|
||||
text: '1. Datang ke<bold> $store</bold>',
|
||||
style: baris,
|
||||
tags: {
|
||||
'bold': StyledTextTag(style: TextStyle(fontWeight: bold)),
|
||||
},
|
||||
),
|
||||
Divider(color: Color(0xff2D2D2D), thickness: 0.5, height: 35),
|
||||
StyledText(
|
||||
text: '2. Tunjukkan <bold>kode pembayaran</bold> ke kasir',
|
||||
style: baris,
|
||||
tags: {
|
||||
'bold': StyledTextTag(style: TextStyle(fontWeight: bold)),
|
||||
},
|
||||
),
|
||||
Divider(color: Color(0xff2D2D2D), thickness: 0.5, height: 35),
|
||||
StyledText(
|
||||
text:
|
||||
'3. Bayar dengan uang tunai sesuai dengan total pembayaran (sudah termasuk biaya layanan)',
|
||||
style: baris,
|
||||
tags: {
|
||||
'bold': StyledTextTag(style: TextStyle(fontWeight: bold)),
|
||||
},
|
||||
),
|
||||
Divider(color: Color(0xff2D2D2D), thickness: 0.5, height: 35),
|
||||
StyledText(
|
||||
text: '4. Transaksi selesai, simpan bukti pembayaran Anda',
|
||||
style: baris,
|
||||
tags: {
|
||||
'bold': StyledTextTag(style: TextStyle(fontWeight: bold)),
|
||||
},
|
||||
),
|
||||
SizedBox(height: 4)
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
263
lib/screens/checkout/components/bottom_sheet_detail.dart
Normal file
263
lib/screens/checkout/components/bottom_sheet_detail.dart
Normal file
@ -0,0 +1,263 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:initial_folder/providers/order_provider.dart' as orderProvider;
|
||||
import 'package:initial_folder/providers/payments_provider.dart';
|
||||
import 'package:initial_folder/providers/user_info_provider.dart'
|
||||
as userInfoProvider;
|
||||
import 'package:initial_folder/size_config.dart';
|
||||
import 'package:initial_folder/theme.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
class BottomSheetDetail extends StatelessWidget {
|
||||
Map<String, String> paymentMethod = {
|
||||
'echannel': 'Bank Transfer',
|
||||
'bank_transfer': 'Bank Transfer',
|
||||
'credit_card': 'Kartu Kredit',
|
||||
'gopay': 'GoPay',
|
||||
'cstore': 'Gerai'
|
||||
};
|
||||
|
||||
Widget listCourse({String? title, String? instructor, String? price}) {
|
||||
return Container(
|
||||
padding: EdgeInsets.symmetric(vertical: 8),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Flexible(
|
||||
flex: 7,
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
title!,
|
||||
// "428 Menit Menjadi Pengusaha Sukses",
|
||||
maxLines: 2,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: primaryTextStyle.copyWith(
|
||||
letterSpacing: 0.5,
|
||||
fontWeight: reguler,
|
||||
fontSize: getProportionateScreenWidth(11),
|
||||
color: tenthColor,
|
||||
),
|
||||
),
|
||||
SizedBox(height: 4),
|
||||
Text(
|
||||
'Oleh $instructor',
|
||||
// 'Oleh Farid Subkhan',
|
||||
|
||||
style: primaryTextStyle.copyWith(
|
||||
letterSpacing: 0.5,
|
||||
fontWeight: reguler,
|
||||
fontSize: getProportionateScreenWidth(9.5),
|
||||
color: secondaryColor,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Flexible(
|
||||
flex: 3,
|
||||
child: Text(
|
||||
'Rp. ${NumberFormat.currency(locale: 'id', symbol: '', decimalDigits: 0).format(double.parse(price!))}',
|
||||
// 'Rp. ${NumberFormat.currency(locale: 'id', symbol: '', decimalDigits: 0).format(50000.0)}',
|
||||
|
||||
style: primaryTextStyle.copyWith(
|
||||
letterSpacing: 0.5,
|
||||
fontWeight: reguler,
|
||||
fontSize: getProportionateScreenWidth(12),
|
||||
color: tenthColor,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
var dataOrder =
|
||||
Provider.of<PaymentsProvider>(context, listen: false).detailOrder;
|
||||
var dataCourse =
|
||||
Provider.of<orderProvider.OrderProvider>(context, listen: false).orders;
|
||||
var dataUser =
|
||||
Provider.of<userInfoProvider.UserInfoProvider>(context, listen: false)
|
||||
.result;
|
||||
return Container(
|
||||
decoration: BoxDecoration(
|
||||
// color: Colors.red,
|
||||
borderRadius: BorderRadius.vertical(top: Radius.circular(20))),
|
||||
foregroundDecoration: BoxDecoration(
|
||||
// color: Colors.red,
|
||||
borderRadius: BorderRadius.all(Radius.circular(20))),
|
||||
child: ListView(
|
||||
shrinkWrap: true,
|
||||
physics: NeverScrollableScrollPhysics(),
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
IconButton(
|
||||
onPressed: () {
|
||||
Navigator.pop(context);
|
||||
},
|
||||
icon: Icon(Icons.keyboard_arrow_down)),
|
||||
Text('Detail Pembayaran')
|
||||
],
|
||||
),
|
||||
Container(
|
||||
height: 6,
|
||||
color: Color(0xff181818),
|
||||
),
|
||||
Container(
|
||||
height: MediaQuery.of(context).size.height * 0.4,
|
||||
child: ListView(
|
||||
shrinkWrap: true,
|
||||
children: [
|
||||
Container(
|
||||
padding: EdgeInsets.symmetric(horizontal: 15, vertical: 20),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text('Informasi Pembeli'),
|
||||
Divider(),
|
||||
Text(
|
||||
'Order ID',
|
||||
style: primaryTextStyle.copyWith(
|
||||
fontSize: 10, color: Color(0xffbfbfbf)),
|
||||
),
|
||||
Text(
|
||||
dataOrder[0].idOrder,
|
||||
style: primaryTextStyle.copyWith(
|
||||
fontSize: 12, color: Color(0xffF4f4f4)),
|
||||
),
|
||||
SizedBox(
|
||||
height: 15,
|
||||
),
|
||||
Text(
|
||||
'Nama Lengkap',
|
||||
style: primaryTextStyle.copyWith(
|
||||
fontSize: 10, color: Color(0xffbfbfbf)),
|
||||
),
|
||||
Text(
|
||||
dataUser!.data[0].fullname!,
|
||||
style: primaryTextStyle.copyWith(
|
||||
fontSize: 12, color: Color(0xffF4f4f4)),
|
||||
),
|
||||
SizedBox(
|
||||
height: 15,
|
||||
),
|
||||
Text(
|
||||
'Email',
|
||||
style: primaryTextStyle.copyWith(
|
||||
fontSize: 10, color: Color(0xffbfbfbf)),
|
||||
),
|
||||
Text(
|
||||
dataUser.data[0].email!,
|
||||
style: primaryTextStyle.copyWith(
|
||||
fontSize: 12, color: Color(0xffF4f4f4)),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Container(
|
||||
height: 6,
|
||||
color: Color(0xff181818),
|
||||
),
|
||||
Container(
|
||||
padding: EdgeInsets.symmetric(horizontal: 15, vertical: 20),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text('Informasi Pembayaran'),
|
||||
Divider(),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text('Metode Pembayaran',
|
||||
style: primaryTextStyle.copyWith(
|
||||
fontSize: 12, color: Color(0xffbfbfbf))),
|
||||
Text(paymentMethod[dataOrder[0].paymentType]!,
|
||||
style: primaryTextStyle.copyWith(
|
||||
fontSize: 12, color: Color(0xffF4f4f4))),
|
||||
],
|
||||
),
|
||||
Divider(),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text('Total Harga',
|
||||
style: primaryTextStyle.copyWith(
|
||||
fontSize: 10, color: Color(0xffbfbfbf))),
|
||||
Text(
|
||||
'Rp. ${NumberFormat.currency(locale: 'id', symbol: '', decimalDigits: 0).format(double.parse(dataOrder[0].totalPayment))}',
|
||||
style: primaryTextStyle.copyWith(
|
||||
fontSize: 12, color: Color(0xffF4f4f4))),
|
||||
],
|
||||
),
|
||||
SizedBox(height: 15),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text('Potongan Kupon',
|
||||
style: primaryTextStyle.copyWith(
|
||||
fontSize: 10, color: Color(0xffbfbfbf))),
|
||||
Text('Rp. 0',
|
||||
style: primaryTextStyle.copyWith(
|
||||
fontSize: 12, color: Color(0xffF4f4f4))),
|
||||
],
|
||||
),
|
||||
Divider(),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text('Total Bayar',
|
||||
style: primaryTextStyle.copyWith(
|
||||
fontSize: 12, color: Color(0xffbfbfbf))),
|
||||
Text(
|
||||
'Rp. ${NumberFormat.currency(locale: 'id', symbol: '', decimalDigits: 0).format(double.parse(dataOrder[0].totalPayment))}',
|
||||
style: primaryTextStyle.copyWith(
|
||||
fontSize: 12, color: Color(0xffF4f4f4))),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Container(
|
||||
height: 6,
|
||||
color: Color(0xff181818),
|
||||
),
|
||||
Container(
|
||||
padding: EdgeInsets.symmetric(horizontal: 15, vertical: 20),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text('Kursus Yang Dibeli'),
|
||||
Divider(),
|
||||
Column(
|
||||
children: dataCourse.map((course) {
|
||||
return listCourse(
|
||||
title: course.title,
|
||||
instructor: course.instructor,
|
||||
price: course.discountPrice == "0"
|
||||
? course.price
|
||||
: course.discountPrice,
|
||||
);
|
||||
}).toList()),
|
||||
// listCourse(),
|
||||
// listCourse(),
|
||||
// listCourse(),
|
||||
// Text('Halo'),
|
||||
// Text('Halo'),
|
||||
// Text('Halo'),
|
||||
// Text('Halo')
|
||||
],
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
262
lib/screens/checkout/components/bottom_sheet_history.dart
Normal file
262
lib/screens/checkout/components/bottom_sheet_history.dart
Normal file
@ -0,0 +1,262 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:initial_folder/providers/order_provider.dart' as orderProvider;
|
||||
import 'package:initial_folder/providers/payments_provider.dart';
|
||||
import 'package:initial_folder/providers/total_price_provider.dart';
|
||||
import 'package:initial_folder/providers/user_info_provider.dart'
|
||||
as userInfoProvider;
|
||||
import 'package:initial_folder/size_config.dart';
|
||||
import 'package:initial_folder/theme.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
class BottomSheetHistory extends StatelessWidget {
|
||||
Map<String, String> paymentMethod = {
|
||||
'echannel': 'Bank Transfer',
|
||||
'bank_transfer': 'Bank Transfer',
|
||||
'credit_card': 'Kartu Kredit',
|
||||
'gopay': 'GoPay',
|
||||
'cstore': 'Gerai'
|
||||
};
|
||||
|
||||
Widget listCourse({String? title, String? instructor, String? price}) {
|
||||
return Container(
|
||||
padding: EdgeInsets.symmetric(vertical: 8),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Flexible(
|
||||
flex: 7,
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
title!,
|
||||
// "428 Menit Menjadi Pengusaha Sukses",
|
||||
maxLines: 2,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: primaryTextStyle.copyWith(
|
||||
letterSpacing: 0.5,
|
||||
fontWeight: reguler,
|
||||
fontSize: getProportionateScreenWidth(11),
|
||||
color: tenthColor,
|
||||
),
|
||||
),
|
||||
SizedBox(height: 4),
|
||||
Text(
|
||||
'Oleh $instructor',
|
||||
// 'Oleh Farid Subkhan',
|
||||
|
||||
style: primaryTextStyle.copyWith(
|
||||
letterSpacing: 0.5,
|
||||
fontWeight: reguler,
|
||||
fontSize: getProportionateScreenWidth(9.5),
|
||||
color: secondaryColor,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Flexible(
|
||||
flex: 3,
|
||||
child: Text(
|
||||
'Rp. ${NumberFormat.currency(locale: 'id', symbol: '', decimalDigits: 0).format(double.parse(price!))}',
|
||||
// 'Rp. ${NumberFormat.currency(locale: 'id', symbol: '', decimalDigits: 0).format(50000.0)}',
|
||||
|
||||
style: primaryTextStyle.copyWith(
|
||||
letterSpacing: 0.5,
|
||||
fontWeight: reguler,
|
||||
fontSize: getProportionateScreenWidth(12),
|
||||
color: tenthColor,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
var dataOrder =
|
||||
Provider.of<PaymentsProvider>(context, listen: false).detailOrder;
|
||||
var dataCourse =
|
||||
Provider.of<orderProvider.OrderProvider>(context, listen: false).orders;
|
||||
var dataUser =
|
||||
Provider.of<userInfoProvider.UserInfoProvider>(context, listen: false)
|
||||
.result;
|
||||
int totalPrices = Provider.of<TotalPriceProvider>(context).totalPrices!;
|
||||
return Container(
|
||||
decoration: BoxDecoration(
|
||||
// color: Colors.red,
|
||||
borderRadius: BorderRadius.vertical(top: Radius.circular(20))),
|
||||
foregroundDecoration: BoxDecoration(
|
||||
// color: Colors.red,
|
||||
borderRadius: BorderRadius.all(Radius.circular(20))),
|
||||
child: ListView(
|
||||
shrinkWrap: true,
|
||||
physics: NeverScrollableScrollPhysics(),
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
IconButton(
|
||||
onPressed: () {
|
||||
Navigator.pop(context);
|
||||
},
|
||||
icon: Icon(Icons.keyboard_arrow_down)),
|
||||
Text('Detail Pembayaran')
|
||||
],
|
||||
),
|
||||
Container(
|
||||
height: 6,
|
||||
color: Color(0xff181818),
|
||||
),
|
||||
Container(
|
||||
height: MediaQuery.of(context).size.height * 0.4,
|
||||
child: ListView(
|
||||
shrinkWrap: true,
|
||||
children: [
|
||||
Container(
|
||||
padding: EdgeInsets.symmetric(horizontal: 15, vertical: 20),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text('Informasi Pembeli'),
|
||||
Divider(),
|
||||
Text(
|
||||
'Order ID',
|
||||
style: primaryTextStyle.copyWith(
|
||||
fontSize: 10, color: Color(0xffbfbfbf)),
|
||||
),
|
||||
Text(
|
||||
dataOrder[0].idOrder,
|
||||
style: primaryTextStyle.copyWith(
|
||||
fontSize: 12, color: Color(0xffF4f4f4)),
|
||||
),
|
||||
SizedBox(
|
||||
height: 15,
|
||||
),
|
||||
Text(
|
||||
'Nama Lengkap',
|
||||
style: primaryTextStyle.copyWith(
|
||||
fontSize: 10, color: Color(0xffbfbfbf)),
|
||||
),
|
||||
Text(
|
||||
dataUser!.data[0].fullname!,
|
||||
style: primaryTextStyle.copyWith(
|
||||
fontSize: 12, color: Color(0xffF4f4f4)),
|
||||
),
|
||||
SizedBox(
|
||||
height: 15,
|
||||
),
|
||||
Text(
|
||||
'Email',
|
||||
style: primaryTextStyle.copyWith(
|
||||
fontSize: 10, color: Color(0xffbfbfbf)),
|
||||
),
|
||||
Text(
|
||||
dataUser.data[0].email!,
|
||||
style: primaryTextStyle.copyWith(
|
||||
fontSize: 12, color: Color(0xffF4f4f4)),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Container(
|
||||
height: 6,
|
||||
color: Color(0xff181818),
|
||||
),
|
||||
Container(
|
||||
padding: EdgeInsets.symmetric(horizontal: 15, vertical: 20),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text('Informasi Pembayaran'),
|
||||
Divider(),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text('Metode Pembayaran',
|
||||
style: primaryTextStyle.copyWith(
|
||||
fontSize: 12, color: Color(0xffbfbfbf))),
|
||||
Text(paymentMethod[dataOrder[0].paymentType]!,
|
||||
style: primaryTextStyle.copyWith(
|
||||
fontSize: 12, color: Color(0xffF4f4f4))),
|
||||
],
|
||||
),
|
||||
Divider(),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text('Total Harga',
|
||||
style: primaryTextStyle.copyWith(
|
||||
fontSize: 10, color: Color(0xffbfbfbf))),
|
||||
Text(
|
||||
'Rp. ${NumberFormat.currency(locale: 'id', symbol: '', decimalDigits: 0).format(double.parse(Provider.of<TotalPriceProvider>(context).totalPrices.toString()))}',
|
||||
style: primaryTextStyle.copyWith(
|
||||
fontSize: 12, color: Color(0xffF4f4f4))),
|
||||
],
|
||||
),
|
||||
SizedBox(height: 15),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text('Potongan Kupon',
|
||||
style: primaryTextStyle.copyWith(
|
||||
fontSize: 10, color: Color(0xffbfbfbf))),
|
||||
Text('Rp. 0',
|
||||
style: primaryTextStyle.copyWith(
|
||||
fontSize: 12, color: Color(0xffF4f4f4))),
|
||||
],
|
||||
),
|
||||
Divider(),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text('Total Bayar',
|
||||
style: primaryTextStyle.copyWith(
|
||||
fontSize: 12, color: Color(0xffbfbfbf))),
|
||||
Text(
|
||||
'Rp. ${NumberFormat.currency(locale: 'id', symbol: '', decimalDigits: 0).format(double.parse(Provider.of<TotalPriceProvider>(context).totalPrices.toString()))}',
|
||||
style: primaryTextStyle.copyWith(
|
||||
fontSize: 12, color: Color(0xffF4f4f4))),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Container(
|
||||
height: 6,
|
||||
color: Color(0xff181818),
|
||||
),
|
||||
// Container(
|
||||
// padding: EdgeInsets.symmetric(horizontal: 15, vertical: 20),
|
||||
// child: Column(
|
||||
// crossAxisAlignment: CrossAxisAlignment.start,
|
||||
// children: [
|
||||
// Text('Kursus Yang Dibeli'),
|
||||
// Divider(),
|
||||
// Column(
|
||||
// children: dataCourse.map((course) {
|
||||
// return listCourse(
|
||||
// title: course.title,
|
||||
// instructor: course.instructor,
|
||||
// price: course.discountPrice);
|
||||
// }).toList()),
|
||||
// listCourse(),
|
||||
// listCourse(),
|
||||
// listCourse(),
|
||||
// Text('Halo'),
|
||||
// Text('Halo'),
|
||||
// Text('Halo'),
|
||||
// Text('Halo')
|
||||
// ],
|
||||
// ),
|
||||
// )
|
||||
],
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
29
lib/screens/checkout/components/cardmonth.dart
Normal file
29
lib/screens/checkout/components/cardmonth.dart
Normal file
@ -0,0 +1,29 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
|
||||
class CardMonthInputFormatter extends TextInputFormatter {
|
||||
@override
|
||||
TextEditingValue formatEditUpdate(
|
||||
TextEditingValue oldValue, TextEditingValue newValue) {
|
||||
var masaController = newValue.text;
|
||||
if (newValue.selection.baseOffset == 0) {
|
||||
return newValue;
|
||||
}
|
||||
|
||||
var buffer = new StringBuffer();
|
||||
|
||||
for (int i = 0; i < masaController.length; i++) {
|
||||
buffer.write(masaController[i]);
|
||||
var nonZeroIndex = i + 1;
|
||||
|
||||
if (nonZeroIndex % 2 == 0 && nonZeroIndex != masaController.length) {
|
||||
buffer.write('/');
|
||||
}
|
||||
}
|
||||
|
||||
var string = buffer.toString();
|
||||
return newValue.copyWith(
|
||||
text: string,
|
||||
selection: new TextSelection.collapsed(offset: string.length));
|
||||
}
|
||||
}
|
28
lib/screens/checkout/components/cardnumber.dart
Normal file
28
lib/screens/checkout/components/cardnumber.dart
Normal file
@ -0,0 +1,28 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
|
||||
class CardNumberInputFormatter extends TextInputFormatter {
|
||||
@override
|
||||
TextEditingValue formatEditUpdate(
|
||||
TextEditingValue oldValue, TextEditingValue newValue) {
|
||||
var text = newValue.text;
|
||||
|
||||
if (newValue.selection.baseOffset == 0) {
|
||||
return newValue;
|
||||
}
|
||||
|
||||
var buffer = new StringBuffer();
|
||||
for (int i = 0; i < text.length; i++) {
|
||||
buffer.write(text[i]);
|
||||
var nonZeroIndex = i + 1;
|
||||
if (nonZeroIndex % 4 == 0 && nonZeroIndex != text.length) {
|
||||
buffer.write(' '); // Add double spaces.
|
||||
}
|
||||
}
|
||||
|
||||
var string = buffer.toString();
|
||||
return newValue.copyWith(
|
||||
text: string,
|
||||
selection: new TextSelection.collapsed(offset: string.length));
|
||||
}
|
||||
}
|
159
lib/screens/checkout/components/course_list.dart
Normal file
159
lib/screens/checkout/components/course_list.dart
Normal file
@ -0,0 +1,159 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:initial_folder/size_config.dart';
|
||||
import 'package:initial_folder/theme.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
|
||||
class CourseList extends StatelessWidget {
|
||||
const CourseList({
|
||||
Key? key,
|
||||
required this.idCourse,
|
||||
required this.title,
|
||||
required this.price,
|
||||
required this.discountPrice,
|
||||
required this.imageUrl,
|
||||
this.isDetailCourse,
|
||||
}) : super(key: key);
|
||||
|
||||
final String idCourse;
|
||||
final String title;
|
||||
final String price;
|
||||
final String discountPrice;
|
||||
final String imageUrl;
|
||||
final bool? isDetailCourse;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
print("Ini price ${price}");
|
||||
print("Ini discountPrice ${discountPrice}");
|
||||
return Column(
|
||||
children: [
|
||||
Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Flexible(
|
||||
flex: 10,
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Container(
|
||||
width: getProportionateScreenWidth(70),
|
||||
height: getProportionateScreenWidth(39),
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(5),
|
||||
image: DecorationImage(
|
||||
fit: BoxFit.cover,
|
||||
image: NetworkImage(imageUrl),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
)),
|
||||
SizedBox(width: getProportionateScreenWidth(10)),
|
||||
Expanded(
|
||||
flex: 15,
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
title,
|
||||
style: thirdTextStyle.copyWith(
|
||||
letterSpacing: 0.5,
|
||||
fontWeight: reguler,
|
||||
fontSize: getProportionateScreenWidth(12),
|
||||
),
|
||||
maxLines: 2,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
],
|
||||
)),
|
||||
Spacer(),
|
||||
Flexible(
|
||||
flex: 10,
|
||||
child: Align(
|
||||
alignment: Alignment.centerRight,
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
crossAxisAlignment: CrossAxisAlignment.end,
|
||||
children: [
|
||||
if (isDetailCourse == null)
|
||||
discountPrice == "0"
|
||||
? Text(
|
||||
'Rp. ${NumberFormat.currency(locale: 'id', symbol: '', decimalDigits: 0).format(double.parse(price))}',
|
||||
style: thirdTextStyle.copyWith(
|
||||
letterSpacing: 0.5,
|
||||
fontWeight: reguler,
|
||||
fontSize: getProportionateScreenWidth(11),
|
||||
),
|
||||
)
|
||||
: Text(
|
||||
'Rp. ${NumberFormat.currency(locale: 'id', symbol: '', decimalDigits: 0).format(double.parse(price))}',
|
||||
style: thirdTextStyle.copyWith(
|
||||
letterSpacing: 0.5,
|
||||
fontWeight: reguler,
|
||||
fontSize: getProportionateScreenWidth(11),
|
||||
),
|
||||
)
|
||||
else
|
||||
discountPrice == "0"
|
||||
? Text(
|
||||
'Rp. ${NumberFormat.currency(locale: 'id', symbol: '', decimalDigits: 0).format(double.parse(price))}',
|
||||
style: thirdTextStyle.copyWith(
|
||||
letterSpacing: 0.5,
|
||||
fontWeight: reguler,
|
||||
fontSize: getProportionateScreenWidth(11),
|
||||
),
|
||||
)
|
||||
: Text(
|
||||
'Rp. ${NumberFormat.currency(locale: 'id', symbol: '', decimalDigits: 0).format(double.parse(price == "0" ? discountPrice : price))}',
|
||||
style: thirdTextStyle.copyWith(
|
||||
letterSpacing: 0.5,
|
||||
fontWeight: reguler,
|
||||
fontSize: getProportionateScreenWidth(11),
|
||||
),
|
||||
),
|
||||
if (isDetailCourse == null)
|
||||
if (discountPrice != "0" && discountPrice != price)
|
||||
Text(
|
||||
'Rp ${NumberFormat.currency(locale: 'id', symbol: '', decimalDigits: 0).format(double.parse(discountPrice))}',
|
||||
style: thirdTextStyle.copyWith(
|
||||
letterSpacing: 0.5,
|
||||
decoration: TextDecoration.lineThrough,
|
||||
color: fourthColor,
|
||||
fontWeight: reguler,
|
||||
fontSize: SizeConfig.blockHorizontal! * 2.7,
|
||||
),
|
||||
)
|
||||
else
|
||||
SizedBox.shrink()
|
||||
else if (price != "0")
|
||||
Text(
|
||||
'Rp ${NumberFormat.currency(locale: 'id', symbol: '', decimalDigits: 0).format(double.parse(discountPrice))}',
|
||||
style: thirdTextStyle.copyWith(
|
||||
letterSpacing: 0.5,
|
||||
decoration: TextDecoration.lineThrough,
|
||||
color: fourthColor,
|
||||
fontWeight: reguler,
|
||||
fontSize: SizeConfig.blockHorizontal! * 2.7,
|
||||
),
|
||||
)
|
||||
else
|
||||
SizedBox.shrink(),
|
||||
SizedBox(height: getProportionateScreenHeight(2)),
|
||||
discountPrice != "0" && discountPrice != price
|
||||
? SizedBox()
|
||||
: SizedBox(),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(height: getProportionateScreenHeight(10)),
|
||||
Divider(color: fourthColor),
|
||||
SizedBox(height: getProportionateScreenHeight(5)),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
130
lib/screens/checkout/components/course_list_coupon.dart
Normal file
130
lib/screens/checkout/components/course_list_coupon.dart
Normal file
@ -0,0 +1,130 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:initial_folder/providers/total_price_provider.dart';
|
||||
import 'package:initial_folder/size_config.dart';
|
||||
import 'package:initial_folder/theme.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
class CourseListCoupon extends StatelessWidget {
|
||||
final String idCourse;
|
||||
final String title;
|
||||
final String price;
|
||||
final String discountPrice;
|
||||
final String imageUrl;
|
||||
const CourseListCoupon({
|
||||
Key? key,
|
||||
required this.idCourse,
|
||||
required this.title,
|
||||
required this.price,
|
||||
required this.discountPrice,
|
||||
required this.imageUrl,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final priceCoupon = Provider.of<TotalPriceProvider>(context).priceCoupon;
|
||||
return Column(
|
||||
children: [
|
||||
Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Flexible(
|
||||
flex: 10,
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Container(
|
||||
width: getProportionateScreenWidth(70),
|
||||
height: getProportionateScreenWidth(39),
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(5),
|
||||
image: DecorationImage(
|
||||
fit: BoxFit.cover,
|
||||
image: NetworkImage(imageUrl),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
)),
|
||||
SizedBox(width: getProportionateScreenWidth(10)),
|
||||
Expanded(
|
||||
flex: 15,
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
title,
|
||||
style: primaryTextStyle.copyWith(
|
||||
letterSpacing: 0.5,
|
||||
fontWeight: reguler,
|
||||
fontSize: getProportionateScreenWidth(12),
|
||||
),
|
||||
maxLines: 2,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
],
|
||||
)),
|
||||
Spacer(),
|
||||
Flexible(
|
||||
flex: 10,
|
||||
child: Align(
|
||||
alignment: Alignment.centerRight,
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
crossAxisAlignment: CrossAxisAlignment.end,
|
||||
children: [
|
||||
discountPrice == "0"
|
||||
? Text(
|
||||
'Rp. ${NumberFormat.currency(locale: 'id', symbol: '', decimalDigits: 0).format(double.parse(price))}',
|
||||
style: primaryTextStyle.copyWith(
|
||||
letterSpacing: 0.5,
|
||||
fontWeight: reguler,
|
||||
fontSize: getProportionateScreenWidth(12),
|
||||
),
|
||||
)
|
||||
: Text(
|
||||
'Rp. ${NumberFormat.currency(locale: 'id', symbol: '', decimalDigits: 0).format(double.parse(discountPrice))}',
|
||||
style: primaryTextStyle.copyWith(
|
||||
letterSpacing: 0.5,
|
||||
fontWeight: reguler,
|
||||
fontSize: getProportionateScreenWidth(12),
|
||||
),
|
||||
),
|
||||
// Text(
|
||||
// 'Rp ${NumberFormat.currency(locale: 'id', symbol: '', decimalDigits: 0).format(double.parse(price))}',
|
||||
// style: primaryTextStyle.copyWith(
|
||||
// letterSpacing: 0.5,
|
||||
// fontWeight: reguler,
|
||||
// fontSize: getProportionateScreenWidth(12),
|
||||
// ),
|
||||
// ),
|
||||
SizedBox(
|
||||
height: getProportionateScreenHeight(2),
|
||||
),
|
||||
priceCoupon.toString() != "0"
|
||||
? Text(
|
||||
'Rp. ${NumberFormat.currency(locale: 'id', symbol: '', decimalDigits: 0).format(double.parse(priceCoupon.toString()))}',
|
||||
style: primaryTextStyle.copyWith(
|
||||
decoration: TextDecoration.lineThrough,
|
||||
color: secondaryColor,
|
||||
letterSpacing: 0.5,
|
||||
fontWeight: reguler,
|
||||
fontSize: getProportionateScreenWidth(10),
|
||||
),
|
||||
)
|
||||
: SizedBox(),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(height: getProportionateScreenHeight(10)),
|
||||
Divider(color: fourthColor),
|
||||
SizedBox(height: getProportionateScreenHeight(5)),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
105
lib/screens/checkout/components/field_kupon.dart
Normal file
105
lib/screens/checkout/components/field_kupon.dart
Normal file
@ -0,0 +1,105 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import '../../../../theme.dart';
|
||||
import '../../../../size_config.dart';
|
||||
|
||||
class FieldKupon extends StatelessWidget {
|
||||
final TextEditingController controler;
|
||||
final IconButton? prefix;
|
||||
const FieldKupon({Key? key, required this.controler, this.prefix})
|
||||
: super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
OutlineInputBorder outlineInputBorder = OutlineInputBorder(
|
||||
borderSide: BorderSide(color: Colors.transparent),
|
||||
gapPadding: 10,
|
||||
);
|
||||
// width: SizeConfig.screenWidth * 0.9,
|
||||
// height: 33,
|
||||
// decoration: BoxDecoration(
|
||||
// color: Colors.white,
|
||||
// borderRadius: BorderRadius.circular(15),
|
||||
// border: Border.all(
|
||||
// color: kSecondaryColor.withOpacity(0.5),
|
||||
// width: 2,
|
||||
|
||||
// return Scaffold(
|
||||
// body: Container(
|
||||
// height: 36,
|
||||
// //padding: EdgeInsets.only(top: getProportionateScreenWidth(20)),
|
||||
// child: TextField(
|
||||
// controller: controler,
|
||||
// cursorColor: secondaryColor,
|
||||
// enabled: true,
|
||||
// //obscureText: true,
|
||||
// textAlignVertical: TextAlignVertical.center,
|
||||
// style: TextStyle(fontSize: 12, color: Colors.white),
|
||||
// onChanged: (value) => print(value),
|
||||
// decoration: InputDecoration(
|
||||
// //isDense: true,
|
||||
// contentPadding: EdgeInsets.only(top: 10, left: 15),
|
||||
// filled: true,
|
||||
// fillColor: Colors.transparent,
|
||||
// enabledBorder: outlineInputBorder,
|
||||
// focusedBorder: outlineInputBorder,
|
||||
// border: outlineInputBorder,
|
||||
// hintText: "Masukkan kode kupon",
|
||||
// hintStyle: primaryTextStyle.copyWith(
|
||||
// fontSize: 12,
|
||||
// color: fourthColor,
|
||||
// fontWeight: reguler,
|
||||
// letterSpacing: 0.5),
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
|
||||
// // SizedBox(height: getProportionateScreenHeight(16)),
|
||||
// );
|
||||
return Column(
|
||||
children: [
|
||||
Container(
|
||||
height: getProportionateScreenHeight(32),
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
color: Theme.of(context).brightness == Brightness.dark
|
||||
? seventeenColor.withOpacity(0.9)
|
||||
: secondaryColor.withOpacity(0.2),
|
||||
),
|
||||
child: TextField(
|
||||
controller: controler,
|
||||
cursorColor: Theme.of(context).colorScheme.onPrimary,
|
||||
enabled: true,
|
||||
textAlignVertical: TextAlignVertical.center,
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
color: Theme.of(context).colorScheme.onPrimary,
|
||||
),
|
||||
onChanged: (value) => print(value),
|
||||
decoration: InputDecoration(
|
||||
prefix: prefix,
|
||||
contentPadding: EdgeInsets.only(
|
||||
top: getProportionateScreenHeight(10),
|
||||
left: getProportionateScreenWidth(15),
|
||||
),
|
||||
filled: true,
|
||||
fillColor: Colors.transparent,
|
||||
enabledBorder: outlineInputBorder,
|
||||
focusedBorder: outlineInputBorder,
|
||||
border: outlineInputBorder,
|
||||
hintText: "Masukkan kode kupon",
|
||||
hintStyle: thirdTextStyle.copyWith(
|
||||
fontSize: getProportionateScreenWidth(10),
|
||||
color: Theme.of(context).brightness == Brightness.dark
|
||||
? baruTextutih.withOpacity(0.5)
|
||||
: Colors.grey,
|
||||
fontWeight: reguler,
|
||||
letterSpacing: 0.5,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(height: getProportionateScreenHeight(16)),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
337
lib/screens/checkout/components/internet_banking.dart
Normal file
337
lib/screens/checkout/components/internet_banking.dart
Normal file
@ -0,0 +1,337 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:initial_folder/size_config.dart';
|
||||
import 'package:initial_folder/theme.dart';
|
||||
import 'package:styled_text/styled_text.dart';
|
||||
|
||||
class InternetBankBNI extends StatelessWidget {
|
||||
final TextStyle baris = thirdTextStyle.copyWith(
|
||||
fontWeight: reguler,
|
||||
fontSize: getProportionateScreenWidth(14),
|
||||
letterSpacing: 0.5,
|
||||
);
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Padding(
|
||||
padding:
|
||||
EdgeInsets.symmetric(horizontal: getProportionateScreenWidth(12)),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
StyledText(
|
||||
// text: '1. Open the <bold>BNI Mobile Banking</bold> app and login',
|
||||
text: '1. Masuk ke https://ibank.bni.co.id',
|
||||
style: baris,
|
||||
tags: {
|
||||
'bold': StyledTextTag(style: TextStyle(fontWeight: bold)),
|
||||
},
|
||||
),
|
||||
Divider(color: Color(0xff2D2D2D), thickness: 0.5, height: 35),
|
||||
StyledText(
|
||||
// text: '2. Choose menu <bold>Transfer</bold>',
|
||||
text: '2. Masukkan User ID dan Password',
|
||||
style: baris,
|
||||
tags: {
|
||||
'bold': StyledTextTag(style: TextStyle(fontWeight: bold)),
|
||||
},
|
||||
),
|
||||
Divider(color: Color(0xff2D2D2D), thickness: 0.5, height: 35),
|
||||
StyledText(
|
||||
// text: '3. Choose menu <bold>Virtual Account Billing</bold>',
|
||||
text:
|
||||
"3. Pilih menu \"Transfer\", lalu pilih \"Tambah Rekening Favorit\". Jika menggunakan Desktop. tambah rekening pada menu \"Transaksi\" kemudian \"Atur Rekening Tujuan\" lalu pilih \"Tambah Rekening Tujuan\" ",
|
||||
style: baris,
|
||||
tags: {
|
||||
'bold': StyledTextTag(style: TextStyle(fontWeight: bold)),
|
||||
},
|
||||
),
|
||||
Divider(color: Color(0xff2D2D2D), thickness: 0.5, height: 35),
|
||||
StyledText(
|
||||
// text: '4. Choose the bank account you want to use',
|
||||
text: "4. Masukkan nomor Virtual Account",
|
||||
style: baris,
|
||||
tags: {
|
||||
'bold': StyledTextTag(style: TextStyle(fontWeight: bold)),
|
||||
},
|
||||
),
|
||||
Divider(color: Color(0xff2D2D2D), thickness: 0.5, height: 35),
|
||||
StyledText(
|
||||
// text: '5. Enter the 16 digits <bold>virtual account number</bold>',
|
||||
text:
|
||||
"5. Masukkan Kode Otentikasi dan Nomor Rekening berhasil ditambahkan",
|
||||
style: baris,
|
||||
tags: {
|
||||
'bold': StyledTextTag(style: TextStyle(fontWeight: bold)),
|
||||
},
|
||||
),
|
||||
Divider(color: Color(0xff2D2D2D), thickness: 0.5, height: 35),
|
||||
StyledText(
|
||||
text:
|
||||
// '6. The billing information will appear on the payment validation page',
|
||||
"6. Pilih menu \"Transfer\", lalu pilih \"Transfer Antar Rekening BNI\", pilih \"Rekening Tujuan\" ",
|
||||
style: baris,
|
||||
tags: {
|
||||
'bold': StyledTextTag(style: TextStyle(fontWeight: bold)),
|
||||
},
|
||||
),
|
||||
Divider(color: Color(0xff2D2D2D), thickness: 0.5, height: 35),
|
||||
StyledText(
|
||||
text:
|
||||
// '7. If the information is correct, enter your password to proceed the payment',
|
||||
"7. Pilih Rekening Debit",
|
||||
style: baris,
|
||||
tags: {
|
||||
'bold': StyledTextTag(style: TextStyle(fontWeight: bold)),
|
||||
},
|
||||
),
|
||||
Divider(color: Color(0xff2D2D2D), thickness: 0.5, height: 35),
|
||||
StyledText(
|
||||
// text: '8. Your transaction will be processed',
|
||||
text: "8. Masukkan jumlah pembayaran sesuai tagihan",
|
||||
style: baris,
|
||||
tags: {
|
||||
'bold': StyledTextTag(style: TextStyle(fontWeight: bold)),
|
||||
},
|
||||
),
|
||||
Divider(color: Color(0xff2D2D2D), thickness: 0.5, height: 35),
|
||||
StyledText(
|
||||
// text: '8. Your transaction will be processed',
|
||||
text: "9. Masukkan Kode Otentikasi",
|
||||
style: baris,
|
||||
tags: {
|
||||
'bold': StyledTextTag(style: TextStyle(fontWeight: bold)),
|
||||
},
|
||||
),
|
||||
SizedBox(height: getProportionateScreenHeight(10)),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class InternetBankBCA extends StatelessWidget {
|
||||
final TextStyle baris = thirdTextStyle.copyWith(
|
||||
fontWeight: reguler,
|
||||
fontSize: getProportionateScreenWidth(14),
|
||||
letterSpacing: 0.5,
|
||||
);
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Padding(
|
||||
padding:
|
||||
EdgeInsets.symmetric(horizontal: getProportionateScreenWidth(12)),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
StyledText(
|
||||
// text: '1. Open the <bold>BNI Mobile Banking</bold> app and login',
|
||||
text: '1. Login pada aplikasi KlikBCA, masukkan user ID & PIN.',
|
||||
style: baris,
|
||||
tags: {
|
||||
'bold': StyledTextTag(style: TextStyle(fontWeight: bold)),
|
||||
},
|
||||
),
|
||||
Divider(color: Color(0xff2D2D2D), thickness: 0.5, height: 35),
|
||||
StyledText(
|
||||
// text: '2. Choose menu <bold>Transfer</bold>',
|
||||
text:
|
||||
"2. Pilih \"Transfer Dana\", kemudian pilih \"Transfer ke BCA Virtual Account\" ",
|
||||
style: baris,
|
||||
tags: {
|
||||
'bold': StyledTextTag(style: TextStyle(fontWeight: bold)),
|
||||
},
|
||||
),
|
||||
Divider(color: Color(0xff2D2D2D), thickness: 0.5, height: 35),
|
||||
StyledText(
|
||||
// text: '3. Choose menu <bold>Virtual Account Billing</bold>',
|
||||
text: "3. Masukkan no. BCA Virtual Account & klik \"Lanjutkan\" ",
|
||||
style: baris,
|
||||
tags: {
|
||||
'bold': StyledTextTag(style: TextStyle(fontWeight: bold)),
|
||||
},
|
||||
),
|
||||
Divider(color: Color(0xff2D2D2D), thickness: 0.5, height: 35),
|
||||
StyledText(
|
||||
// text: '4. Choose the bank account you want to use',
|
||||
text:
|
||||
"4. Pastikan data yang dimasukkan sudah benar, dan Input \"Respon KeyBCA\", lalu klik \"Kirim\" ",
|
||||
style: baris,
|
||||
tags: {
|
||||
'bold': StyledTextTag(style: TextStyle(fontWeight: bold)),
|
||||
},
|
||||
),
|
||||
SizedBox(height: getProportionateScreenHeight(10)),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class InternetBankMandiri extends StatelessWidget {
|
||||
final TextStyle baris = thirdTextStyle.copyWith(
|
||||
fontWeight: reguler,
|
||||
fontSize: getProportionateScreenWidth(14),
|
||||
letterSpacing: 0.5,
|
||||
);
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Padding(
|
||||
padding:
|
||||
EdgeInsets.symmetric(horizontal: getProportionateScreenWidth(12)),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
StyledText(
|
||||
// text: '1. Open the <bold>BNI Mobile Banking</bold> app and login',
|
||||
text: '1. Lakukan Login ke Internet Banking Mandiri kamu.',
|
||||
style: baris,
|
||||
tags: {
|
||||
'bold': StyledTextTag(style: TextStyle(fontWeight: bold)),
|
||||
},
|
||||
),
|
||||
Divider(color: Color(0xff2D2D2D), thickness: 0.5, height: 35),
|
||||
StyledText(
|
||||
// text: '2. Choose menu <bold>Transfer</bold>',
|
||||
text:
|
||||
"2. Pada menu utama, pilih menu \"Bayar\" lalu pilih menu \"Multi Payment\" ",
|
||||
style: baris,
|
||||
tags: {
|
||||
'bold': StyledTextTag(style: TextStyle(fontWeight: bold)),
|
||||
},
|
||||
),
|
||||
Divider(color: Color(0xff2D2D2D), thickness: 0.5, height: 35),
|
||||
StyledText(
|
||||
// text: '3. Choose menu <bold>Virtual Account Billing</bold>',
|
||||
text:
|
||||
"3. Pilih akun anda di bagian Dari Rekening, kemudian di Penyedia Jasa ",
|
||||
style: baris,
|
||||
tags: {
|
||||
'bold': StyledTextTag(style: TextStyle(fontWeight: bold)),
|
||||
},
|
||||
),
|
||||
Divider(color: Color(0xff2D2D2D), thickness: 0.5, height: 35),
|
||||
StyledText(
|
||||
// text: '4. Choose the bank account you want to use',
|
||||
text:
|
||||
"4. Masukkan kode pembayaran (kode pembayaran Mandiri billpayment kamu), dan klik \"Lanjutkan\" ",
|
||||
style: baris,
|
||||
tags: {
|
||||
'bold': StyledTextTag(style: TextStyle(fontWeight: bold)),
|
||||
},
|
||||
),
|
||||
Divider(color: Color(0xff2D2D2D), thickness: 0.5, height: 35),
|
||||
StyledText(
|
||||
// text: '4. Choose the bank account you want to use',
|
||||
text:
|
||||
"5. Periksa kembali nama perusahaan, nomor pesanan, dan jumlah pembayaran anda ",
|
||||
style: baris,
|
||||
tags: {
|
||||
'bold': StyledTextTag(style: TextStyle(fontWeight: bold)),
|
||||
},
|
||||
),
|
||||
Divider(color: Color(0xff2D2D2D), thickness: 0.5, height: 35),
|
||||
StyledText(
|
||||
// text: '4. Choose the bank account you want to use',
|
||||
text: "6. Selesaikan pembayaran dengan menggunakan Token Mandiri ",
|
||||
style: baris,
|
||||
tags: {
|
||||
'bold': StyledTextTag(style: TextStyle(fontWeight: bold)),
|
||||
},
|
||||
),
|
||||
SizedBox(height: getProportionateScreenHeight(10)),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class InternetBankPermata extends StatelessWidget {
|
||||
final TextStyle baris = thirdTextStyle.copyWith(
|
||||
fontWeight: reguler,
|
||||
fontSize: getProportionateScreenWidth(14),
|
||||
letterSpacing: 0.5,
|
||||
);
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Padding(
|
||||
padding:
|
||||
EdgeInsets.symmetric(horizontal: getProportionateScreenWidth(12)),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
StyledText(
|
||||
// text: '1. Open the <bold>BNI Mobile Banking</bold> app and login',
|
||||
text: '1. Buka Website PermataNet',
|
||||
style: baris,
|
||||
tags: {
|
||||
'bold': StyledTextTag(style: TextStyle(fontWeight: bold)),
|
||||
},
|
||||
),
|
||||
Divider(color: Color(0xff2D2D2D), thickness: 0.5, height: 35),
|
||||
StyledText(
|
||||
// text: '2. Choose menu <bold>Transfer</bold>',
|
||||
text: "2. Masukan User ID dan Password ",
|
||||
style: baris,
|
||||
tags: {
|
||||
'bold': StyledTextTag(style: TextStyle(fontWeight: bold)),
|
||||
},
|
||||
),
|
||||
Divider(color: Color(0xff2D2D2D), thickness: 0.5, height: 35),
|
||||
StyledText(
|
||||
// text: '3. Choose menu <bold>Virtual Account Billing</bold>',
|
||||
text: "3. Pilih Pembayaran Tagihan ",
|
||||
style: baris,
|
||||
tags: {
|
||||
'bold': StyledTextTag(style: TextStyle(fontWeight: bold)),
|
||||
},
|
||||
),
|
||||
Divider(color: Color(0xff2D2D2D), thickness: 0.5, height: 35),
|
||||
StyledText(
|
||||
// text: '4. Choose the bank account you want to use',
|
||||
text: "4. Pilih Virtual Account ",
|
||||
style: baris,
|
||||
tags: {
|
||||
'bold': StyledTextTag(style: TextStyle(fontWeight: bold)),
|
||||
},
|
||||
),
|
||||
Divider(color: Color(0xff2D2D2D), thickness: 0.5, height: 35),
|
||||
StyledText(
|
||||
// text: '4. Choose the bank account you want to use',
|
||||
text: "5. Masukkan 16 digit kode bayar ",
|
||||
style: baris,
|
||||
tags: {
|
||||
'bold': StyledTextTag(style: TextStyle(fontWeight: bold)),
|
||||
},
|
||||
),
|
||||
Divider(color: Color(0xff2D2D2D), thickness: 0.5, height: 35),
|
||||
StyledText(
|
||||
// text: '4. Choose the bank account you want to use',
|
||||
text: "6. Masukkan nominal pembayaran ",
|
||||
style: baris,
|
||||
tags: {
|
||||
'bold': StyledTextTag(style: TextStyle(fontWeight: bold)),
|
||||
},
|
||||
),
|
||||
Divider(color: Color(0xff2D2D2D), thickness: 0.5, height: 35),
|
||||
StyledText(
|
||||
// text: '4. Choose the bank account you want to use',
|
||||
text: "7. Muncul konfirmasi pembayaran ",
|
||||
style: baris,
|
||||
tags: {
|
||||
'bold': StyledTextTag(style: TextStyle(fontWeight: bold)),
|
||||
},
|
||||
),
|
||||
Divider(color: Color(0xff2D2D2D), thickness: 0.5, height: 35),
|
||||
StyledText(
|
||||
// text: '4. Choose the bank account you want to use',
|
||||
text: "8. Masukan Mobile PIN",
|
||||
style: baris,
|
||||
tags: {
|
||||
'bold': StyledTextTag(style: TextStyle(fontWeight: bold)),
|
||||
},
|
||||
),
|
||||
SizedBox(height: getProportionateScreenHeight(10)),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
351
lib/screens/checkout/components/mobile_banking.dart
Normal file
351
lib/screens/checkout/components/mobile_banking.dart
Normal file
@ -0,0 +1,351 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:initial_folder/size_config.dart';
|
||||
import 'package:initial_folder/theme.dart';
|
||||
import 'package:styled_text/styled_text.dart';
|
||||
|
||||
class MobileBankBNI extends StatelessWidget {
|
||||
final TextStyle baris = thirdTextStyle.copyWith(
|
||||
fontWeight: reguler,
|
||||
fontSize: getProportionateScreenWidth(14),
|
||||
letterSpacing: 0.5,
|
||||
);
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Padding(
|
||||
padding:
|
||||
EdgeInsets.symmetric(horizontal: getProportionateScreenWidth(12)),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
StyledText(
|
||||
// text: '1. Open the <bold>BNI Mobile Banking</bold> app and login',
|
||||
text: "1. Akses BNI Mobile Banking melalui handphone",
|
||||
style: baris,
|
||||
tags: {
|
||||
'bold': StyledTextTag(style: TextStyle(fontWeight: bold)),
|
||||
},
|
||||
),
|
||||
Divider(color: Color(0xff2D2D2D), thickness: 0.5, height: 35),
|
||||
StyledText(
|
||||
// text: '2. Choose menu <bold>Transfer</bold>',
|
||||
text: "2. Masukkan User ID dan Password",
|
||||
style: baris,
|
||||
tags: {
|
||||
'bold': StyledTextTag(style: TextStyle(fontWeight: bold)),
|
||||
},
|
||||
),
|
||||
Divider(color: Color(0xff2D2D2D), thickness: 0.5, height: 35),
|
||||
StyledText(
|
||||
// text: '3. Choose menu <bold>Virtual Account Billing</bold>',
|
||||
text:
|
||||
"3. Pilih menu \"Transfer\", lalu pilih \"Antar Rekening BNI\", pilih \"Input Rekening Baru\" ",
|
||||
style: baris,
|
||||
tags: {
|
||||
'bold': StyledTextTag(style: TextStyle(fontWeight: bold)),
|
||||
},
|
||||
),
|
||||
Divider(color: Color(0xff2D2D2D), thickness: 0.5, height: 35),
|
||||
StyledText(
|
||||
// text: '4. Choose the bank account you want to use',
|
||||
text: "4. Masukkan nomor Virtual Account",
|
||||
style: baris,
|
||||
tags: {
|
||||
'bold': StyledTextTag(style: TextStyle(fontWeight: bold)),
|
||||
},
|
||||
),
|
||||
Divider(color: Color(0xff2D2D2D), thickness: 0.5, height: 35),
|
||||
StyledText(
|
||||
// text: '5. Enter the 16 digits <bold>virtual account number</bold>',
|
||||
text:
|
||||
"5.Di halaman konfirmasi, pastikan data transaksi sudah benar kemudian pilih \"Ya\"",
|
||||
style: baris,
|
||||
tags: {
|
||||
'bold': StyledTextTag(style: TextStyle(fontWeight: bold)),
|
||||
},
|
||||
),
|
||||
Divider(color: Color(0xff2D2D2D), thickness: 0.5, height: 35),
|
||||
StyledText(
|
||||
text:
|
||||
// '6. The billing information will appear on the payment validation page',
|
||||
"6. Masukkan password anda ",
|
||||
style: baris,
|
||||
tags: {
|
||||
'bold': StyledTextTag(style: TextStyle(fontWeight: bold)),
|
||||
},
|
||||
),
|
||||
SizedBox(height: getProportionateScreenHeight(10)),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class MobileBankBCA extends StatelessWidget {
|
||||
final TextStyle baris = thirdTextStyle.copyWith(
|
||||
fontWeight: reguler,
|
||||
fontSize: getProportionateScreenWidth(14),
|
||||
letterSpacing: 0.5,
|
||||
);
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Padding(
|
||||
padding:
|
||||
EdgeInsets.symmetric(horizontal: getProportionateScreenWidth(12)),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
StyledText(
|
||||
// text: '1. Open the <bold>BNI Mobile Banking</bold> app and login',
|
||||
text: '1. Lakukan log in pada aplikasi BCA mobile.',
|
||||
style: baris,
|
||||
tags: {
|
||||
'bold': StyledTextTag(style: TextStyle(fontWeight: bold)),
|
||||
},
|
||||
),
|
||||
Divider(color: Color(0xff2D2D2D), thickness: 0.5, height: 35),
|
||||
StyledText(
|
||||
// text: '2. Choose menu <bold>Transfer</bold>',
|
||||
text: "2. Pilih \"m-BCA\" masukan kode akses m-BCA. ",
|
||||
style: baris,
|
||||
tags: {
|
||||
'bold': StyledTextTag(style: TextStyle(fontWeight: bold)),
|
||||
},
|
||||
),
|
||||
Divider(color: Color(0xff2D2D2D), thickness: 0.5, height: 35),
|
||||
StyledText(
|
||||
// text: '3. Choose menu <bold>Virtual Account Billing</bold>',
|
||||
text: "3. Pilih \"m-Transfer\" ",
|
||||
style: baris,
|
||||
tags: {
|
||||
'bold': StyledTextTag(style: TextStyle(fontWeight: bold)),
|
||||
},
|
||||
),
|
||||
Divider(color: Color(0xff2D2D2D), thickness: 0.5, height: 35),
|
||||
StyledText(
|
||||
// text: '4. Choose the bank account you want to use',
|
||||
text: "4. Pilih \"BCA Virtual Account\" ",
|
||||
style: baris,
|
||||
tags: {
|
||||
'bold': StyledTextTag(style: TextStyle(fontWeight: bold)),
|
||||
},
|
||||
),
|
||||
Divider(color: Color(0xff2D2D2D), thickness: 0.5, height: 35),
|
||||
StyledText(
|
||||
// text: '4. Choose the bank account you want to use',
|
||||
text: "5. Masukkan nomor BCA Virtual Account dan klik \"OK\" ",
|
||||
style: baris,
|
||||
tags: {
|
||||
'bold': StyledTextTag(style: TextStyle(fontWeight: bold)),
|
||||
},
|
||||
),
|
||||
Divider(color: Color(0xff2D2D2D), thickness: 0.5, height: 35),
|
||||
StyledText(
|
||||
// text: '4. Choose the bank account you want to use',
|
||||
text: "6. Konfirmasi no virtual account dan rekening pendebetan ",
|
||||
style: baris,
|
||||
tags: {
|
||||
'bold': StyledTextTag(style: TextStyle(fontWeight: bold)),
|
||||
},
|
||||
),
|
||||
Divider(color: Color(0xff2D2D2D), thickness: 0.5, height: 35),
|
||||
StyledText(
|
||||
// text: '4. Choose the bank account you want to use',
|
||||
text:
|
||||
"7. Periksa kembalian rincian pembayaran kamu, lalu klik \"Ya\" ",
|
||||
style: baris,
|
||||
tags: {
|
||||
'bold': StyledTextTag(style: TextStyle(fontWeight: bold)),
|
||||
},
|
||||
),
|
||||
Divider(color: Color(0xff2D2D2D), thickness: 0.5, height: 35),
|
||||
StyledText(
|
||||
// text: '4. Choose the bank account you want to use',
|
||||
text: "8. Masukan pin m-BCA ",
|
||||
style: baris,
|
||||
tags: {
|
||||
'bold': StyledTextTag(style: TextStyle(fontWeight: bold)),
|
||||
},
|
||||
),
|
||||
SizedBox(height: getProportionateScreenHeight(10)),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class MobileBankMandiri extends StatelessWidget {
|
||||
final TextStyle baris = thirdTextStyle.copyWith(
|
||||
fontWeight: reguler,
|
||||
fontSize: getProportionateScreenWidth(14),
|
||||
letterSpacing: 0.5,
|
||||
);
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Padding(
|
||||
padding:
|
||||
EdgeInsets.symmetric(horizontal: getProportionateScreenWidth(12)),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
StyledText(
|
||||
// text: '1. Open the <bold>BNI Mobile Banking</bold> app and login',
|
||||
text: '1. Lakukan Login ke Mandiri Online kamu',
|
||||
style: baris,
|
||||
tags: {
|
||||
'bold': StyledTextTag(style: TextStyle(fontWeight: bold)),
|
||||
},
|
||||
),
|
||||
Divider(color: Color(0xff2D2D2D), thickness: 0.5, height: 35),
|
||||
StyledText(
|
||||
// text: '2. Choose menu <bold>Transfer</bold>',
|
||||
text: "2. Pada menu utama, pilih menu \"Bayar\"",
|
||||
style: baris,
|
||||
tags: {
|
||||
'bold': StyledTextTag(style: TextStyle(fontWeight: bold)),
|
||||
},
|
||||
),
|
||||
Divider(color: Color(0xff2D2D2D), thickness: 0.5, height: 35),
|
||||
StyledText(
|
||||
// text: '3. Choose menu <bold>Virtual Account Billing</bold>',
|
||||
text: "3. Lalu pilih menu \"Multi Payment\" ",
|
||||
style: baris,
|
||||
tags: {
|
||||
'bold': StyledTextTag(style: TextStyle(fontWeight: bold)),
|
||||
},
|
||||
),
|
||||
Divider(color: Color(0xff2D2D2D), thickness: 0.5, height: 35),
|
||||
StyledText(
|
||||
// text: '4. Choose the bank account you want to use',
|
||||
text: "4. kemudian pilih Penyedia Jasa ",
|
||||
style: baris,
|
||||
tags: {
|
||||
'bold': StyledTextTag(style: TextStyle(fontWeight: bold)),
|
||||
},
|
||||
),
|
||||
Divider(color: Color(0xff2D2D2D), thickness: 0.5, height: 35),
|
||||
StyledText(
|
||||
// text: '4. Choose the bank account you want to use',
|
||||
text:
|
||||
"5. Masukkan kode pembayaran [Kode pembayaran Mandiri billpayment], dan klik \"Lanjutkan\" ",
|
||||
style: baris,
|
||||
tags: {
|
||||
'bold': StyledTextTag(style: TextStyle(fontWeight: bold)),
|
||||
},
|
||||
),
|
||||
Divider(color: Color(0xff2D2D2D), thickness: 0.5, height: 35),
|
||||
StyledText(
|
||||
// text: '4. Choose the bank account you want to use',
|
||||
text:
|
||||
"6. Periksa kembali data transaksi kamu dan selesaikan proses pembayaran ",
|
||||
style: baris,
|
||||
tags: {
|
||||
'bold': StyledTextTag(style: TextStyle(fontWeight: bold)),
|
||||
},
|
||||
),
|
||||
SizedBox(height: getProportionateScreenHeight(10)),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class MobileBankPermata extends StatelessWidget {
|
||||
final TextStyle baris = thirdTextStyle.copyWith(
|
||||
fontWeight: reguler,
|
||||
fontSize: getProportionateScreenWidth(14),
|
||||
letterSpacing: 0.5,
|
||||
);
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Padding(
|
||||
padding:
|
||||
EdgeInsets.symmetric(horizontal: getProportionateScreenWidth(12)),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
StyledText(
|
||||
// text: '1. Open the <bold>BNI Mobile Banking</bold> app and login',
|
||||
text: '1. Buka aplikasi PermataMobile X',
|
||||
style: baris,
|
||||
tags: {
|
||||
'bold': StyledTextTag(style: TextStyle(fontWeight: bold)),
|
||||
},
|
||||
),
|
||||
Divider(color: Color(0xff2D2D2D), thickness: 0.5, height: 35),
|
||||
StyledText(
|
||||
// text: '2. Choose menu <bold>Transfer</bold>',
|
||||
text: "2. Masukan Password ",
|
||||
style: baris,
|
||||
tags: {
|
||||
'bold': StyledTextTag(style: TextStyle(fontWeight: bold)),
|
||||
},
|
||||
),
|
||||
Divider(color: Color(0xff2D2D2D), thickness: 0.5, height: 35),
|
||||
StyledText(
|
||||
// text: '3. Choose menu <bold>Virtual Account Billing</bold>',
|
||||
text: "3. Pilih Pembayaran Tagihan ",
|
||||
style: baris,
|
||||
tags: {
|
||||
'bold': StyledTextTag(style: TextStyle(fontWeight: bold)),
|
||||
},
|
||||
),
|
||||
Divider(color: Color(0xff2D2D2D), thickness: 0.5, height: 35),
|
||||
StyledText(
|
||||
// text: '4. Choose the bank account you want to use',
|
||||
text: "4. Pilih Virtual Account ",
|
||||
style: baris,
|
||||
tags: {
|
||||
'bold': StyledTextTag(style: TextStyle(fontWeight: bold)),
|
||||
},
|
||||
),
|
||||
Divider(color: Color(0xff2D2D2D), thickness: 0.5, height: 35),
|
||||
StyledText(
|
||||
// text: '4. Choose the bank account you want to use',
|
||||
text: "5. Masukan Nomor Virtual Account ",
|
||||
style: baris,
|
||||
tags: {
|
||||
'bold': StyledTextTag(style: TextStyle(fontWeight: bold)),
|
||||
},
|
||||
),
|
||||
Divider(color: Color(0xff2D2D2D), thickness: 0.5, height: 35),
|
||||
StyledText(
|
||||
// text: '4. Choose the bank account you want to use',
|
||||
text: "6. Pilih Rekening",
|
||||
style: baris,
|
||||
tags: {
|
||||
'bold': StyledTextTag(style: TextStyle(fontWeight: bold)),
|
||||
},
|
||||
),
|
||||
Divider(color: Color(0xff2D2D2D), thickness: 0.5, height: 35),
|
||||
StyledText(
|
||||
// text: '4. Choose the bank account you want to use',
|
||||
text: "7. Masukkan nominal pembayaran ",
|
||||
style: baris,
|
||||
tags: {
|
||||
'bold': StyledTextTag(style: TextStyle(fontWeight: bold)),
|
||||
},
|
||||
),
|
||||
Divider(color: Color(0xff2D2D2D), thickness: 0.5, height: 35),
|
||||
StyledText(
|
||||
// text: '4. Choose the bank account you want to use',
|
||||
text: "8. Muncul konfirmasi pembayaran ",
|
||||
style: baris,
|
||||
tags: {
|
||||
'bold': StyledTextTag(style: TextStyle(fontWeight: bold)),
|
||||
},
|
||||
),
|
||||
Divider(color: Color(0xff2D2D2D), thickness: 0.5, height: 35),
|
||||
StyledText(
|
||||
// text: '4. Choose the bank account you want to use',
|
||||
text: "9. Masukan Mobile PIN",
|
||||
style: baris,
|
||||
tags: {
|
||||
'bold': StyledTextTag(style: TextStyle(fontWeight: bold)),
|
||||
},
|
||||
),
|
||||
SizedBox(height: getProportionateScreenHeight(10)),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
145
lib/screens/checkout/components/tab_bar_batas_bayar.dart
Normal file
145
lib/screens/checkout/components/tab_bar_batas_bayar.dart
Normal file
@ -0,0 +1,145 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:initial_folder/models/detail_order_model.dart';
|
||||
import 'package:initial_folder/providers/payments_provider.dart' as payProv;
|
||||
import 'package:initial_folder/providers/tab_provider.dart';
|
||||
import 'package:initial_folder/screens/checkout/components/atm.dart';
|
||||
import 'package:initial_folder/screens/checkout/components/internet_banking.dart';
|
||||
import 'package:initial_folder/screens/checkout/components/mobile_banking.dart';
|
||||
import 'package:initial_folder/size_config.dart';
|
||||
import 'package:initial_folder/theme.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
class TabBarBatasBayar extends StatelessWidget {
|
||||
TabBarBatasBayar({
|
||||
Key? key,
|
||||
this.bank,
|
||||
}) : super(key: key);
|
||||
|
||||
final String? bank;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
print("Apa hayoo ${bank}");
|
||||
List<DetailOrderModel> detailOrder =
|
||||
Provider.of<payProv.PaymentsProvider>(context).detailOrder;
|
||||
String? bankName = detailOrder.isNotEmpty ? detailOrder[0].bankName : null;
|
||||
print("Apa hayoo2 ${bankName}");
|
||||
TabProvider tab = Provider.of<TabProvider>(context);
|
||||
|
||||
Widget buildContent(int currentIndex) {
|
||||
switch (currentIndex) {
|
||||
case 0:
|
||||
switch (bank ?? bankName) {
|
||||
case 'bni':
|
||||
return ATMBNI();
|
||||
case 'bca':
|
||||
return ATMBCA();
|
||||
case 'mandiri':
|
||||
case 'echannel':
|
||||
return AtmMandiri();
|
||||
case 'permata':
|
||||
return AtmPermata();
|
||||
default:
|
||||
return SizedBox();
|
||||
}
|
||||
case 1:
|
||||
switch (bank ?? bankName) {
|
||||
case 'bni':
|
||||
return InternetBankBNI();
|
||||
case 'bca':
|
||||
return InternetBankBCA();
|
||||
case 'mandiri':
|
||||
case 'echannel':
|
||||
return InternetBankMandiri();
|
||||
case 'permata':
|
||||
return InternetBankPermata();
|
||||
default:
|
||||
return SizedBox();
|
||||
}
|
||||
case 2:
|
||||
switch (bank ?? bankName) {
|
||||
case 'bni':
|
||||
return MobileBankBNI();
|
||||
case 'bca':
|
||||
return MobileBankBCA();
|
||||
case 'mandiri':
|
||||
case 'echannel':
|
||||
return MobileBankMandiri();
|
||||
case 'permata':
|
||||
return MobileBankPermata();
|
||||
default:
|
||||
return SizedBox();
|
||||
}
|
||||
default:
|
||||
return SizedBox();
|
||||
}
|
||||
}
|
||||
|
||||
return Column(
|
||||
children: [
|
||||
ExpansionTile(
|
||||
title: Text(
|
||||
'ATM',
|
||||
style: thirdTextStyle.copyWith(
|
||||
fontSize: getProportionateScreenWidth(13)),
|
||||
),
|
||||
children: [
|
||||
buildContent(0),
|
||||
],
|
||||
),
|
||||
Container(
|
||||
margin:
|
||||
EdgeInsets.symmetric(horizontal: getProportionateScreenWidth(8)),
|
||||
height: getProportionateScreenHeight(3),
|
||||
decoration: BoxDecoration(
|
||||
color: secondaryColor.withOpacity(0.1),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: secondaryColor.withOpacity(0.1),
|
||||
spreadRadius: 1,
|
||||
blurRadius: 1,
|
||||
offset: Offset(0, 1),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
ExpansionTile(
|
||||
title: Text(
|
||||
'Internet Banking',
|
||||
style: thirdTextStyle.copyWith(
|
||||
fontSize: getProportionateScreenWidth(13)),
|
||||
),
|
||||
children: [
|
||||
buildContent(1),
|
||||
],
|
||||
),
|
||||
Container(
|
||||
margin:
|
||||
EdgeInsets.symmetric(horizontal: getProportionateScreenWidth(8)),
|
||||
height: getProportionateScreenHeight(3),
|
||||
decoration: BoxDecoration(
|
||||
color: secondaryColor.withOpacity(0.1),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: secondaryColor.withOpacity(0.1),
|
||||
spreadRadius: 1,
|
||||
blurRadius: 1,
|
||||
offset: Offset(0, 1),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
ExpansionTile(
|
||||
title: Text(
|
||||
'Mobile Banking',
|
||||
style: thirdTextStyle.copyWith(
|
||||
fontSize: getProportionateScreenWidth(13)),
|
||||
),
|
||||
children: [
|
||||
buildContent(2),
|
||||
],
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
435
lib/screens/checkout/detail_zero_payment.dart
Normal file
435
lib/screens/checkout/detail_zero_payment.dart
Normal file
@ -0,0 +1,435 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:initial_folder/models/zero_price_model.dart';
|
||||
import 'package:initial_folder/providers/cart_provider.dart';
|
||||
import 'package:initial_folder/providers/carts_provider.dart';
|
||||
import 'package:initial_folder/providers/my_course_provider.dart';
|
||||
import 'package:initial_folder/providers/order_provider.dart';
|
||||
import 'package:initial_folder/providers/payments_provider.dart';
|
||||
import 'package:initial_folder/providers/user_info_provider.dart' as userInfo;
|
||||
import 'package:initial_folder/screens/checkout/batas_bayar.dart';
|
||||
import 'package:initial_folder/screens/checkout/success_paid_course.dart';
|
||||
import 'package:initial_folder/size_config.dart';
|
||||
import 'package:initial_folder/theme.dart';
|
||||
import 'package:initial_folder/widgets/login_regist/default_button.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
class DetailZeroPayment extends StatelessWidget {
|
||||
final String? discountPrice;
|
||||
final String? price;
|
||||
final List<String>? idCart;
|
||||
const DetailZeroPayment(
|
||||
{Key? key, this.idCart, this.discountPrice, this.price})
|
||||
: super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
Future<void> deleteCourse() async {
|
||||
List<String> idCarts = idCart!;
|
||||
|
||||
idCarts.forEach((element) async {
|
||||
await Provider.of<CartProvider>(context, listen: false)
|
||||
.deleteCart(element);
|
||||
await Provider.of<CartsProvider>(context, listen: false).getCarts();
|
||||
});
|
||||
}
|
||||
|
||||
var invoice = Provider.of<OrderProvider>(context, listen: false).invoice;
|
||||
var totalPrice =
|
||||
Provider.of<OrderProvider>(context, listen: false).totalPrice!;
|
||||
var orders = Provider.of<OrderProvider>(context, listen: false).orders;
|
||||
print(orders);
|
||||
var zero = Provider.of<PaymentsProvider>(context).zeroPrice;
|
||||
Widget bottomNav() {
|
||||
return Container(
|
||||
margin: EdgeInsets.symmetric(
|
||||
horizontal: getProportionateScreenWidth(90),
|
||||
vertical: getProportionateScreenHeight(10)),
|
||||
child: DefaultButton(
|
||||
text: 'Lanjutkan',
|
||||
press: () {
|
||||
Provider.of<PaymentsProvider>(context, listen: false)
|
||||
.zeroPayment(invoice, totalPrice.toString());
|
||||
deleteCourse();
|
||||
Navigator.of(context).push(
|
||||
MaterialPageRoute(builder: (context) => SuccessPaidCourse()));
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget listCourse({String? title, String? instructor, String? price}) {
|
||||
return Container(
|
||||
padding: EdgeInsets.symmetric(vertical: 8),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Flexible(
|
||||
flex: 7,
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
title!,
|
||||
maxLines: 2,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: primaryTextStyle.copyWith(
|
||||
letterSpacing: 0.5,
|
||||
fontWeight: reguler,
|
||||
fontSize: getProportionateScreenWidth(11),
|
||||
color: tenthColor,
|
||||
),
|
||||
),
|
||||
SizedBox(height: 4),
|
||||
Text(
|
||||
'Oleh $instructor',
|
||||
style: primaryTextStyle.copyWith(
|
||||
letterSpacing: 0.5,
|
||||
fontWeight: reguler,
|
||||
fontSize: getProportionateScreenWidth(9.5),
|
||||
color: secondaryColor,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Flexible(
|
||||
flex: 3,
|
||||
child: Text(
|
||||
'Rp. ${NumberFormat.currency(locale: 'id', symbol: '', decimalDigits: 0).format(double.parse(price!))}',
|
||||
style: primaryTextStyle.copyWith(
|
||||
letterSpacing: 0.5,
|
||||
fontWeight: reguler,
|
||||
fontSize: getProportionateScreenWidth(12),
|
||||
color: tenthColor,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
var user = Provider.of<userInfo.UserInfoProvider>(context).result;
|
||||
// var zero = Provider.of<PaymentsProvider>(context).zeroPrice;
|
||||
return Scaffold(
|
||||
//backgroundColor: Colors.black,
|
||||
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(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
SizedBox(height: 10),
|
||||
Container(
|
||||
decoration: BoxDecoration(
|
||||
color: Color(0xFF212121),
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
),
|
||||
margin: EdgeInsets.only(
|
||||
left: getProportionateScreenWidth(2),
|
||||
right: getProportionateScreenWidth(2)),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Container(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Container(
|
||||
padding: EdgeInsets.symmetric(
|
||||
vertical: 15,
|
||||
horizontal: getProportionateScreenWidth(15)),
|
||||
child: Text(
|
||||
'Informasi Pembeli',
|
||||
style: secondaryTextStyle.copyWith(
|
||||
letterSpacing: 1,
|
||||
fontWeight: semiBold,
|
||||
fontSize: getProportionateScreenWidth(14),
|
||||
color: tenthColor,
|
||||
),
|
||||
),
|
||||
),
|
||||
Divider(
|
||||
color: Color(0xff2D2D2D),
|
||||
thickness: 0.5,
|
||||
height: 1),
|
||||
Container(
|
||||
padding: EdgeInsets.symmetric(
|
||||
vertical: 10,
|
||||
horizontal: getProportionateScreenWidth(15)),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
// Text(
|
||||
// 'Order ID',
|
||||
// style: primaryTextStyle.copyWith(
|
||||
// letterSpacing: 0.5,
|
||||
// fontWeight: reguler,
|
||||
// fontSize: getProportionateScreenWidth(10),
|
||||
// color: secondaryColor,
|
||||
// ),
|
||||
// ),
|
||||
// Text(
|
||||
// // state.detailOrder[0].idOrder,
|
||||
// // zero!.data![0].orderId as String,
|
||||
// '123',
|
||||
// style: primaryTextStyle.copyWith(
|
||||
// letterSpacing: 0.5,
|
||||
// fontWeight: reguler,
|
||||
// fontSize: getProportionateScreenWidth(12),
|
||||
// color: tenthColor,
|
||||
// ),
|
||||
// ),
|
||||
// SizedBox(height: 16),
|
||||
Text(
|
||||
'Nama Lengkap',
|
||||
style: primaryTextStyle.copyWith(
|
||||
letterSpacing: 0.5,
|
||||
fontWeight: reguler,
|
||||
fontSize: getProportionateScreenWidth(10),
|
||||
color: secondaryColor,
|
||||
),
|
||||
),
|
||||
Text(
|
||||
user!.data[0].fullname as String,
|
||||
style: primaryTextStyle.copyWith(
|
||||
letterSpacing: 0.5,
|
||||
fontWeight: reguler,
|
||||
fontSize: getProportionateScreenWidth(12),
|
||||
color: tenthColor,
|
||||
),
|
||||
),
|
||||
SizedBox(height: 16),
|
||||
Text(
|
||||
'Email',
|
||||
style: primaryTextStyle.copyWith(
|
||||
letterSpacing: 0.5,
|
||||
fontWeight: reguler,
|
||||
fontSize: getProportionateScreenWidth(10),
|
||||
color: secondaryColor,
|
||||
),
|
||||
),
|
||||
Text(
|
||||
user.data[0].email as String,
|
||||
style: primaryTextStyle.copyWith(
|
||||
letterSpacing: 0.5,
|
||||
fontWeight: reguler,
|
||||
fontSize: getProportionateScreenWidth(12),
|
||||
color: tenthColor,
|
||||
),
|
||||
),
|
||||
SizedBox(height: 12),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
height: getProportionateScreenHeight(20),
|
||||
),
|
||||
Container(
|
||||
decoration: BoxDecoration(
|
||||
color: Color(0xFF212121),
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
),
|
||||
margin: EdgeInsets.only(
|
||||
left: getProportionateScreenWidth(2),
|
||||
right: getProportionateScreenWidth(2)),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Container(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Container(
|
||||
padding: EdgeInsets.symmetric(
|
||||
vertical: 15,
|
||||
horizontal: getProportionateScreenWidth(15)),
|
||||
child: Text(
|
||||
'Informasi Pembeli',
|
||||
style: secondaryTextStyle.copyWith(
|
||||
letterSpacing: 1,
|
||||
fontWeight: semiBold,
|
||||
fontSize: getProportionateScreenWidth(14),
|
||||
color: tenthColor,
|
||||
),
|
||||
),
|
||||
),
|
||||
Divider(
|
||||
color: Color(0xff2D2D2D),
|
||||
thickness: 0.5,
|
||||
height: 1),
|
||||
Container(
|
||||
padding: EdgeInsets.symmetric(
|
||||
vertical: 15,
|
||||
horizontal: getProportionateScreenWidth(15)),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
SizedBox(height: 20),
|
||||
Row(
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(
|
||||
'Total Harga',
|
||||
style: primaryTextStyle.copyWith(
|
||||
letterSpacing: 0.5,
|
||||
fontWeight: reguler,
|
||||
fontSize:
|
||||
getProportionateScreenWidth(10),
|
||||
color: secondaryColor,
|
||||
),
|
||||
),
|
||||
discountPrice != "0"
|
||||
? Text(
|
||||
"Rp. ${NumberFormat.currency(locale: 'id', symbol: '', decimalDigits: 0).format(double.parse(discountPrice!))}",
|
||||
style: primaryTextStyle.copyWith(
|
||||
letterSpacing: 0.5,
|
||||
fontWeight: reguler,
|
||||
fontSize:
|
||||
getProportionateScreenWidth(
|
||||
12),
|
||||
color: tenthColor,
|
||||
),
|
||||
)
|
||||
: Text(
|
||||
"Rp. ${NumberFormat.currency(locale: 'id', symbol: '', decimalDigits: 0).format(double.parse(price!))}",
|
||||
style: primaryTextStyle.copyWith(
|
||||
letterSpacing: 0.5,
|
||||
fontWeight: reguler,
|
||||
fontSize:
|
||||
getProportionateScreenWidth(
|
||||
12),
|
||||
color: tenthColor,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(height: 16),
|
||||
Divider(
|
||||
color: Color(0xff2D2D2D),
|
||||
thickness: 0.5,
|
||||
height: 1),
|
||||
SizedBox(height: 16),
|
||||
Row(
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(
|
||||
'Total Bayar',
|
||||
style: primaryTextStyle.copyWith(
|
||||
letterSpacing: 0.5,
|
||||
fontWeight: reguler,
|
||||
fontSize:
|
||||
getProportionateScreenWidth(12),
|
||||
color: secondaryColor,
|
||||
),
|
||||
),
|
||||
Text(
|
||||
'Rp. 0',
|
||||
style: secondaryTextStyle.copyWith(
|
||||
letterSpacing: 1,
|
||||
fontWeight: semiBold,
|
||||
fontSize:
|
||||
getProportionateScreenWidth(14),
|
||||
color: tenthColor,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
height: getProportionateScreenHeight(20),
|
||||
),
|
||||
Container(
|
||||
decoration: BoxDecoration(
|
||||
color: Color(0xFF212121),
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
),
|
||||
margin: EdgeInsets.only(
|
||||
left: getProportionateScreenWidth(2),
|
||||
right: getProportionateScreenWidth(2)),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Container(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Container(
|
||||
padding: EdgeInsets.symmetric(
|
||||
vertical: 15,
|
||||
horizontal: getProportionateScreenWidth(15)),
|
||||
child: Text(
|
||||
'Kursus yang dibeli',
|
||||
style: secondaryTextStyle.copyWith(
|
||||
letterSpacing: 1,
|
||||
fontWeight: semiBold,
|
||||
fontSize: getProportionateScreenWidth(14),
|
||||
color: tenthColor,
|
||||
),
|
||||
),
|
||||
),
|
||||
Divider(
|
||||
color: Color(0xff2D2D2D),
|
||||
thickness: 0.5,
|
||||
height: 1),
|
||||
Container(
|
||||
padding: EdgeInsets.symmetric(
|
||||
vertical: 15,
|
||||
horizontal: getProportionateScreenWidth(15)),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: orders.map((e) {
|
||||
return listCourse(
|
||||
instructor: e.instructor,
|
||||
title: e.title,
|
||||
price: e.discountPrice);
|
||||
}).toList(),
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
height: getProportionateScreenHeight(15),
|
||||
),
|
||||
bottomNav(),
|
||||
SizedBox(
|
||||
height: getProportionateScreenHeight(15),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
377
lib/screens/checkout/gopay/batas_bayar_gopay.dart
Normal file
377
lib/screens/checkout/gopay/batas_bayar_gopay.dart
Normal file
@ -0,0 +1,377 @@
|
||||
import 'dart:convert';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:initial_folder/helper/user_info.dart';
|
||||
import 'package:initial_folder/providers/cart_provider.dart';
|
||||
import 'package:initial_folder/providers/carts_provider.dart';
|
||||
import 'package:initial_folder/providers/payments_provider.dart';
|
||||
import 'package:initial_folder/screens/checkout/components/bottom_sheet_detail.dart';
|
||||
import 'package:initial_folder/screens/checkout/gopay/payment_instruction_gopay.dart';
|
||||
import 'package:initial_folder/screens/checkout/gopay/qr_code_gopay.dart';
|
||||
import 'package:initial_folder/screens/checkout/success_paid_course.dart';
|
||||
import 'package:initial_folder/size_config.dart';
|
||||
import 'package:initial_folder/theme.dart';
|
||||
import 'package:initial_folder/widgets/login_regist/default_button.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:pusher_client/pusher_client.dart';
|
||||
|
||||
class BatasBayarGopay extends StatefulWidget {
|
||||
final List<String>? idCart;
|
||||
BatasBayarGopay({this.idCart});
|
||||
@override
|
||||
State<BatasBayarGopay> createState() => _BatasBayarGopayState();
|
||||
}
|
||||
|
||||
class _BatasBayarGopayState extends State<BatasBayarGopay> {
|
||||
Channel? _channel;
|
||||
String? statusTransaction;
|
||||
|
||||
Future<void> deleteCourse() async {
|
||||
List<String> idCarts = widget.idCart ?? [];
|
||||
|
||||
idCarts.forEach((element) async {
|
||||
await Provider.of<CartProvider>(context, listen: false)
|
||||
.deleteCart(element);
|
||||
await Provider.of<CartsProvider>(context, listen: false).getCarts();
|
||||
});
|
||||
}
|
||||
|
||||
Future<void> initPusher() async {
|
||||
int? idUser = await UsersInfo().getIdUser();
|
||||
|
||||
PusherClient pusher = PusherClient(
|
||||
'92060797e94ac7033edb', PusherOptions(cluster: 'ap1'),
|
||||
autoConnect: false);
|
||||
|
||||
pusher.connect();
|
||||
|
||||
// pusher.onConnectionStateChange((state) {
|
||||
// print(state!.currentState);
|
||||
// });
|
||||
// pusher.onConnectionError((error) {
|
||||
// print(error);
|
||||
// });
|
||||
|
||||
_channel = pusher.subscribe('payment-channel');
|
||||
|
||||
_channel!.bind('paid-event-$idUser', (event) {
|
||||
if (mounted) {
|
||||
final status = jsonDecode(event!.data!);
|
||||
setState(() {
|
||||
statusTransaction = status['status_code'];
|
||||
if (statusTransaction == "201") {
|
||||
print(status['message']);
|
||||
print(widget.idCart);
|
||||
deleteCourse();
|
||||
// Navigator.of(context).pushAndRemoveUntil(
|
||||
// MaterialPageRoute(
|
||||
// builder: (context) => SuccessPaidCourse(),
|
||||
// ),
|
||||
// (route) => false,
|
||||
// );
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
initPusher();
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
var detailOrder = Provider.of<PaymentsProvider>(context).detailOrder;
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: Text(
|
||||
'Selesaikan Pembayaran',
|
||||
style: secondaryTextStyle.copyWith(
|
||||
letterSpacing: 1,
|
||||
fontWeight: semiBold,
|
||||
fontSize: getProportionateScreenWidth(14)),
|
||||
),
|
||||
),
|
||||
body: SingleChildScrollView(
|
||||
child: Container(
|
||||
margin:
|
||||
EdgeInsets.symmetric(horizontal: getProportionateScreenWidth(16)),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
SizedBox(height: getProportionateScreenHeight(10)),
|
||||
Center(
|
||||
child: Column(
|
||||
children: [
|
||||
Text(
|
||||
'Batas akhir pembayaran sampai',
|
||||
style: primaryTextStyle.copyWith(
|
||||
color: secondaryColor,
|
||||
letterSpacing: 0.5,
|
||||
fontWeight: reguler,
|
||||
fontSize: getProportionateScreenWidth(10),
|
||||
),
|
||||
),
|
||||
SizedBox(height: getProportionateScreenHeight(5)),
|
||||
Text(
|
||||
// 'Rabu, 13 Oktober 2021 (Pukul 19:32)',
|
||||
DateFormat('E, d MMM y (H:m)')
|
||||
.format(detailOrder[0].transactionTimeLimit),
|
||||
style: secondaryTextStyle.copyWith(
|
||||
letterSpacing: 1,
|
||||
fontWeight: semiBold,
|
||||
color: tenthColor,
|
||||
fontSize: SizeConfig.blockHorizontal! * 3,
|
||||
),
|
||||
),
|
||||
SizedBox(height: getProportionateScreenHeight(5)),
|
||||
Text(
|
||||
'Segera selesaikan pembayaran atau pesananmu',
|
||||
style: primaryTextStyle.copyWith(
|
||||
color: secondaryColor,
|
||||
letterSpacing: 0.5,
|
||||
fontWeight: reguler,
|
||||
fontSize: getProportionateScreenWidth(10),
|
||||
),
|
||||
),
|
||||
Text(
|
||||
'akan dibatalkan secara otomatis',
|
||||
style: primaryTextStyle.copyWith(
|
||||
color: secondaryColor,
|
||||
letterSpacing: 0.5,
|
||||
fontWeight: reguler,
|
||||
fontSize: getProportionateScreenWidth(10),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
height: getProportionateScreenHeight(30),
|
||||
),
|
||||
Container(
|
||||
decoration: BoxDecoration(
|
||||
color: Color(0xFF212121),
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
),
|
||||
margin: EdgeInsets.only(
|
||||
left: getProportionateScreenWidth(2),
|
||||
right: getProportionateScreenWidth(2)),
|
||||
child: Container(
|
||||
padding: EdgeInsets.symmetric(
|
||||
vertical: 16,
|
||||
horizontal: getProportionateScreenWidth(10)),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
'Metode Pembayaran',
|
||||
style: primaryTextStyle.copyWith(
|
||||
color: Colors.white,
|
||||
letterSpacing: 0.5,
|
||||
fontWeight: reguler,
|
||||
fontSize: getProportionateScreenWidth(10),
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
height: getProportionateScreenHeight(8),
|
||||
),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(
|
||||
'GoPay',
|
||||
style: primaryTextStyle.copyWith(
|
||||
color: Colors.white,
|
||||
letterSpacing: 1,
|
||||
fontWeight: semiBold,
|
||||
fontSize: getProportionateScreenWidth(13),
|
||||
),
|
||||
),
|
||||
Container(
|
||||
width: getProportionateScreenWidth(50),
|
||||
height: getProportionateScreenWidth(17),
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(2),
|
||||
image: DecorationImage(
|
||||
fit: BoxFit.scaleDown,
|
||||
image: AssetImage('assets/images/gopay2.png'),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(
|
||||
height: getProportionateScreenHeight(16),
|
||||
),
|
||||
Text(
|
||||
'Kode QR',
|
||||
style: primaryTextStyle.copyWith(
|
||||
color: Colors.white,
|
||||
letterSpacing: 0.5,
|
||||
fontWeight: reguler,
|
||||
fontSize: getProportionateScreenWidth(10),
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
height: getProportionateScreenHeight(8),
|
||||
),
|
||||
Row(
|
||||
children: [
|
||||
Icon(Icons.qr_code),
|
||||
Spacer(),
|
||||
GestureDetector(
|
||||
onTap: () {
|
||||
// Navigator.push(
|
||||
// context,
|
||||
// MaterialPageRoute(
|
||||
// builder: (context) => QRCodeGopay()));
|
||||
Navigator.pop(context);
|
||||
},
|
||||
child: Text(
|
||||
"Scan Kode QR",
|
||||
style: primaryTextStyle.copyWith(
|
||||
letterSpacing: 0.5,
|
||||
color: primaryColor,
|
||||
fontSize: getProportionateScreenWidth(10),
|
||||
fontWeight: reguler),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(
|
||||
height: getProportionateScreenHeight(16),
|
||||
),
|
||||
Text(
|
||||
'Total Pembayaran',
|
||||
style: primaryTextStyle.copyWith(
|
||||
color: Colors.white,
|
||||
letterSpacing: 0.5,
|
||||
fontWeight: reguler,
|
||||
fontSize: getProportionateScreenWidth(10),
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
height: getProportionateScreenHeight(8),
|
||||
),
|
||||
Row(
|
||||
children: [
|
||||
Text(
|
||||
'Rp. ${NumberFormat.currency(locale: 'id', symbol: '', decimalDigits: 0).format(double.parse(detailOrder[0].totalPayment))}',
|
||||
style: primaryTextStyle.copyWith(
|
||||
color: Colors.white,
|
||||
letterSpacing: 1,
|
||||
fontWeight: semiBold,
|
||||
fontSize: getProportionateScreenWidth(14),
|
||||
),
|
||||
),
|
||||
Spacer(),
|
||||
GestureDetector(
|
||||
onTap: () {
|
||||
showModalBottomSheet(
|
||||
context: context,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.vertical(
|
||||
top: Radius.circular(20))),
|
||||
builder: (context) {
|
||||
return BottomSheetDetail();
|
||||
});
|
||||
},
|
||||
child: Text(
|
||||
"Detail Pembayaran",
|
||||
style: primaryTextStyle.copyWith(
|
||||
letterSpacing: 0.5,
|
||||
color: primaryColor,
|
||||
fontSize: getProportionateScreenWidth(10),
|
||||
fontWeight: reguler),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(
|
||||
height: getProportionateScreenHeight(16),
|
||||
),
|
||||
Text(
|
||||
'Status Pembayaran',
|
||||
style: primaryTextStyle.copyWith(
|
||||
color: Colors.white,
|
||||
letterSpacing: 0.5,
|
||||
fontWeight: reguler,
|
||||
fontSize: getProportionateScreenWidth(10),
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
height: getProportionateScreenHeight(8),
|
||||
),
|
||||
Text(
|
||||
statusTransaction == '201' || statusTransaction == null
|
||||
? 'Pending'
|
||||
: 'Success',
|
||||
style: primaryTextStyle.copyWith(
|
||||
color: Color(0xffEDA923),
|
||||
letterSpacing: 1,
|
||||
fontWeight: medium,
|
||||
fontSize: getProportionateScreenWidth(12),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
height: getProportionateScreenHeight(24),
|
||||
),
|
||||
DefaultButton(
|
||||
text: 'Belanja kursus lainnya',
|
||||
weight: reguler,
|
||||
press: () {
|
||||
Navigator.pushNamedAndRemoveUntil(
|
||||
context, "/home", (r) => false);
|
||||
},
|
||||
),
|
||||
SizedBox(
|
||||
height: getProportionateScreenHeight(32),
|
||||
),
|
||||
Container(
|
||||
decoration: BoxDecoration(
|
||||
color: Color(0xFF212121),
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
),
|
||||
margin: EdgeInsets.only(
|
||||
left: getProportionateScreenWidth(2),
|
||||
right: getProportionateScreenWidth(2)),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Container(
|
||||
padding: EdgeInsets.symmetric(
|
||||
vertical: 16,
|
||||
horizontal: getProportionateScreenWidth(16)),
|
||||
child: Text(
|
||||
'Cara Pembayaran',
|
||||
style: secondaryTextStyle.copyWith(
|
||||
color: tenthColor,
|
||||
letterSpacing: 1,
|
||||
fontWeight: semiBold,
|
||||
fontSize: getProportionateScreenWidth(14),
|
||||
),
|
||||
),
|
||||
),
|
||||
Divider(
|
||||
color: Color(0xff2D2D2D), thickness: 0.5, height: 0.5),
|
||||
PaymentInstructionGopay()
|
||||
],
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
height: getProportionateScreenHeight(30),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
249
lib/screens/checkout/gopay/bayargopay.dart
Normal file
249
lib/screens/checkout/gopay/bayargopay.dart
Normal file
@ -0,0 +1,249 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:initial_folder/providers/payments_provider.dart';
|
||||
import 'package:initial_folder/screens/checkout/components/bottom_sheet_detail.dart';
|
||||
import 'package:initial_folder/screens/checkout/gopay/payment_instruction_gopay.dart';
|
||||
import 'package:initial_folder/screens/checkout/gopay/qr_code_gopay.dart';
|
||||
import 'package:initial_folder/size_config.dart';
|
||||
import 'package:initial_folder/theme.dart';
|
||||
import 'package:initial_folder/widgets/login_regist/default_button.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
class BayarGopay extends StatelessWidget {
|
||||
BayarGopay({this.idCart});
|
||||
|
||||
final List<String>? idCart;
|
||||
|
||||
static String routeName = "/bayarGopay";
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
Widget bottomNav() {
|
||||
return DefaultButton(
|
||||
text: 'Bayar dengan QRIS',
|
||||
press: () {
|
||||
Navigator.of(context).push(
|
||||
MaterialPageRoute(
|
||||
builder: (context) => GopaySplashScreen(idCart: idCart),
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
return Scaffold(
|
||||
backgroundColor: Theme.of(context).colorScheme.background,
|
||||
appBar: AppBar(
|
||||
backgroundColor: Theme.of(context).colorScheme.background,
|
||||
title: Text(
|
||||
'Bayar Dengan QRIS',
|
||||
style: thirdTextStyle.copyWith(
|
||||
letterSpacing: 1,
|
||||
fontWeight: semiBold,
|
||||
fontSize: getProportionateScreenWidth(14),
|
||||
),
|
||||
),
|
||||
),
|
||||
body: Consumer<PaymentsProvider>(
|
||||
builder: (context, state, _) {
|
||||
if (state.stateProcess == Process.loading) {
|
||||
return SizedBox(
|
||||
height: MediaQuery.of(context).size.height,
|
||||
child: Center(child: CircularProgressIndicator()));
|
||||
} else if (state.state == ResultState.gagal) {
|
||||
return Center(child: Text('Terjadi Kesalahan'));
|
||||
} else {
|
||||
return SingleChildScrollView(
|
||||
child: Container(
|
||||
margin: EdgeInsets.symmetric(
|
||||
horizontal: getProportionateScreenWidth(16)),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
SizedBox(height: 10),
|
||||
Container(
|
||||
width: double.infinity,
|
||||
decoration: BoxDecoration(
|
||||
color: Theme.of(context).colorScheme.primaryContainer,
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Colors.black.withOpacity(0.1),
|
||||
spreadRadius: 0,
|
||||
blurRadius: 4,
|
||||
offset: Offset(0, 2),
|
||||
),
|
||||
],
|
||||
),
|
||||
margin: EdgeInsets.only(
|
||||
left: getProportionateScreenWidth(2),
|
||||
right: getProportionateScreenWidth(2)),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Container(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Container(
|
||||
padding: EdgeInsets.symmetric(
|
||||
vertical: 15,
|
||||
horizontal:
|
||||
getProportionateScreenWidth(15)),
|
||||
child: Text(
|
||||
'Informasi Pembayaran',
|
||||
style: thirdTextStyle.copyWith(
|
||||
fontWeight: semiBold,
|
||||
fontSize: getProportionateScreenWidth(14),
|
||||
color: Theme.of(context)
|
||||
.colorScheme
|
||||
.onBackground,
|
||||
),
|
||||
),
|
||||
),
|
||||
Container(
|
||||
padding: EdgeInsets.symmetric(
|
||||
horizontal:
|
||||
getProportionateScreenWidth(15)),
|
||||
child: Column(
|
||||
crossAxisAlignment:
|
||||
CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
'Order ID',
|
||||
style: thirdTextStyle.copyWith(
|
||||
fontWeight: reguler,
|
||||
fontSize:
|
||||
getProportionateScreenWidth(10),
|
||||
fontFamily: "Poppins",
|
||||
),
|
||||
),
|
||||
Row(
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(
|
||||
state.detailOrder[0].idOrder,
|
||||
style: thirdTextStyle.copyWith(
|
||||
fontWeight: reguler,
|
||||
fontSize:
|
||||
getProportionateScreenWidth(
|
||||
12),
|
||||
),
|
||||
),
|
||||
GestureDetector(
|
||||
onTap: () {
|
||||
Clipboard.setData(ClipboardData(
|
||||
text: state
|
||||
.detailOrder[0].idOrder,
|
||||
)).then(
|
||||
(_) {
|
||||
ScaffoldMessenger.of(context)
|
||||
.showSnackBar(
|
||||
SnackBar(
|
||||
content: Text(
|
||||
'Berhasil Menyalin Kode Pembayaran'),
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
child: Text(
|
||||
"Salin",
|
||||
style: primaryTextStyle.copyWith(
|
||||
letterSpacing: 0.5,
|
||||
color: primaryColor,
|
||||
fontSize:
|
||||
getProportionateScreenWidth(
|
||||
10),
|
||||
fontWeight: reguler),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(
|
||||
height:
|
||||
getProportionateScreenHeight(10)),
|
||||
Text(
|
||||
'Total Pembayaran',
|
||||
style: thirdTextStyle.copyWith(
|
||||
fontWeight: reguler,
|
||||
fontSize:
|
||||
getProportionateScreenWidth(10),
|
||||
fontFamily: "Poppins",
|
||||
),
|
||||
),
|
||||
Row(
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(
|
||||
'Rp. ${NumberFormat.currency(locale: 'id', symbol: '').format(double.parse(state.detailOrder[0].totalPayment))}',
|
||||
style: thirdTextStyle.copyWith(
|
||||
fontWeight: semiBold,
|
||||
fontSize:
|
||||
getProportionateScreenWidth(
|
||||
12),
|
||||
),
|
||||
),
|
||||
GestureDetector(
|
||||
onTap: () {
|
||||
showModalBottomSheet(
|
||||
backgroundColor:
|
||||
Theme.of(context)
|
||||
.colorScheme
|
||||
.background,
|
||||
elevation: 0.0,
|
||||
context: context,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius:
|
||||
BorderRadius.vertical(
|
||||
top: Radius.circular(20),
|
||||
),
|
||||
),
|
||||
builder: (context) {
|
||||
return BottomSheetDetail();
|
||||
},
|
||||
);
|
||||
},
|
||||
child: Text(
|
||||
"Detail Pembayaran",
|
||||
style: thirdTextStyle.copyWith(
|
||||
letterSpacing: 0.5,
|
||||
color: primaryColor,
|
||||
fontSize:
|
||||
getProportionateScreenWidth(
|
||||
10),
|
||||
fontWeight: reguler),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(
|
||||
height:
|
||||
getProportionateScreenHeight(12)),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
SizedBox(height: getProportionateScreenHeight(30)),
|
||||
PaymentInstructionGopay(),
|
||||
SizedBox(height: getProportionateScreenHeight(15)),
|
||||
bottomNav(),
|
||||
SizedBox(height: getProportionateScreenHeight(15)),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
395
lib/screens/checkout/gopay/gopay_payment_confirmation.dart
Normal file
395
lib/screens/checkout/gopay/gopay_payment_confirmation.dart
Normal file
@ -0,0 +1,395 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_countdown_timer/current_remaining_time.dart';
|
||||
import 'package:flutter_countdown_timer/flutter_countdown_timer.dart';
|
||||
import 'package:initial_folder/base_service.dart';
|
||||
import 'package:initial_folder/providers/order_provider.dart';
|
||||
import 'package:initial_folder/providers/payments_provider.dart';
|
||||
import 'package:initial_folder/screens/checkout/components/bottom_sheet_detail.dart';
|
||||
import 'package:initial_folder/screens/checkout/gopay/payment_instruction_gopay.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
import '../../../size_config.dart';
|
||||
import '../../../theme.dart';
|
||||
|
||||
class GopayPaymentConfirmation extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
var detailOrder =
|
||||
Provider.of<PaymentsProvider>(context, listen: false).detailOrder;
|
||||
var orders = Provider.of<OrderProvider>(context, listen: false).orders;
|
||||
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
backgroundColor: Theme.of(context).colorScheme.background,
|
||||
centerTitle: true,
|
||||
scrolledUnderElevation: 0.0,
|
||||
title: Text(
|
||||
'Cara Pembayaran',
|
||||
style: secondaryTextStyle.copyWith(
|
||||
letterSpacing: 1,
|
||||
fontWeight: semiBold,
|
||||
fontSize: getProportionateScreenWidth(14),
|
||||
),
|
||||
),
|
||||
),
|
||||
body: Padding(
|
||||
padding:
|
||||
EdgeInsets.symmetric(horizontal: getProportionateScreenWidth(10)),
|
||||
child: SingleChildScrollView(
|
||||
child: Column(
|
||||
children: [
|
||||
Container(
|
||||
height: getProportionateScreenHeight(290),
|
||||
decoration: BoxDecoration(
|
||||
color: Theme.of(context).colorScheme.primaryContainer,
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Colors.black.withOpacity(0.1),
|
||||
spreadRadius: 0,
|
||||
blurRadius: 4,
|
||||
offset: Offset(0, 2),
|
||||
),
|
||||
],
|
||||
),
|
||||
margin: EdgeInsets.symmetric(
|
||||
vertical: getProportionateScreenHeight(9),
|
||||
),
|
||||
padding: EdgeInsets.symmetric(
|
||||
horizontal: getProportionateScreenWidth(10),
|
||||
vertical: getProportionateScreenHeight(15),
|
||||
),
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
'Batas Waktu Pembayaran',
|
||||
style: thirdTextStyle.copyWith(
|
||||
fontFamily: "Poppins",
|
||||
fontSize: getProportionateScreenWidth(11),
|
||||
),
|
||||
),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(
|
||||
DateFormat('E, d MMM y H:m WIB')
|
||||
.format(detailOrder[0].transactionTimeLimit),
|
||||
style: thirdTextStyle.copyWith(
|
||||
fontWeight: semiBold,
|
||||
fontSize: SizeConfig.blockHorizontal! * 3,
|
||||
),
|
||||
),
|
||||
Container(
|
||||
decoration: BoxDecoration(
|
||||
color: sevenColor,
|
||||
borderRadius: BorderRadius.circular(4),
|
||||
),
|
||||
padding: EdgeInsets.symmetric(
|
||||
horizontal: getProportionateScreenWidth(3),
|
||||
vertical: getProportionateScreenHeight(2),
|
||||
),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
children: [
|
||||
Icon(
|
||||
Icons.access_time,
|
||||
color: baruTextutih,
|
||||
size: getProportionateScreenWidth(14),
|
||||
),
|
||||
SizedBox(width: getProportionateScreenWidth(2)),
|
||||
CountdownTimer(
|
||||
endTime: DateTime.now()
|
||||
.add(Duration(hours: 24))
|
||||
.millisecondsSinceEpoch,
|
||||
widgetBuilder: (_, CurrentRemainingTime? time) {
|
||||
if (time == null) {
|
||||
return Text(
|
||||
'00:00:00',
|
||||
style: thirdTextStyle.copyWith(
|
||||
fontWeight: semiBold,
|
||||
letterSpacing: 1,
|
||||
fontSize:
|
||||
getProportionateScreenWidth(10),
|
||||
color: baruTextutih,
|
||||
),
|
||||
);
|
||||
} else {
|
||||
return Text(
|
||||
'${time.hours}:${time.min}:${time.sec}',
|
||||
style: thirdTextStyle.copyWith(
|
||||
fontWeight: semiBold,
|
||||
letterSpacing: 1,
|
||||
fontSize:
|
||||
getProportionateScreenWidth(10),
|
||||
color: baruTextutih,
|
||||
),
|
||||
);
|
||||
}
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(height: getProportionateScreenHeight(4)),
|
||||
Divider(
|
||||
color: secondaryColor,
|
||||
thickness: 1,
|
||||
),
|
||||
Text(
|
||||
"Kursus",
|
||||
style: thirdTextStyle.copyWith(
|
||||
fontFamily: "Poppins",
|
||||
fontSize: getProportionateScreenWidth(11),
|
||||
),
|
||||
),
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: orders.map((e) {
|
||||
return listCourse(
|
||||
imageUrl: e.imageUrl,
|
||||
instructor: e.instructor,
|
||||
title: e.title,
|
||||
price: e.price,
|
||||
discountPrice: e.discountPrice,
|
||||
);
|
||||
}).toList(),
|
||||
),
|
||||
SizedBox(height: getProportionateScreenHeight(10)),
|
||||
Text(
|
||||
'Metode Pembayaran',
|
||||
style: thirdTextStyle.copyWith(
|
||||
letterSpacing: 0.5,
|
||||
fontWeight: reguler,
|
||||
fontSize: getProportionateScreenWidth(10),
|
||||
),
|
||||
),
|
||||
SizedBox(height: getProportionateScreenHeight(5)),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(
|
||||
"QRIS",
|
||||
style: thirdTextStyle.copyWith(
|
||||
letterSpacing: 1,
|
||||
fontWeight: semiBold,
|
||||
fontSize: getProportionateScreenWidth(13),
|
||||
),
|
||||
),
|
||||
Container(
|
||||
width: getProportionateScreenWidth(50),
|
||||
height: getProportionateScreenWidth(17),
|
||||
decoration: BoxDecoration(
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color:
|
||||
Theme.of(context).colorScheme.brightness ==
|
||||
Brightness.dark
|
||||
? Colors.transparent
|
||||
: baruTexthitam.withOpacity(0.3),
|
||||
spreadRadius: 1,
|
||||
blurRadius: 3,
|
||||
offset: Offset(0, 1),
|
||||
),
|
||||
],
|
||||
borderRadius: BorderRadius.circular(2),
|
||||
image: DecorationImage(
|
||||
fit: BoxFit.fill,
|
||||
image: AssetImage("assets/images/qris.png"),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(height: getProportionateScreenHeight(15)),
|
||||
Text(
|
||||
"Order ID",
|
||||
style: thirdTextStyle.copyWith(
|
||||
letterSpacing: 0.5,
|
||||
fontWeight: reguler,
|
||||
fontSize: getProportionateScreenWidth(10),
|
||||
),
|
||||
),
|
||||
SizedBox(height: getProportionateScreenHeight(5)),
|
||||
Row(
|
||||
children: [
|
||||
Text(
|
||||
detailOrder[0].idOrder,
|
||||
style: thirdTextStyle.copyWith(
|
||||
letterSpacing: 1,
|
||||
fontWeight: semiBold,
|
||||
fontSize: getProportionateScreenWidth(14),
|
||||
),
|
||||
),
|
||||
Spacer(),
|
||||
GestureDetector(
|
||||
onTap: () {
|
||||
Clipboard.setData(
|
||||
ClipboardData(text: detailOrder[0].idOrder))
|
||||
.then(
|
||||
(_) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
content: Text('Berhasil Menyalin Order ID'),
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
child: Text(
|
||||
"Salin",
|
||||
style: thirdTextStyle.copyWith(
|
||||
letterSpacing: 0.5,
|
||||
color: primaryColor,
|
||||
fontSize: getProportionateScreenWidth(10),
|
||||
fontWeight: reguler),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(height: getProportionateScreenHeight(15)),
|
||||
Text(
|
||||
'Total Pembayaran',
|
||||
style: thirdTextStyle.copyWith(
|
||||
letterSpacing: 0.5,
|
||||
fontWeight: reguler,
|
||||
fontSize: getProportionateScreenWidth(10),
|
||||
),
|
||||
),
|
||||
SizedBox(height: getProportionateScreenHeight(6)),
|
||||
Row(
|
||||
children: [
|
||||
Text(
|
||||
'Rp. ${NumberFormat.currency(locale: 'id', symbol: '', decimalDigits: 0).format(double.parse(detailOrder[0].totalPayment))}',
|
||||
style: thirdTextStyle.copyWith(
|
||||
letterSpacing: 1,
|
||||
fontWeight: semiBold,
|
||||
fontSize: getProportionateScreenWidth(14),
|
||||
),
|
||||
),
|
||||
Spacer(),
|
||||
GestureDetector(
|
||||
onTap: () {
|
||||
Clipboard.setData(ClipboardData(
|
||||
text: detailOrder[0].totalPayment))
|
||||
.then(
|
||||
(_) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
content: Text(
|
||||
'Berhasil Menyalin Total Pembayaran'),
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
child: Text(
|
||||
"Salin",
|
||||
style: thirdTextStyle.copyWith(
|
||||
letterSpacing: 0.5,
|
||||
color: primaryColor,
|
||||
fontSize: getProportionateScreenWidth(10),
|
||||
fontWeight: reguler),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
SizedBox(height: getProportionateScreenHeight(13)),
|
||||
PaymentInstructionGopay(),
|
||||
SizedBox(height: getProportionateScreenHeight(17)),
|
||||
Padding(
|
||||
padding: EdgeInsets.symmetric(
|
||||
horizontal: getProportionateScreenWidth(10)),
|
||||
child: GestureDetector(
|
||||
child: Container(
|
||||
padding: EdgeInsets.all(16),
|
||||
width: double.infinity,
|
||||
height: getProportionateScreenHeight(42),
|
||||
decoration: BoxDecoration(
|
||||
color: primaryColor,
|
||||
border: Border.all(
|
||||
color: primaryColor,
|
||||
width: 1,
|
||||
),
|
||||
borderRadius: BorderRadius.circular(10)),
|
||||
child: Center(
|
||||
child: Text(
|
||||
'Lihat QRIS',
|
||||
style: thirdTextStyle.copyWith(
|
||||
fontSize: getProportionateScreenWidth(13),
|
||||
fontWeight: semiBold,
|
||||
color: baruTextutih,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
onTap: () {
|
||||
Navigator.pop(context);
|
||||
},
|
||||
),
|
||||
),
|
||||
SizedBox(height: getProportionateScreenHeight(21)),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget listCourse({
|
||||
String? imageUrl,
|
||||
String? title,
|
||||
String? instructor,
|
||||
String? price,
|
||||
String? discountPrice,
|
||||
int? totalPrices,
|
||||
}) {
|
||||
return Container(
|
||||
padding: EdgeInsets.symmetric(vertical: getProportionateScreenHeight(9)),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
Container(
|
||||
width: getProportionateScreenWidth(60),
|
||||
height: getProportionateScreenHeight(30),
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(2),
|
||||
image: DecorationImage(
|
||||
image: NetworkImage(imageUrl ??
|
||||
'$baseUrl/uploads/courses_thumbnail/course_thumbnail_default_57.jpg'),
|
||||
fit: BoxFit.cover,
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(width: getProportionateScreenWidth(10)),
|
||||
Flexible(
|
||||
flex: 7,
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
title!,
|
||||
maxLines: 2,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: thirdTextStyle.copyWith(
|
||||
letterSpacing: 0.5,
|
||||
fontWeight: reguler,
|
||||
fontSize: getProportionateScreenWidth(11),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
102
lib/screens/checkout/gopay/payment_instruction_gopay.dart
Normal file
102
lib/screens/checkout/gopay/payment_instruction_gopay.dart
Normal file
@ -0,0 +1,102 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:styled_text/styled_text.dart';
|
||||
|
||||
import '../../../size_config.dart';
|
||||
import '../../../theme.dart';
|
||||
|
||||
class PaymentInstructionGopay extends StatelessWidget {
|
||||
final TextStyle baris = thirdTextStyle.copyWith(
|
||||
fontFamily: "Poppins",
|
||||
fontSize: getProportionateScreenWidth(14),
|
||||
);
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
decoration: BoxDecoration(
|
||||
color: Theme.of(context).colorScheme.primaryContainer,
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Colors.black.withOpacity(0.1),
|
||||
spreadRadius: 0,
|
||||
blurRadius: 4,
|
||||
offset: Offset(0, 2),
|
||||
),
|
||||
],
|
||||
),
|
||||
margin: EdgeInsets.only(
|
||||
left: getProportionateScreenWidth(2),
|
||||
right: getProportionateScreenWidth(2)),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Container(
|
||||
padding: EdgeInsets.symmetric(
|
||||
vertical: getProportionateScreenHeight(15),
|
||||
horizontal: getProportionateScreenWidth(16),
|
||||
),
|
||||
child: Text(
|
||||
'Cara Pembayaran',
|
||||
style: thirdTextStyle.copyWith(
|
||||
fontWeight: semiBold,
|
||||
fontSize: getProportionateScreenWidth(14),
|
||||
),
|
||||
),
|
||||
),
|
||||
Container(
|
||||
padding: EdgeInsets.symmetric(
|
||||
horizontal: getProportionateScreenWidth(16)),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
StyledText(
|
||||
text:
|
||||
'1. Buka aplikasi <bold>Gojek</bold> atau <bold>e-Wallet</bold> apapun milik anda',
|
||||
style: baris,
|
||||
tags: {
|
||||
'bold': StyledTextTag(style: TextStyle(fontWeight: bold)),
|
||||
},
|
||||
),
|
||||
SizedBox(height: getProportionateScreenHeight(15)),
|
||||
StyledText(
|
||||
text:
|
||||
'2. Scan <bold>QR Code</bold> yang tertera dan masukkan nominal sesuai tagihan transaksi',
|
||||
style: baris,
|
||||
tags: {
|
||||
'bold': StyledTextTag(style: TextStyle(fontWeight: bold)),
|
||||
},
|
||||
),
|
||||
SizedBox(height: getProportionateScreenHeight(15)),
|
||||
StyledText(
|
||||
text:
|
||||
'3. Periksa detail transaksi Anda pada aplikasi, lalu tap tombol Bayar.',
|
||||
style: baris,
|
||||
tags: {
|
||||
'bold': StyledTextTag(style: TextStyle(fontWeight: bold)),
|
||||
},
|
||||
),
|
||||
SizedBox(height: getProportionateScreenHeight(15)),
|
||||
StyledText(
|
||||
text: '4. Masukkan pin Anda',
|
||||
style: baris,
|
||||
tags: {
|
||||
'bold': StyledTextTag(style: TextStyle(fontWeight: bold)),
|
||||
},
|
||||
),
|
||||
SizedBox(height: getProportionateScreenHeight(15)),
|
||||
StyledText(
|
||||
text: '5. Transaksi Anda telah selesai',
|
||||
style: baris,
|
||||
tags: {
|
||||
'bold': StyledTextTag(style: TextStyle(fontWeight: bold)),
|
||||
},
|
||||
),
|
||||
SizedBox(height: getProportionateScreenHeight(15)),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
345
lib/screens/checkout/gopay/qr_code_gopay.dart
Normal file
345
lib/screens/checkout/gopay/qr_code_gopay.dart
Normal file
@ -0,0 +1,345 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:initial_folder/providers/payments_provider.dart';
|
||||
import 'package:initial_folder/screens/checkout/batas_bayar.dart';
|
||||
import 'package:initial_folder/screens/checkout/gopay/batas_bayar_gopay.dart';
|
||||
import 'package:initial_folder/screens/checkout/gopay/gopay_payment_confirmation.dart';
|
||||
import 'package:initial_folder/screens/profile/account_sign_in/riwayat_transaksi_pending.dart';
|
||||
import 'package:initial_folder/size_config.dart';
|
||||
import 'package:initial_folder/theme.dart';
|
||||
import 'package:initial_folder/widgets/custom_navigator.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:url_launcher/url_launcher.dart';
|
||||
|
||||
class QRCodeGopay extends StatelessWidget {
|
||||
final List<String>? idCart;
|
||||
QRCodeGopay({this.idCart});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
var detailOrder =
|
||||
Provider.of<PaymentsProvider>(context, listen: false).detailOrder;
|
||||
return Scaffold(
|
||||
backgroundColor: Theme.of(context).colorScheme.background,
|
||||
appBar: AppBar(
|
||||
backgroundColor: Theme.of(context).colorScheme.background,
|
||||
scrolledUnderElevation: 0.0,
|
||||
leading: IconButton(
|
||||
icon: Icon(Icons.close),
|
||||
onPressed: () {
|
||||
Navigator.pop(context);
|
||||
},
|
||||
),
|
||||
),
|
||||
body: SingleChildScrollView(
|
||||
child: Padding(
|
||||
padding: EdgeInsets.symmetric(
|
||||
horizontal: getProportionateScreenWidth(10),
|
||||
vertical: getProportionateScreenHeight(10),
|
||||
),
|
||||
child: Column(
|
||||
children: [
|
||||
Stack(
|
||||
children: [
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Image.asset(
|
||||
"assets/images/qris_background.png",
|
||||
width: getProportionateScreenWidth(328),
|
||||
height: getProportionateScreenHeight(470),
|
||||
),
|
||||
],
|
||||
),
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
SizedBox(height: getProportionateScreenHeight(45)),
|
||||
Text(
|
||||
"VOCASIA",
|
||||
style: secondaryTextStyle.copyWith(
|
||||
fontWeight: bold,
|
||||
fontSize: getProportionateScreenWidth(13),
|
||||
color: baruTexthitam,
|
||||
),
|
||||
),
|
||||
SizedBox(height: getProportionateScreenHeight(15)),
|
||||
Padding(
|
||||
padding: EdgeInsets.symmetric(
|
||||
horizontal: getProportionateScreenWidth(40)),
|
||||
child: Text(
|
||||
"Lakukan pembayaran dengan cara scan code dibawah ini dan lakukan pembayaran sesuai dengan tagihan yang diterima.",
|
||||
textAlign: TextAlign.center,
|
||||
style: secondaryTextStyle.copyWith(
|
||||
fontSize: getProportionateScreenWidth(9),
|
||||
color: baruTexthitam,
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(height: getProportionateScreenHeight(15)),
|
||||
Center(
|
||||
child: Container(
|
||||
height: getProportionateScreenHeight(150),
|
||||
width: getProportionateScreenWidth(150),
|
||||
child: Image.network(detailOrder[0].qrCodeUrl!
|
||||
// 'https://api.sandbox.midtrans.com/v2/gopay/916c417c-dd69-455f-9f8d-997b31d38c21/qr-code'
|
||||
),
|
||||
),
|
||||
),
|
||||
// Image.network(),
|
||||
SizedBox(height: getProportionateScreenHeight(5)),
|
||||
Text(
|
||||
'Order ID',
|
||||
style: thirdTextStyle.copyWith(
|
||||
fontSize: getProportionateScreenWidth(13),
|
||||
color: baruTexthitam,
|
||||
),
|
||||
),
|
||||
SizedBox(height: getProportionateScreenHeight(2)),
|
||||
Text(
|
||||
detailOrder[0].idOrder,
|
||||
style: thirdTextStyle.copyWith(
|
||||
fontSize: getProportionateScreenWidth(13),
|
||||
color: baruTexthitam,
|
||||
fontWeight: semiBold,
|
||||
letterSpacing: 1,
|
||||
),
|
||||
),
|
||||
SizedBox(height: getProportionateScreenHeight(6)),
|
||||
Text(
|
||||
'Total',
|
||||
style: thirdTextStyle.copyWith(
|
||||
fontSize: getProportionateScreenWidth(13),
|
||||
color: baruTexthitam,
|
||||
),
|
||||
),
|
||||
SizedBox(height: getProportionateScreenHeight(2)),
|
||||
Text(
|
||||
'Rp. ${NumberFormat.currency(locale: 'id', symbol: '').format(double.parse(detailOrder[0].totalPayment))}',
|
||||
style: thirdTextStyle.copyWith(
|
||||
fontSize: getProportionateScreenWidth(13),
|
||||
color: baruTexthitam,
|
||||
fontWeight: semiBold,
|
||||
letterSpacing: 2,
|
||||
),
|
||||
),
|
||||
|
||||
// Center(
|
||||
// child: Text(
|
||||
// detailOrder[0].qrCodeUrl!.toString(),
|
||||
// style: thirdTextStyle.copyWith(
|
||||
// fontWeight: semiBold,
|
||||
// fontSize: 14,
|
||||
// color: Color(0xff181818)),
|
||||
// ),
|
||||
// ),
|
||||
|
||||
// GestureDetector(
|
||||
// child: Container(
|
||||
// padding: EdgeInsets.all(16),
|
||||
// width: double.infinity,
|
||||
// height: getProportionateScreenHeight(44),
|
||||
// decoration: BoxDecoration(
|
||||
// color: Color(0xff25D366),
|
||||
// border: Border.all(color: Color(0xff25D366), width: 1),
|
||||
// borderRadius: BorderRadius.circular(10)),
|
||||
// child: Center(
|
||||
// child: Text(
|
||||
// 'Pembayaran Gojek',
|
||||
// style: thirdTextStyle.copyWith(
|
||||
// fontSize: 14, color: Color(0xfff4f4f4)),
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
// onTap: () async {
|
||||
// await openUrl(detailOrder[0].urlGopay!.toString());
|
||||
// },
|
||||
// ),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(height: getProportionateScreenHeight(10)),
|
||||
Padding(
|
||||
padding: EdgeInsets.symmetric(
|
||||
horizontal: getProportionateScreenWidth(10)),
|
||||
child: GestureDetector(
|
||||
child: Container(
|
||||
padding: EdgeInsets.all(16),
|
||||
width: double.infinity,
|
||||
height: getProportionateScreenHeight(40),
|
||||
decoration: BoxDecoration(
|
||||
color: Theme.of(context).colorScheme.primaryContainer,
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Colors.black.withOpacity(0.1),
|
||||
spreadRadius: 0,
|
||||
blurRadius: 4,
|
||||
offset: Offset(0, 2),
|
||||
),
|
||||
],
|
||||
),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(
|
||||
'Cara Pembayaran',
|
||||
style: thirdTextStyle.copyWith(
|
||||
fontSize: getProportionateScreenWidth(11),
|
||||
fontWeight: semiBold,
|
||||
),
|
||||
),
|
||||
Icon(
|
||||
Icons.keyboard_arrow_down_outlined,
|
||||
size: getProportionateScreenWidth(22),
|
||||
color: Theme.of(context).colorScheme.onBackground,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
onTap: () {
|
||||
Navigator.push(
|
||||
context,
|
||||
CustomNavigator(
|
||||
child: GopayPaymentConfirmation(),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
SizedBox(height: getProportionateScreenHeight(20)),
|
||||
Padding(
|
||||
padding: EdgeInsets.symmetric(
|
||||
horizontal: getProportionateScreenWidth(10)),
|
||||
child: GestureDetector(
|
||||
child: Container(
|
||||
padding: EdgeInsets.all(16),
|
||||
width: double.infinity,
|
||||
height: getProportionateScreenHeight(43),
|
||||
decoration: BoxDecoration(
|
||||
color: primaryColor,
|
||||
border: Border.all(
|
||||
color: primaryColor,
|
||||
width: 1,
|
||||
),
|
||||
borderRadius: BorderRadius.circular(10)),
|
||||
child: Center(
|
||||
child: Text(
|
||||
'Unduh QRIS',
|
||||
style: thirdTextStyle.copyWith(
|
||||
fontSize: getProportionateScreenWidth(13),
|
||||
fontWeight: semiBold,
|
||||
color: baruTextutih,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
onTap: () {
|
||||
// Navigator.push(
|
||||
// context,
|
||||
// MaterialPageRoute(
|
||||
// builder: (context) => GopayPaymentConfirmation()));
|
||||
},
|
||||
),
|
||||
),
|
||||
SizedBox(height: 16),
|
||||
Padding(
|
||||
padding: EdgeInsets.symmetric(
|
||||
horizontal: getProportionateScreenWidth(10)),
|
||||
child: GestureDetector(
|
||||
child: Container(
|
||||
padding: EdgeInsets.all(16),
|
||||
width: double.infinity,
|
||||
height: getProportionateScreenHeight(43),
|
||||
decoration: BoxDecoration(
|
||||
border: Border.all(
|
||||
color: primaryColor,
|
||||
width: 1,
|
||||
),
|
||||
borderRadius: BorderRadius.circular(10)),
|
||||
child: Center(
|
||||
child: Text(
|
||||
'Cek Status Transaksi',
|
||||
style: thirdTextStyle.copyWith(
|
||||
fontSize: getProportionateScreenWidth(13),
|
||||
color: primaryColor,
|
||||
fontWeight: semiBold,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
onTap: () {
|
||||
print(idCart);
|
||||
// Navigator.push(
|
||||
// context,
|
||||
// MaterialPageRoute(
|
||||
// builder: (context) => BatasBayarGopay(idCart: idCart),
|
||||
// ),
|
||||
// );
|
||||
Navigator.pushReplacement(
|
||||
context,
|
||||
CustomNavigator(
|
||||
child: RiwayatTransaksiPending(),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
SizedBox(height: getProportionateScreenHeight(20)),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class GopaySplashScreen extends StatefulWidget {
|
||||
final List<String>? idCart;
|
||||
GopaySplashScreen({this.idCart});
|
||||
|
||||
@override
|
||||
State<GopaySplashScreen> createState() => _GopaySplashScreenState();
|
||||
}
|
||||
|
||||
class _GopaySplashScreenState extends State<GopaySplashScreen> {
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
Timer(
|
||||
Duration(seconds: 2),
|
||||
() => Navigator.pushReplacement(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) => QRCodeGopay(idCart: widget.idCart),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
// TODO: implement build
|
||||
return Scaffold(
|
||||
body: SafeArea(
|
||||
child: Container(
|
||||
color: Color(0xff4DC256),
|
||||
alignment: Alignment.center,
|
||||
child: Image(
|
||||
image: AssetImage('assets/images/gopay1.png'),
|
||||
height: 50,
|
||||
),
|
||||
)),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> openUrl(String url,
|
||||
{bool forceWebView = false, enableJavaScript = false}) async {
|
||||
await launchUrl(Uri.parse(url));
|
||||
}
|
151
lib/screens/checkout/not_success_paid_course.dart
Normal file
151
lib/screens/checkout/not_success_paid_course.dart
Normal file
@ -0,0 +1,151 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:initial_folder/providers/my_course_provider.dart';
|
||||
import 'package:initial_folder/providers/order_provider.dart';
|
||||
import 'package:initial_folder/providers/page_provider.dart';
|
||||
import 'package:initial_folder/providers/payments_provider.dart';
|
||||
import 'package:initial_folder/screens/home/components/body_comp/latest_course.dart';
|
||||
import 'package:initial_folder/screens/home/components/home_page.dart';
|
||||
import 'package:initial_folder/screens/home/home_screen.dart';
|
||||
// import 'package:initial_folder/models/course_model.dart';
|
||||
import 'package:initial_folder/size_config.dart';
|
||||
import 'package:initial_folder/theme.dart';
|
||||
import 'package:initial_folder/widgets/login_regist/default_button.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
class NotSuccessPaidCourse extends StatelessWidget {
|
||||
const NotSuccessPaidCourse({
|
||||
Key? key,
|
||||
this.title,
|
||||
this.id,
|
||||
this.thumbnail,
|
||||
this.instructor,
|
||||
}) : super(key: key);
|
||||
|
||||
final String? instructor, id, thumbnail, title;
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
PageProvider pageProvider = Provider.of<PageProvider>(context);
|
||||
|
||||
var orders = Provider.of<OrderProvider>(context).orders;
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
leadingWidth: 14,
|
||||
),
|
||||
body: ListView(
|
||||
children: [
|
||||
SizedBox(height: getProportionateScreenHeight(8)),
|
||||
Text(
|
||||
'TRANSAKSI DIBATALKAN',
|
||||
style: secondaryTextStyle.copyWith(
|
||||
fontWeight: bold,
|
||||
color: primaryColor,
|
||||
fontSize: getProportionateScreenWidth(20),
|
||||
letterSpacing: 1),
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
SizedBox(
|
||||
height: getProportionateScreenHeight(16),
|
||||
),
|
||||
// Column(
|
||||
// children: [
|
||||
// Text(
|
||||
// 'Order ID',
|
||||
// style: primaryTextStyle.copyWith(
|
||||
// letterSpacing: 0.5,
|
||||
// fontWeight: bold,
|
||||
// fontSize: getProportionateScreenWidth(10),
|
||||
// color: secondaryColor,
|
||||
// ),
|
||||
// ),
|
||||
// Text(
|
||||
// '123',
|
||||
// style: primaryTextStyle.copyWith(
|
||||
// letterSpacing: 0.5,
|
||||
// fontWeight: reguler,
|
||||
// fontSize: getProportionateScreenWidth(12),
|
||||
// color: tenthColor,
|
||||
// ),
|
||||
// ),
|
||||
// ],
|
||||
// ),
|
||||
// SizedBox(
|
||||
// height: getProportionateScreenHeight(16),
|
||||
// ),
|
||||
Container(
|
||||
margin: EdgeInsets.only(left: 16, right: 16),
|
||||
width: SizeConfig.screenWidth,
|
||||
height: getProportionateScreenHeight(180),
|
||||
child: Column(
|
||||
children: [
|
||||
Container(
|
||||
width: getProportionateScreenWidth(278),
|
||||
height: getProportionateScreenHeight(156),
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(5),
|
||||
image: DecorationImage(
|
||||
image: NetworkImage(thumbnail ??
|
||||
// '$baseUrl/uploads/courses_thumbnail/course_thumbnail_default_57.jpg'
|
||||
orders[0].imageUrl),
|
||||
fit: BoxFit.fill)),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Container(
|
||||
margin: EdgeInsets.only(
|
||||
left: getProportionateScreenWidth(16),
|
||||
right: getProportionateScreenWidth(16),
|
||||
bottom: getProportionateScreenHeight(8),
|
||||
),
|
||||
child: Center(
|
||||
child: Text(
|
||||
title ?? '',
|
||||
style: secondaryTextStyle.copyWith(
|
||||
fontSize: 20, letterSpacing: 0.2),
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
),
|
||||
),
|
||||
Container(
|
||||
child: Center(
|
||||
child: Text(
|
||||
instructor == null
|
||||
? 'Oleh ${orders[0].instructor}'
|
||||
: 'Oleh $instructor ',
|
||||
style:
|
||||
primaryTextStyle.copyWith(fontSize: 14, letterSpacing: 0.5),
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
),
|
||||
),
|
||||
Container(
|
||||
child: Text(
|
||||
orders.length == 1 ? '' : '(${orders.length} kursus lainnya)'),
|
||||
),
|
||||
SizedBox(
|
||||
height: getProportionateScreenHeight(20),
|
||||
),
|
||||
Container(
|
||||
margin: EdgeInsets.only(left: 16, right: 16),
|
||||
child: DefaultButton(
|
||||
text: 'Kembali Ke Home',
|
||||
press: () async {
|
||||
await Provider.of<MyCourseProvider>(context, listen: false)
|
||||
.getMyCourse();
|
||||
pageProvider.currentIndex = 0;
|
||||
Navigator.pushAndRemoveUntil(
|
||||
context,
|
||||
MaterialPageRoute(builder: (context) => HomePage()),
|
||||
(route) => false);
|
||||
},
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
height: getProportionateScreenHeight(20),
|
||||
),
|
||||
LatestCourse(text: "Kursus Terbaru")
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
361
lib/screens/checkout/snap_payment_page.dart
Normal file
361
lib/screens/checkout/snap_payment_page.dart
Normal file
@ -0,0 +1,361 @@
|
||||
import 'dart:convert';
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:file_saver/file_saver.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_dotenv/flutter_dotenv.dart';
|
||||
import 'package:initial_folder/base_service.dart';
|
||||
import 'package:initial_folder/providers/order_provider.dart';
|
||||
import 'package:initial_folder/screens/profile/account_sign_in/riwayat_transaksi.dart';
|
||||
import 'package:initial_folder/screens/profile/account_sign_in/riwayat_transaksi_pending.dart';
|
||||
import 'package:path_provider/path_provider.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:webview_flutter/webview_flutter.dart';
|
||||
import 'package:initial_folder/theme.dart';
|
||||
import 'package:url_launcher/url_launcher.dart'; // Import url_launcher
|
||||
|
||||
import 'success_paid_course.dart';
|
||||
|
||||
class SnapPaymentPage extends StatefulWidget {
|
||||
final String transactionToken;
|
||||
final String orderId;
|
||||
final int grossAmount;
|
||||
|
||||
final String courseTitle;
|
||||
final String courseThumbnail;
|
||||
final String courseInstructor;
|
||||
final String courseId;
|
||||
|
||||
SnapPaymentPage({
|
||||
required this.transactionToken,
|
||||
required this.orderId,
|
||||
required this.grossAmount,
|
||||
required this.courseTitle,
|
||||
required this.courseThumbnail,
|
||||
required this.courseInstructor,
|
||||
required this.courseId,
|
||||
});
|
||||
|
||||
@override
|
||||
_SnapPaymentPageState createState() => _SnapPaymentPageState();
|
||||
}
|
||||
|
||||
class _SnapPaymentPageState extends State<SnapPaymentPage> {
|
||||
// Controller untuk WebView
|
||||
late WebViewController _controller;
|
||||
double _progress = 0; // Menyimpan progress loading WebView
|
||||
bool _isLoading = true; // Status loading halaman
|
||||
String? baseUrlmidtrans = dotenv.env['BASE_URL_MIDTRANS']; // Base URL Midtrans
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
// Inisialisasi WebViewController dan pengaturan event handler
|
||||
_controller = WebViewController()
|
||||
..setJavaScriptMode(JavaScriptMode.unrestricted)
|
||||
..setBackgroundColor(const Color(0x00000000))
|
||||
..setNavigationDelegate(
|
||||
NavigationDelegate(
|
||||
onProgress: _onProgress, // Handler progress loading
|
||||
onPageStarted: _onPageStarted, // Handler saat halaman mulai dimuat
|
||||
onPageFinished: _onPageFinished, // Handler saat halaman selesai dimuat
|
||||
onWebResourceError: _onWebResourceError, // Handler error resource
|
||||
onNavigationRequest: _onNavigationRequest, // Handler navigasi
|
||||
),
|
||||
)
|
||||
..addJavaScriptChannel(
|
||||
'BlobDataChannel',
|
||||
// Handler pesan dari JavaScript untuk download QRIS
|
||||
onMessageReceived: (JavaScriptMessage message) async {
|
||||
if (message.message.startsWith('error:')) {
|
||||
// Jika error saat fetch blob
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (context) => AlertDialog(
|
||||
title: Text('Download Sedang Tidak Tersedia'),
|
||||
content: Text(
|
||||
'Silahkan screenshot Qris tersebut untuk menyimpan ke perangkat kamu.'),
|
||||
actions: [
|
||||
TextButton(
|
||||
onPressed: () {
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
child: Text('OK'),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
// ScaffoldMessenger.of(context).showSnackBar(
|
||||
// SnackBar(content: Text('Gagal mengunduh QRIS. Silakan coba lagi.')),
|
||||
// );
|
||||
} else {
|
||||
// Jika berhasil, proses data blob
|
||||
await _handleBlobData(message.message);
|
||||
}
|
||||
},
|
||||
)
|
||||
// Memuat halaman pembayaran Midtrans
|
||||
..loadRequest(Uri.parse(
|
||||
"$baseUrlmidtrans/snap/v2/vtweb/${widget.transactionToken}",
|
||||
));
|
||||
}
|
||||
|
||||
// Handler progress loading WebView
|
||||
void _onProgress(int progressValue) {
|
||||
setState(() {
|
||||
_progress = progressValue / 100;
|
||||
});
|
||||
}
|
||||
|
||||
// Handler saat halaman mulai dimuat
|
||||
void _onPageStarted(String url) {
|
||||
setState(() {
|
||||
_isLoading = true;
|
||||
});
|
||||
}
|
||||
|
||||
// Handler saat halaman selesai dimuat
|
||||
void _onPageFinished(String url) {
|
||||
setState(() {
|
||||
_isLoading = false;
|
||||
_progress = 0;
|
||||
});
|
||||
}
|
||||
|
||||
// Handler jika terjadi error pada resource WebView
|
||||
void _onWebResourceError(WebResourceError error) {
|
||||
setState(() {
|
||||
_isLoading = false;
|
||||
});
|
||||
_showErrorDialog(error.description ?? 'Unknown Error');
|
||||
}
|
||||
|
||||
// Handler navigasi pada WebView
|
||||
NavigationDecision _onNavigationRequest(NavigationRequest request) {
|
||||
// Redirect ke aplikasi pembayaran jika diperlukan
|
||||
if (request.url.startsWith('https://gopay.co.id/') ||
|
||||
request.url.startsWith('https://app.shopeepay.co.id/')) {
|
||||
print('Redirecting to GoPay/GoJek app');
|
||||
_launchURL(request.url);
|
||||
return NavigationDecision.prevent;
|
||||
}
|
||||
|
||||
// Jika link blob (download QRIS), jalankan fetch blob
|
||||
if (request.url.startsWith('blob:')) {
|
||||
print('Redirecting download qris');
|
||||
|
||||
_fetchBlobData(baseUrlmidtrans ?? "https://app.sandbox.midtrans.com",
|
||||
widget.transactionToken);
|
||||
return NavigationDecision.prevent;
|
||||
}
|
||||
|
||||
// Redirect ke halaman riwayat transaksi jika status pending
|
||||
if (request.url.contains('transaction_status=pending') ||
|
||||
request.url.contains('https://vocasia.id/')) {
|
||||
Navigator.of(context)
|
||||
.pushReplacementNamed(RiwayatTransaksiPending.routeName);
|
||||
return NavigationDecision.prevent;
|
||||
}
|
||||
|
||||
// Jika pembayaran sukses, tambahkan order dan redirect ke halaman sukses
|
||||
if (request.url.contains('transaction_status=settlement') ||
|
||||
request.url.contains('transaction_status=capture')) {
|
||||
var orderProvider = Provider.of<OrderProvider>(context, listen: false);
|
||||
orderProvider.addOrder(
|
||||
id: widget.courseId,
|
||||
title: widget.courseTitle,
|
||||
price: widget.grossAmount.toString(),
|
||||
imageUrl: widget.courseThumbnail,
|
||||
instructor: widget.courseInstructor,
|
||||
discountPrice: '',
|
||||
);
|
||||
|
||||
Navigator.of(context).pushReplacementNamed(
|
||||
SuccessPaidCourse.routeName,
|
||||
);
|
||||
return NavigationDecision.prevent;
|
||||
}
|
||||
|
||||
// Jika user menekan tombol kembali di halaman pembayaran
|
||||
if (request.url.contains('action=back')) {
|
||||
Navigator.of(context).pop();
|
||||
return NavigationDecision.prevent;
|
||||
}
|
||||
|
||||
// Default: lanjutkan navigasi
|
||||
return NavigationDecision.navigate;
|
||||
}
|
||||
|
||||
// Menjalankan JavaScript untuk mengambil data blob QRIS dari WebView
|
||||
Future<void> _fetchBlobData(String baseUrl, String transactionId) async {
|
||||
print('Fetching transaction URL: $transactionId');
|
||||
final realUrl =
|
||||
baseUrl + "/snap/v1/transactions/" + transactionId + "/qr-code";
|
||||
final script = '''
|
||||
(async function() {
|
||||
try {
|
||||
const response = await fetch('$baseUrl')
|
||||
const blob = await response.blob();
|
||||
const reader = new FileReader();
|
||||
reader.onloadend = function() {
|
||||
const base64data = reader.result.split(',')[1];
|
||||
BlobDataChannel.postMessage(base64data);
|
||||
};
|
||||
reader.readAsDataURL(blob);
|
||||
} catch (error) {
|
||||
console.error('Failed to fetch blob:', error);
|
||||
BlobDataChannel.postMessage('error: ' + error.message);
|
||||
}
|
||||
})();
|
||||
''';
|
||||
_controller.runJavaScript(script);
|
||||
}
|
||||
|
||||
// Menyimpan data QRIS hasil download ke file lokal
|
||||
Future<void> _handleBlobData(String base64Data) async {
|
||||
try {
|
||||
final decodedBytes = base64Decode(base64Data);
|
||||
final directory = await getApplicationDocumentsDirectory();
|
||||
final path = directory.path;
|
||||
final file = File('$path/qris_download.png');
|
||||
await file.writeAsBytes(decodedBytes);
|
||||
|
||||
await FileSaver.instance.saveAs(
|
||||
name: 'qris_download',
|
||||
ext: 'png',
|
||||
mimeType: MimeType.png,
|
||||
file: file,
|
||||
);
|
||||
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(content: Text('QRIS berhasil diunduh')),
|
||||
);
|
||||
} catch (e) {
|
||||
_showErrorDialog('Gagal mengunduh QRIS: $e');
|
||||
}
|
||||
}
|
||||
|
||||
// Menampilkan dialog error
|
||||
void _showErrorDialog(String errorMessage) {
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (context) => AlertDialog(
|
||||
title: Text('Error'),
|
||||
content: Text(errorMessage),
|
||||
actions: [
|
||||
TextButton(
|
||||
onPressed: () {
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
child: Text('OK'),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
// Membuka aplikasi eksternal (misal: GoPay/ShopeePay)
|
||||
Future<void> _launchURL(String url) async {
|
||||
if (await canLaunch(url)) {
|
||||
await launch(url);
|
||||
} else {
|
||||
_showErrorDialog('Could not open the app');
|
||||
}
|
||||
}
|
||||
|
||||
// Handler ketika user menekan tombol back (hardware/software)
|
||||
Future<bool> _onWillPop() async {
|
||||
return (await showDialog(
|
||||
context: context,
|
||||
builder: (context) => AlertDialog(
|
||||
title: Text('Pembayaran Belum Selesai'),
|
||||
content: Text('Apakah Anda yakin ingin keluar dari halaman ini?'),
|
||||
actions: <Widget>[
|
||||
TextButton(
|
||||
onPressed: () => Navigator.of(context).pop(false),
|
||||
child: Text('Batal'),
|
||||
),
|
||||
TextButton(
|
||||
onPressed: () {
|
||||
Navigator.of(context).pop(true);
|
||||
Navigator.of(context)
|
||||
.pushReplacementNamed(RiwayatTransaksi.routeName);
|
||||
},
|
||||
child: Text('Keluar'),
|
||||
),
|
||||
],
|
||||
),
|
||||
)) ??
|
||||
false;
|
||||
}
|
||||
|
||||
// Melakukan reload halaman pembayaran
|
||||
void _refreshPage() {
|
||||
_controller.reload();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
// Widget utama halaman pembayaran
|
||||
return WillPopScope(
|
||||
onWillPop: _onWillPop,
|
||||
child: Scaffold(
|
||||
appBar: PreferredSize(
|
||||
preferredSize: Size.fromHeight(kToolbarHeight),
|
||||
child: AppBar(
|
||||
elevation: 5,
|
||||
title: Center(
|
||||
child: Text(
|
||||
'Pembayaran',
|
||||
style: primaryTextStyle.copyWith(
|
||||
color: Colors.white,
|
||||
),
|
||||
),
|
||||
),
|
||||
backgroundColor: primaryColor,
|
||||
iconTheme: IconThemeData(color: Colors.white),
|
||||
leading: IconButton(
|
||||
icon: Icon(Icons.arrow_back),
|
||||
onPressed: () async {
|
||||
bool shouldExit = await _onWillPop();
|
||||
if (shouldExit) {
|
||||
Navigator.of(context)
|
||||
.pushReplacementNamed(RiwayatTransaksi.routeName);
|
||||
}
|
||||
},
|
||||
),
|
||||
actions: [
|
||||
IconButton(
|
||||
icon: Icon(Icons.refresh),
|
||||
onPressed: _refreshPage,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
body: Stack(
|
||||
children: [
|
||||
// Widget WebView untuk menampilkan halaman pembayaran
|
||||
RefreshIndicator(
|
||||
onRefresh: () async {
|
||||
_refreshPage();
|
||||
},
|
||||
child: WebViewWidget(controller: _controller),
|
||||
),
|
||||
// Progress bar saat loading
|
||||
if (_isLoading)
|
||||
LinearProgressIndicator(
|
||||
value: _progress,
|
||||
color: sevenColor,
|
||||
backgroundColor: secondaryColor,
|
||||
),
|
||||
// Spinner loading di tengah layar
|
||||
if (_isLoading)
|
||||
Center(
|
||||
child: CircularProgressIndicator(),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
130
lib/screens/checkout/success_paid_course.dart
Normal file
130
lib/screens/checkout/success_paid_course.dart
Normal file
@ -0,0 +1,130 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:initial_folder/providers/order_provider.dart';
|
||||
import 'package:initial_folder/providers/page_provider.dart';
|
||||
import 'package:initial_folder/screens/home/home_screen.dart';
|
||||
import 'package:initial_folder/size_config.dart';
|
||||
import 'package:initial_folder/theme.dart';
|
||||
import 'package:initial_folder/widgets/login_regist/default_button_payment.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
import '../../providers/my_course_provider.dart';
|
||||
|
||||
class SuccessPaidCourse extends StatefulWidget {
|
||||
static const String routeName = "/success-paid-course";
|
||||
|
||||
@override
|
||||
State<SuccessPaidCourse> createState() => _SuccessPaidCourseState();
|
||||
}
|
||||
|
||||
class _SuccessPaidCourseState extends State<SuccessPaidCourse> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
var orders = Provider.of<OrderProvider>(context).orders;
|
||||
var pageProvider = Provider.of<PageProvider>(context);
|
||||
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
scrolledUnderElevation: 0.0,
|
||||
backgroundColor: Theme.of(context).colorScheme.background,
|
||||
leadingWidth: 14,
|
||||
),
|
||||
body: ListView(
|
||||
children: [
|
||||
Image.asset(
|
||||
"assets/images/success_pay.png",
|
||||
width: getProportionateScreenWidth(100),
|
||||
height: getProportionateScreenHeight(100),
|
||||
),
|
||||
SizedBox(height: getProportionateScreenHeight(15)),
|
||||
Text(
|
||||
'Pembayaran Berhasil',
|
||||
style: thirdTextStyle.copyWith(
|
||||
fontWeight: semiBold,
|
||||
fontSize: getProportionateScreenWidth(14),
|
||||
),
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
SizedBox(height: getProportionateScreenHeight(15)),
|
||||
Container(
|
||||
margin: EdgeInsets.symmetric(horizontal: 16),
|
||||
width: SizeConfig.screenWidth,
|
||||
height: getProportionateScreenHeight(169),
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(5),
|
||||
),
|
||||
child: Column(
|
||||
children: [
|
||||
Container(
|
||||
width: getProportionateScreenWidth(278),
|
||||
height: getProportionateScreenHeight(145),
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(5),
|
||||
image: DecorationImage(
|
||||
image: NetworkImage(
|
||||
orders[0].imageUrl, // Ambil dari OrderProvider
|
||||
),
|
||||
fit: BoxFit.cover,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Padding(
|
||||
padding: EdgeInsets.symmetric(
|
||||
horizontal: getProportionateScreenWidth(15)),
|
||||
child: Container(
|
||||
margin: EdgeInsets.only(
|
||||
bottom: getProportionateScreenHeight(8),
|
||||
),
|
||||
child: Center(
|
||||
child: Text(
|
||||
orders[0].title ?? '', // Ambil dari OrderProvider
|
||||
style: thirdTextStyle.copyWith(
|
||||
fontSize: getProportionateScreenWidth(14),
|
||||
letterSpacing: 0.2,
|
||||
),
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
Container(
|
||||
child: Center(
|
||||
child: Text(
|
||||
'Oleh ${orders[0].instructor}', // Ambil dari OrderProvider
|
||||
style: thirdTextStyle.copyWith(
|
||||
fontSize: getProportionateScreenWidth(11),
|
||||
letterSpacing: 0.5,
|
||||
fontFamily: "Poppins",
|
||||
),
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(height: getProportionateScreenHeight(10)),
|
||||
Container(
|
||||
margin: EdgeInsets.symmetric(horizontal: 16),
|
||||
child: DefaultButtonPayment(
|
||||
width: double.infinity,
|
||||
height: getProportionateScreenHeight(34),
|
||||
text: 'Lihat Kursus',
|
||||
press: () async {
|
||||
await Provider.of<MyCourseProvider>(context, listen: false)
|
||||
.getMyCourse();
|
||||
pageProvider.currentIndex = 2;
|
||||
Navigator.pushAndRemoveUntil(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) => HomeScreen(),
|
||||
),
|
||||
(route) => false,
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user