From 2d596a25b91dcf8d6081bff7ddabf78366e79cdb Mon Sep 17 00:00:00 2001 From: efrilm Date: Fri, 29 Aug 2025 19:08:18 +0700 Subject: [PATCH] feat: order detail --- .../main/pages/order/widgets/order_card.dart | 37 +- .../order/order_detail/order_detail_page.dart | 905 ++++++++++++++++++ lib/presentation/router/app_router.dart | 3 + lib/presentation/router/app_router.gr.dart | 263 ++--- 4 files changed, 1076 insertions(+), 132 deletions(-) create mode 100644 lib/presentation/pages/order/order_detail/order_detail_page.dart diff --git a/lib/presentation/pages/main/pages/order/widgets/order_card.dart b/lib/presentation/pages/main/pages/order/widgets/order_card.dart index 15efd3c..f874667 100644 --- a/lib/presentation/pages/main/pages/order/widgets/order_card.dart +++ b/lib/presentation/pages/main/pages/order/widgets/order_card.dart @@ -1,7 +1,9 @@ +import 'package:auto_route/auto_route.dart'; import 'package:flutter/material.dart'; import 'package:intl/intl.dart'; import '../../../../../../common/theme/theme.dart'; +import '../../../../../router/app_router.gr.dart'; import '../order_page.dart'; class OrderCard extends StatelessWidget { @@ -10,22 +12,21 @@ class OrderCard extends StatelessWidget { @override Widget build(BuildContext context) { - return Container( - margin: const EdgeInsets.only(bottom: 16), - decoration: BoxDecoration( - color: AppColor.white, - borderRadius: BorderRadius.circular(16), - boxShadow: [ - BoxShadow( - color: AppColor.black.withOpacity(0.06), - blurRadius: 16, - offset: const Offset(0, 3), - ), - ], - ), - child: InkWell( - onTap: () => _showOrderDetail(order), - borderRadius: BorderRadius.circular(16), + return GestureDetector( + onTap: () => context.router.push(OrderDetailRoute(order: order)), + child: Container( + margin: const EdgeInsets.only(bottom: 16), + decoration: BoxDecoration( + color: AppColor.white, + borderRadius: BorderRadius.circular(16), + boxShadow: [ + BoxShadow( + color: AppColor.black.withOpacity(0.06), + blurRadius: 16, + offset: const Offset(0, 3), + ), + ], + ), child: Padding( padding: const EdgeInsets.all(18), child: Column( @@ -325,8 +326,4 @@ class OrderCard extends StatelessWidget { final formatter = NumberFormat('#,###'); return formatter.format(amount); } - - void _showOrderDetail(Order order) { - // Implementation for showing order details - } } diff --git a/lib/presentation/pages/order/order_detail/order_detail_page.dart b/lib/presentation/pages/order/order_detail/order_detail_page.dart new file mode 100644 index 0000000..1c2d99f --- /dev/null +++ b/lib/presentation/pages/order/order_detail/order_detail_page.dart @@ -0,0 +1,905 @@ +import 'package:auto_route/auto_route.dart'; +import 'package:flutter/material.dart'; + +import '../../../../../common/theme/theme.dart'; +import '../../main/pages/order/order_page.dart'; + +@RoutePage() +class OrderDetailPage extends StatefulWidget { + final Order order; + + const OrderDetailPage({super.key, required this.order}); + + @override + State createState() => _OrderDetailPageState(); +} + +class _OrderDetailPageState extends State { + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: AppColor.white, + appBar: _buildAppBar(), + body: SingleChildScrollView( + padding: const EdgeInsets.all(16), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + _buildOrderHeader(), + const SizedBox(height: 24), + _buildCustomerInfo(), + const SizedBox(height: 24), + _buildOrderItems(), + const SizedBox(height: 24), + _buildOrderSummary(), + if (widget.order.notes != null) ...[ + const SizedBox(height: 24), + _buildOrderNotes(), + ], + const SizedBox(height: 32), + _buildActionButtons(), + const SizedBox(height: 16), + ], + ), + ), + ); + } + + PreferredSizeWidget _buildAppBar() { + return AppBar( + elevation: 0, + backgroundColor: AppColor.white, + leading: IconButton( + onPressed: () => context.router.back(), + icon: const Icon(Icons.arrow_back, color: AppColor.textPrimary), + ), + title: Text( + 'Detail Pesanan', + style: AppStyle.lg.copyWith( + fontWeight: FontWeight.bold, + color: AppColor.textPrimary, + ), + ), + actions: [ + IconButton( + onPressed: _shareOrder, + icon: const Icon(Icons.share, color: AppColor.textSecondary), + ), + PopupMenuButton( + onSelected: _handleMenuAction, + icon: const Icon(Icons.more_vert, color: AppColor.textSecondary), + itemBuilder: (context) => [ + const PopupMenuItem( + value: 'edit', + child: Row( + children: [ + Icon(Icons.edit, size: 20), + SizedBox(width: 12), + Text('Edit Pesanan'), + ], + ), + ), + const PopupMenuItem( + value: 'duplicate', + child: Row( + children: [ + Icon(Icons.content_copy, size: 20), + SizedBox(width: 12), + Text('Duplikat Pesanan'), + ], + ), + ), + const PopupMenuItem( + value: 'delete', + child: Row( + children: [ + Icon(Icons.delete, size: 20, color: Colors.red), + SizedBox(width: 12), + Text('Hapus Pesanan', style: TextStyle(color: Colors.red)), + ], + ), + ), + ], + ), + ], + ); + } + + Widget _buildOrderHeader() { + return Container( + padding: const EdgeInsets.all(20), + decoration: BoxDecoration( + color: AppColor.background, + borderRadius: BorderRadius.circular(12), + border: Border.all(color: AppColor.border), + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + widget.order.id, + style: AppStyle.lg.copyWith( + fontWeight: FontWeight.bold, + color: AppColor.textPrimary, + ), + ), + _buildStatusBadge(widget.order.status), + ], + ), + const SizedBox(height: 12), + Row( + children: [ + Icon(Icons.access_time, size: 16, color: AppColor.textSecondary), + const SizedBox(width: 8), + Text( + _formatDateTime(widget.order.orderDate), + style: AppStyle.sm.copyWith(color: AppColor.textSecondary), + ), + ], + ), + ], + ), + ); + } + + Widget _buildStatusBadge(OrderStatus status) { + Color backgroundColor; + Color textColor; + String text; + + switch (status) { + case OrderStatus.pending: + backgroundColor = Colors.orange.withOpacity(0.1); + textColor = Colors.orange; + text = 'Menunggu'; + break; + case OrderStatus.processing: + backgroundColor = Colors.blue.withOpacity(0.1); + textColor = Colors.blue; + text = 'Diproses'; + break; + case OrderStatus.completed: + backgroundColor = Colors.green.withOpacity(0.1); + textColor = Colors.green; + text = 'Selesai'; + break; + case OrderStatus.cancelled: + backgroundColor = Colors.red.withOpacity(0.1); + textColor = Colors.red; + text = 'Dibatalkan'; + break; + } + + return Container( + padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 6), + decoration: BoxDecoration( + color: backgroundColor, + borderRadius: BorderRadius.circular(20), + ), + child: Text( + text, + style: AppStyle.sm.copyWith( + fontWeight: FontWeight.w600, + color: textColor, + ), + ), + ); + } + + Widget _buildCustomerInfo() { + return Container( + padding: const EdgeInsets.all(20), + decoration: BoxDecoration( + color: AppColor.background, + borderRadius: BorderRadius.circular(12), + border: Border.all(color: AppColor.border), + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + 'Informasi Pelanggan', + style: AppStyle.md.copyWith( + fontWeight: FontWeight.bold, + color: AppColor.textPrimary, + ), + ), + const SizedBox(height: 16), + _buildInfoRow( + icon: Icons.person, + label: 'Nama', + value: widget.order.customerName, + ), + if (widget.order.phoneNumber != null) ...[ + const SizedBox(height: 12), + _buildInfoRow( + icon: Icons.phone, + label: 'Telepon', + value: widget.order.phoneNumber!, + isClickable: true, + ), + ], + if (widget.order.address != null) ...[ + const SizedBox(height: 12), + _buildInfoRow( + icon: Icons.location_on, + label: 'Alamat', + value: widget.order.address!, + isMultiline: true, + ), + ], + ], + ), + ); + } + + Widget _buildInfoRow({ + required IconData icon, + required String label, + required String value, + bool isClickable = false, + bool isMultiline = false, + }) { + return Row( + crossAxisAlignment: isMultiline + ? CrossAxisAlignment.start + : CrossAxisAlignment.center, + children: [ + Container( + padding: const EdgeInsets.all(8), + decoration: BoxDecoration( + color: AppColor.primary.withOpacity(0.1), + borderRadius: BorderRadius.circular(8), + ), + child: Icon(icon, size: 18, color: AppColor.primary), + ), + const SizedBox(width: 12), + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + label, + style: AppStyle.xs.copyWith( + color: AppColor.textSecondary, + fontWeight: FontWeight.w500, + ), + ), + const SizedBox(height: 2), + GestureDetector( + onTap: isClickable ? () => _callCustomer(value) : null, + child: Text( + value, + style: AppStyle.sm.copyWith( + color: isClickable + ? AppColor.primary + : AppColor.textPrimary, + fontWeight: FontWeight.w500, + decoration: isClickable ? TextDecoration.underline : null, + ), + ), + ), + ], + ), + ), + ], + ); + } + + Widget _buildOrderItems() { + return Container( + padding: const EdgeInsets.all(20), + decoration: BoxDecoration( + color: AppColor.background, + borderRadius: BorderRadius.circular(12), + border: Border.all(color: AppColor.border), + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + 'Item Pesanan', + style: AppStyle.md.copyWith( + fontWeight: FontWeight.bold, + color: AppColor.textPrimary, + ), + ), + const SizedBox(height: 16), + ...widget.order.items.asMap().entries.map((entry) { + final index = entry.key; + final item = entry.value; + return Column( + children: [ + if (index > 0) + Padding( + padding: const EdgeInsets.symmetric(vertical: 12), + child: Divider(color: AppColor.border, height: 1), + ), + _buildOrderItem(item), + ], + ); + }).toList(), + ], + ), + ); + } + + Widget _buildOrderItem(OrderItem item) { + return Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Container( + width: 60, + height: 60, + decoration: BoxDecoration( + color: AppColor.primary.withOpacity(0.1), + borderRadius: BorderRadius.circular(8), + ), + child: item.imageUrl != null + ? ClipRRect( + borderRadius: BorderRadius.circular(8), + child: Image.network( + item.imageUrl!, + fit: BoxFit.cover, + errorBuilder: (context, error, stackTrace) { + return Icon( + Icons.restaurant, + color: AppColor.primary, + size: 24, + ); + }, + ), + ) + : Icon(Icons.restaurant, color: AppColor.primary, size: 24), + ), + const SizedBox(width: 16), + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + item.name, + style: AppStyle.md.copyWith( + fontWeight: FontWeight.w600, + color: AppColor.textPrimary, + ), + ), + const SizedBox(height: 4), + Text( + 'Rp ${_formatCurrency(item.price)} x ${item.quantity}', + style: AppStyle.sm.copyWith(color: AppColor.textSecondary), + ), + if (item.notes != null) ...[ + const SizedBox(height: 4), + Text( + 'Catatan: ${item.notes}', + style: AppStyle.xs.copyWith( + color: AppColor.textSecondary, + fontStyle: FontStyle.italic, + ), + ), + ], + ], + ), + ), + Text( + 'Rp ${_formatCurrency(item.price * item.quantity)}', + style: AppStyle.md.copyWith( + fontWeight: FontWeight.bold, + color: AppColor.textPrimary, + ), + ), + ], + ); + } + + Widget _buildOrderSummary() { + final subtotal = widget.order.items.fold( + 0, + (sum, item) => sum + (item.price * item.quantity), + ); + + return Container( + padding: const EdgeInsets.all(20), + decoration: BoxDecoration( + color: AppColor.background, + borderRadius: BorderRadius.circular(12), + border: Border.all(color: AppColor.border), + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + 'Ringkasan Pesanan', + style: AppStyle.md.copyWith( + fontWeight: FontWeight.bold, + color: AppColor.textPrimary, + ), + ), + const SizedBox(height: 16), + _buildSummaryRow('Subtotal', subtotal), + const SizedBox(height: 8), + _buildSummaryRow('Ongkos Kirim', 10000), + const SizedBox(height: 8), + _buildSummaryRow('Pajak', subtotal * 0.1), + const SizedBox(height: 12), + Divider(color: AppColor.border, height: 1), + const SizedBox(height: 12), + _buildSummaryRow('Total', widget.order.totalAmount, isBold: true), + ], + ), + ); + } + + Widget _buildSummaryRow(String label, double amount, {bool isBold = false}) { + return Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + label, + style: AppStyle.sm.copyWith( + color: AppColor.textSecondary, + fontWeight: isBold ? FontWeight.bold : FontWeight.normal, + ), + ), + Text( + 'Rp ${_formatCurrency(amount)}', + style: AppStyle.sm.copyWith( + color: isBold ? AppColor.textPrimary : AppColor.textSecondary, + fontWeight: isBold ? FontWeight.bold : FontWeight.w500, + ), + ), + ], + ); + } + + Widget _buildOrderNotes() { + return Container( + padding: const EdgeInsets.all(20), + decoration: BoxDecoration( + color: AppColor.background, + borderRadius: BorderRadius.circular(12), + border: Border.all(color: AppColor.border), + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + children: [ + Icon(Icons.note, size: 18, color: AppColor.primary), + const SizedBox(width: 8), + Text( + 'Catatan Pesanan', + style: AppStyle.md.copyWith( + fontWeight: FontWeight.bold, + color: AppColor.textPrimary, + ), + ), + ], + ), + const SizedBox(height: 12), + Container( + width: double.infinity, + padding: const EdgeInsets.all(16), + decoration: BoxDecoration( + color: AppColor.white, + borderRadius: BorderRadius.circular(8), + border: Border.all(color: AppColor.border), + ), + child: Text( + widget.order.notes!, + style: AppStyle.sm.copyWith( + color: AppColor.textPrimary, + height: 1.5, + ), + ), + ), + ], + ), + ); + } + + Widget _buildActionButtons() { + return Column( + children: [ + if (widget.order.status == OrderStatus.pending) ...[ + Row( + children: [ + Expanded( + child: OutlinedButton.icon( + onPressed: _cancelOrder, + icon: const Icon(Icons.cancel, size: 20), + label: const Text('Batalkan'), + style: OutlinedButton.styleFrom( + foregroundColor: Colors.red, + side: const BorderSide(color: Colors.red), + padding: const EdgeInsets.symmetric(vertical: 16), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(8), + ), + ), + ), + ), + const SizedBox(width: 12), + Expanded( + child: ElevatedButton.icon( + onPressed: _processOrder, + icon: const Icon(Icons.check, size: 20), + label: const Text('Proses'), + style: ElevatedButton.styleFrom( + backgroundColor: AppColor.primary, + foregroundColor: AppColor.white, + padding: const EdgeInsets.symmetric(vertical: 16), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(8), + ), + ), + ), + ), + ], + ), + ] else if (widget.order.status == OrderStatus.processing) ...[ + SizedBox( + width: double.infinity, + child: ElevatedButton.icon( + onPressed: _completeOrder, + icon: const Icon(Icons.check_circle, size: 20), + label: const Text('Selesaikan Pesanan'), + style: ElevatedButton.styleFrom( + backgroundColor: Colors.green, + foregroundColor: AppColor.white, + padding: const EdgeInsets.symmetric(vertical: 16), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(8), + ), + ), + ), + ), + ], + const SizedBox(height: 12), + SizedBox( + width: double.infinity, + child: OutlinedButton.icon( + onPressed: _contactCustomer, + icon: const Icon(Icons.chat, size: 20), + label: const Text('Hubungi Pelanggan'), + style: OutlinedButton.styleFrom( + foregroundColor: AppColor.primary, + side: BorderSide(color: AppColor.primary), + padding: const EdgeInsets.symmetric(vertical: 16), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(8), + ), + ), + ), + ), + ], + ); + } + + String _formatDateTime(DateTime dateTime) { + final months = [ + 'Jan', + 'Feb', + 'Mar', + 'Apr', + 'Mei', + 'Jun', + 'Jul', + 'Ags', + 'Sep', + 'Okt', + 'Nov', + 'Des', + ]; + + final day = dateTime.day; + final month = months[dateTime.month - 1]; + final year = dateTime.year; + final hour = dateTime.hour.toString().padLeft(2, '0'); + final minute = dateTime.minute.toString().padLeft(2, '0'); + + return '$day $month $year, $hour:$minute WIB'; + } + + String _formatCurrency(double amount) { + return amount + .toStringAsFixed(0) + .replaceAllMapped( + RegExp(r'(\d)(?=(\d{3})+(?!\d))'), + (Match m) => '${m[1]}.', + ); + } + + void _shareOrder() { + // Implement share functionality + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text('Fitur berbagi akan segera hadir'), + backgroundColor: AppColor.primary, + ), + ); + } + + void _handleMenuAction(String action) { + switch (action) { + case 'edit': + _editOrder(); + break; + case 'duplicate': + _duplicateOrder(); + break; + case 'delete': + _deleteOrder(); + break; + } + } + + void _editOrder() { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text('Fitur edit pesanan akan segera hadir'), + backgroundColor: AppColor.primary, + ), + ); + } + + void _duplicateOrder() { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text('Pesanan berhasil diduplikat'), + backgroundColor: Colors.green, + ), + ); + } + + void _deleteOrder() { + showDialog( + context: context, + builder: (context) => AlertDialog( + title: Text( + 'Hapus Pesanan', + style: AppStyle.lg.copyWith(fontWeight: FontWeight.bold), + ), + content: Text( + 'Apakah Anda yakin ingin menghapus pesanan ${widget.order.id}? Tindakan ini tidak dapat dibatalkan.', + style: AppStyle.md, + ), + actions: [ + TextButton( + onPressed: () => Navigator.pop(context), + child: Text( + 'Batal', + style: AppStyle.md.copyWith(color: AppColor.textSecondary), + ), + ), + ElevatedButton( + onPressed: () { + context.router.back(); + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text('Pesanan berhasil dihapus'), + backgroundColor: Colors.red, + ), + ); + }, + style: ElevatedButton.styleFrom( + backgroundColor: Colors.red, + foregroundColor: Colors.white, + ), + child: const Text('Hapus'), + ), + ], + ), + ); + } + + void _processOrder() { + showDialog( + context: context, + builder: (context) => AlertDialog( + title: Text( + 'Proses Pesanan', + style: AppStyle.lg.copyWith(fontWeight: FontWeight.bold), + ), + content: Text( + 'Apakah Anda yakin ingin memproses pesanan ${widget.order.id}?', + style: AppStyle.md, + ), + actions: [ + TextButton( + onPressed: () => Navigator.pop(context), + child: Text( + 'Batal', + style: AppStyle.md.copyWith(color: AppColor.textSecondary), + ), + ), + ElevatedButton( + onPressed: () { + Navigator.pop(context); + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text('Pesanan sedang diproses'), + backgroundColor: Colors.blue, + ), + ); + }, + style: ElevatedButton.styleFrom( + backgroundColor: AppColor.primary, + foregroundColor: Colors.white, + ), + child: const Text('Proses'), + ), + ], + ), + ); + } + + void _completeOrder() { + showDialog( + context: context, + builder: (context) => AlertDialog( + title: Text( + 'Selesaikan Pesanan', + style: AppStyle.lg.copyWith(fontWeight: FontWeight.bold), + ), + content: Text( + 'Apakah pesanan ${widget.order.id} sudah selesai dan siap dikirim?', + style: AppStyle.md, + ), + actions: [ + TextButton( + onPressed: () => Navigator.pop(context), + child: Text( + 'Belum', + style: AppStyle.md.copyWith(color: AppColor.textSecondary), + ), + ), + ElevatedButton( + onPressed: () { + Navigator.pop(context); + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text('Pesanan berhasil diselesaikan'), + backgroundColor: Colors.green, + ), + ); + }, + style: ElevatedButton.styleFrom( + backgroundColor: Colors.green, + foregroundColor: Colors.white, + ), + child: const Text('Selesai'), + ), + ], + ), + ); + } + + void _cancelOrder() { + showDialog( + context: context, + builder: (context) => AlertDialog( + title: Text( + 'Batalkan Pesanan', + style: AppStyle.lg.copyWith(fontWeight: FontWeight.bold), + ), + content: Text( + 'Apakah Anda yakin ingin membatalkan pesanan ${widget.order.id}?', + style: AppStyle.md, + ), + actions: [ + TextButton( + onPressed: () => Navigator.pop(context), + child: Text( + 'Tidak', + style: AppStyle.md.copyWith(color: AppColor.textSecondary), + ), + ), + ElevatedButton( + onPressed: () { + Navigator.pop(context); + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text('Pesanan berhasil dibatalkan'), + backgroundColor: Colors.red, + ), + ); + }, + style: ElevatedButton.styleFrom( + backgroundColor: Colors.red, + foregroundColor: Colors.white, + ), + child: const Text('Batalkan'), + ), + ], + ), + ); + } + + void _contactCustomer() { + showModalBottomSheet( + context: context, + backgroundColor: AppColor.white, + shape: const RoundedRectangleBorder( + borderRadius: BorderRadius.vertical(top: Radius.circular(16)), + ), + builder: (context) => Container( + padding: const EdgeInsets.all(24), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Container( + width: 40, + height: 4, + decoration: BoxDecoration( + color: AppColor.border, + borderRadius: BorderRadius.circular(2), + ), + ), + const SizedBox(height: 20), + Text( + 'Hubungi ${widget.order.customerName}', + style: AppStyle.lg.copyWith( + fontWeight: FontWeight.bold, + color: AppColor.textPrimary, + ), + ), + const SizedBox(height: 24), + if (widget.order.phoneNumber != null) + ListTile( + leading: Container( + padding: const EdgeInsets.all(12), + decoration: BoxDecoration( + color: Colors.green.withOpacity(0.1), + borderRadius: BorderRadius.circular(8), + ), + child: const Icon(Icons.phone, color: Colors.green), + ), + title: const Text('Telepon'), + subtitle: Text(widget.order.phoneNumber!), + onTap: () => _callCustomer(widget.order.phoneNumber!), + ), + ListTile( + leading: Container( + padding: const EdgeInsets.all(12), + decoration: BoxDecoration( + color: Colors.blue.withOpacity(0.1), + borderRadius: BorderRadius.circular(8), + ), + child: const Icon(Icons.chat, color: Colors.blue), + ), + title: const Text('Kirim Pesan'), + subtitle: const Text('Via WhatsApp'), + onTap: () => _sendMessage(), + ), + const SizedBox(height: 16), + ], + ), + ), + ); + } + + void _callCustomer(String phoneNumber) { + Navigator.pop(context); + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text('Menghubungi $phoneNumber...'), + backgroundColor: Colors.green, + ), + ); + } + + void _sendMessage() { + Navigator.pop(context); + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text('Membuka WhatsApp...'), + backgroundColor: Colors.blue, + ), + ); + } +} diff --git a/lib/presentation/router/app_router.dart b/lib/presentation/router/app_router.dart index 10da740..8dfec6b 100644 --- a/lib/presentation/router/app_router.dart +++ b/lib/presentation/router/app_router.dart @@ -47,5 +47,8 @@ class AppRouter extends RootStackRouter { // Notification AutoRoute(page: NotificationRoute.page), + + // Order + AutoRoute(page: OrderDetailRoute.page), ]; } diff --git a/lib/presentation/router/app_router.gr.dart b/lib/presentation/router/app_router.gr.dart index a8a5134..41872cf 100644 --- a/lib/presentation/router/app_router.gr.dart +++ b/lib/presentation/router/app_router.gr.dart @@ -9,16 +9,16 @@ // coverage:ignore-file // ignore_for_file: no_leading_underscores_for_library_prefixes -import 'package:auto_route/auto_route.dart' as _i22; +import 'package:auto_route/auto_route.dart' as _i23; import 'package:enaklo/presentation/pages/auth/create_password/create_password_page.dart' as _i1; import 'package:enaklo/presentation/pages/auth/login/login_page.dart' as _i5; -import 'package:enaklo/presentation/pages/auth/otp/otp_page.dart' as _i12; +import 'package:enaklo/presentation/pages/auth/otp/otp_page.dart' as _i13; import 'package:enaklo/presentation/pages/auth/password/password_page.dart' - as _i13; -import 'package:enaklo/presentation/pages/auth/pin/pin_page.dart' as _i14; + as _i14; +import 'package:enaklo/presentation/pages/auth/pin/pin_page.dart' as _i15; import 'package:enaklo/presentation/pages/auth/register/register_page.dart' - as _i17; + as _i18; import 'package:enaklo/presentation/pages/draw/draw_page.dart' as _i3; import 'package:enaklo/presentation/pages/draw/pages/draw_detail/draw_detail_page.dart' as _i2; @@ -26,11 +26,11 @@ import 'package:enaklo/presentation/pages/main/main_page.dart' as _i6; import 'package:enaklo/presentation/pages/main/pages/home/home_page.dart' as _i4; import 'package:enaklo/presentation/pages/main/pages/order/order_page.dart' - as _i11; + as _i12; import 'package:enaklo/presentation/pages/main/pages/profile/profile_page.dart' - as _i16; + as _i17; import 'package:enaklo/presentation/pages/main/pages/voucher/voucher_page.dart' - as _i21; + as _i22; import 'package:enaklo/presentation/pages/merchant/merchant_page.dart' as _i8; import 'package:enaklo/presentation/pages/merchant/pages/merchant_detail/merchant_detail_page.dart' as _i7; @@ -38,23 +38,25 @@ import 'package:enaklo/presentation/pages/notification/notification_page.dart' as _i9; import 'package:enaklo/presentation/pages/onboarding/onboarding_page.dart' as _i10; +import 'package:enaklo/presentation/pages/order/order_detail/order_detail_page.dart' + as _i11; import 'package:enaklo/presentation/pages/reward/pages/product_redeem/product_redeem_page.dart' - as _i15; -import 'package:enaklo/presentation/pages/reward/reward_page.dart' as _i18; -import 'package:enaklo/presentation/pages/splash/splash_page.dart' as _i19; + as _i16; +import 'package:enaklo/presentation/pages/reward/reward_page.dart' as _i19; +import 'package:enaklo/presentation/pages/splash/splash_page.dart' as _i20; import 'package:enaklo/presentation/pages/voucher/voucher_detail/voucher_detail_page.dart' - as _i20; -import 'package:flutter/material.dart' as _i23; + as _i21; +import 'package:flutter/material.dart' as _i24; /// generated route for /// [_i1.CreatePasswordPage] -class CreatePasswordRoute extends _i22.PageRouteInfo { - const CreatePasswordRoute({List<_i22.PageRouteInfo>? children}) +class CreatePasswordRoute extends _i23.PageRouteInfo { + const CreatePasswordRoute({List<_i23.PageRouteInfo>? children}) : super(CreatePasswordRoute.name, initialChildren: children); static const String name = 'CreatePasswordRoute'; - static _i22.PageInfo page = _i22.PageInfo( + static _i23.PageInfo page = _i23.PageInfo( name, builder: (data) { return const _i1.CreatePasswordPage(); @@ -64,11 +66,11 @@ class CreatePasswordRoute extends _i22.PageRouteInfo { /// generated route for /// [_i2.DrawDetailPage] -class DrawDetailRoute extends _i22.PageRouteInfo { +class DrawDetailRoute extends _i23.PageRouteInfo { DrawDetailRoute({ - _i23.Key? key, + _i24.Key? key, required _i3.DrawEvent drawEvent, - List<_i22.PageRouteInfo>? children, + List<_i23.PageRouteInfo>? children, }) : super( DrawDetailRoute.name, args: DrawDetailRouteArgs(key: key, drawEvent: drawEvent), @@ -77,7 +79,7 @@ class DrawDetailRoute extends _i22.PageRouteInfo { static const String name = 'DrawDetailRoute'; - static _i22.PageInfo page = _i22.PageInfo( + static _i23.PageInfo page = _i23.PageInfo( name, builder: (data) { final args = data.argsAs(); @@ -89,7 +91,7 @@ class DrawDetailRoute extends _i22.PageRouteInfo { class DrawDetailRouteArgs { const DrawDetailRouteArgs({this.key, required this.drawEvent}); - final _i23.Key? key; + final _i24.Key? key; final _i3.DrawEvent drawEvent; @@ -101,13 +103,13 @@ class DrawDetailRouteArgs { /// generated route for /// [_i3.DrawPage] -class DrawRoute extends _i22.PageRouteInfo { - const DrawRoute({List<_i22.PageRouteInfo>? children}) +class DrawRoute extends _i23.PageRouteInfo { + const DrawRoute({List<_i23.PageRouteInfo>? children}) : super(DrawRoute.name, initialChildren: children); static const String name = 'DrawRoute'; - static _i22.PageInfo page = _i22.PageInfo( + static _i23.PageInfo page = _i23.PageInfo( name, builder: (data) { return const _i3.DrawPage(); @@ -117,13 +119,13 @@ class DrawRoute extends _i22.PageRouteInfo { /// generated route for /// [_i4.HomePage] -class HomeRoute extends _i22.PageRouteInfo { - const HomeRoute({List<_i22.PageRouteInfo>? children}) +class HomeRoute extends _i23.PageRouteInfo { + const HomeRoute({List<_i23.PageRouteInfo>? children}) : super(HomeRoute.name, initialChildren: children); static const String name = 'HomeRoute'; - static _i22.PageInfo page = _i22.PageInfo( + static _i23.PageInfo page = _i23.PageInfo( name, builder: (data) { return const _i4.HomePage(); @@ -133,13 +135,13 @@ class HomeRoute extends _i22.PageRouteInfo { /// generated route for /// [_i5.LoginPage] -class LoginRoute extends _i22.PageRouteInfo { - const LoginRoute({List<_i22.PageRouteInfo>? children}) +class LoginRoute extends _i23.PageRouteInfo { + const LoginRoute({List<_i23.PageRouteInfo>? children}) : super(LoginRoute.name, initialChildren: children); static const String name = 'LoginRoute'; - static _i22.PageInfo page = _i22.PageInfo( + static _i23.PageInfo page = _i23.PageInfo( name, builder: (data) { return const _i5.LoginPage(); @@ -149,13 +151,13 @@ class LoginRoute extends _i22.PageRouteInfo { /// generated route for /// [_i6.MainPage] -class MainRoute extends _i22.PageRouteInfo { - const MainRoute({List<_i22.PageRouteInfo>? children}) +class MainRoute extends _i23.PageRouteInfo { + const MainRoute({List<_i23.PageRouteInfo>? children}) : super(MainRoute.name, initialChildren: children); static const String name = 'MainRoute'; - static _i22.PageInfo page = _i22.PageInfo( + static _i23.PageInfo page = _i23.PageInfo( name, builder: (data) { return const _i6.MainPage(); @@ -165,11 +167,11 @@ class MainRoute extends _i22.PageRouteInfo { /// generated route for /// [_i7.MerchantDetailPage] -class MerchantDetailRoute extends _i22.PageRouteInfo { +class MerchantDetailRoute extends _i23.PageRouteInfo { MerchantDetailRoute({ - _i23.Key? key, + _i24.Key? key, required _i8.MerchantModel merchant, - List<_i22.PageRouteInfo>? children, + List<_i23.PageRouteInfo>? children, }) : super( MerchantDetailRoute.name, args: MerchantDetailRouteArgs(key: key, merchant: merchant), @@ -178,7 +180,7 @@ class MerchantDetailRoute extends _i22.PageRouteInfo { static const String name = 'MerchantDetailRoute'; - static _i22.PageInfo page = _i22.PageInfo( + static _i23.PageInfo page = _i23.PageInfo( name, builder: (data) { final args = data.argsAs(); @@ -190,7 +192,7 @@ class MerchantDetailRoute extends _i22.PageRouteInfo { class MerchantDetailRouteArgs { const MerchantDetailRouteArgs({this.key, required this.merchant}); - final _i23.Key? key; + final _i24.Key? key; final _i8.MerchantModel merchant; @@ -202,13 +204,13 @@ class MerchantDetailRouteArgs { /// generated route for /// [_i8.MerchantPage] -class MerchantRoute extends _i22.PageRouteInfo { - const MerchantRoute({List<_i22.PageRouteInfo>? children}) +class MerchantRoute extends _i23.PageRouteInfo { + const MerchantRoute({List<_i23.PageRouteInfo>? children}) : super(MerchantRoute.name, initialChildren: children); static const String name = 'MerchantRoute'; - static _i22.PageInfo page = _i22.PageInfo( + static _i23.PageInfo page = _i23.PageInfo( name, builder: (data) { return const _i8.MerchantPage(); @@ -218,13 +220,13 @@ class MerchantRoute extends _i22.PageRouteInfo { /// generated route for /// [_i9.NotificationPage] -class NotificationRoute extends _i22.PageRouteInfo { - const NotificationRoute({List<_i22.PageRouteInfo>? children}) +class NotificationRoute extends _i23.PageRouteInfo { + const NotificationRoute({List<_i23.PageRouteInfo>? children}) : super(NotificationRoute.name, initialChildren: children); static const String name = 'NotificationRoute'; - static _i22.PageInfo page = _i22.PageInfo( + static _i23.PageInfo page = _i23.PageInfo( name, builder: (data) { return const _i9.NotificationPage(); @@ -234,13 +236,13 @@ class NotificationRoute extends _i22.PageRouteInfo { /// generated route for /// [_i10.OnboardingPage] -class OnboardingRoute extends _i22.PageRouteInfo { - const OnboardingRoute({List<_i22.PageRouteInfo>? children}) +class OnboardingRoute extends _i23.PageRouteInfo { + const OnboardingRoute({List<_i23.PageRouteInfo>? children}) : super(OnboardingRoute.name, initialChildren: children); static const String name = 'OnboardingRoute'; - static _i22.PageInfo page = _i22.PageInfo( + static _i23.PageInfo page = _i23.PageInfo( name, builder: (data) { return const _i10.OnboardingPage(); @@ -249,61 +251,98 @@ class OnboardingRoute extends _i22.PageRouteInfo { } /// generated route for -/// [_i11.OrderPage] -class OrderRoute extends _i22.PageRouteInfo { - const OrderRoute({List<_i22.PageRouteInfo>? children}) +/// [_i11.OrderDetailPage] +class OrderDetailRoute extends _i23.PageRouteInfo { + OrderDetailRoute({ + _i24.Key? key, + required _i12.Order order, + List<_i23.PageRouteInfo>? children, + }) : super( + OrderDetailRoute.name, + args: OrderDetailRouteArgs(key: key, order: order), + initialChildren: children, + ); + + static const String name = 'OrderDetailRoute'; + + static _i23.PageInfo page = _i23.PageInfo( + name, + builder: (data) { + final args = data.argsAs(); + return _i11.OrderDetailPage(key: args.key, order: args.order); + }, + ); +} + +class OrderDetailRouteArgs { + const OrderDetailRouteArgs({this.key, required this.order}); + + final _i24.Key? key; + + final _i12.Order order; + + @override + String toString() { + return 'OrderDetailRouteArgs{key: $key, order: $order}'; + } +} + +/// generated route for +/// [_i12.OrderPage] +class OrderRoute extends _i23.PageRouteInfo { + const OrderRoute({List<_i23.PageRouteInfo>? children}) : super(OrderRoute.name, initialChildren: children); static const String name = 'OrderRoute'; - static _i22.PageInfo page = _i22.PageInfo( + static _i23.PageInfo page = _i23.PageInfo( name, builder: (data) { - return const _i11.OrderPage(); + return const _i12.OrderPage(); }, ); } /// generated route for -/// [_i12.OtpPage] -class OtpRoute extends _i22.PageRouteInfo { - const OtpRoute({List<_i22.PageRouteInfo>? children}) +/// [_i13.OtpPage] +class OtpRoute extends _i23.PageRouteInfo { + const OtpRoute({List<_i23.PageRouteInfo>? children}) : super(OtpRoute.name, initialChildren: children); static const String name = 'OtpRoute'; - static _i22.PageInfo page = _i22.PageInfo( + static _i23.PageInfo page = _i23.PageInfo( name, builder: (data) { - return const _i12.OtpPage(); + return const _i13.OtpPage(); }, ); } /// generated route for -/// [_i13.PasswordPage] -class PasswordRoute extends _i22.PageRouteInfo { - const PasswordRoute({List<_i22.PageRouteInfo>? children}) +/// [_i14.PasswordPage] +class PasswordRoute extends _i23.PageRouteInfo { + const PasswordRoute({List<_i23.PageRouteInfo>? children}) : super(PasswordRoute.name, initialChildren: children); static const String name = 'PasswordRoute'; - static _i22.PageInfo page = _i22.PageInfo( + static _i23.PageInfo page = _i23.PageInfo( name, builder: (data) { - return const _i13.PasswordPage(); + return const _i14.PasswordPage(); }, ); } /// generated route for -/// [_i14.PinPage] -class PinRoute extends _i22.PageRouteInfo { +/// [_i15.PinPage] +class PinRoute extends _i23.PageRouteInfo { PinRoute({ - _i23.Key? key, + _i24.Key? key, bool isCreatePin = true, String? title, - List<_i22.PageRouteInfo>? children, + List<_i23.PageRouteInfo>? children, }) : super( PinRoute.name, args: PinRouteArgs(key: key, isCreatePin: isCreatePin, title: title), @@ -312,13 +351,13 @@ class PinRoute extends _i22.PageRouteInfo { static const String name = 'PinRoute'; - static _i22.PageInfo page = _i22.PageInfo( + static _i23.PageInfo page = _i23.PageInfo( name, builder: (data) { final args = data.argsAs( orElse: () => const PinRouteArgs(), ); - return _i14.PinPage( + return _i15.PinPage( key: args.key, isCreatePin: args.isCreatePin, title: args.title, @@ -330,7 +369,7 @@ class PinRoute extends _i22.PageRouteInfo { class PinRouteArgs { const PinRouteArgs({this.key, this.isCreatePin = true, this.title}); - final _i23.Key? key; + final _i24.Key? key; final bool isCreatePin; @@ -343,14 +382,14 @@ class PinRouteArgs { } /// generated route for -/// [_i15.ProductRedeemPage] -class ProductRedeemRoute extends _i22.PageRouteInfo { +/// [_i16.ProductRedeemPage] +class ProductRedeemRoute extends _i23.PageRouteInfo { ProductRedeemRoute({ - _i23.Key? key, - required _i18.Product product, - required _i18.Merchant merchant, - required _i18.PointCard pointCard, - List<_i22.PageRouteInfo>? children, + _i24.Key? key, + required _i19.Product product, + required _i19.Merchant merchant, + required _i19.PointCard pointCard, + List<_i23.PageRouteInfo>? children, }) : super( ProductRedeemRoute.name, args: ProductRedeemRouteArgs( @@ -364,11 +403,11 @@ class ProductRedeemRoute extends _i22.PageRouteInfo { static const String name = 'ProductRedeemRoute'; - static _i22.PageInfo page = _i22.PageInfo( + static _i23.PageInfo page = _i23.PageInfo( name, builder: (data) { final args = data.argsAs(); - return _i15.ProductRedeemPage( + return _i16.ProductRedeemPage( key: args.key, product: args.product, merchant: args.merchant, @@ -386,13 +425,13 @@ class ProductRedeemRouteArgs { required this.pointCard, }); - final _i23.Key? key; + final _i24.Key? key; - final _i18.Product product; + final _i19.Product product; - final _i18.Merchant merchant; + final _i19.Merchant merchant; - final _i18.PointCard pointCard; + final _i19.PointCard pointCard; @override String toString() { @@ -401,97 +440,97 @@ class ProductRedeemRouteArgs { } /// generated route for -/// [_i16.ProfilePage] -class ProfileRoute extends _i22.PageRouteInfo { - const ProfileRoute({List<_i22.PageRouteInfo>? children}) +/// [_i17.ProfilePage] +class ProfileRoute extends _i23.PageRouteInfo { + const ProfileRoute({List<_i23.PageRouteInfo>? children}) : super(ProfileRoute.name, initialChildren: children); static const String name = 'ProfileRoute'; - static _i22.PageInfo page = _i22.PageInfo( + static _i23.PageInfo page = _i23.PageInfo( name, builder: (data) { - return const _i16.ProfilePage(); + return const _i17.ProfilePage(); }, ); } /// generated route for -/// [_i17.RegisterPage] -class RegisterRoute extends _i22.PageRouteInfo { - const RegisterRoute({List<_i22.PageRouteInfo>? children}) +/// [_i18.RegisterPage] +class RegisterRoute extends _i23.PageRouteInfo { + const RegisterRoute({List<_i23.PageRouteInfo>? children}) : super(RegisterRoute.name, initialChildren: children); static const String name = 'RegisterRoute'; - static _i22.PageInfo page = _i22.PageInfo( + static _i23.PageInfo page = _i23.PageInfo( name, builder: (data) { - return const _i17.RegisterPage(); + return const _i18.RegisterPage(); }, ); } /// generated route for -/// [_i18.RewardPage] -class RewardRoute extends _i22.PageRouteInfo { - const RewardRoute({List<_i22.PageRouteInfo>? children}) +/// [_i19.RewardPage] +class RewardRoute extends _i23.PageRouteInfo { + const RewardRoute({List<_i23.PageRouteInfo>? children}) : super(RewardRoute.name, initialChildren: children); static const String name = 'RewardRoute'; - static _i22.PageInfo page = _i22.PageInfo( + static _i23.PageInfo page = _i23.PageInfo( name, builder: (data) { - return const _i18.RewardPage(); + return const _i19.RewardPage(); }, ); } /// generated route for -/// [_i19.SplashPage] -class SplashRoute extends _i22.PageRouteInfo { - const SplashRoute({List<_i22.PageRouteInfo>? children}) +/// [_i20.SplashPage] +class SplashRoute extends _i23.PageRouteInfo { + const SplashRoute({List<_i23.PageRouteInfo>? children}) : super(SplashRoute.name, initialChildren: children); static const String name = 'SplashRoute'; - static _i22.PageInfo page = _i22.PageInfo( + static _i23.PageInfo page = _i23.PageInfo( name, builder: (data) { - return const _i19.SplashPage(); + return const _i20.SplashPage(); }, ); } /// generated route for -/// [_i20.VoucherDetailPage] -class VoucherDetailRoute extends _i22.PageRouteInfo { - const VoucherDetailRoute({List<_i22.PageRouteInfo>? children}) +/// [_i21.VoucherDetailPage] +class VoucherDetailRoute extends _i23.PageRouteInfo { + const VoucherDetailRoute({List<_i23.PageRouteInfo>? children}) : super(VoucherDetailRoute.name, initialChildren: children); static const String name = 'VoucherDetailRoute'; - static _i22.PageInfo page = _i22.PageInfo( + static _i23.PageInfo page = _i23.PageInfo( name, builder: (data) { - return const _i20.VoucherDetailPage(); + return const _i21.VoucherDetailPage(); }, ); } /// generated route for -/// [_i21.VoucherPage] -class VoucherRoute extends _i22.PageRouteInfo { - const VoucherRoute({List<_i22.PageRouteInfo>? children}) +/// [_i22.VoucherPage] +class VoucherRoute extends _i23.PageRouteInfo { + const VoucherRoute({List<_i23.PageRouteInfo>? children}) : super(VoucherRoute.name, initialChildren: children); static const String name = 'VoucherRoute'; - static _i22.PageInfo page = _i22.PageInfo( + static _i23.PageInfo page = _i23.PageInfo( name, builder: (data) { - return const _i21.VoucherPage(); + return const _i22.VoucherPage(); }, ); }