Compare commits
2 Commits
a6e58a8cc0
...
0693411cf7
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0693411cf7 | ||
|
|
a514a8abdb |
@ -41,7 +41,12 @@ class OrderFormBloc extends Bloc<OrderFormEvent, OrderFormState> {
|
||||
createOrderWithPayment: (e) async {
|
||||
Either<OrderFailure, Order> failureOrOrder;
|
||||
|
||||
emit(state.copyWith(isCreating: true, failureOrCreateOrder: none()));
|
||||
emit(
|
||||
state.copyWith(
|
||||
isCreatingWithPayment: true,
|
||||
failureOrCreateOrderWithPayment: none(),
|
||||
),
|
||||
);
|
||||
|
||||
final outlet = await _outletRepository.currentOutlet();
|
||||
|
||||
@ -73,8 +78,8 @@ class OrderFormBloc extends Bloc<OrderFormEvent, OrderFormState> {
|
||||
|
||||
emit(
|
||||
state.copyWith(
|
||||
isCreating: false,
|
||||
failureOrCreateOrder: optionOf(failureOrOrder),
|
||||
isCreatingWithPayment: false,
|
||||
failureOrCreateOrderWithPayment: optionOf(failureOrOrder),
|
||||
),
|
||||
);
|
||||
},
|
||||
|
||||
@ -4,6 +4,7 @@ class CustomModalDialog extends StatelessWidget {
|
||||
final String title;
|
||||
final String? subtitle;
|
||||
final Widget child;
|
||||
final Widget? bottom;
|
||||
final VoidCallback? onClose;
|
||||
final double? minWidth;
|
||||
final double? maxWidth;
|
||||
@ -22,6 +23,7 @@ class CustomModalDialog extends StatelessWidget {
|
||||
this.minHeight,
|
||||
this.maxHeight,
|
||||
this.contentPadding,
|
||||
this.bottom,
|
||||
});
|
||||
|
||||
@override
|
||||
@ -96,6 +98,7 @@ class CustomModalDialog extends StatelessWidget {
|
||||
child: child,
|
||||
),
|
||||
),
|
||||
if (bottom != null) bottom!,
|
||||
],
|
||||
),
|
||||
),
|
||||
|
||||
@ -0,0 +1,260 @@
|
||||
import 'package:dropdown_search/dropdown_search.dart';
|
||||
import 'package:flutter/material.dart' hide Table;
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
|
||||
import '../../../../application/checkout/checkout_form/checkout_form_bloc.dart';
|
||||
import '../../../../application/order/order_form/order_form_bloc.dart';
|
||||
import '../../../../common/extension/extension.dart';
|
||||
import '../../../../common/theme/theme.dart';
|
||||
import '../../../../domain/table/table.dart';
|
||||
import '../../button/button.dart';
|
||||
import '../../spaces/space.dart';
|
||||
import '../dialog.dart';
|
||||
|
||||
class OrderPayLaterDialog extends StatelessWidget {
|
||||
final List<Table> tables;
|
||||
const OrderPayLaterDialog({super.key, required this.tables});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return BlocBuilder<CheckoutFormBloc, CheckoutFormState>(
|
||||
builder: (context, state) {
|
||||
return CustomModalDialog(
|
||||
title: 'Bayar Nanti',
|
||||
subtitle: 'Simpan pesanan dan bayar nanti',
|
||||
contentPadding: const EdgeInsets.symmetric(
|
||||
horizontal: 16.0,
|
||||
vertical: 24.0,
|
||||
),
|
||||
minWidth: context.deviceWidth * 0.4,
|
||||
minHeight: context.deviceHeight * 0.4,
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
'Pilih Meja',
|
||||
style: AppStyle.md.copyWith(
|
||||
color: AppColor.black,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
const SpaceHeight(6.0),
|
||||
Builder(
|
||||
builder: (context) {
|
||||
if (tables.isEmpty) {
|
||||
return Container(
|
||||
padding: const EdgeInsets.all(16),
|
||||
decoration: BoxDecoration(
|
||||
color: AppColor.warning.withOpacity(0.15),
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
border: Border.all(color: AppColor.warning, width: 1),
|
||||
),
|
||||
child: Text(
|
||||
'Tidak ada meja yang tersedia. Silakan pilih opsi lain.',
|
||||
style: AppStyle.md.copyWith(color: AppColor.warning),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
return DropdownSearch<Table>(
|
||||
items: tables,
|
||||
selectedItem: state.table,
|
||||
|
||||
// Dropdown properties
|
||||
dropdownDecoratorProps: DropDownDecoratorProps(
|
||||
dropdownSearchDecoration: InputDecoration(
|
||||
hintText: "Pilih meja",
|
||||
hintStyle: TextStyle(
|
||||
color: Colors.grey.shade600,
|
||||
fontSize: 14,
|
||||
),
|
||||
prefixIcon: Icon(
|
||||
Icons.category_outlined,
|
||||
color: Colors.grey.shade500,
|
||||
size: 20,
|
||||
),
|
||||
border: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
borderSide: BorderSide(
|
||||
color: Colors.grey.shade300,
|
||||
width: 1.5,
|
||||
),
|
||||
),
|
||||
enabledBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
borderSide: BorderSide(
|
||||
color: Colors.grey.shade300,
|
||||
width: 1.5,
|
||||
),
|
||||
),
|
||||
focusedBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
borderSide: BorderSide(
|
||||
color: Colors.blue.shade400,
|
||||
width: 2,
|
||||
),
|
||||
),
|
||||
filled: true,
|
||||
fillColor: Colors.white,
|
||||
contentPadding: const EdgeInsets.symmetric(
|
||||
horizontal: 16,
|
||||
vertical: 16,
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
// Popup properties
|
||||
popupProps: PopupProps.menu(
|
||||
showSearchBox: true,
|
||||
searchFieldProps: TextFieldProps(
|
||||
decoration: InputDecoration(
|
||||
hintText: "Cari meja...",
|
||||
prefixIcon: const Icon(Icons.search),
|
||||
border: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
),
|
||||
contentPadding: const EdgeInsets.symmetric(
|
||||
horizontal: 16,
|
||||
vertical: 12,
|
||||
),
|
||||
),
|
||||
),
|
||||
menuProps: MenuProps(
|
||||
backgroundColor: Colors.white,
|
||||
elevation: 8,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
),
|
||||
),
|
||||
itemBuilder: (context, category, isSelected) {
|
||||
return Container(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 16,
|
||||
vertical: 12,
|
||||
),
|
||||
decoration: BoxDecoration(
|
||||
color: isSelected
|
||||
? Colors.blue.shade50
|
||||
: Colors.transparent,
|
||||
border: Border(
|
||||
bottom: BorderSide(
|
||||
color: Colors.grey.shade100,
|
||||
width: 0.5,
|
||||
),
|
||||
),
|
||||
),
|
||||
child: Row(
|
||||
children: [
|
||||
Container(
|
||||
width: 8,
|
||||
height: 8,
|
||||
decoration: BoxDecoration(
|
||||
color: isSelected
|
||||
? Colors.blue.shade600
|
||||
: Colors.grey.shade400,
|
||||
shape: BoxShape.circle,
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 12),
|
||||
Expanded(
|
||||
child: Text(
|
||||
category.tableName,
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
fontWeight: isSelected
|
||||
? FontWeight.w600
|
||||
: FontWeight.w500,
|
||||
color: isSelected
|
||||
? Colors.blue.shade700
|
||||
: Colors.black87,
|
||||
),
|
||||
),
|
||||
),
|
||||
if (isSelected)
|
||||
Icon(
|
||||
Icons.check,
|
||||
color: Colors.blue.shade600,
|
||||
size: 18,
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
},
|
||||
emptyBuilder: (context, searchEntry) {
|
||||
return Container(
|
||||
padding: const EdgeInsets.all(20),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Icon(
|
||||
Icons.search_off,
|
||||
color: Colors.grey.shade400,
|
||||
size: 48,
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
Text(
|
||||
searchEntry.isEmpty
|
||||
? "Tidak ada meja tersedia"
|
||||
: "Tidak ditemukan meja dengan '${searchEntry}'",
|
||||
style: TextStyle(
|
||||
color: Colors.grey.shade600,
|
||||
fontSize: 14,
|
||||
),
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
|
||||
// Item as string (for search functionality)
|
||||
itemAsString: (Table table) => table.tableName,
|
||||
|
||||
// Comparison function
|
||||
compareFn: (Table? item1, Table? item2) {
|
||||
return item1?.id == item2?.id;
|
||||
},
|
||||
|
||||
// On changed callback
|
||||
onChanged: (Table? selectedTable) {
|
||||
context.read<CheckoutFormBloc>().add(
|
||||
CheckoutFormEvent.updateTable(selectedTable),
|
||||
);
|
||||
},
|
||||
|
||||
// Validator (optional)
|
||||
validator: (Table? value) {
|
||||
if (value == null) {
|
||||
return "Meja harus dipilih";
|
||||
}
|
||||
return null;
|
||||
},
|
||||
);
|
||||
},
|
||||
),
|
||||
SpaceHeight(24),
|
||||
BlocBuilder<OrderFormBloc, OrderFormState>(
|
||||
builder: (context, orderState) {
|
||||
return AppElevatedButton.filled(
|
||||
label: 'Simpan',
|
||||
isLoading: orderState.isCreating,
|
||||
onPressed: () {
|
||||
context.read<OrderFormBloc>().add(
|
||||
OrderFormEvent.createOrder(
|
||||
items: state.items,
|
||||
orderType: state.orderType,
|
||||
table: state.table,
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,240 @@
|
||||
import 'package:auto_route/auto_route.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
|
||||
import '../../../../application/checkout/checkout_form/checkout_form_bloc.dart';
|
||||
import '../../../../application/order/order_form/order_form_bloc.dart';
|
||||
import '../../../../common/extension/extension.dart';
|
||||
import '../../../../common/theme/theme.dart';
|
||||
import '../../../../common/types/order_type.dart';
|
||||
import '../../button/button.dart';
|
||||
import '../../spaces/space.dart';
|
||||
import '../dialog.dart';
|
||||
|
||||
class OrderSaveConfirmDialog extends StatelessWidget {
|
||||
final CheckoutFormState checkoutState;
|
||||
const OrderSaveConfirmDialog({super.key, required this.checkoutState});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return BlocBuilder<OrderFormBloc, OrderFormState>(
|
||||
builder: (context, state) {
|
||||
return CustomModalDialog(
|
||||
title: 'Konfirmasi Pesanan',
|
||||
subtitle: 'Tindakan ini tidak dapat dibatalkan',
|
||||
contentPadding: const EdgeInsets.symmetric(
|
||||
horizontal: 16.0,
|
||||
vertical: 24.0,
|
||||
),
|
||||
minWidth: context.deviceWidth * 0.5,
|
||||
minHeight: context.deviceHeight * 0.8,
|
||||
bottom: Container(
|
||||
padding: EdgeInsets.all(16),
|
||||
child: Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: AppElevatedButton.outlined(
|
||||
onPressed: () => context.maybePop(),
|
||||
label: 'Batalkan',
|
||||
),
|
||||
),
|
||||
SpaceWidth(12),
|
||||
Expanded(
|
||||
child: AppElevatedButton.filled(
|
||||
isLoading: state.isCreating,
|
||||
onPressed: state.isCreating
|
||||
? null
|
||||
: () {
|
||||
context.read<OrderFormBloc>().add(
|
||||
OrderFormEvent.createOrder(
|
||||
items: checkoutState.items,
|
||||
orderType: checkoutState.orderType,
|
||||
table: checkoutState.table,
|
||||
),
|
||||
);
|
||||
},
|
||||
label: 'Konfirmasi',
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
child: Column(
|
||||
children: [
|
||||
Container(
|
||||
width: double.infinity,
|
||||
padding: EdgeInsets.all(16),
|
||||
decoration: BoxDecoration(
|
||||
color: AppColor.textSecondary.withOpacity(0.05),
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
border: Border.all(color: AppColor.border),
|
||||
),
|
||||
child: Text(
|
||||
message(state.customerName ?? '-'),
|
||||
style: AppStyle.md.copyWith(fontSize: 14, height: 1.4),
|
||||
),
|
||||
),
|
||||
if (checkoutState.items.isNotEmpty) ...[
|
||||
SpaceHeight(16),
|
||||
Container(
|
||||
width: double.infinity,
|
||||
decoration: BoxDecoration(
|
||||
color: AppColor.primaryWithOpacity(0.05),
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
border: Border.all(color: AppColor.primaryWithOpacity(0.2)),
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Padding(
|
||||
padding: EdgeInsets.all(16),
|
||||
child: Row(
|
||||
children: [
|
||||
Container(
|
||||
padding: EdgeInsets.all(6),
|
||||
decoration: BoxDecoration(
|
||||
color: AppColor.primary,
|
||||
borderRadius: BorderRadius.circular(6),
|
||||
),
|
||||
child: Icon(
|
||||
Icons.list_alt_rounded,
|
||||
color: AppColor.white,
|
||||
size: 16,
|
||||
),
|
||||
),
|
||||
SizedBox(width: 8),
|
||||
Text(
|
||||
'Item yang akan dipesan:',
|
||||
style: AppStyle.md.copyWith(
|
||||
fontWeight: FontWeight.bold,
|
||||
color: AppColor.primary,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Container(
|
||||
constraints: BoxConstraints(maxHeight: 120),
|
||||
child: Scrollbar(
|
||||
child: SingleChildScrollView(
|
||||
padding: EdgeInsets.only(
|
||||
left: 16,
|
||||
right: 16,
|
||||
bottom: 16,
|
||||
),
|
||||
child: Column(
|
||||
children: checkoutState.items.map((item) {
|
||||
return Container(
|
||||
margin: EdgeInsets.only(bottom: 6),
|
||||
padding: EdgeInsets.all(10),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(6),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Colors.black.withOpacity(0.03),
|
||||
blurRadius: 2,
|
||||
offset: Offset(0, 1),
|
||||
),
|
||||
],
|
||||
),
|
||||
child: Row(
|
||||
children: [
|
||||
Container(
|
||||
width: 6,
|
||||
height: 6,
|
||||
decoration: BoxDecoration(
|
||||
color: AppColor.primary,
|
||||
shape: BoxShape.circle,
|
||||
),
|
||||
),
|
||||
SizedBox(width: 8),
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment:
|
||||
CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
item.product.name,
|
||||
style: AppStyle.md.copyWith(
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
Text(
|
||||
'${item.quantity} qty',
|
||||
style: AppStyle.sm.copyWith(
|
||||
color: AppColor.textSecondary,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Container(
|
||||
padding: EdgeInsets.symmetric(
|
||||
horizontal: 6,
|
||||
vertical: 2,
|
||||
),
|
||||
decoration: BoxDecoration(
|
||||
color: AppColor.primaryWithOpacity(
|
||||
0.1,
|
||||
),
|
||||
borderRadius: BorderRadius.circular(
|
||||
4,
|
||||
),
|
||||
),
|
||||
child: Text(
|
||||
((item.product.price) * item.quantity)
|
||||
.currencyFormatRpV2,
|
||||
style: AppStyle.md.copyWith(
|
||||
fontWeight: FontWeight.bold,
|
||||
color: AppColor.primary,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}).toList(),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
],
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
String message(String customerName) {
|
||||
switch (checkoutState.orderType) {
|
||||
case OrderType.dineIn:
|
||||
return 'Konfirmasi untuk menyimpan pesanan Dine-In\n\n'
|
||||
'Pesanan untuk ${customerName.isNotEmpty ? customerName : "Pelanggan"} akan disimpan ke dalam sistem. '
|
||||
'Pelanggan dapat langsung menikmati pesanan di meja yang telah disediakan. '
|
||||
'Pastikan semua item pesanan sudah sesuai sebelum menyimpan.';
|
||||
|
||||
case OrderType.delivery:
|
||||
return 'Konfirmasi untuk menyimpan pesanan Delivery\n\n'
|
||||
'Pesanan delivery untuk ${customerName.isNotEmpty ? customerName : "Pelanggan"} akan disimpan. '
|
||||
'${checkoutState.delivery != null ? "Pengiriman: ${checkoutState.delivery?.name ?? "-"}. " : ""}'
|
||||
'Tim delivery akan segera mempersiapkan pesanan.';
|
||||
|
||||
case OrderType.takeAway:
|
||||
return 'Konfirmasi untuk menyimpan pesanan Take Away\n\n'
|
||||
'Pesanan take away untuk ${customerName.isNotEmpty ? customerName : "Pelanggan"} akan disimpan. '
|
||||
'Dapur akan mulai mempersiapkan pesanan dan pelanggan dapat mengambil pesanan sesuai estimasi waktu yang diberikan.';
|
||||
|
||||
case OrderType.freeTable:
|
||||
return 'Konfirmasi untuk menyimpan pesanan Free Table\n\n'
|
||||
'Pesanan free table untuk ${customerName.isNotEmpty ? customerName : "Pelanggan"} akan disimpan. '
|
||||
'Meja akan direservasi dan pesanan akan dipersiapkan sesuai dengan waktu kedatangan pelanggan.';
|
||||
}
|
||||
}
|
||||
}
|
||||
107
lib/presentation/components/dialog/order/order_save_dialog.dart
Normal file
107
lib/presentation/components/dialog/order/order_save_dialog.dart
Normal file
@ -0,0 +1,107 @@
|
||||
import 'package:auto_route/auto_route.dart';
|
||||
import 'package:flutter/material.dart' hide Table;
|
||||
|
||||
import '../../../../application/checkout/checkout_form/checkout_form_bloc.dart';
|
||||
import '../../../../common/theme/theme.dart';
|
||||
import '../../../../common/types/order_type.dart';
|
||||
import '../../../../domain/table/table.dart';
|
||||
import '../../spaces/space.dart';
|
||||
import '../dialog.dart';
|
||||
import 'order_pay_later_dialog.dart';
|
||||
import 'order_save_confirm_dialog.dart';
|
||||
|
||||
class OrderSaveDialog extends StatelessWidget {
|
||||
final CheckoutFormState checkoutState;
|
||||
final List<Table> tables;
|
||||
const OrderSaveDialog({
|
||||
super.key,
|
||||
required this.checkoutState,
|
||||
required this.tables,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return CustomModalDialog(
|
||||
title: 'Pilih Aksi',
|
||||
subtitle: 'Lanjutkan proses pesanan atau simpan untuk nanti.',
|
||||
contentPadding: const EdgeInsets.symmetric(
|
||||
horizontal: 16.0,
|
||||
vertical: 24.0,
|
||||
),
|
||||
child: Column(
|
||||
children: [
|
||||
_item(
|
||||
icon: Icons.schedule_outlined,
|
||||
title: 'Bayar Nanti',
|
||||
subtitle: 'Simpan pesanan dan bayar nanti',
|
||||
onTap: () {
|
||||
context.maybePop();
|
||||
|
||||
if (checkoutState.orderType == OrderType.dineIn) {
|
||||
Future.delayed(Duration(milliseconds: 100), () {
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (context) => OrderPayLaterDialog(tables: tables),
|
||||
);
|
||||
});
|
||||
} else {
|
||||
Future.delayed(Duration(milliseconds: 100), () {
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (context) =>
|
||||
OrderSaveConfirmDialog(checkoutState: checkoutState),
|
||||
);
|
||||
});
|
||||
}
|
||||
},
|
||||
),
|
||||
SpaceHeight(16.0),
|
||||
_item(
|
||||
icon: Icons.shopping_cart_checkout_outlined,
|
||||
title: 'Tambahkan Pesanan',
|
||||
subtitle: 'Tambah item ke daftar pesanan',
|
||||
onTap: () {},
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _item({
|
||||
required IconData icon,
|
||||
required String title,
|
||||
required String subtitle,
|
||||
required Function() onTap,
|
||||
}) {
|
||||
return GestureDetector(
|
||||
onTap: onTap,
|
||||
child: Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16.0, vertical: 12.0),
|
||||
decoration: BoxDecoration(
|
||||
color: AppColor.white,
|
||||
borderRadius: BorderRadius.circular(8.0),
|
||||
border: Border.all(color: AppColor.border, width: 1.0),
|
||||
),
|
||||
child: Row(
|
||||
children: [
|
||||
Icon(icon, color: AppColor.primary, size: 26.0),
|
||||
SpaceWidth(12.0),
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
title,
|
||||
style: AppStyle.md.copyWith(fontWeight: FontWeight.w600),
|
||||
),
|
||||
Text(
|
||||
subtitle,
|
||||
style: AppStyle.md.copyWith(color: AppColor.textSecondary),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -5,6 +5,7 @@ import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import '../../../application/checkout/checkout_form/checkout_form_bloc.dart';
|
||||
import '../../../application/order/order_form/order_form_bloc.dart';
|
||||
import '../../../application/payment_method/payment_method_loader/payment_method_loader_bloc.dart';
|
||||
import '../../../application/table/table_loader/table_loader_bloc.dart';
|
||||
import '../../../common/theme/theme.dart';
|
||||
import '../../../injection.dart';
|
||||
import '../../components/spaces/space.dart';
|
||||
@ -19,23 +20,48 @@ class CheckoutPage extends StatelessWidget implements AutoRouteWrapper {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return BlocListener<OrderFormBloc, OrderFormState>(
|
||||
listenWhen: (previous, current) =>
|
||||
previous.failureOrCreateOrder != current.failureOrCreateOrder,
|
||||
listener: (context, state) {
|
||||
state.failureOrCreateOrder.fold(() {}, (either) {
|
||||
either.fold((f) => AppFlushbar.showOrderFailureToast(context, f), (
|
||||
order,
|
||||
) {
|
||||
if (context.mounted) {
|
||||
context.read<CheckoutFormBloc>().add(
|
||||
CheckoutFormEvent.started([]),
|
||||
return MultiBlocListener(
|
||||
listeners: [
|
||||
BlocListener<OrderFormBloc, OrderFormState>(
|
||||
listenWhen: (previous, current) =>
|
||||
previous.failureOrCreateOrderWithPayment !=
|
||||
current.failureOrCreateOrderWithPayment,
|
||||
listener: (context, state) {
|
||||
state.failureOrCreateOrderWithPayment.fold(() {}, (either) {
|
||||
either.fold(
|
||||
(f) => AppFlushbar.showOrderFailureToast(context, f),
|
||||
(order) {
|
||||
if (context.mounted) {
|
||||
context.read<CheckoutFormBloc>().add(
|
||||
CheckoutFormEvent.started([]),
|
||||
);
|
||||
context.router.replace(SuccessOrderRoute(order: order));
|
||||
}
|
||||
},
|
||||
);
|
||||
context.router.replace(SuccessOrderRoute(order: order));
|
||||
}
|
||||
});
|
||||
});
|
||||
},
|
||||
});
|
||||
},
|
||||
),
|
||||
BlocListener<OrderFormBloc, OrderFormState>(
|
||||
listenWhen: (previous, current) =>
|
||||
previous.failureOrCreateOrder != current.failureOrCreateOrder,
|
||||
listener: (context, state) {
|
||||
state.failureOrCreateOrder.fold(() {}, (either) {
|
||||
either.fold(
|
||||
(f) => AppFlushbar.showOrderFailureToast(context, f),
|
||||
(order) {
|
||||
if (context.mounted) {
|
||||
context.read<CheckoutFormBloc>().add(
|
||||
CheckoutFormEvent.started([]),
|
||||
);
|
||||
context.router.replace(SuccessOrderRoute(order: order));
|
||||
}
|
||||
},
|
||||
);
|
||||
});
|
||||
},
|
||||
),
|
||||
],
|
||||
child: SafeArea(
|
||||
child: Hero(
|
||||
tag: 'checkout_screen',
|
||||
@ -80,10 +106,18 @@ class CheckoutPage extends StatelessWidget implements AutoRouteWrapper {
|
||||
}
|
||||
|
||||
@override
|
||||
Widget wrappedRoute(BuildContext context) => BlocProvider(
|
||||
create: (context) =>
|
||||
getIt<PaymentMethodLoaderBloc>()
|
||||
..add(PaymentMethodLoaderEvent.fetched(isRefresh: true)),
|
||||
Widget wrappedRoute(BuildContext context) => MultiBlocProvider(
|
||||
providers: [
|
||||
BlocProvider(
|
||||
create: (context) =>
|
||||
getIt<PaymentMethodLoaderBloc>()
|
||||
..add(PaymentMethodLoaderEvent.fetched(isRefresh: true)),
|
||||
),
|
||||
BlocProvider(
|
||||
create: (context) => getIt<TableLoaderBloc>()
|
||||
..add(TableLoaderEvent.fetched(isRefresh: true, status: 'available')),
|
||||
),
|
||||
],
|
||||
child: this,
|
||||
);
|
||||
}
|
||||
|
||||
@ -1,14 +1,16 @@
|
||||
import 'package:auto_route/auto_route.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
|
||||
import '../../../../application/checkout/checkout_form/checkout_form_bloc.dart';
|
||||
import '../../../../application/order/order_form/order_form_bloc.dart';
|
||||
import '../../../../application/payment_method/payment_method_loader/payment_method_loader_bloc.dart';
|
||||
import '../../../../application/table/table_loader/table_loader_bloc.dart';
|
||||
import '../../../../common/extension/extension.dart';
|
||||
import '../../../../common/theme/theme.dart';
|
||||
import '../../../components/button/button.dart';
|
||||
import '../../../components/card/payment_card.dart';
|
||||
import '../../../components/dialog/order/order_save_dialog.dart';
|
||||
import '../../../components/error/payment_method_error_state_widget.dart';
|
||||
import '../../../components/field/field.dart';
|
||||
import '../../../components/loader/loader_with_text.dart';
|
||||
@ -276,36 +278,37 @@ class _CheckoutRightPanelState extends State<CheckoutRightPanel> {
|
||||
),
|
||||
SpaceWidth(12),
|
||||
Expanded(
|
||||
child: AppElevatedButton.filled(
|
||||
onPressed: () {
|
||||
if (customerController.text == '') {
|
||||
AppFlushbar.showError(
|
||||
context,
|
||||
'Pilih Pelanggan terlebih dahulu',
|
||||
);
|
||||
return;
|
||||
}
|
||||
child: BlocBuilder<TableLoaderBloc, TableLoaderState>(
|
||||
builder: (context, tableState) {
|
||||
return AppElevatedButton.filled(
|
||||
isLoading: tableState.isFetching,
|
||||
onPressed: () {
|
||||
if (customerController.text == '') {
|
||||
AppFlushbar.showError(
|
||||
context,
|
||||
'Pilih Pelanggan terlebih dahulu',
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
// showDialog(
|
||||
// context: context,
|
||||
// builder: (dcontext) => SaveDialog(
|
||||
// selectedTable: widget.table,
|
||||
// customerName: customerController.text,
|
||||
// items: items,
|
||||
// orderType: orderType,
|
||||
// customer: selectedCustomer,
|
||||
// deliveryModel: delivery,
|
||||
// ),
|
||||
// );
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (dcontext) => OrderSaveDialog(
|
||||
checkoutState: widget.checkoutState,
|
||||
tables: tableState.tables,
|
||||
),
|
||||
);
|
||||
},
|
||||
label: 'Simpan',
|
||||
);
|
||||
},
|
||||
label: 'Simpan',
|
||||
),
|
||||
),
|
||||
SpaceWidth(12),
|
||||
Expanded(
|
||||
child: AppElevatedButton.filled(
|
||||
isLoading: orderState.isCreating,
|
||||
onPressed: orderState.isCreating
|
||||
isLoading: orderState.isCreatingWithPayment,
|
||||
onPressed: orderState.isCreatingWithPayment
|
||||
? null
|
||||
: () {
|
||||
if (customerController.text == '') {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user