Files
Vocasia-LMS-Mobile-apps--TA…/lib/screens/profile/account_sign_in/detail_transaksi.dart

925 lines
42 KiB
Dart

import 'dart:async';
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/models/history_transaction_model.dart';
import 'package:initial_folder/providers/page_provider.dart';
import 'package:initial_folder/providers/theme_provider.dart';
import 'package:initial_folder/screens/checkout/components/bar_batas_bayar.dart';
import 'package:initial_folder/screens/checkout/components/tab_bar_batas_bayar.dart';
import 'package:initial_folder/screens/checkout/gopay/payment_instruction_gopay.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/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:initial_folder/providers/detail_invoice_provider.dart'
as detailProv;
import 'package:shared_preferences/shared_preferences.dart';
class DetailInvoice extends StatefulWidget {
const DetailInvoice({
Key? key,
this.orderId,
this.dataHistoryTransactionModel,
}) : super(key: key);
final String? orderId;
final HistoryTransactionModel? dataHistoryTransactionModel;
@override
State<DetailInvoice> createState() => _DetailInvoiceState();
}
class _DetailInvoiceState extends State<DetailInvoice> {
Duration? remainingTime;
final TextStyle baris = primaryTextStyle.copyWith(
fontWeight: reguler,
color: secondaryColor,
fontSize: getProportionateScreenWidth(14),
letterSpacing: 0.5,
);
Future<void> saveRemainingTime(Duration remainingTime) async {
final prefs = await SharedPreferences.getInstance();
prefs.setInt('remainingTime', remainingTime.inSeconds);
}
Future<void> loadRemainingTime() async {
final prefs = await SharedPreferences.getInstance();
final remainingTimeInSeconds = prefs.getInt('remainingTime');
if (remainingTimeInSeconds != null) {
remainingTime = Duration(seconds: remainingTimeInSeconds);
}
}
Timer? countdownTimer;
@override
void initState() {
super.initState();
WidgetsBinding.instance.addPostFrameCallback((_) {
if (widget.dataHistoryTransactionModel?.dateExpired != null) {
final now = DateTime.now();
final expiryTime = widget.dataHistoryTransactionModel!.dateExpired!;
setState(() {
remainingTime = expiryTime.isAfter(now)
? expiryTime.difference(now)
: Duration.zero;
});
// Mulai timer hanya jika ada waktu tersisa
if (remainingTime != Duration.zero) {
startCountdownTimer();
}
}
if (widget.orderId?.isNotEmpty ?? false) {
Provider.of<detailProv.DetailInvoiceProvider>(context, listen: false)
.fetchDetailInvoice(widget.orderId);
}
});
}
void startCountdownTimer() {
countdownTimer = Timer.periodic(Duration(seconds: 1), (_) {
if (remainingTime == null || remainingTime!.inSeconds <= 0) {
countdownTimer?.cancel();
setState(() {
remainingTime = Duration.zero;
});
} else {
setState(() {
remainingTime = remainingTime! - Duration(seconds: 1);
});
print('Remaining time: $remainingTime');
}
});
}
@override
void dispose() {
countdownTimer?.cancel();
if (remainingTime != null) {
saveRemainingTime(remainingTime!);
}
super.dispose();
}
Widget buildCountdownTimer() {
if (remainingTime == null || remainingTime!.inSeconds <= 0) {
return Text(
'00:00:00',
style: thirdTextStyle.copyWith(
fontWeight: semiBold,
letterSpacing: 1,
fontSize: getProportionateScreenWidth(10),
color: baruTextutih,
),
);
}
final hours = remainingTime!.inHours.toString().padLeft(2, '0');
final minutes = (remainingTime!.inMinutes % 60).toString().padLeft(2, '0');
final seconds = (remainingTime!.inSeconds % 60).toString().padLeft(2, '0');
return Text(
'$hours:$minutes:$seconds',
style: thirdTextStyle.copyWith(
fontWeight: semiBold,
letterSpacing: 1,
fontSize: getProportionateScreenWidth(10),
color: baruTextutih,
),
);
}
@override
Widget build(BuildContext context) {
PageProvider pageProvider = Provider.of<PageProvider>(context);
final themeProvider = Provider.of<ThemeProvider>(context);
return Scaffold(
appBar: AppBar(
centerTitle: true,
scrolledUnderElevation: 0.0,
backgroundColor: Theme.of(context).colorScheme.background,
title: Text(
"Cara Pembayaran",
style: thirdTextStyle.copyWith(
fontWeight: semiBold,
fontSize: getProportionateScreenWidth(15),
),
),
),
body: SingleChildScrollView(
child: Consumer<detailProv.DetailInvoiceProvider>(
builder: (context, provider, child) {
if (provider.state == detailProv.ResultState.loading) {
return Center(
child: Column(
children: [
Padding(
padding: EdgeInsets.only(
top: getProportionateScreenHeight(100)),
child: CircularProgressIndicator(
strokeWidth: 2,
color: primaryColor,
),
),
],
),
);
} else if (provider.state == detailProv.ResultState.hasData) {
Widget buildTextWidget() {
String text = "";
if (provider.detailInvoice![0].permataVaNumber != null) {
text = "Permata Virtual Account";
} else if (provider.detailInvoice![0].billerCode != null) {
text = "Mandiri Virtual Account";
} else if (provider.detailInvoice![0].vaNumbers != null &&
provider.detailInvoice![0].vaNumbers!
.any((va) => va.bank == 'bni')) {
text = "BNI Virtual Account";
} else if (provider.detailInvoice![0].vaNumbers != null &&
provider.detailInvoice![0].vaNumbers!
.any((va) => va.bank == 'bca')) {
text = "BCA Virtual Account";
} else if (provider.detailInvoice![0].billerCode != null) {
text = "Mandiri Virtual Account";
} else if (provider.detailInvoice![0].store == "alfamart") {
text = "Alfamart";
} else if (provider.detailInvoice![0].store == "indomaret") {
text = "Indomart";
} else if (provider.detailInvoice![0].paymentType ==
"credit_card") {
text = "Credit Card";
} else {
text = "QRIS";
}
return Text(
text,
style: thirdTextStyle.copyWith(
fontWeight: semiBold,
fontSize: getProportionateScreenWidth(13),
),
);
}
String getVAText() {
String text = provider.detailInvoice![0].orderId!;
if (provider.detailInvoice != null &&
provider.detailInvoice!.isNotEmpty) {
var invoice = provider.detailInvoice![0];
if (invoice.permataVaNumber != null) {
text = invoice.permataVaNumber!;
} else if (invoice.billerCode != null) {
text = invoice.billKey!;
} else if (invoice.vaNumbers != null &&
invoice.vaNumbers!.any((va) => va.bank == 'bni')) {
text = invoice.vaNumbers![0].vaNumber!;
} else if (invoice.vaNumbers != null &&
invoice.vaNumbers!.any((va) => va.bank == 'bca')) {
text = invoice.vaNumbers![0].vaNumber!;
} else if (invoice.billerCode != null) {
text = invoice.billKey!;
} else if (invoice.store == "alfamart") {
text = provider.detailInvoice![0].paymentCode!;
} else if (invoice.store == "indomaret") {
text = provider.detailInvoice![0].paymentCode!;
} else if (provider.detailInvoice![0].paymentType ==
"credit_card") {
text = provider.detailInvoice![0].maskedCard!
.replaceAll('-', '');
} else {
text = provider.detailInvoice![0].orderId!;
}
}
return text;
}
Widget buildVAaWidget() {
String text = getVAText();
return Text(
text,
style: thirdTextStyle.copyWith(
fontWeight: semiBold,
fontSize: getProportionateScreenWidth(13),
),
);
}
Widget buildImageWidget() {
String imageName = "qris";
if (provider.detailInvoice![0].permataVaNumber != null) {
imageName = "permata";
} else if (provider.detailInvoice![0].billerCode != null) {
imageName = "mandiri";
} else if (provider.detailInvoice![0].vaNumbers != null &&
provider.detailInvoice![0].vaNumbers!
.any((va) => va.bank == 'bni')) {
imageName = "bni";
} else if (provider.detailInvoice![0].vaNumbers != null &&
provider.detailInvoice![0].vaNumbers!
.any((va) => va.bank == 'bca')) {
imageName = "bca";
} else if (provider.detailInvoice![0].store == "alfamart") {
imageName = "alfamart";
} else if (provider.detailInvoice![0].store == "indomaret") {
imageName = "indomaret";
} else if (provider.detailInvoice![0].paymentType ==
"credit_card") {
imageName = "qris";
}
return Container(
width: getProportionateScreenWidth(50),
height: getProportionateScreenWidth(17),
decoration: BoxDecoration(
boxShadow: [
BoxShadow(
color: Theme.of(context).colorScheme.brightness ==
Brightness.dark
? Colors.transparent
: (provider.detailInvoice![0].paymentType ==
"gopay")
? baruTexthitam.withOpacity(0.3)
: Colors.transparent,
spreadRadius: 1,
blurRadius: 3,
offset: Offset(0, 1),
),
],
borderRadius: BorderRadius.circular(2),
image: DecorationImage(
image: AssetImage('assets/images/$imageName.png'),
),
),
);
}
return Padding(
padding: EdgeInsets.symmetric(
horizontal: getProportionateScreenWidth(10),
vertical: getProportionateScreenHeight(10),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
width: double.infinity,
decoration: BoxDecoration(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(4),
topRight: Radius.circular(4),
),
color: Theme.of(context).colorScheme.primaryContainer,
),
padding: EdgeInsets.only(
left: getProportionateScreenWidth(10),
right: getProportionateScreenWidth(10),
top: getProportionateScreenHeight(15),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Batas Waktu Pembayaran',
style: thirdTextStyle.copyWith(
fontFamily: "Poppins",
fontSize: getProportionateScreenWidth(11),
),
),
SizedBox(height: getProportionateScreenHeight(2)),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
DateFormat('E, d MMM y HH:mm WIB').format(
DateTime.parse(provider
.detailInvoice![0].expiryTime!)),
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)),
buildCountdownTimer(),
],
),
),
],
),
if (provider.detailInvoice![0].paymentType == "gopay")
SizedBox(height: getProportionateScreenHeight(5)),
if (provider.detailInvoice![0].paymentType == "gopay")
Divider(
color: secondaryColor,
thickness: 1,
),
],
),
),
Container(
width: double.infinity,
decoration: BoxDecoration(
borderRadius: BorderRadius.only(
bottomLeft: Radius.circular(4),
bottomRight: Radius.circular(4),
),
color: Theme.of(context).colorScheme.primaryContainer,
boxShadow: [
BoxShadow(
color:
Theme.of(context).brightness == Brightness.dark
? Colors.transparent
: secondaryColor.withOpacity(0.2),
spreadRadius: 1,
blurRadius: 2,
offset: Offset(0, getProportionateScreenHeight(4)),
),
],
),
padding: EdgeInsets.symmetric(
horizontal: getProportionateScreenWidth(10)),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SizedBox(height: getProportionateScreenHeight(10)),
Text(
"Kursus",
style: thirdTextStyle.copyWith(
fontFamily: "Poppins",
fontSize: getProportionateScreenWidth(11),
),
),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
listCourse(
imageUrl: provider.thumbnail,
title: widget.dataHistoryTransactionModel!
.courses?[0].title,
instructor: widget.dataHistoryTransactionModel!
.courses?[0].instructor,
price: widget.dataHistoryTransactionModel!
.courses?[0].price,
discountPrice: widget
.dataHistoryTransactionModel!
.courses?[0]
.price,
totalPrices: 0,
),
],
),
if (provider.detailInvoice![0].paymentType == "gopay")
Divider(
color: secondaryColor,
thickness: 1,
),
Text(
'Metode Pembayaran',
style: thirdTextStyle.copyWith(
fontWeight: reguler,
fontSize: getProportionateScreenWidth(10),
),
),
SizedBox(height: getProportionateScreenHeight(5)),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
buildTextWidget(),
buildImageWidget(),
],
),
SizedBox(height: getProportionateScreenHeight(12)),
provider.detailInvoice![0].store == null &&
provider.detailInvoice![0].paymentType !=
"credit_card"
? (provider.detailInvoice![0].paymentType !=
"gopay")
? Text(
"Nomor Virtual Akun",
style: thirdTextStyle.copyWith(
fontWeight: reguler,
fontSize:
getProportionateScreenWidth(10),
),
)
: provider.detailInvoice![0].paymentType !=
"credit_card"
? (provider.detailInvoice![0]
.paymentType !=
"gopay")
? Text(
"Nomor Pesananan",
style: thirdTextStyle.copyWith(
fontWeight: reguler,
fontSize:
getProportionateScreenWidth(
10),
),
)
: Text(
"Order ID",
style: thirdTextStyle.copyWith(
fontWeight: reguler,
fontSize:
getProportionateScreenWidth(
10),
),
)
: SizedBox.shrink()
: Text(
"Kode Pembayaran",
style: thirdTextStyle.copyWith(
fontWeight: reguler,
fontSize: getProportionateScreenWidth(10),
),
),
if (provider.detailInvoice![0].paymentType ==
"credit_card")
Text(
"Nomor Kartu Kredit",
style: primaryTextStyle.copyWith(
color: Colors.white,
letterSpacing: 0.5,
fontWeight: reguler,
fontSize: getProportionateScreenWidth(10),
),
),
SizedBox(height: getProportionateScreenHeight(5)),
Row(
children: [
buildVAaWidget(),
Spacer(),
GestureDetector(
onTap: () {
Clipboard.setData(ClipboardData(
text: getVAText().toString()))
.then(
(_) {
ScaffoldMessenger.of(context)
.showSnackBar(
SnackBar(
content: Text(
'Berhasil Menyalin Ke Clipboard'),
),
);
},
);
},
child: Text(
"Salin",
style: thirdTextStyle.copyWith(
color: themeProvider.themeData == ThemeClass.darkmode
?primaryColor : primaryColorligtmode,
fontSize: getProportionateScreenWidth(10),
fontWeight: reguler,
),
),
),
],
),
SizedBox(height: getProportionateScreenHeight(10)),
if (provider.detailInvoice?[0].billKey != null ||
provider.detailInvoice?[0].store == "indomaret")
Padding(
padding: EdgeInsets.only(
bottom: getProportionateScreenHeight(5)),
child: Text(
"Merchant id",
style: thirdTextStyle.copyWith(
fontWeight: reguler,
fontSize: getProportionateScreenWidth(10),
),
),
),
if (provider.detailInvoice?[0].billKey != null)
Padding(
padding: EdgeInsets.only(
bottom: getProportionateScreenHeight(16)),
child: Row(
children: [
Text(
provider.detailInvoice![0].billerCode!,
style: thirdTextStyle.copyWith(
fontWeight: semiBold,
fontSize: getProportionateScreenWidth(13),
),
),
Spacer(),
GestureDetector(
onTap: () {
Clipboard.setData(ClipboardData(
text: provider
.detailInvoice![0].billerCode
.toString()))
.then(
(_) {
ScaffoldMessenger.of(context)
.showSnackBar(
SnackBar(
content: Text(
'Berhasil Menyalin Kode Pembayaran'),
),
);
},
);
},
child: Text(
"Salin",
style: thirdTextStyle.copyWith(
color: primaryColor,
fontSize:
getProportionateScreenWidth(10),
fontWeight: reguler,
),
),
),
],
),
),
if (provider.detailInvoice?[0].store == "indomaret")
Padding(
padding: EdgeInsets.only(
bottom: getProportionateScreenHeight(10)),
child: Row(
children: [
Text(
provider.detailInvoice![0].merchantId!,
style: primaryTextStyle.copyWith(
color: Colors.black,
letterSpacing: 1,
fontWeight: semiBold,
fontSize: getProportionateScreenWidth(13),
),
),
Spacer(),
GestureDetector(
onTap: () {
Clipboard.setData(ClipboardData(
text: provider
.detailInvoice![0].merchantId
.toString()))
.then(
(_) {
ScaffoldMessenger.of(context)
.showSnackBar(
SnackBar(
content: Text(
'Berhasil Menyalin Kode Merchant'),
),
);
},
);
},
child: Text(
"Salin",
style: thirdTextStyle.copyWith(
color: primaryColor,
fontSize:
getProportionateScreenWidth(10),
fontWeight: reguler,
),
),
),
],
),
),
Text(
'Total Pembayaran',
style: thirdTextStyle.copyWith(
fontWeight: reguler,
fontSize: getProportionateScreenWidth(10),
),
),
SizedBox(height: getProportionateScreenHeight(8)),
Row(
children: [
Text(
'Rp. ${NumberFormat.currency(locale: 'id', symbol: '', decimalDigits: 0).format(double.parse(provider.detailInvoice![0].grossAmount!))}',
style: thirdTextStyle.copyWith(
fontWeight: semiBold,
fontSize: getProportionateScreenWidth(13),
),
),
Spacer(),
GestureDetector(
onTap: () {
Clipboard.setData(ClipboardData(
text: double.parse(provider
.detailInvoice![0]
.grossAmount!)
.toString()))
.then(
(_) {
ScaffoldMessenger.of(context)
.showSnackBar(
SnackBar(
content: Text(
'Berhasil Menyalin Ke Clipboard'),
),
);
},
);
},
child: Text(
"Salin",
style: thirdTextStyle.copyWith(
color: themeProvider.themeData == ThemeClass.darkmode
?primaryColor : primaryColorligtmode,
fontSize: getProportionateScreenWidth(10),
fontWeight: reguler,
),
),
),
],
),
SizedBox(height: getProportionateScreenHeight(10)),
],
),
),
SizedBox(height: getProportionateScreenHeight(24)),
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: [
provider.detailInvoice![0].paymentType != "gopay"
? Container(
width: double.infinity,
padding: EdgeInsets.only(
top: getProportionateScreenHeight(15),
bottom: getProportionateScreenHeight(7),
left: getProportionateScreenWidth(18),
),
decoration: BoxDecoration(
color: Theme.of(context)
.colorScheme
.primaryContainer,
borderRadius: BorderRadius.only(
topLeft: Radius.circular(4),
topRight: Radius.circular(4),
),
boxShadow: [
BoxShadow(
color: secondaryColor.withOpacity(0.2),
spreadRadius: 0,
blurRadius: 2,
offset: Offset(
0, getProportionateScreenHeight(4)),
),
],
),
child: Text(
'Cara Pembayaran',
style: secondaryTextStyle.copyWith(
letterSpacing: 1,
fontWeight: semiBold,
fontSize: getProportionateScreenWidth(14),
),
),
)
: SizedBox.shrink(),
Container(
padding: EdgeInsets.symmetric(
horizontal: getProportionateScreenWidth(5),
),
child: provider.detailInvoice![0].store ==
'indomaret' ||
provider.detailInvoice![0].store ==
'alfamart'
? BarBatasBayar(
provider.detailInvoice![0].store!)
: (provider.detailInvoice![0].paymentType !=
"gopay")
? TabBarBatasBayar(
bank: provider.detailInvoice![0]
.vaNumbers !=
null
? provider.detailInvoice![0]
.vaNumbers![0].bank
: (provider.detailInvoice?[0]
.permataVaNumber !=
null
? "permata"
: provider.detailInvoice![0]
.paymentType),
)
: PaymentInstructionGopay(),
),
],
),
),
SizedBox(height: getProportionateScreenHeight(15)),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
DefaultButton(
text: 'Belanja kursus lainnya',
weight: semiBold,
press: () {
pageProvider.currentIndex == 0;
Navigator.pushAndRemoveUntil(
context,
CustomNavigatorPop(
child: HomeScreen(),
),
(route) => false);
},
),
],
),
SizedBox(height: getProportionateScreenHeight(10)),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
SizedBox(
width: getProportionateScreenWidth(300),
height: getProportionateScreenHeight(38),
child: TextButton(
onPressed: () {
Navigator.pop(context);
},
child: Text(
"Cek Status Transaksi",
style: thirdTextStyle.copyWith(
fontSize: getProportionateScreenWidth(12),
fontWeight: semiBold,
color: themeProvider.themeData == ThemeClass.darkmode
?primaryColor : primaryColorligtmode,
letterSpacing: 0.5,
),
),
style: TextButton.styleFrom(
foregroundColor:
Theme.of(context).colorScheme.background,
shape: RoundedRectangleBorder(
side: BorderSide( color: themeProvider.themeData == ThemeClass.darkmode
?primaryColor : primaryColorligtmode),
borderRadius: BorderRadius.circular(
getProportionateScreenWidth(10)),
),
backgroundColor: Colors.transparent,
),
),
),
],
),
],
),
);
} else if (provider.state == detailProv.ResultState.noData) {
return Center(child: Text(provider.message ?? ''));
} else if (provider.state == detailProv.ResultState.error) {
return Center(child: Text(provider.message ?? ''));
} else {
return Container();
}
},
),
),
);
}
Widget listCourse({
String? imageUrl,
String? title,
String? instructor,
String? price,
String? discountPrice,
int? totalPrices,
}) {
return Container(
padding: EdgeInsets.only(
top: getProportionateScreenHeight(6),
bottom: getProportionateScreenHeight(10),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Container(
width: getProportionateScreenWidth(60),
height: getProportionateScreenHeight(30),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(2),
image: DecorationImage(
image: NetworkImage(imageUrl == null || imageUrl.isEmpty
? '$baseUrl/images/default-thumbnail.png'
: imageUrl.startsWith("http")
? imageUrl
: '$baseUrl/uploads/thumbnail/course_thumbnails/$imageUrl'),
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),
),
),
],
),
),
],
),
);
}
}