order page

This commit is contained in:
efrilm
2025-10-27 21:55:19 +07:00
parent b8eefcbac0
commit 8bd61eb58e
38 changed files with 8795 additions and 89 deletions
@@ -0,0 +1,71 @@
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 '../../../application/order/order_loader/order_loader_bloc.dart';
import '../../../common/theme/theme.dart';
import '../../../injection.dart';
import 'widgets/order_left_panel.dart';
import 'widgets/order_right_panel.dart';
@RoutePage()
class OrderPage extends StatelessWidget implements AutoRouteWrapper {
final String status;
const OrderPage({super.key, required this.status});
@override
Widget build(BuildContext context) {
return MultiBlocListener(
listeners: [
BlocListener<OrderLoaderBloc, OrderLoaderState>(
listenWhen: (previous, current) =>
previous.startDate != current.startDate ||
previous.endDate != current.endDate,
listener: (context, state) {
context.read<OrderLoaderBloc>().add(
OrderLoaderEvent.fetched(status: status, isRefresh: true),
);
},
),
BlocListener<OrderLoaderBloc, OrderLoaderState>(
listenWhen: (previous, current) => previous.search != current.search,
listener: (context, state) {
context.read<OrderLoaderBloc>().add(
OrderLoaderEvent.fetched(status: status, isRefresh: true),
);
},
),
],
child: SafeArea(
child: Scaffold(
backgroundColor: AppColor.background,
body: BlocBuilder<OrderLoaderBloc, OrderLoaderState>(
builder: (context, state) {
return Row(
children: [
Expanded(
flex: 2,
child: Material(
color: AppColor.white,
child: OrderLeftPanel(state: state, status: status),
),
),
Expanded(flex: 4, child: OrderRightPanel(state: state)),
],
);
},
),
),
),
);
}
@override
Widget wrappedRoute(BuildContext context) => BlocProvider(
create: (context) =>
getIt<OrderLoaderBloc>()
..add(OrderLoaderEvent.fetched(status: status, isRefresh: true)),
child: this,
);
}
@@ -0,0 +1,130 @@
import 'package:flutter/material.dart';
import '../../../../common/extension/extension.dart';
import '../../../../common/theme/theme.dart';
import '../../../../domain/order/order.dart';
import '../../../components/spaces/space.dart';
class OrderInformation extends StatelessWidget {
final Order? order;
const OrderInformation({super.key, this.order});
@override
Widget build(BuildContext context) {
return Container(
width: double.infinity,
padding: const EdgeInsets.all(16),
decoration: BoxDecoration(
color: AppColor.primary,
borderRadius: BorderRadius.circular(8),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
order?.orderNumber ?? "",
style: const TextStyle(
color: Colors.white,
fontSize: 18,
fontWeight: FontWeight.bold,
),
),
_buildStatus(),
],
),
const SizedBox(height: 8),
Row(
children: [
if (order?.orderType == 'dineIn') ...[
_buildRowItem(
Icons.table_restaurant_outlined,
'Meja ${order?.tableNumber}',
),
const SizedBox(width: 16),
],
_buildRowItem(Icons.restaurant_outlined, '${order?.orderType}'),
],
),
const SizedBox(height: 8),
Text(
'Pelanggan: ${order?.metadata['customer_name'] ?? ""}',
style: const TextStyle(color: Colors.white, fontSize: 14),
),
Text(
'Dibuat: ${order?.createdAt.toFormattedDateTime() ?? ""}',
style: const TextStyle(color: Colors.white70, fontSize: 12),
),
],
),
);
}
Row _buildRowItem(IconData icon, String title) {
return Row(
children: [
Icon(icon, color: Colors.white70, size: 16),
const SpaceWidth(4),
Text(
title,
style: const TextStyle(color: Colors.white70, fontSize: 14),
),
],
);
}
Container _buildStatus() {
switch (order?.status) {
case 'pending':
return Container(
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 4),
decoration: BoxDecoration(
color: Colors.orange,
borderRadius: BorderRadius.circular(12),
),
child: Text(
(order?.status ?? "").toUpperCase(),
style: TextStyle(
color: Colors.white,
fontSize: 12,
fontWeight: FontWeight.bold,
),
),
);
case 'completed':
return Container(
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 4),
decoration: BoxDecoration(
color: Colors.greenAccent,
borderRadius: BorderRadius.circular(12),
),
child: Text(
(order?.status ?? "").toUpperCase(),
style: TextStyle(
color: Colors.white,
fontSize: 12,
fontWeight: FontWeight.bold,
),
),
);
default:
return Container(
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 4),
decoration: BoxDecoration(
color: Colors.grey,
borderRadius: BorderRadius.circular(12),
),
child: Text(
(order?.status ?? "").toUpperCase(),
style: TextStyle(
color: Colors.white,
fontSize: 12,
fontWeight: FontWeight.bold,
),
),
);
}
}
}
@@ -0,0 +1,71 @@
import 'package:flutter/widgets.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import '../../../../application/order/order_loader/order_loader_bloc.dart';
import '../../../../common/theme/theme.dart';
import '../../../components/card/order_card.dart';
import '../../../components/error/order_loader_error_state_widget.dart';
import '../../../components/loader/loader_with_text.dart';
import 'order_title.dart';
class OrderLeftPanel extends StatelessWidget {
final String status;
final OrderLoaderState state;
const OrderLeftPanel({super.key, required this.state, required this.status});
@override
Widget build(BuildContext context) {
return Column(
children: [
OrderTitle(
startDate: state.startDate,
endDate: state.endDate,
title: status == 'pending' ? "Pending Pesanan" : "Daftar Pesanan",
onChanged: (value) {
Future.delayed(const Duration(milliseconds: 800), () {
context.read<OrderLoaderBloc>().add(
OrderLoaderEvent.searchChange(value),
);
});
},
onDateRangeChanged: (start, end) {
context.read<OrderLoaderBloc>().add(
OrderLoaderEvent.dateTimeRangeChange(start!, end!),
);
},
),
Expanded(
child: state.failureOption.fold(() {
if (state.isFetching) {
return Center(child: LoaderWithText());
}
if (state.orders.isEmpty) {
return Center(
child: Text(
"Belum ada transaksi saat ini. ",
style: AppStyle.lg.copyWith(fontWeight: FontWeight.bold),
),
);
}
return ListView.builder(
itemCount: state.orders.length,
itemBuilder: (context, index) => GestureDetector(
onTap: () {
context.read<OrderLoaderBloc>().add(
OrderLoaderEvent.setSelectedOrder(state.orders[index]),
);
},
child: OrderCard(
order: state.orders[index],
isActive: state.orders[index] == state.selectedOrder,
),
),
);
}, (f) => OrderLoaderErrorStateWidget(failure: f, status: status)),
),
],
);
}
}
@@ -0,0 +1,357 @@
import 'package:flutter/material.dart';
import '../../../../common/extension/extension.dart';
import '../../../../common/theme/theme.dart';
import '../../../../domain/order/order.dart';
import '../../../components/spaces/space.dart';
class OrderList extends StatelessWidget {
final Order? order;
const OrderList({super.key, this.order});
@override
Widget build(BuildContext context) {
return Container(
margin: const EdgeInsets.only(top: 16),
decoration: BoxDecoration(
color: AppColor.white,
borderRadius: BorderRadius.circular(16),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
_buildHeader(context),
const SpaceHeight(8),
_buildItemsList(context),
const SpaceHeight(8),
],
),
);
}
Widget _buildHeader(BuildContext context) {
return Container(
padding: const EdgeInsets.all(20),
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [
AppColor.primary.withOpacity(0.1),
AppColor.primary.withOpacity(0.05),
],
begin: Alignment.topLeft,
end: Alignment.bottomRight,
),
borderRadius: const BorderRadius.only(
topLeft: Radius.circular(16),
topRight: Radius.circular(16),
),
border: Border(
bottom: BorderSide(
color: AppColor.primary.withOpacity(0.1),
width: 1,
),
),
),
child: Row(
children: [
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Daftar Pembelian',
style: AppStyle.xl.copyWith(
fontWeight: FontWeight.w700,
letterSpacing: -0.5,
),
),
const SizedBox(height: 4),
Text(
'${order?.orderItems.length ?? 0} item',
style: TextStyle(
color: Colors.grey.shade600,
fontSize: 14,
fontWeight: FontWeight.w500,
),
),
],
),
),
Container(
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 6),
decoration: BoxDecoration(
color: AppColor.primary.withOpacity(0.1),
borderRadius: BorderRadius.circular(20),
border: Border.all(color: AppColor.primary.withOpacity(0.2)),
),
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
Icon(
Icons.shopping_cart_outlined,
size: 16,
color: AppColor.primary,
),
const SizedBox(width: 4),
Text(
'Order',
style: AppStyle.sm.copyWith(
fontSize: 12,
fontWeight: FontWeight.w600,
),
),
],
),
),
],
),
);
}
Widget _buildItemsList(BuildContext context) {
return Column(
children: List.generate(order?.orderItems.length ?? 0, (index) {
final item = order!.orderItems[index];
return _buildItem(context, item, index);
}).toList(),
);
}
Widget _buildItem(BuildContext context, OrderItem product, int index) {
return AnimatedContainer(
duration: const Duration(milliseconds: 200),
margin: const EdgeInsets.symmetric(horizontal: 16, vertical: 4),
decoration: BoxDecoration(
color: AppColor.white,
borderRadius: BorderRadius.circular(12),
border: Border.all(color: Colors.grey.shade200, width: 1),
),
child: Padding(
padding: const EdgeInsets.all(16),
child: Column(
children: [
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded(
child: Text(
product.productName,
style: const TextStyle(
fontSize: 16,
fontWeight: FontWeight.w600,
letterSpacing: -0.2,
),
),
),
_buildStatusBadge(product.status),
],
),
if (product.productVariantName != '') ...[
const SizedBox(height: 4),
Container(
padding: const EdgeInsets.symmetric(
horizontal: 8,
vertical: 4,
),
decoration: BoxDecoration(
color: Colors.grey.shade100,
borderRadius: BorderRadius.circular(6),
),
child: Text(
product.productVariantName,
style: TextStyle(
fontSize: 12,
fontWeight: FontWeight.w500,
color: Colors.grey.shade700,
),
),
),
],
const SizedBox(height: 12),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Harga Satuan',
style: TextStyle(
fontSize: 12,
color: Colors.grey.shade600,
fontWeight: FontWeight.w500,
),
),
const SizedBox(height: 2),
Text(
(product.unitPrice)
.toString()
.currencyFormatRpV2,
style: const TextStyle(
fontSize: 14,
fontWeight: FontWeight.w600,
),
),
],
),
Container(
padding: const EdgeInsets.symmetric(
horizontal: 12,
vertical: 6,
),
decoration: BoxDecoration(
color: AppColor.primary.withOpacity(0.1),
borderRadius: BorderRadius.circular(8),
),
child: Text(
'x${product.quantity}',
style: AppStyle.md.copyWith(
fontWeight: FontWeight.w600,
color: AppColor.primary,
),
),
),
Column(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
Text(
'Total',
style: AppStyle.sm.copyWith(
color: Colors.grey.shade600,
fontWeight: FontWeight.w500,
),
),
const SizedBox(height: 2),
Text(
(product.totalPrice)
.toString()
.currencyFormatRpV2,
style: AppStyle.lg.copyWith(
fontWeight: FontWeight.w700,
color: AppColor.primary,
),
),
],
),
],
),
],
),
),
],
),
if (order?.splitType == 'ITEM' && order?.status == 'pending') ...[
SpaceHeight(6),
Align(
alignment: Alignment.centerRight,
child: Container(
padding: const EdgeInsets.symmetric(
horizontal: 10,
vertical: 4,
),
decoration: BoxDecoration(
color: AppColor.primary.withOpacity(0.2),
borderRadius: BorderRadius.circular(8),
border: Border.all(color: AppColor.primary),
),
child: RichText(
text: TextSpan(
children: [
TextSpan(
text: '${product.paidQuantity} ',
style: AppStyle.sm.copyWith(
fontWeight: FontWeight.w600,
color: AppColor.primary,
),
),
TextSpan(
text: 'dari ',
style: AppStyle.sm.copyWith(color: AppColor.primary),
),
TextSpan(
text: '${product.quantity} ',
style: AppStyle.sm.copyWith(
fontWeight: FontWeight.w600,
color: AppColor.primary,
),
),
TextSpan(
text: 'kuantiti telah dibayar.',
style: AppStyle.sm.copyWith(color: AppColor.primary),
),
],
),
),
),
),
],
],
),
),
);
}
Widget _buildStatusBadge(String? status) {
Color backgroundColor;
Color textColor;
String displayText;
IconData icon;
switch (status) {
case "pending":
backgroundColor = Colors.white;
textColor = Colors.white;
displayText = "Pending";
icon = Icons.access_time;
break;
case "cancelled":
backgroundColor = Colors.red.withOpacity(0.1);
textColor = Colors.red.shade700;
displayText = "Batal";
icon = Icons.cancel_outlined;
break;
case "refund":
backgroundColor = Colors.purple.withOpacity(0.1);
textColor = Colors.purple.shade700;
displayText = "Refund";
icon = Icons.undo;
break;
default:
backgroundColor = Colors.green.withOpacity(0.1);
textColor = Colors.green.shade700;
displayText = "Selesai";
icon = Icons.check_circle_outline;
}
return Container(
padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 6),
decoration: BoxDecoration(
color: backgroundColor,
borderRadius: BorderRadius.circular(20),
border: Border.all(color: textColor.withOpacity(0.2)),
),
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
Icon(icon, size: 14, color: textColor),
const SizedBox(width: 4),
Text(
displayText,
style: TextStyle(
fontSize: 12,
fontWeight: FontWeight.w600,
color: textColor,
),
),
],
),
);
}
}
@@ -0,0 +1,166 @@
import 'package:flutter/material.dart';
import '../../../../common/extension/extension.dart';
import '../../../../common/theme/theme.dart';
import '../../../../domain/order/order.dart';
import '../../../components/spaces/space.dart';
class OrderListPayment extends StatelessWidget {
final Order? order;
const OrderListPayment({super.key, this.order});
@override
Widget build(BuildContext context) {
return Container(
width: double.infinity,
padding: const EdgeInsets.all(16),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(8),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
'Informasi Pembayaran',
style: AppStyle.lg.copyWith(
fontWeight: FontWeight.bold,
color: AppColor.primary,
),
),
_buildPaymentStatus(),
],
),
const SpaceHeight(12),
...List.generate(
order?.payments.length ?? 0,
(index) => Padding(
padding: const EdgeInsets.only(bottom: 8.0),
child: _buildPaymentItem(
order?.payments[index] ?? PaymentOrder.empty(),
),
),
),
const SpaceHeight(4),
const Divider(),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
'Jumlah yang Dibayar',
style: AppStyle.md.copyWith(color: Colors.grey.shade700),
),
Text(
(order?.totalPaid ?? 0).currencyFormatRpV2,
style: TextStyle(fontWeight: FontWeight.w500),
),
],
),
if (((order?.totalAmount ?? 0) - (order?.totalPaid ?? 0)) != 0) ...[
const SpaceHeight(4),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
'Sisa Tagihan',
style: TextStyle(
color: Colors.red.shade700,
fontWeight: FontWeight.w500,
),
),
Text(
((order?.totalAmount ?? 0) - (order?.totalPaid ?? 0))
.currencyFormatRpV2,
style: TextStyle(
color: Colors.red.shade700,
fontWeight: FontWeight.w500,
),
),
],
),
],
],
),
);
}
Container _buildPaymentStatus() {
switch (order?.paymentStatus) {
case 'completed':
return Container(
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4),
decoration: BoxDecoration(
color: AppColor.success.withOpacity(0.2),
borderRadius: BorderRadius.circular(4),
),
child: Text(
(order?.paymentStatus ?? "").toTitleCase(),
style: AppStyle.xs.copyWith(
fontSize: 10,
fontWeight: FontWeight.bold,
color: AppColor.success,
),
),
);
default:
return Container(
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4),
decoration: BoxDecoration(
color: Colors.amber.shade100,
borderRadius: BorderRadius.circular(4),
),
child: Text(
(order?.paymentStatus ?? "").toTitleCase(),
style: AppStyle.xs.copyWith(
fontSize: 10,
fontWeight: FontWeight.bold,
color: Colors.amber.shade800,
),
),
);
}
}
Row _buildPaymentItem(PaymentOrder payment) {
return Row(
children: [
Container(
width: 32,
height: 32,
decoration: BoxDecoration(
color: Colors.green.shade100,
borderRadius: BorderRadius.circular(4),
),
child: Icon(Icons.payments, color: Colors.green.shade700, size: 16),
),
const SizedBox(width: 12),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
payment.paymentMethodName,
style: AppStyle.md.copyWith(fontWeight: FontWeight.w500),
),
if ((payment.splitTotal) > 1)
Text(
'Split ${payment.splitNumber} of ${payment.splitTotal}',
style: AppStyle.md.copyWith(color: Colors.grey.shade600),
),
],
),
),
Text(
(payment.amount).currencyFormatRpV2,
style: AppStyle.md.copyWith(
fontWeight: FontWeight.w600,
color: AppColor.success,
),
),
],
);
}
}
@@ -0,0 +1,88 @@
import 'package:flutter/material.dart';
import '../../../../common/extension/extension.dart';
import '../../../../common/theme/theme.dart';
import '../../../../domain/order/order.dart';
import '../../../components/border/dashed_border.dart';
import '../../../components/spaces/space.dart';
class OrderPaymentSummary extends StatelessWidget {
final Order? order;
const OrderPaymentSummary({super.key, this.order});
@override
Widget build(BuildContext context) {
return Container(
width: double.infinity,
padding: const EdgeInsets.all(16),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(8),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Ringkasan Pembayaran',
style: AppStyle.lg.copyWith(
fontWeight: FontWeight.bold,
color: AppColor.primary,
),
),
const SpaceHeight(12),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
'Subtotal',
style: AppStyle.md.copyWith(color: Colors.grey.shade700),
),
Text((order?.subtotal ?? 0).currencyFormatRpV2),
],
),
const SpaceHeight(4),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
'Tax',
style: AppStyle.md.copyWith(color: Colors.grey.shade700),
),
Text((order?.taxAmount ?? 0).currencyFormatRpV2),
],
),
const SpaceHeight(4),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
'Discount',
style: AppStyle.md.copyWith(color: Colors.grey.shade700),
),
Text((order?.discountAmount ?? 0).currencyFormatRpV2),
],
),
const SpaceHeight(8),
const DashedDivider(color: AppColor.border),
const SpaceHeight(8),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
const Text(
'Total',
style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold),
),
Text(
(order?.totalAmount ?? 0).currencyFormatRpV2,
style: AppStyle.lg.copyWith(
fontWeight: FontWeight.bold,
color: AppColor.primary,
),
),
],
),
],
),
);
}
}
@@ -0,0 +1,114 @@
import 'package:flutter/material.dart';
import '../../../../application/order/order_loader/order_loader_bloc.dart';
import '../../../../common/theme/theme.dart';
import '../../../components/button/button.dart';
import '../../../components/spaces/space.dart';
import 'order_information.dart';
import 'order_list.dart';
import 'order_list_payment.dart';
import 'order_payment_summary.dart';
class OrderRightPanel extends StatelessWidget {
final OrderLoaderState state;
const OrderRightPanel({super.key, required this.state});
@override
Widget build(BuildContext context) {
if (state.selectedOrder == null) {
return Center(
child: Text(
"Belum ada order yang dipilih.",
style: AppStyle.lg.copyWith(fontWeight: FontWeight.bold),
),
);
}
return Column(
children: [
Expanded(
child: SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
OrderInformation(order: state.selectedOrder),
OrderList(order: state.selectedOrder),
const SpaceHeight(16),
OrderPaymentSummary(order: state.selectedOrder),
const SpaceHeight(16),
if (state.selectedOrder?.payments != null &&
state.selectedOrder?.payments.isNotEmpty == true) ...[
OrderListPayment(order: state.selectedOrder),
const SpaceHeight(20),
],
],
),
),
),
),
Container(
padding: EdgeInsets.all(16),
decoration: BoxDecoration(color: AppColor.white),
child: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
AppElevatedButton.outlined(
onPressed: () {
if (state.selectedOrder?.status == 'completed') {
// onPrintRecipt(
// context,
// order: orderDetail!,
// paymentMethod:
// orderDetail!.payments
// ?.map((p) => p.paymentMethodName)
// .join(', ') ??
// "",
// nominalBayar: orderDetail?.totalPaid ?? 0,
// kembalian: 0,
// productQuantity: orderDetail!.orderItems!
// .toProductQuantities(),
// );
} else {
// onPrintBill(
// context,
// productQuantity: orderDetail!.orderItems!
// .toProductQuantities(),
// order: orderDetail!,
// );
}
},
label: 'Print Bill',
icon: Icon(Icons.print),
),
SpaceWidth(8),
if (state.selectedOrder?.status == 'pending') ...[
AppElevatedButton.outlined(
onPressed: () {},
label: 'Void',
icon: Icon(Icons.undo),
),
SpaceWidth(8),
AppElevatedButton.outlined(
onPressed: () {
// context.push(SplitBillPage(order: orderDetail!));
},
label: 'Split Bill',
icon: Icon(Icons.calculate_outlined),
),
SpaceWidth(8),
AppElevatedButton.filled(
width: 120,
onPressed: () {},
label: 'Bayar',
icon: Icon(Icons.payment, color: Colors.white),
),
],
],
),
),
],
);
}
}
@@ -0,0 +1,93 @@
import 'package:flutter/material.dart';
import '../../../../common/extension/extension.dart';
import '../../../../common/theme/theme.dart';
import '../../../components/field/field.dart';
import '../../../components/page/page_title.dart';
import '../../../components/picker/date_range_picker.dart';
import '../../../components/spaces/space.dart';
class OrderTitle extends StatelessWidget {
final String title;
final DateTime startDate;
final DateTime endDate;
final Function(String) onChanged;
final void Function(DateTime? start, DateTime? end) onDateRangeChanged;
const OrderTitle({
super.key,
required this.title,
required this.startDate,
required this.endDate,
required this.onChanged,
required this.onDateRangeChanged,
});
@override
Widget build(BuildContext context) {
return PageTitle(
title: title,
bottom: Container(
padding: const EdgeInsets.symmetric(horizontal: 16.0, vertical: 12.0),
decoration: BoxDecoration(
color: AppColor.white,
border: Border(
bottom: BorderSide(color: AppColor.border, width: 1.0),
),
),
child: Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
startDate.toFormattedDate() == endDate.toFormattedDate()
? startDate.toFormattedDate()
: '${startDate.toFormattedDate()} - ${endDate.toFormattedDate()}',
style: AppStyle.md.copyWith(fontWeight: FontWeight.w600),
),
Text(
'0 Pesanan',
style: AppStyle.md.copyWith(fontWeight: FontWeight.w600),
),
],
),
SpaceHeight(16),
Row(
children: [
Expanded(
child: AppTextFormField(
onChanged: onChanged,
label: 'Cari Pesanan',
showLabel: false,
),
),
SpaceWidth(12),
GestureDetector(
onTap: () => DateRangePickerModal.show(
context: context,
initialStartDate: startDate,
initialEndDate: endDate,
primaryColor: AppColor.primary,
onChanged: onDateRangeChanged,
),
child: Container(
padding: const EdgeInsets.all(12),
decoration: BoxDecoration(
color: AppColor.primary,
borderRadius: BorderRadius.circular(12),
),
child: Icon(
Icons.filter_list_outlined,
color: AppColor.white,
size: 24,
),
),
),
],
),
],
),
),
);
}
}