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

992 lines
46 KiB
Dart

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),
),
),
],
),
),
],
),
);
}
}