1024 lines
49 KiB
Dart
1024 lines
49 KiB
Dart
import 'package:customer/constant/const_texts.dart';
|
|
import 'package:customer/screen_ui/parcel_service/parcel_review_screen.dart';
|
|
import 'package:dotted_border/dotted_border.dart';
|
|
|
|
import 'package:flutter/material.dart';
|
|
import 'package:flutter_svg/svg.dart';
|
|
import 'package:get/get.dart';
|
|
import '../../constant/constant.dart';
|
|
import '../../controllers/parcel_order_details_controller.dart';
|
|
import '../../controllers/theme_controller.dart';
|
|
import '../../models/user_model.dart';
|
|
import '../../service/fire_store_utils.dart';
|
|
import '../../themes/app_them_data.dart';
|
|
import '../../themes/round_button_border.dart';
|
|
import '../../themes/round_button_fill.dart';
|
|
import '../../themes/show_toast_dialog.dart';
|
|
import '../../utils/network_image_widget.dart';
|
|
import '../multi_vendor_service/chat_screens/chat_screen.dart';
|
|
|
|
class ParcelOrderDetails extends StatelessWidget {
|
|
const ParcelOrderDetails({super.key});
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
final themeController = Get.find<ThemeController>();
|
|
final isDark = themeController.isDark.value;
|
|
return GetX(
|
|
init: ParcelOrderDetailsController(),
|
|
builder: (controller) {
|
|
return Scaffold(
|
|
appBar: AppBar(
|
|
automaticallyImplyLeading: false,
|
|
backgroundColor: AppThemeData.primary300,
|
|
title: Padding(
|
|
padding: const EdgeInsets.only(bottom: 10),
|
|
child: Row(
|
|
children: [
|
|
InkWell(
|
|
borderRadius: BorderRadius.circular(50),
|
|
onTap: () => Get.back(),
|
|
child: Container(
|
|
height: 42,
|
|
width: 42,
|
|
decoration: BoxDecoration(
|
|
shape: BoxShape.circle,
|
|
color: AppThemeData.grey50,
|
|
),
|
|
child: Center(
|
|
child: Padding(
|
|
padding: const EdgeInsets.only(left: 5),
|
|
child: Icon(
|
|
Icons.arrow_back_ios,
|
|
color: AppThemeData.grey900,
|
|
size: 20,
|
|
),
|
|
),
|
|
),
|
|
),
|
|
),
|
|
const SizedBox(width: 10),
|
|
Expanded(
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
Text(
|
|
"Order Details".tr,
|
|
style: AppThemeData.boldTextStyle(
|
|
fontSize: 18,
|
|
color: AppThemeData.grey900,
|
|
),
|
|
),
|
|
Text(
|
|
"Your parcel is on the way. Track it in real time below."
|
|
.tr,
|
|
maxLines: 1,
|
|
overflow: TextOverflow.ellipsis,
|
|
style: AppThemeData.mediumTextStyle(
|
|
fontSize: 14,
|
|
color: AppThemeData.grey900,
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
body:
|
|
controller.isLoading.value
|
|
? Constant.loader()
|
|
: SingleChildScrollView(
|
|
padding: const EdgeInsets.all(16),
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
Container(
|
|
decoration: BoxDecoration(
|
|
borderRadius: BorderRadius.circular(15),
|
|
color:
|
|
isDark
|
|
? AppThemeData.greyDark50
|
|
: AppThemeData.grey50,
|
|
border: Border.all(
|
|
color:
|
|
isDark
|
|
? AppThemeData.greyDark200
|
|
: AppThemeData.grey200,
|
|
),
|
|
),
|
|
width: double.infinity,
|
|
padding: const EdgeInsets.all(16),
|
|
child: Text(
|
|
"${'Order Id:'.tr} ${Constant.orderId(orderId: controller.parcelOrder.value.id.toString())}"
|
|
.tr,
|
|
textAlign: TextAlign.start,
|
|
style: TextStyle(
|
|
fontFamily: AppThemeData.semiBold,
|
|
fontSize: 18,
|
|
color:
|
|
isDark
|
|
? AppThemeData.grey50
|
|
: AppThemeData.grey900,
|
|
),
|
|
),
|
|
),
|
|
const SizedBox(height: 16),
|
|
Container(
|
|
decoration: BoxDecoration(
|
|
borderRadius: BorderRadius.circular(15),
|
|
color:
|
|
isDark
|
|
? AppThemeData.greyDark50
|
|
: AppThemeData.grey50,
|
|
border: Border.all(
|
|
color:
|
|
isDark
|
|
? AppThemeData.greyDark200
|
|
: AppThemeData.grey200,
|
|
),
|
|
),
|
|
padding: const EdgeInsets.all(16),
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
Row(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
// Timeline with icons and line
|
|
Column(
|
|
children: [
|
|
Image.asset(
|
|
"assets/images/image_parcel.png",
|
|
height: 32,
|
|
width: 32,
|
|
),
|
|
DottedBorder(
|
|
options: CustomPathDottedBorderOptions(
|
|
color: Colors.grey.shade400,
|
|
strokeWidth: 2,
|
|
dashPattern: [4, 4],
|
|
customPath:
|
|
(size) =>
|
|
Path()
|
|
..moveTo(size.width / 2, 0)
|
|
..lineTo(
|
|
size.width / 2,
|
|
size.height,
|
|
),
|
|
),
|
|
child: const SizedBox(
|
|
width: 20,
|
|
height: 95,
|
|
),
|
|
),
|
|
Image.asset(
|
|
"assets/images/image_parcel.png",
|
|
height: 32,
|
|
width: 32,
|
|
),
|
|
],
|
|
),
|
|
const SizedBox(width: 12),
|
|
// Address Details
|
|
Expanded(
|
|
child: Column(
|
|
crossAxisAlignment:
|
|
CrossAxisAlignment.start,
|
|
children: [
|
|
_infoSection(
|
|
"Pickup Address (Sender):".tr,
|
|
controller
|
|
.parcelOrder
|
|
.value
|
|
.sender
|
|
?.name ??
|
|
'',
|
|
controller
|
|
.parcelOrder
|
|
.value
|
|
.sender
|
|
?.address ??
|
|
'',
|
|
controller
|
|
.parcelOrder
|
|
.value
|
|
.sender
|
|
?.phone ??
|
|
'',
|
|
// controller.parcelOrder.value.senderPickupDateTime != null
|
|
// ? "Pickup Time: ${controller.formatDate(controller.parcelOrder.value.senderPickupDateTime!)}"
|
|
// : '',
|
|
isDark,
|
|
),
|
|
const SizedBox(height: 16),
|
|
_infoSection(
|
|
"Delivery Address (Receiver):".tr,
|
|
controller
|
|
.parcelOrder
|
|
.value
|
|
.receiver
|
|
?.name ??
|
|
'',
|
|
controller
|
|
.parcelOrder
|
|
.value
|
|
.receiver
|
|
?.address ??
|
|
'',
|
|
controller
|
|
.parcelOrder
|
|
.value
|
|
.receiver
|
|
?.phone ??
|
|
'',
|
|
// controller.parcelOrder.value.receiverPickupDateTime != null
|
|
// ? "Delivery Time: ${controller.formatDate(controller.parcelOrder.value.receiverPickupDateTime!)}"
|
|
// : '',
|
|
isDark,
|
|
),
|
|
],
|
|
),
|
|
),
|
|
],
|
|
),
|
|
|
|
const Divider(),
|
|
|
|
if (controller.parcelOrder.value.isSchedule ==
|
|
true)
|
|
Padding(
|
|
padding: const EdgeInsets.only(bottom: 8.0),
|
|
child: Text(
|
|
"${'Schedule Pickup time:'.tr} ${controller.formatDate(controller.parcelOrder.value.senderPickupDateTime!)}",
|
|
style: AppThemeData.mediumTextStyle(
|
|
fontSize: 14,
|
|
color: AppThemeData.info400,
|
|
),
|
|
),
|
|
),
|
|
|
|
Padding(
|
|
padding: const EdgeInsets.only(bottom: 8.0),
|
|
child: Text(
|
|
"${'Order Date:'.tr}${controller.parcelOrder.value.isSchedule == true ? controller.formatDate(controller.parcelOrder.value.createdAt!) : controller.formatDate(controller.parcelOrder.value.senderPickupDateTime!)}",
|
|
style: AppThemeData.mediumTextStyle(
|
|
fontSize: 14,
|
|
color: AppThemeData.info400,
|
|
),
|
|
),
|
|
),
|
|
|
|
Row(
|
|
mainAxisAlignment:
|
|
MainAxisAlignment.spaceBetween,
|
|
children: [
|
|
Text(
|
|
"Parcel Type:".tr,
|
|
style: AppThemeData.semiBoldTextStyle(
|
|
fontSize: 16,
|
|
color:
|
|
isDark
|
|
? AppThemeData.greyDark800
|
|
: AppThemeData.grey800,
|
|
),
|
|
),
|
|
Row(
|
|
children: [
|
|
Text(
|
|
controller
|
|
.parcelOrder
|
|
.value
|
|
.parcelType ??
|
|
'',
|
|
style: AppThemeData.semiBoldTextStyle(
|
|
fontSize: 16,
|
|
color:
|
|
isDark
|
|
? AppThemeData.greyDark800
|
|
: AppThemeData.grey800,
|
|
),
|
|
),
|
|
const SizedBox(width: 8),
|
|
if (controller
|
|
.getSelectedCategory()
|
|
?.image !=
|
|
null &&
|
|
controller
|
|
.getSelectedCategory()!
|
|
.image!
|
|
.isNotEmpty)
|
|
NetworkImageWidget(
|
|
imageUrl:
|
|
controller
|
|
.getSelectedCategory()
|
|
?.image ??
|
|
'',
|
|
height: 20,
|
|
width: 20,
|
|
),
|
|
],
|
|
),
|
|
],
|
|
),
|
|
controller.parcelOrder.value.parcelImages!.isEmpty
|
|
? SizedBox()
|
|
: SizedBox(
|
|
height: 120,
|
|
child: ListView.builder(
|
|
itemCount:
|
|
controller
|
|
.parcelOrder
|
|
.value
|
|
.parcelImages!
|
|
.length,
|
|
shrinkWrap: true,
|
|
scrollDirection: Axis.horizontal,
|
|
itemBuilder: (context, index) {
|
|
return Padding(
|
|
padding: const EdgeInsets.all(8.0),
|
|
child: ClipRRect(
|
|
borderRadius: BorderRadius.circular(
|
|
10,
|
|
),
|
|
child: NetworkImageWidget(
|
|
imageUrl:
|
|
controller
|
|
.parcelOrder
|
|
.value
|
|
.parcelImages![index],
|
|
width: 100,
|
|
fit: BoxFit.cover,
|
|
borderRadius: 10,
|
|
),
|
|
),
|
|
);
|
|
},
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
const SizedBox(height: 16),
|
|
// Distance, Weight, Rate
|
|
Container(
|
|
decoration: BoxDecoration(
|
|
borderRadius: BorderRadius.circular(15),
|
|
color:
|
|
isDark
|
|
? AppThemeData.greyDark50
|
|
: AppThemeData.grey50,
|
|
border: Border.all(
|
|
color:
|
|
isDark
|
|
? AppThemeData.greyDark200
|
|
: AppThemeData.grey200,
|
|
),
|
|
),
|
|
padding: EdgeInsets.all(16),
|
|
child: Row(
|
|
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
|
children: [
|
|
_iconTile(
|
|
"${controller.parcelOrder.value.distance ?? '--'} ${Constant.distanceType}",
|
|
"Distance".tr,
|
|
"assets/icons/ic_distance_parcel.svg",
|
|
isDark,
|
|
),
|
|
_iconTile(
|
|
controller.parcelOrder.value.parcelWeight ??
|
|
'--',
|
|
"Weight".tr,
|
|
"assets/icons/ic_weight_parcel.svg",
|
|
isDark,
|
|
),
|
|
_iconTile(
|
|
Constant.amountShow(
|
|
amount: controller.parcelOrder.value.subTotal,
|
|
),
|
|
"Rate".tr,
|
|
"assets/icons/ic_rate_parcel.svg",
|
|
isDark,
|
|
),
|
|
],
|
|
),
|
|
),
|
|
const SizedBox(height: 16),
|
|
if (controller.parcelOrder.value.driver != null)
|
|
Column(
|
|
children: [
|
|
Container(
|
|
decoration: BoxDecoration(
|
|
borderRadius: BorderRadius.circular(15),
|
|
color:
|
|
isDark
|
|
? AppThemeData.greyDark50
|
|
: AppThemeData.grey50,
|
|
border: Border.all(
|
|
color:
|
|
isDark
|
|
? AppThemeData.greyDark200
|
|
: AppThemeData.grey200,
|
|
),
|
|
),
|
|
padding: const EdgeInsets.all(16),
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
Text(
|
|
"About Driver".tr,
|
|
style: AppThemeData.boldTextStyle(
|
|
fontSize: 14,
|
|
color:
|
|
isDark
|
|
? AppThemeData.greyDark500
|
|
: AppThemeData.grey500,
|
|
),
|
|
),
|
|
const SizedBox(height: 8),
|
|
Row(
|
|
mainAxisAlignment:
|
|
MainAxisAlignment.spaceBetween,
|
|
crossAxisAlignment:
|
|
CrossAxisAlignment.center,
|
|
children: [
|
|
Row(
|
|
children: [
|
|
SizedBox(
|
|
width: 52,
|
|
height: 52,
|
|
child: ClipRRect(
|
|
borderRadius:
|
|
BorderRadiusGeometry.circular(
|
|
10,
|
|
),
|
|
child: NetworkImageWidget(
|
|
imageUrl:
|
|
controller
|
|
.driverUser
|
|
.value
|
|
?.profilePictureURL ??
|
|
'',
|
|
height: 70,
|
|
width: 70,
|
|
borderRadius: 35,
|
|
),
|
|
),
|
|
),
|
|
SizedBox(width: 20),
|
|
Text(
|
|
controller
|
|
.parcelOrder
|
|
.value
|
|
.driver
|
|
?.fullName() ??
|
|
'',
|
|
style: AppThemeData.boldTextStyle(
|
|
color:
|
|
isDark
|
|
? AppThemeData
|
|
.greyDark900
|
|
: AppThemeData.grey900,
|
|
fontSize: 18,
|
|
),
|
|
),
|
|
],
|
|
),
|
|
RoundedButtonBorder(
|
|
title: controller
|
|
.driverUser
|
|
.value!
|
|
.averageRating
|
|
.toStringAsFixed(1),
|
|
width: 20,
|
|
height: 3.5,
|
|
radius: 10,
|
|
isRight: false,
|
|
isCenter: true,
|
|
textColor: AppThemeData.warning400,
|
|
borderColor: AppThemeData.warning400,
|
|
color: AppThemeData.warning50,
|
|
icon: SvgPicture.asset(
|
|
"assets/icons/ic_start.svg",
|
|
),
|
|
onPress: () {},
|
|
),
|
|
],
|
|
),
|
|
Visibility(
|
|
visible:
|
|
controller.parcelOrder.value.status ==
|
|
Constant.orderCompleted
|
|
? true
|
|
: false,
|
|
child: Padding(
|
|
padding: const EdgeInsets.symmetric(
|
|
vertical: 10,
|
|
),
|
|
child: RoundedButtonFill(
|
|
title:
|
|
controller.ratingModel.value.id !=
|
|
null &&
|
|
controller
|
|
.ratingModel
|
|
.value
|
|
.id!
|
|
.isNotEmpty
|
|
? 'Update Review'.tr
|
|
: 'Add Review'.tr,
|
|
onPress: () async {
|
|
final result = await Get.to(
|
|
() => ParcelReviewScreen(),
|
|
arguments: {
|
|
'order':
|
|
controller
|
|
.parcelOrder
|
|
.value,
|
|
},
|
|
);
|
|
|
|
// If review was submitted successfully
|
|
if (result == true) {
|
|
await controller
|
|
.fetchDriverDetails();
|
|
}
|
|
},
|
|
height: 5,
|
|
borderRadius: 15,
|
|
color: Colors.orange,
|
|
textColor:
|
|
isDark
|
|
? AppThemeData.greyDark900
|
|
: AppThemeData.grey900,
|
|
),
|
|
),
|
|
),
|
|
if (controller.parcelOrder.value.status !=
|
|
Constant.orderCompleted)
|
|
Row(
|
|
mainAxisAlignment:
|
|
MainAxisAlignment.spaceBetween,
|
|
children: [
|
|
InkWell(
|
|
onTap: () {
|
|
Constant.makePhoneCall(
|
|
controller
|
|
.parcelOrder
|
|
.value
|
|
.driver!
|
|
.phoneNumber
|
|
.toString(),
|
|
);
|
|
},
|
|
child: Container(
|
|
width: 150,
|
|
height: 42,
|
|
decoration: ShapeDecoration(
|
|
shape: RoundedRectangleBorder(
|
|
side: BorderSide(
|
|
width: 1,
|
|
color:
|
|
isDark
|
|
? AppThemeData
|
|
.grey700
|
|
: AppThemeData
|
|
.grey200,
|
|
),
|
|
borderRadius:
|
|
BorderRadius.circular(
|
|
120,
|
|
),
|
|
),
|
|
),
|
|
child: Padding(
|
|
padding: const EdgeInsets.all(
|
|
8.0,
|
|
),
|
|
child: SvgPicture.asset(
|
|
"assets/icons/ic_phone_call.svg",
|
|
),
|
|
),
|
|
),
|
|
),
|
|
const SizedBox(width: 10),
|
|
InkWell(
|
|
onTap: () async {
|
|
ShowToastDialog.showLoader(
|
|
ConstTexts.pleaseWait.tr,
|
|
);
|
|
|
|
UserModel? customer =
|
|
await FireStoreUtils.getUserProfile(
|
|
controller
|
|
.parcelOrder
|
|
.value
|
|
.authorID ??
|
|
'',
|
|
);
|
|
UserModel? driverUser =
|
|
await FireStoreUtils.getUserProfile(
|
|
controller
|
|
.parcelOrder
|
|
.value
|
|
.driverId ??
|
|
'',
|
|
);
|
|
|
|
ShowToastDialog.closeLoader();
|
|
|
|
Get.to(
|
|
const ChatScreen(),
|
|
arguments: {
|
|
"customerName":
|
|
customer?.fullName(),
|
|
"restaurantName":
|
|
driverUser?.fullName(),
|
|
"orderId":
|
|
controller
|
|
.parcelOrder
|
|
.value
|
|
.id,
|
|
"restaurantId":
|
|
driverUser?.id,
|
|
"customerId": customer?.id,
|
|
"customerProfileImage":
|
|
customer
|
|
?.profilePictureURL,
|
|
"restaurantProfileImage":
|
|
driverUser
|
|
?.profilePictureURL,
|
|
"token": driverUser?.fcmToken,
|
|
"chatType": "Driver",
|
|
},
|
|
);
|
|
},
|
|
child: Container(
|
|
width: 150,
|
|
height: 42,
|
|
decoration: ShapeDecoration(
|
|
shape: RoundedRectangleBorder(
|
|
side: BorderSide(
|
|
width: 1,
|
|
color:
|
|
isDark
|
|
? AppThemeData
|
|
.grey700
|
|
: AppThemeData
|
|
.grey200,
|
|
),
|
|
borderRadius:
|
|
BorderRadius.circular(
|
|
120,
|
|
),
|
|
),
|
|
),
|
|
child: Padding(
|
|
padding: const EdgeInsets.all(
|
|
8.0,
|
|
),
|
|
child: SvgPicture.asset(
|
|
"assets/icons/ic_wechat.svg",
|
|
),
|
|
),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
],
|
|
),
|
|
),
|
|
const SizedBox(height: 15),
|
|
],
|
|
),
|
|
Container(
|
|
decoration: BoxDecoration(
|
|
borderRadius: BorderRadius.circular(15),
|
|
color:
|
|
isDark
|
|
? AppThemeData.greyDark50
|
|
: AppThemeData.grey50,
|
|
border: Border.all(
|
|
color:
|
|
isDark
|
|
? AppThemeData.greyDark200
|
|
: AppThemeData.grey200,
|
|
),
|
|
),
|
|
padding: const EdgeInsets.all(16),
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
Text(
|
|
"Order Summary".tr,
|
|
style: AppThemeData.boldTextStyle(
|
|
fontSize: 14,
|
|
color: AppThemeData.grey500,
|
|
),
|
|
),
|
|
const SizedBox(height: 8),
|
|
|
|
// Subtotal
|
|
_summaryTile(
|
|
"Subtotal".tr,
|
|
Constant.amountShow(
|
|
amount: controller.subTotal.value.toString(),
|
|
),
|
|
isDark,
|
|
),
|
|
|
|
// Discount
|
|
_summaryTile(
|
|
"Discount".tr,
|
|
Constant.amountShow(
|
|
amount: controller.discount.value.toString(),
|
|
),
|
|
isDark,
|
|
),
|
|
|
|
// Tax List
|
|
...List.generate(
|
|
controller.parcelOrder.value.taxSetting!.length,
|
|
(index) {
|
|
return _summaryTile(
|
|
"${controller.parcelOrder.value.taxSetting![index].title} ${controller.parcelOrder.value.taxSetting![index].type == 'fix' ? '' : '(${controller.parcelOrder.value.taxSetting![index].tax}%)'}",
|
|
Constant.amountShow(
|
|
amount:
|
|
Constant.getTaxValue(
|
|
amount:
|
|
((double.tryParse(
|
|
controller
|
|
.parcelOrder
|
|
.value
|
|
.subTotal
|
|
.toString(),
|
|
) ??
|
|
0.0) -
|
|
(double.tryParse(
|
|
controller
|
|
.parcelOrder
|
|
.value
|
|
.discount
|
|
.toString(),
|
|
) ??
|
|
0.0))
|
|
.toString(),
|
|
taxModel:
|
|
controller
|
|
.parcelOrder
|
|
.value
|
|
.taxSetting![index],
|
|
).toString(),
|
|
),
|
|
isDark,
|
|
);
|
|
},
|
|
),
|
|
|
|
const Divider(),
|
|
|
|
// Total
|
|
_summaryTile(
|
|
"Order Total".tr,
|
|
Constant.amountShow(
|
|
amount:
|
|
controller.totalAmount.value.toString(),
|
|
),
|
|
isDark,
|
|
),
|
|
],
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
bottomNavigationBar:
|
|
controller.parcelOrder.value.status == Constant.orderPlaced
|
|
? Padding(
|
|
padding: const EdgeInsets.all(16.0),
|
|
child: RoundedButtonFill(
|
|
title: "Cancel Parcel".tr,
|
|
onPress: () {
|
|
controller.cancelParcelOrder();
|
|
},
|
|
height: 5,
|
|
borderRadius: 15,
|
|
color: AppThemeData.primary300,
|
|
textColor:
|
|
isDark
|
|
? AppThemeData.greyDark900
|
|
: AppThemeData.grey900,
|
|
),
|
|
)
|
|
: SizedBox(),
|
|
);
|
|
},
|
|
);
|
|
}
|
|
|
|
Widget statusBottomSheet(
|
|
BuildContext context,
|
|
ParcelOrderDetailsController controller,
|
|
bool isDark,
|
|
) {
|
|
return DraggableScrollableSheet(
|
|
initialChildSize: 0.30,
|
|
minChildSize: 0.20,
|
|
maxChildSize: 0.6,
|
|
expand: false,
|
|
builder: (context, scrollController) {
|
|
return Container(
|
|
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 20),
|
|
decoration: BoxDecoration(
|
|
color: isDark ? AppThemeData.grey500 : Colors.white,
|
|
borderRadius: BorderRadius.vertical(top: Radius.circular(24)),
|
|
),
|
|
child: SingleChildScrollView(
|
|
controller: scrollController,
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
Text(
|
|
"Parcel Status Timeline".tr,
|
|
style: AppThemeData.semiBoldTextStyle(
|
|
color:
|
|
isDark
|
|
? AppThemeData.greyDark900
|
|
: AppThemeData.grey900,
|
|
fontSize: 18,
|
|
),
|
|
),
|
|
const SizedBox(height: 8),
|
|
|
|
// Dynamic List
|
|
Obx(() {
|
|
final history =
|
|
controller.parcelOrder.value.statusHistory ?? [];
|
|
|
|
if (history.isEmpty) {
|
|
return SizedBox(
|
|
height: 80,
|
|
child: Center(
|
|
child: Text(
|
|
"No status updates yet".tr,
|
|
style: AppThemeData.mediumTextStyle(
|
|
color:
|
|
isDark
|
|
? AppThemeData.greyDark900
|
|
: AppThemeData.grey900,
|
|
),
|
|
),
|
|
),
|
|
);
|
|
}
|
|
|
|
return SizedBox(
|
|
height: history.length * 70.0,
|
|
child: ListView.builder(
|
|
physics: const BouncingScrollPhysics(),
|
|
itemCount: history.length,
|
|
itemBuilder: (context, index) {
|
|
final statusUpdate = history[index];
|
|
final isCompleted = index < history.length;
|
|
|
|
return Padding(
|
|
padding: const EdgeInsets.symmetric(vertical: 8.0),
|
|
child: Row(
|
|
crossAxisAlignment: CrossAxisAlignment.center,
|
|
children: [
|
|
Image.asset(
|
|
isCompleted
|
|
? "assets/images/image_status_timeline.png"
|
|
: "assets/images/image_timeline.png",
|
|
height: 48,
|
|
width: 48,
|
|
),
|
|
const SizedBox(width: 20),
|
|
Expanded(
|
|
child: Text(
|
|
statusUpdate.status ?? '',
|
|
style: AppThemeData.semiBoldTextStyle(
|
|
color:
|
|
isCompleted
|
|
? (isDark
|
|
? AppThemeData.greyDark900
|
|
: AppThemeData.grey900)
|
|
: AppThemeData.grey500,
|
|
fontSize: 18,
|
|
),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
);
|
|
},
|
|
),
|
|
);
|
|
}),
|
|
],
|
|
),
|
|
),
|
|
);
|
|
},
|
|
);
|
|
}
|
|
|
|
Widget _infoSection(
|
|
String title,
|
|
String name,
|
|
String address,
|
|
String phone,
|
|
bool isDark,
|
|
) {
|
|
return Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
Text(
|
|
title,
|
|
style: AppThemeData.semiBoldTextStyle(
|
|
fontSize: 18,
|
|
color: isDark ? AppThemeData.greyDark900 : AppThemeData.grey900,
|
|
),
|
|
),
|
|
Text(
|
|
name,
|
|
style: AppThemeData.semiBoldTextStyle(
|
|
fontSize: 16,
|
|
color: isDark ? AppThemeData.greyDark900 : AppThemeData.grey900,
|
|
),
|
|
),
|
|
Text(
|
|
address,
|
|
style: AppThemeData.mediumTextStyle(
|
|
fontSize: 14,
|
|
color: isDark ? AppThemeData.greyDark900 : AppThemeData.grey900,
|
|
),
|
|
),
|
|
Text(
|
|
phone,
|
|
style: AppThemeData.mediumTextStyle(
|
|
fontSize: 14,
|
|
color: isDark ? AppThemeData.greyDark900 : AppThemeData.grey900,
|
|
),
|
|
),
|
|
// Text(time, style: AppThemeData.semiBoldTextStyle(fontSize: 14, color: isDark ? AppThemeData.greyDark900 : AppThemeData.grey900)),
|
|
],
|
|
);
|
|
}
|
|
|
|
Widget _iconTile(String value, title, icon, bool isDark) {
|
|
return Column(
|
|
children: [
|
|
// Icon(icon, color: AppThemeData.primary300),
|
|
SvgPicture.asset(
|
|
icon,
|
|
height: 28,
|
|
width: 28,
|
|
color: isDark ? AppThemeData.greyDark800 : AppThemeData.grey800,
|
|
),
|
|
const SizedBox(height: 6),
|
|
Text(
|
|
value,
|
|
style: AppThemeData.semiBoldTextStyle(
|
|
fontSize: 16,
|
|
color: isDark ? AppThemeData.greyDark800 : AppThemeData.grey800,
|
|
),
|
|
),
|
|
const SizedBox(height: 6),
|
|
Text(
|
|
title,
|
|
style: AppThemeData.semiBoldTextStyle(
|
|
fontSize: 12,
|
|
color: isDark ? AppThemeData.greyDark900 : AppThemeData.grey900,
|
|
),
|
|
),
|
|
],
|
|
);
|
|
}
|
|
|
|
Widget _summaryTile(String title, String value, bool isDark) {
|
|
return Padding(
|
|
padding: const EdgeInsets.symmetric(vertical: 4),
|
|
child: Row(
|
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
children: [
|
|
Text(
|
|
title,
|
|
style: AppThemeData.mediumTextStyle(
|
|
fontSize: 16,
|
|
color: isDark ? AppThemeData.greyDark800 : AppThemeData.grey800,
|
|
),
|
|
),
|
|
Text(
|
|
value,
|
|
style: AppThemeData.semiBoldTextStyle(
|
|
fontSize: title == "Order Total".tr ? 18 : 16,
|
|
color: isDark ? AppThemeData.greyDark900 : AppThemeData.grey900,
|
|
),
|
|
),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
}
|