Files

783 lines
35 KiB
Dart

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();
}
}