Compare commits
No commits in common. "0693411cf707a74c9f28d2d6aa6e2fb7e0caaaa2" and "a6e58a8cc02c874925f97a85f45b47dd63b973cf" have entirely different histories.
0693411cf7
...
a6e58a8cc0
@ -41,12 +41,7 @@ class OrderFormBloc extends Bloc<OrderFormEvent, OrderFormState> {
|
|||||||
createOrderWithPayment: (e) async {
|
createOrderWithPayment: (e) async {
|
||||||
Either<OrderFailure, Order> failureOrOrder;
|
Either<OrderFailure, Order> failureOrOrder;
|
||||||
|
|
||||||
emit(
|
emit(state.copyWith(isCreating: true, failureOrCreateOrder: none()));
|
||||||
state.copyWith(
|
|
||||||
isCreatingWithPayment: true,
|
|
||||||
failureOrCreateOrderWithPayment: none(),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
|
|
||||||
final outlet = await _outletRepository.currentOutlet();
|
final outlet = await _outletRepository.currentOutlet();
|
||||||
|
|
||||||
@ -78,8 +73,8 @@ class OrderFormBloc extends Bloc<OrderFormEvent, OrderFormState> {
|
|||||||
|
|
||||||
emit(
|
emit(
|
||||||
state.copyWith(
|
state.copyWith(
|
||||||
isCreatingWithPayment: false,
|
isCreating: false,
|
||||||
failureOrCreateOrderWithPayment: optionOf(failureOrOrder),
|
failureOrCreateOrder: optionOf(failureOrOrder),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|||||||
@ -4,7 +4,6 @@ class CustomModalDialog extends StatelessWidget {
|
|||||||
final String title;
|
final String title;
|
||||||
final String? subtitle;
|
final String? subtitle;
|
||||||
final Widget child;
|
final Widget child;
|
||||||
final Widget? bottom;
|
|
||||||
final VoidCallback? onClose;
|
final VoidCallback? onClose;
|
||||||
final double? minWidth;
|
final double? minWidth;
|
||||||
final double? maxWidth;
|
final double? maxWidth;
|
||||||
@ -23,7 +22,6 @@ class CustomModalDialog extends StatelessWidget {
|
|||||||
this.minHeight,
|
this.minHeight,
|
||||||
this.maxHeight,
|
this.maxHeight,
|
||||||
this.contentPadding,
|
this.contentPadding,
|
||||||
this.bottom,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -98,7 +96,6 @@ class CustomModalDialog extends StatelessWidget {
|
|||||||
child: child,
|
child: child,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
if (bottom != null) bottom!,
|
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|||||||
@ -1,260 +0,0 @@
|
|||||||
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,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,240 +0,0 @@
|
|||||||
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.';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,107 +0,0 @@
|
|||||||
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,7 +5,6 @@ import 'package:flutter_bloc/flutter_bloc.dart';
|
|||||||
import '../../../application/checkout/checkout_form/checkout_form_bloc.dart';
|
import '../../../application/checkout/checkout_form/checkout_form_bloc.dart';
|
||||||
import '../../../application/order/order_form/order_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/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 '../../../common/theme/theme.dart';
|
||||||
import '../../../injection.dart';
|
import '../../../injection.dart';
|
||||||
import '../../components/spaces/space.dart';
|
import '../../components/spaces/space.dart';
|
||||||
@ -20,48 +19,23 @@ class CheckoutPage extends StatelessWidget implements AutoRouteWrapper {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return MultiBlocListener(
|
return BlocListener<OrderFormBloc, OrderFormState>(
|
||||||
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));
|
|
||||||
}
|
|
||||||
},
|
|
||||||
);
|
|
||||||
});
|
|
||||||
},
|
|
||||||
),
|
|
||||||
BlocListener<OrderFormBloc, OrderFormState>(
|
|
||||||
listenWhen: (previous, current) =>
|
listenWhen: (previous, current) =>
|
||||||
previous.failureOrCreateOrder != current.failureOrCreateOrder,
|
previous.failureOrCreateOrder != current.failureOrCreateOrder,
|
||||||
listener: (context, state) {
|
listener: (context, state) {
|
||||||
state.failureOrCreateOrder.fold(() {}, (either) {
|
state.failureOrCreateOrder.fold(() {}, (either) {
|
||||||
either.fold(
|
either.fold((f) => AppFlushbar.showOrderFailureToast(context, f), (
|
||||||
(f) => AppFlushbar.showOrderFailureToast(context, f),
|
order,
|
||||||
(order) {
|
) {
|
||||||
if (context.mounted) {
|
if (context.mounted) {
|
||||||
context.read<CheckoutFormBloc>().add(
|
context.read<CheckoutFormBloc>().add(
|
||||||
CheckoutFormEvent.started([]),
|
CheckoutFormEvent.started([]),
|
||||||
);
|
);
|
||||||
context.router.replace(SuccessOrderRoute(order: order));
|
context.router.replace(SuccessOrderRoute(order: order));
|
||||||
}
|
}
|
||||||
},
|
});
|
||||||
);
|
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
),
|
|
||||||
],
|
|
||||||
child: SafeArea(
|
child: SafeArea(
|
||||||
child: Hero(
|
child: Hero(
|
||||||
tag: 'checkout_screen',
|
tag: 'checkout_screen',
|
||||||
@ -106,18 +80,10 @@ class CheckoutPage extends StatelessWidget implements AutoRouteWrapper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget wrappedRoute(BuildContext context) => MultiBlocProvider(
|
Widget wrappedRoute(BuildContext context) => BlocProvider(
|
||||||
providers: [
|
|
||||||
BlocProvider(
|
|
||||||
create: (context) =>
|
create: (context) =>
|
||||||
getIt<PaymentMethodLoaderBloc>()
|
getIt<PaymentMethodLoaderBloc>()
|
||||||
..add(PaymentMethodLoaderEvent.fetched(isRefresh: true)),
|
..add(PaymentMethodLoaderEvent.fetched(isRefresh: true)),
|
||||||
),
|
|
||||||
BlocProvider(
|
|
||||||
create: (context) => getIt<TableLoaderBloc>()
|
|
||||||
..add(TableLoaderEvent.fetched(isRefresh: true, status: 'available')),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
child: this,
|
child: this,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,16 +1,14 @@
|
|||||||
import 'package:auto_route/auto_route.dart';
|
import 'package:auto_route/auto_route.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/widgets.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
|
|
||||||
import '../../../../application/checkout/checkout_form/checkout_form_bloc.dart';
|
import '../../../../application/checkout/checkout_form/checkout_form_bloc.dart';
|
||||||
import '../../../../application/order/order_form/order_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/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/extension/extension.dart';
|
||||||
import '../../../../common/theme/theme.dart';
|
import '../../../../common/theme/theme.dart';
|
||||||
import '../../../components/button/button.dart';
|
import '../../../components/button/button.dart';
|
||||||
import '../../../components/card/payment_card.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/error/payment_method_error_state_widget.dart';
|
||||||
import '../../../components/field/field.dart';
|
import '../../../components/field/field.dart';
|
||||||
import '../../../components/loader/loader_with_text.dart';
|
import '../../../components/loader/loader_with_text.dart';
|
||||||
@ -278,10 +276,7 @@ class _CheckoutRightPanelState extends State<CheckoutRightPanel> {
|
|||||||
),
|
),
|
||||||
SpaceWidth(12),
|
SpaceWidth(12),
|
||||||
Expanded(
|
Expanded(
|
||||||
child: BlocBuilder<TableLoaderBloc, TableLoaderState>(
|
child: AppElevatedButton.filled(
|
||||||
builder: (context, tableState) {
|
|
||||||
return AppElevatedButton.filled(
|
|
||||||
isLoading: tableState.isFetching,
|
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
if (customerController.text == '') {
|
if (customerController.text == '') {
|
||||||
AppFlushbar.showError(
|
AppFlushbar.showError(
|
||||||
@ -291,24 +286,26 @@ class _CheckoutRightPanelState extends State<CheckoutRightPanel> {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
showDialog(
|
// showDialog(
|
||||||
context: context,
|
// context: context,
|
||||||
builder: (dcontext) => OrderSaveDialog(
|
// builder: (dcontext) => SaveDialog(
|
||||||
checkoutState: widget.checkoutState,
|
// selectedTable: widget.table,
|
||||||
tables: tableState.tables,
|
// customerName: customerController.text,
|
||||||
),
|
// items: items,
|
||||||
);
|
// orderType: orderType,
|
||||||
|
// customer: selectedCustomer,
|
||||||
|
// deliveryModel: delivery,
|
||||||
|
// ),
|
||||||
|
// );
|
||||||
},
|
},
|
||||||
label: 'Simpan',
|
label: 'Simpan',
|
||||||
);
|
|
||||||
},
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
SpaceWidth(12),
|
SpaceWidth(12),
|
||||||
Expanded(
|
Expanded(
|
||||||
child: AppElevatedButton.filled(
|
child: AppElevatedButton.filled(
|
||||||
isLoading: orderState.isCreatingWithPayment,
|
isLoading: orderState.isCreating,
|
||||||
onPressed: orderState.isCreatingWithPayment
|
onPressed: orderState.isCreating
|
||||||
? null
|
? null
|
||||||
: () {
|
: () {
|
||||||
if (customerController.text == '') {
|
if (customerController.text == '') {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user