BASE: Update Icons & Name Of The App.

This commit is contained in:
2025-12-04 10:23:59 +05:00
parent b04050384d
commit e602782edd
228 changed files with 34364 additions and 7905 deletions

View File

@@ -8,7 +8,7 @@ import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_svg/svg.dart';
import 'package:get/get.dart';
import 'package:get/get.dart' hide Trans;
import '../../constant/constant.dart';
import '../../controllers/book_parcel_controller.dart';
import '../../controllers/theme_controller.dart';
@@ -43,8 +43,20 @@ class BookParcelScreen extends StatelessWidget {
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))),
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),
@@ -52,12 +64,21 @@ class BookParcelScreen extends StatelessWidget {
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text("Book Your Document Delivery".tr(), style: AppThemeData.boldTextStyle(fontSize: 18, color: AppThemeData.grey900)),
Text(
"Book Your Document Delivery".tr(),
style: AppThemeData.boldTextStyle(
fontSize: 18,
color: AppThemeData.grey900,
),
),
Text(
"Schedule a secure and timely pickup & delivery".tr(),
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: AppThemeData.mediumTextStyle(fontSize: 12, color: AppThemeData.grey900),
style: AppThemeData.mediumTextStyle(
fontSize: 12,
color: AppThemeData.grey900,
),
),
],
),
@@ -84,7 +105,8 @@ class BookParcelScreen extends StatelessWidget {
nameController: controller.senderNameController.value,
mobileController: controller.senderMobileController.value,
noteController: controller.senderNoteController.value,
countryCodeController: controller.senderCountryCodeController.value,
countryCodeController:
controller.senderCountryCodeController.value,
showWeight: true,
isDark: isDark,
context: context,
@@ -95,14 +117,25 @@ class BookParcelScreen extends StatelessWidget {
if (result != null) {
final firstPlace = result;
if (Constant.checkZoneCheck(firstPlace.coordinates.latitude, firstPlace.coordinates.longitude) == true) {
if (Constant.checkZoneCheck(
firstPlace.coordinates.latitude,
firstPlace.coordinates.longitude,
) ==
true) {
final address = firstPlace.address;
final lat = firstPlace.coordinates.latitude;
final lng = firstPlace.coordinates.longitude;
controller.senderLocationController.value.text = address; // ✅
controller.senderLocation.value = UserLocation(latitude: lat, longitude: lng); // ✅ <-- Add this
controller.senderLocationController.value.text =
address; // ✅
controller.senderLocation.value = UserLocation(
latitude: lat,
longitude: lng,
); // ✅ <-- Add this
} else {
ShowToastDialog.showToast("Service is unavailable at the selected address.".tr());
ShowToastDialog.showToast(
"Service is unavailable at the selected address."
.tr(),
);
}
}
} else {
@@ -110,11 +143,27 @@ class BookParcelScreen extends StatelessWidget {
if (value != null) {
SelectedLocationModel selectedLocationModel = value;
if (Constant.checkZoneCheck(selectedLocationModel.latLng!.latitude, selectedLocationModel.latLng!.longitude) == true) {
controller.senderLocationController.value.text = Utils.formatAddress(selectedLocation: selectedLocationModel);
controller.senderLocation.value = UserLocation(latitude: selectedLocationModel.latLng!.latitude, longitude: selectedLocationModel.latLng!.longitude);
if (Constant.checkZoneCheck(
selectedLocationModel.latLng!.latitude,
selectedLocationModel.latLng!.longitude,
) ==
true) {
controller
.senderLocationController
.value
.text = Utils.formatAddress(
selectedLocation: selectedLocationModel,
);
controller.senderLocation.value = UserLocation(
latitude: selectedLocationModel.latLng!.latitude,
longitude:
selectedLocationModel.latLng!.longitude,
);
} else {
ShowToastDialog.showToast("Service is unavailable at the selected address.".tr());
ShowToastDialog.showToast(
"Service is unavailable at the selected address."
.tr(),
);
}
// ✅ <-- Add this
}
@@ -125,11 +174,13 @@ class BookParcelScreen extends StatelessWidget {
const SizedBox(height: 16),
buildInfoSectionView(
title: "Receiver Information".tr(),
locationController: controller.receiverLocationController.value,
locationController:
controller.receiverLocationController.value,
nameController: controller.receiverNameController.value,
mobileController: controller.receiverMobileController.value,
noteController: controller.receiverNoteController.value,
countryCodeController: controller.receiverCountryCodeController.value,
countryCodeController:
controller.receiverCountryCodeController.value,
showWeight: false,
isDark: isDark,
context: context,
@@ -140,15 +191,26 @@ class BookParcelScreen extends StatelessWidget {
if (result != null) {
final firstPlace = result;
if (Constant.checkZoneCheck(firstPlace.coordinates.latitude, firstPlace.coordinates.longitude) == true) {
if (Constant.checkZoneCheck(
firstPlace.coordinates.latitude,
firstPlace.coordinates.longitude,
) ==
true) {
final lat = firstPlace.coordinates.latitude;
final lng = firstPlace.coordinates.longitude;
final address = firstPlace.address;
controller.receiverLocationController.value.text = address; // ✅
controller.receiverLocation.value = UserLocation(latitude: lat, longitude: lng);
controller.receiverLocationController.value.text =
address; // ✅
controller.receiverLocation.value = UserLocation(
latitude: lat,
longitude: lng,
);
} else {
ShowToastDialog.showToast("Service is unavailable at the selected address.".tr());
ShowToastDialog.showToast(
"Service is unavailable at the selected address."
.tr(),
);
}
}
} else {
@@ -156,11 +218,27 @@ class BookParcelScreen extends StatelessWidget {
if (value != null) {
SelectedLocationModel selectedLocationModel = value;
if (Constant.checkZoneCheck(selectedLocationModel.latLng!.latitude, selectedLocationModel.latLng!.longitude) == true) {
controller.receiverLocationController.value.text = Utils.formatAddress(selectedLocation: selectedLocationModel);
controller.receiverLocation.value = UserLocation(latitude: selectedLocationModel.latLng!.latitude, longitude: selectedLocationModel.latLng!.longitude); // ✅ <-- Add this
if (Constant.checkZoneCheck(
selectedLocationModel.latLng!.latitude,
selectedLocationModel.latLng!.longitude,
) ==
true) {
controller
.receiverLocationController
.value
.text = Utils.formatAddress(
selectedLocation: selectedLocationModel,
);
controller.receiverLocation.value = UserLocation(
latitude: selectedLocationModel.latLng!.latitude,
longitude:
selectedLocationModel.latLng!.longitude,
); // ✅ <-- Add this
} else {
ShowToastDialog.showToast("Service is unavailable at the selected address.".tr());
ShowToastDialog.showToast(
"Service is unavailable at the selected address."
.tr(),
);
}
}
});
@@ -187,18 +265,30 @@ class BookParcelScreen extends StatelessWidget {
);
}
Widget selectDeliveryTypeView(BookParcelController controller, bool isDark, BuildContext context) {
Widget selectDeliveryTypeView(
BookParcelController controller,
bool isDark,
BuildContext context,
) {
return Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(15),
color: isDark ? AppThemeData.greyDark50 : AppThemeData.grey50,
border: Border.all(color: isDark ? AppThemeData.greyDark200 : AppThemeData.grey200),
border: Border.all(
color: isDark ? AppThemeData.greyDark200 : AppThemeData.grey200,
),
),
padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 15),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text("Select delivery type".tr(), style: AppThemeData.boldTextStyle(color: isDark ? AppThemeData.greyDark500 : AppThemeData.grey500, fontSize: 13)),
Text(
"Select delivery type".tr(),
style: AppThemeData.boldTextStyle(
color: isDark ? AppThemeData.greyDark500 : AppThemeData.grey500,
fontSize: 13,
),
),
const SizedBox(height: 10),
InkWell(
onTap: () {
@@ -207,12 +297,34 @@ class BookParcelScreen extends StatelessWidget {
},
child: Row(
children: [
Image.asset("assets/images/image_parcel.png", height: 38, width: 38),
Image.asset(
"assets/images/image_parcel.png",
height: 38,
width: 38,
),
const SizedBox(width: 20),
Expanded(child: Text("As soon as possible".tr(), style: AppThemeData.semiBoldTextStyle(color: isDark ? AppThemeData.greyDark900 : AppThemeData.grey900, fontSize: 16))),
Expanded(
child: Text(
"As soon as possible".tr(),
style: AppThemeData.semiBoldTextStyle(
color:
isDark
? AppThemeData.greyDark900
: AppThemeData.grey900,
fontSize: 16,
),
),
),
Icon(
controller.selectedDeliveryType.value == 'now' ? Icons.radio_button_checked : Icons.radio_button_off,
color: controller.selectedDeliveryType.value == 'now' ? AppThemeData.primary300 : (isDark ? AppThemeData.greyDark500 : AppThemeData.grey500),
controller.selectedDeliveryType.value == 'now'
? Icons.radio_button_checked
: Icons.radio_button_off,
color:
controller.selectedDeliveryType.value == 'now'
? AppThemeData.primary300
: (isDark
? AppThemeData.greyDark500
: AppThemeData.grey500),
size: 20,
),
],
@@ -228,12 +340,34 @@ class BookParcelScreen extends StatelessWidget {
children: [
Row(
children: [
Image.asset("assets/images/image_parcel_scheduled.png", height: 38, width: 38),
Image.asset(
"assets/images/image_parcel_scheduled.png",
height: 38,
width: 38,
),
const SizedBox(width: 20),
Expanded(child: Text("Scheduled".tr(), style: AppThemeData.semiBoldTextStyle(color: isDark ? AppThemeData.greyDark900 : AppThemeData.grey900, fontSize: 16))),
Expanded(
child: Text(
"Scheduled".tr(),
style: AppThemeData.semiBoldTextStyle(
color:
isDark
? AppThemeData.greyDark900
: AppThemeData.grey900,
fontSize: 16,
),
),
),
Icon(
controller.selectedDeliveryType.value == 'later' ? Icons.radio_button_checked : Icons.radio_button_off,
color: controller.selectedDeliveryType.value == 'later' ? AppThemeData.primary300 : (isDark ? AppThemeData.greyDark500 : AppThemeData.grey500),
controller.selectedDeliveryType.value == 'later'
? Icons.radio_button_checked
: Icons.radio_button_off,
color:
controller.selectedDeliveryType.value == 'later'
? AppThemeData.primary300
: (isDark
? AppThemeData.greyDark500
: AppThemeData.grey500),
size: 20,
),
],
@@ -246,9 +380,18 @@ class BookParcelScreen extends StatelessWidget {
hintText: "When to pickup at this address".tr(),
controller: controller.scheduledDateController.value,
enable: false,
backgroundColor: isDark ? AppThemeData.surfaceDark : AppThemeData.surface,
borderColor: isDark ? AppThemeData.greyDark200 : AppThemeData.grey200,
suffix: const Padding(padding: EdgeInsets.only(right: 10), child: Icon(Icons.calendar_month_outlined)),
backgroundColor:
isDark
? AppThemeData.surfaceDark
: AppThemeData.surface,
borderColor:
isDark
? AppThemeData.greyDark200
: AppThemeData.grey200,
suffix: const Padding(
padding: EdgeInsets.only(right: 10),
child: Icon(Icons.calendar_month_outlined),
),
),
),
const SizedBox(height: 10),
@@ -259,9 +402,18 @@ class BookParcelScreen extends StatelessWidget {
controller: controller.scheduledTimeController.value,
enable: false,
// onchange: (v) => controller.pickScheduledTime(context),
backgroundColor: isDark ? AppThemeData.surfaceDark : AppThemeData.surface,
borderColor: isDark ? AppThemeData.greyDark200 : AppThemeData.grey200,
suffix: const Padding(padding: EdgeInsets.only(right: 10), child: Icon(Icons.access_time)),
backgroundColor:
isDark
? AppThemeData.surfaceDark
: AppThemeData.surface,
borderColor:
isDark
? AppThemeData.greyDark200
: AppThemeData.grey200,
suffix: const Padding(
padding: EdgeInsets.only(right: 10),
child: Icon(Icons.access_time),
),
),
),
],
@@ -278,29 +430,75 @@ class BookParcelScreen extends StatelessWidget {
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(15),
color: isDark ? AppThemeData.greyDark50 : AppThemeData.grey50,
border: Border.all(color: isDark ? AppThemeData.greyDark200 : AppThemeData.grey200),
border: Border.all(
color: isDark ? AppThemeData.greyDark200 : AppThemeData.grey200,
),
),
padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 15),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text("Upload parcel image".tr(), style: AppThemeData.boldTextStyle(color: isDark ? AppThemeData.greyDark500 : AppThemeData.grey500, fontSize: 13)),
Text(
"Upload parcel image".tr(),
style: AppThemeData.boldTextStyle(
color: isDark ? AppThemeData.greyDark500 : AppThemeData.grey500,
fontSize: 13,
),
),
const SizedBox(height: 10),
DottedBorder(
options: RoundedRectDottedBorderOptions(strokeWidth: 1, radius: const Radius.circular(10), color: isDark ? AppThemeData.greyDark300 : AppThemeData.grey300),
options: RoundedRectDottedBorderOptions(
strokeWidth: 1,
radius: const Radius.circular(10),
color: isDark ? AppThemeData.greyDark300 : AppThemeData.grey300,
),
child: Container(
alignment: Alignment.center,
decoration: BoxDecoration(borderRadius: BorderRadius.circular(10), color: isDark ? AppThemeData.greyDark50 : AppThemeData.grey50),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
color: isDark ? AppThemeData.greyDark50 : AppThemeData.grey50,
),
padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 50),
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
SvgPicture.asset("assets/icons/ic_upload_parcel.svg", height: 40, width: 40),
SvgPicture.asset(
"assets/icons/ic_upload_parcel.svg",
height: 40,
width: 40,
),
const SizedBox(height: 10),
Text("Upload Parcel Image".tr(), style: AppThemeData.mediumTextStyle(fontSize: 16, color: isDark ? AppThemeData.greyDark900 : AppThemeData.grey900)),
Text(
"Upload Parcel Image".tr(),
style: AppThemeData.mediumTextStyle(
fontSize: 16,
color:
isDark
? AppThemeData.greyDark900
: AppThemeData.grey900,
),
),
const SizedBox(height: 4),
Text("Supported: .jpg, .jpeg, .png".tr(), style: AppThemeData.semiBoldTextStyle(fontSize: 12, color: isDark ? AppThemeData.greyDark800 : AppThemeData.grey800)),
Text("Max size 1MB".tr(), style: AppThemeData.semiBoldTextStyle(fontSize: 12, color: isDark ? AppThemeData.greyDark800 : AppThemeData.grey800)),
Text(
"Supported: .jpg, .jpeg, .png".tr(),
style: AppThemeData.semiBoldTextStyle(
fontSize: 12,
color:
isDark
? AppThemeData.greyDark800
: AppThemeData.grey800,
),
),
Text(
"Max size 1MB".tr(),
style: AppThemeData.semiBoldTextStyle(
fontSize: 12,
color:
isDark
? AppThemeData.greyDark800
: AppThemeData.grey800,
),
),
const SizedBox(height: 8),
RoundedButtonFill(
title: "Browse Image".tr(),
@@ -326,7 +524,15 @@ class BookParcelScreen extends StatelessWidget {
children: [
Container(
padding: const EdgeInsets.only(top: 20, right: 20),
child: ClipRRect(borderRadius: BorderRadius.circular(8), child: Image.file(File(image.path), width: 70, height: 70, fit: BoxFit.cover)),
child: ClipRRect(
borderRadius: BorderRadius.circular(8),
child: Image.file(
File(image.path),
width: 70,
height: 70,
fit: BoxFit.cover,
),
),
),
Positioned.fill(
top: 0,
@@ -334,7 +540,11 @@ class BookParcelScreen extends StatelessWidget {
child: Align(
alignment: Alignment.topRight,
child: IconButton(
icon: const Icon(Icons.cancel, color: AppThemeData.danger300, size: 20),
icon: const Icon(
Icons.cancel,
color: AppThemeData.danger300,
size: 20,
),
onPressed: () {
controller.images.remove(image);
},
@@ -367,13 +577,21 @@ class BookParcelScreen extends StatelessWidget {
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(15),
color: isDark ? AppThemeData.greyDark50 : AppThemeData.grey50,
border: Border.all(color: isDark ? AppThemeData.greyDark200 : AppThemeData.grey200),
border: Border.all(
color: isDark ? AppThemeData.greyDark200 : AppThemeData.grey200,
),
),
padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 15),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(title, style: AppThemeData.boldTextStyle(color: isDark ? AppThemeData.greyDark500 : AppThemeData.grey500, fontSize: 13)),
Text(
title,
style: AppThemeData.boldTextStyle(
color: isDark ? AppThemeData.greyDark500 : AppThemeData.grey500,
fontSize: 13,
),
),
const SizedBox(height: 10),
GestureDetector(
@@ -382,9 +600,14 @@ class BookParcelScreen extends StatelessWidget {
hintText: "Your Location".tr(),
controller: locationController,
suffix: const Padding(padding: EdgeInsets.only(right: 10), child: Icon(Icons.location_on_outlined)),
backgroundColor: isDark ? AppThemeData.surfaceDark : AppThemeData.surface,
borderColor: isDark ? AppThemeData.greyDark200 : AppThemeData.grey200,
suffix: const Padding(
padding: EdgeInsets.only(right: 10),
child: Icon(Icons.location_on_outlined),
),
backgroundColor:
isDark ? AppThemeData.surfaceDark : AppThemeData.surface,
borderColor:
isDark ? AppThemeData.greyDark200 : AppThemeData.grey200,
enable: false,
),
),
@@ -393,8 +616,10 @@ class BookParcelScreen extends StatelessWidget {
TextFieldWidget(
hintText: "Name".tr(),
controller: nameController,
backgroundColor: isDark ? AppThemeData.surfaceDark : AppThemeData.surface,
borderColor: isDark ? AppThemeData.greyDark200 : AppThemeData.grey200,
backgroundColor:
isDark ? AppThemeData.surfaceDark : AppThemeData.surface,
borderColor:
isDark ? AppThemeData.greyDark200 : AppThemeData.grey200,
),
const SizedBox(height: 10),
@@ -402,24 +627,49 @@ class BookParcelScreen extends StatelessWidget {
hintText: "Enter Mobile number".tr(),
controller: mobileController,
textInputType: TextInputType.number,
inputFormatters: [FilteringTextInputFormatter.allow(RegExp('[0-9]')), LengthLimitingTextInputFormatter(10)],
backgroundColor: isDark ? AppThemeData.surfaceDark : AppThemeData.surface,
borderColor: isDark ? AppThemeData.greyDark200 : AppThemeData.grey200,
inputFormatters: [
FilteringTextInputFormatter.allow(RegExp('[0-9]')),
LengthLimitingTextInputFormatter(10),
],
backgroundColor:
isDark ? AppThemeData.surfaceDark : AppThemeData.surface,
borderColor:
isDark ? AppThemeData.greyDark200 : AppThemeData.grey200,
prefix: Row(
mainAxisSize: MainAxisSize.min,
children: [
CountryCodePicker(
onChanged: (value) {
countryCodeController.text = value.dialCode ?? Constant.defaultCountryCode;
countryCodeController.text =
value.dialCode ?? Constant.defaultCountryCode;
},
initialSelection: countryCodeController.text.isNotEmpty ? countryCodeController.text : Constant.defaultCountryCode,
initialSelection:
countryCodeController.text.isNotEmpty
? countryCodeController.text
: Constant.defaultCountryCode,
showCountryOnly: false,
showOnlyCountryWhenClosed: false,
alignLeft: false,
textStyle: TextStyle(fontSize: 16, color: isDark ? AppThemeData.greyDark900 : Colors.black),
dialogTextStyle: TextStyle(fontSize: 16, color: isDark ? AppThemeData.greyDark900 : AppThemeData.grey900),
searchStyle: TextStyle(fontSize: 16, color: isDark ? AppThemeData.greyDark900 : AppThemeData.grey900),
dialogBackgroundColor: isDark ? AppThemeData.surfaceDark : AppThemeData.surface,
textStyle: TextStyle(
fontSize: 16,
color: isDark ? AppThemeData.greyDark900 : Colors.black,
),
dialogTextStyle: TextStyle(
fontSize: 16,
color:
isDark
? AppThemeData.greyDark900
: AppThemeData.grey900,
),
searchStyle: TextStyle(
fontSize: 16,
color:
isDark
? AppThemeData.greyDark900
: AppThemeData.grey900,
),
dialogBackgroundColor:
isDark ? AppThemeData.surfaceDark : AppThemeData.surface,
padding: EdgeInsets.zero,
),
// const Icon(Icons.keyboard_arrow_down_rounded, size: 24, color: AppThemeData.grey400),
@@ -437,19 +687,37 @@ class BookParcelScreen extends StatelessWidget {
enableSearch: false,
textFieldDecoration: InputDecoration(
hintText: "Select parcel Weight".tr(),
hintStyle: AppThemeData.regularTextStyle(fontSize: 14, color: isDark ? AppThemeData.grey400 : AppThemeData.greyDark400),
hintStyle: AppThemeData.regularTextStyle(
fontSize: 14,
color:
isDark ? AppThemeData.grey400 : AppThemeData.greyDark400,
),
filled: true,
fillColor: isDark ? AppThemeData.surfaceDark : AppThemeData.surface,
contentPadding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12),
border: OutlineInputBorder(borderRadius: BorderRadius.circular(10), borderSide: BorderSide(color: AppThemeData.grey200)),
enabledBorder: OutlineInputBorder(borderRadius: BorderRadius.circular(10), borderSide: BorderSide(color: AppThemeData.grey200)),
focusedBorder: OutlineInputBorder(borderRadius: BorderRadius.circular(10), borderSide: BorderSide(color: AppThemeData.grey200)),
fillColor:
isDark ? AppThemeData.surfaceDark : AppThemeData.surface,
contentPadding: const EdgeInsets.symmetric(
horizontal: 16,
vertical: 12,
),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
borderSide: BorderSide(color: AppThemeData.grey200),
),
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
borderSide: BorderSide(color: AppThemeData.grey200),
),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
borderSide: BorderSide(color: AppThemeData.grey200),
),
),
dropDownList:
controller.parcelWeight.map((e) {
return DropDownValueModel(
name: e.title ?? 'Normal'.tr(),
value: e.title ?? 'Normal'.tr(), // safer to use title string
value:
e.title ?? 'Normal'.tr(), // safer to use title string
);
}).toList(),
onChanged: (val) {
@@ -457,7 +725,8 @@ class BookParcelScreen extends StatelessWidget {
controller.senderWeightController.value.setDropDown(val);
// Link it to the selectedWeight object
controller.selectedWeight = controller.parcelWeight.firstWhereOrNull((e) => e.title == val.value);
controller.selectedWeight = controller.parcelWeight
.firstWhereOrNull((e) => e.title == val.value);
}
},
),
@@ -467,8 +736,10 @@ class BookParcelScreen extends StatelessWidget {
TextFieldWidget(
hintText: "Notes (Optional)".tr(),
controller: noteController,
backgroundColor: isDark ? AppThemeData.surfaceDark : AppThemeData.surface,
borderColor: isDark ? AppThemeData.greyDark200 : AppThemeData.grey200,
backgroundColor:
isDark ? AppThemeData.surfaceDark : AppThemeData.surface,
borderColor:
isDark ? AppThemeData.greyDark200 : AppThemeData.grey200,
),
],
),

View File

@@ -3,7 +3,7 @@ import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:geocoding/geocoding.dart';
import 'package:geolocator/geolocator.dart';
import 'package:get/get.dart';
import 'package:get/get.dart' hide Trans;
import '../../controllers/home_parcel_controller.dart';
import '../../controllers/theme_controller.dart';
import '../../models/banner_model.dart';
@@ -46,8 +46,20 @@ class HomeParcelScreen extends StatelessWidget {
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))),
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),
@@ -60,9 +72,21 @@ class HomeParcelScreen extends StatelessWidget {
onTap: () {
Get.offAll(const LoginScreen());
},
child: Text("Login".tr(), style: AppThemeData.boldTextStyle(fontSize: 14, color: AppThemeData.grey900)),
child: Text(
"Login".tr(),
style: AppThemeData.boldTextStyle(
fontSize: 14,
color: AppThemeData.grey900,
),
),
)
: Text(Constant.userModel!.fullName(), style: AppThemeData.boldTextStyle(fontSize: 14, color: AppThemeData.grey900)),
: Text(
Constant.userModel!.fullName(),
style: AppThemeData.boldTextStyle(
fontSize: 14,
color: AppThemeData.grey900,
),
),
InkWell(
onTap: () async {
if (Constant.userModel != null) {
@@ -75,9 +99,12 @@ class HomeParcelScreen extends StatelessWidget {
} else {
Constant.checkPermission(
onTap: () async {
ShowToastDialog.showLoader("Please wait...".tr());
ShowToastDialog.showLoader(
"Please wait...".tr(),
);
ShippingAddress shippingAddress = ShippingAddress();
ShippingAddress shippingAddress =
ShippingAddress();
try {
await Geolocator.requestPermission();
@@ -85,40 +112,71 @@ class HomeParcelScreen extends StatelessWidget {
ShowToastDialog.closeLoader();
if (Constant.selectedMapType == 'osm') {
final result = await Get.to(() => MapPickerPage());
final result = await Get.to(
() => MapPickerPage(),
);
if (result != null) {
final firstPlace = result;
final lat = firstPlace.coordinates.latitude;
final lng = firstPlace.coordinates.longitude;
final lat =
firstPlace.coordinates.latitude;
final lng =
firstPlace.coordinates.longitude;
final address = firstPlace.address;
shippingAddress.addressAs = "Home";
shippingAddress.locality = address.toString();
shippingAddress.location = UserLocation(latitude: lat, longitude: lng);
shippingAddress.locality =
address.toString();
shippingAddress.location = UserLocation(
latitude: lat,
longitude: lng,
);
Constant.selectedLocation = shippingAddress;
Constant.selectedLocation =
shippingAddress;
Get.back();
}
} else {
Get.to(LocationPickerScreen())!.then((value) async {
Get.to(LocationPickerScreen())!.then((
value,
) async {
if (value != null) {
SelectedLocationModel selectedLocationModel = value;
SelectedLocationModel
selectedLocationModel = value;
shippingAddress.addressAs = "Home";
shippingAddress.location = UserLocation(latitude: selectedLocationModel.latLng!.latitude, longitude: selectedLocationModel.latLng!.longitude);
shippingAddress.locality = "Picked from Map";
shippingAddress
.location = UserLocation(
latitude:
selectedLocationModel
.latLng!
.latitude,
longitude:
selectedLocationModel
.latLng!
.longitude,
);
shippingAddress.locality =
"Picked from Map";
Constant.selectedLocation = shippingAddress;
Constant.selectedLocation =
shippingAddress;
}
});
}
} catch (e) {
await placemarkFromCoordinates(19.228825, 72.854118).then((valuePlaceMaker) {
await placemarkFromCoordinates(
19.228825,
72.854118,
).then((valuePlaceMaker) {
Placemark placeMark = valuePlaceMaker[0];
shippingAddress.location = UserLocation(latitude: 19.228825, longitude: 72.854118);
shippingAddress.location = UserLocation(
latitude: 19.228825,
longitude: 72.854118,
);
String currentLocation =
"${placeMark.name}, ${placeMark.subLocality}, ${placeMark.locality}, ${placeMark.administrativeArea}, ${placeMark.postalCode}, ${placeMark.country}";
shippingAddress.locality = currentLocation;
shippingAddress.locality =
currentLocation;
});
Constant.selectedLocation = shippingAddress;
@@ -133,7 +191,10 @@ class HomeParcelScreen extends StatelessWidget {
Constant.selectedLocation.getFullAddress(),
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: AppThemeData.boldTextStyle(fontSize: 18, color: AppThemeData.grey900),
style: AppThemeData.boldTextStyle(
fontSize: 18,
color: AppThemeData.grey900,
),
),
),
],
@@ -160,22 +221,46 @@ class HomeParcelScreen extends StatelessWidget {
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text("What are you sending?".tr(), style: AppThemeData.mediumTextStyle(fontSize: 18, color: isDark ? AppThemeData.greyDark900 : AppThemeData.grey900)),
Text(
"What are you sending?".tr(),
style: AppThemeData.mediumTextStyle(
fontSize: 18,
color:
isDark
? AppThemeData.greyDark900
: AppThemeData.grey900,
),
),
const SizedBox(height: 12),
Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(15),
color: isDark ? AppThemeData.greyDark50 : AppThemeData.grey50,
border: Border.all(color: isDark ? AppThemeData.greyDark200 : AppThemeData.grey200),
color:
isDark
? AppThemeData.greyDark50
: AppThemeData.grey50,
border: Border.all(
color:
isDark
? AppThemeData.greyDark200
: AppThemeData.grey200,
),
),
padding: const EdgeInsets.symmetric(
horizontal: 20,
),
padding: const EdgeInsets.symmetric(horizontal: 20),
child: ListView.builder(
itemCount: controller.parcelCategory.length,
shrinkWrap: true,
physics: const ScrollPhysics(),
padding: const EdgeInsets.symmetric(vertical: 10),
padding: const EdgeInsets.symmetric(
vertical: 10,
),
itemBuilder: (context, index) {
return buildItems(item: controller.parcelCategory[index], isDark: isDark);
return buildItems(
item: controller.parcelCategory[index],
isDark: isDark,
);
},
),
),
@@ -199,16 +284,36 @@ class HomeParcelScreen extends StatelessWidget {
if (Constant.userModel == null) {
Get.to(const LoginScreen());
} else {
Get.to(const BookParcelScreen(), arguments: {'parcelCategory': item});
Get.to(
const BookParcelScreen(),
arguments: {'parcelCategory': item},
);
}
},
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
NetworkImageWidget(imageUrl: item.image ?? '', height: 38, width: 38),
NetworkImageWidget(
imageUrl: item.image ?? '',
height: 38,
width: 38,
),
const SizedBox(width: 20),
Expanded(child: Text(item.title ?? '', style: AppThemeData.semiBoldTextStyle(color: isDark ? AppThemeData.greyDark900 : AppThemeData.grey900, fontSize: 16))),
Icon(Icons.arrow_forward_ios, color: isDark ? AppThemeData.greyDark800 : AppThemeData.grey800, size: 20),
Expanded(
child: Text(
item.title ?? '',
style: AppThemeData.semiBoldTextStyle(
color:
isDark ? AppThemeData.greyDark900 : AppThemeData.grey900,
fontSize: 16,
),
),
),
Icon(
Icons.arrow_forward_ios,
color: isDark ? AppThemeData.greyDark800 : AppThemeData.grey800,
size: 20,
),
],
),
),
@@ -256,7 +361,13 @@ class BannerView extends StatelessWidget {
final banner = bannerList[index];
return ClipRRect(
borderRadius: BorderRadius.circular(15),
child: SizedBox(width: MediaQuery.of(context).size.width * 0.8, child: NetworkImageWidget(imageUrl: banner.photo ?? '', fit: BoxFit.cover)),
child: SizedBox(
width: MediaQuery.of(context).size.width * 0.8,
child: NetworkImageWidget(
imageUrl: banner.photo ?? '',
fit: BoxFit.cover,
),
),
);
},
),
@@ -266,7 +377,18 @@ class BannerView extends StatelessWidget {
return Row(
children: List.generate(bannerList.length, (index) {
bool isSelected = currentPage.value == index;
return Expanded(child: Container(height: 4, decoration: BoxDecoration(color: isSelected ? AppThemeData.grey300 : AppThemeData.grey100, borderRadius: BorderRadius.circular(5))));
return Expanded(
child: Container(
height: 4,
decoration: BoxDecoration(
color:
isSelected
? AppThemeData.grey300
: AppThemeData.grey100,
borderRadius: BorderRadius.circular(5),
),
),
);
}),
);
}),

View File

@@ -3,7 +3,7 @@ import 'package:customer/screen_ui/parcel_service/parcel_order_details.dart';
import 'package:customer/themes/round_button_fill.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:get/get.dart' hide Trans;
import '../../constant/constant.dart';
import '../../controllers/parcel_my_booking_controller.dart';
import '../../controllers/theme_controller.dart';
@@ -23,14 +23,27 @@ class MyBookingScreen extends StatelessWidget {
builder: (controller) {
return DefaultTabController(
length: controller.tabTitles.length,
initialIndex: controller.tabTitles.indexOf(controller.selectedTab.value),
initialIndex: controller.tabTitles.indexOf(
controller.selectedTab.value,
),
child: Scaffold(
appBar: AppBar(
automaticallyImplyLeading: false,
backgroundColor: AppThemeData.primary300,
title: Padding(
padding: const EdgeInsets.only(bottom: 10),
child: Row(children: [const SizedBox(width: 10), Text("Parcel History".tr(), style: AppThemeData.boldTextStyle(fontSize: 18, color: AppThemeData.grey900))]),
child: Row(
children: [
const SizedBox(width: 10),
Text(
"Parcel History".tr(),
style: AppThemeData.boldTextStyle(
fontSize: 18,
color: AppThemeData.grey900,
),
),
],
),
),
bottom: TabBar(
// don't re-subscribe onTap — just update selectedTab (optional)
@@ -41,8 +54,13 @@ class MyBookingScreen extends StatelessWidget {
labelColor: AppThemeData.parcelService500,
unselectedLabelColor: AppThemeData.parcelService500,
labelStyle: AppThemeData.boldTextStyle(fontSize: 15),
unselectedLabelStyle: AppThemeData.mediumTextStyle(fontSize: 15),
tabs: controller.tabTitles.map((title) => Tab(child: Center(child: Text(title)))).toList(),
unselectedLabelStyle: AppThemeData.mediumTextStyle(
fontSize: 15,
),
tabs:
controller.tabTitles
.map((title) => Tab(child: Center(child: Text(title))))
.toList(),
),
),
@@ -56,12 +74,30 @@ class MyBookingScreen extends StatelessWidget {
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Text("Please Log In to Continue".tr(), style: TextStyle(color: isDark ? AppThemeData.grey100 : AppThemeData.grey800, fontSize: 22, fontFamily: AppThemeData.semiBold)),
Text(
"Please Log In to Continue".tr(),
style: TextStyle(
color:
isDark
? AppThemeData.grey100
: AppThemeData.grey800,
fontSize: 22,
fontFamily: AppThemeData.semiBold,
),
),
const SizedBox(height: 5),
Text(
"Youre not logged in. Please sign in to access your account and explore all features.".tr(),
"Youre not logged in. Please sign in to access your account and explore all features."
.tr(),
textAlign: TextAlign.center,
style: TextStyle(color: isDark ? AppThemeData.grey50 : AppThemeData.grey500, fontSize: 16, fontFamily: AppThemeData.bold),
style: TextStyle(
color:
isDark
? AppThemeData.grey50
: AppThemeData.grey500,
fontSize: 16,
fontFamily: AppThemeData.bold,
),
),
const SizedBox(height: 20),
RoundedButtonFill(
@@ -83,7 +119,17 @@ class MyBookingScreen extends StatelessWidget {
final orders = controller.getOrdersForTab(title);
if (orders.isEmpty) {
return Center(child: Text("No orders found".tr(), style: AppThemeData.mediumTextStyle(color: isDark ? AppThemeData.greyDark900 : AppThemeData.grey900)));
return Center(
child: Text(
"No orders found".tr(),
style: AppThemeData.mediumTextStyle(
color:
isDark
? AppThemeData.greyDark900
: AppThemeData.grey900,
),
),
);
}
return ListView.builder(
@@ -93,55 +139,98 @@ class MyBookingScreen extends StatelessWidget {
final order = orders[index];
return GestureDetector(
onTap: () {
Get.to(() => const ParcelOrderDetails(), arguments: order);
Get.to(
() => const ParcelOrderDetails(),
arguments: order,
);
},
child: Container(
margin: const EdgeInsets.only(bottom: 16),
padding: const EdgeInsets.all(16),
decoration: BoxDecoration(
color: isDark ? AppThemeData.greyDark50 : AppThemeData.grey50,
color:
isDark
? AppThemeData.greyDark50
: AppThemeData.grey50,
borderRadius: BorderRadius.circular(15),
border: Border.all(color: isDark ? AppThemeData.greyDark200 : AppThemeData.grey200),
border: Border.all(
color:
isDark
? AppThemeData.greyDark200
: AppThemeData.grey200,
),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
Padding(
padding: const EdgeInsets.only(bottom: 8.0),
padding: const EdgeInsets.only(
bottom: 8.0,
),
child: Text(
"${'Order Date:'.tr()}${order.isSchedule == true ? controller.formatDate(order.createdAt!) : controller.formatDate(order.senderPickupDateTime!)}",
style: AppThemeData.mediumTextStyle(fontSize: 14, color: AppThemeData.info400),
style: AppThemeData.mediumTextStyle(
fontSize: 14,
color: AppThemeData.info400,
),
),
),
Row(
crossAxisAlignment: CrossAxisAlignment.start,
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
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,
),
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,
),
Image.asset("assets/images/image_parcel.png", height: 32, width: 32),
],
),
const SizedBox(width: 12),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
_infoSection(
"Pickup Address (Sender):".tr(),
"Pickup Address (Sender):"
.tr(),
order.sender?.name ?? '',
order.sender?.address ?? '',
order.sender?.phone ?? '',
@@ -153,9 +242,11 @@ class MyBookingScreen extends StatelessWidget {
),
const SizedBox(height: 16),
_infoSection(
"Delivery Address (Receiver):".tr(),
"Delivery Address (Receiver):"
.tr(),
order.receiver?.name ?? '',
order.receiver?.address ?? '',
order.receiver?.address ??
'',
order.receiver?.phone ?? '',
// order.receiverPickupDateTime != null
// ? "Delivery Time: ${controller.formatDate(order.receiverPickupDateTime!)}"
@@ -182,27 +273,74 @@ class MyBookingScreen extends StatelessWidget {
);
}
Widget _infoSection(String title, String name, String address, String phone, String? status, bool isDark) {
Widget _infoSection(
String title,
String name,
String address,
String phone,
String? status,
bool isDark,
) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Expanded(
child: Text(title, style: AppThemeData.semiBoldTextStyle(fontSize: 16, color: isDark ? AppThemeData.greyDark900 : AppThemeData.grey900), maxLines: 1, overflow: TextOverflow.ellipsis),
child: Text(
title,
style: AppThemeData.semiBoldTextStyle(
fontSize: 16,
color:
isDark ? AppThemeData.greyDark900 : AppThemeData.grey900,
),
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
),
if (status != null) ...[
Container(
padding: const EdgeInsets.symmetric(vertical: 6, horizontal: 12),
decoration: BoxDecoration(color: AppThemeData.info50, border: Border.all(color: AppThemeData.info300), borderRadius: BorderRadius.circular(12)),
child: Text(status, style: AppThemeData.boldTextStyle(fontSize: 14, color: AppThemeData.info500)),
padding: const EdgeInsets.symmetric(
vertical: 6,
horizontal: 12,
),
decoration: BoxDecoration(
color: AppThemeData.info50,
border: Border.all(color: AppThemeData.info300),
borderRadius: BorderRadius.circular(12),
),
child: Text(
status,
style: AppThemeData.boldTextStyle(
fontSize: 14,
color: AppThemeData.info500,
),
),
),
],
],
),
Text(name, style: AppThemeData.semiBoldTextStyle(fontSize: 14, 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(
name,
style: AppThemeData.semiBoldTextStyle(
fontSize: 14,
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)),
],
);

View File

@@ -1,7 +1,7 @@
import 'package:customer/screen_ui/parcel_service/parcel_dashboard_screen.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:get/get.dart' hide Trans;
import 'package:customer/themes/app_them_data.dart';
import 'package:customer/themes/round_button_fill.dart';
import '../../controllers/parcel_dashboard_controller.dart';
@@ -24,13 +24,21 @@ class OrderSuccessfullyPlaced extends StatelessWidget {
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Image.asset("assets/images/parcel_order_successfully_placed.png"),
Image.asset(
"assets/images/parcel_order_successfully_placed.png",
),
const SizedBox(height: 20),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 25),
child: Text(
"Your Order Has Been Placed!".tr(),
style: AppThemeData.boldTextStyle(fontSize: 22, color: isDark ? AppThemeData.greyDark900 : AppThemeData.grey900),
style: AppThemeData.boldTextStyle(
fontSize: 22,
color:
isDark
? AppThemeData.greyDark900
: AppThemeData.grey900,
),
textAlign: TextAlign.center,
),
),
@@ -38,8 +46,15 @@ class OrderSuccessfullyPlaced extends StatelessWidget {
Padding(
padding: const EdgeInsets.symmetric(horizontal: 50),
child: Text(
"Weve received your parcel booking and its now being processed. You can track its status in real time.".tr(),
style: AppThemeData.mediumTextStyle(fontSize: 16, color: isDark ? AppThemeData.greyDark600 : AppThemeData.grey600),
"Weve received your parcel booking and its now being processed. You can track its status in real time."
.tr(),
style: AppThemeData.mediumTextStyle(
fontSize: 16,
color:
isDark
? AppThemeData.greyDark600
: AppThemeData.grey600,
),
textAlign: TextAlign.center,
),
),
@@ -50,7 +65,9 @@ class OrderSuccessfullyPlaced extends StatelessWidget {
print("Tracking Order: $parcelOrder");
//Get.to(() => TrackOrderScreen(), arguments: {'order': parcelOrder});
Get.offAll(const ParcelDashboardScreen());
ParcelDashboardController controller = Get.put(ParcelDashboardController());
ParcelDashboardController controller = Get.put(
ParcelDashboardController(),
);
controller.selectedIndex.value = 1;
},
color: AppThemeData.primary300,

View File

@@ -8,7 +8,7 @@ import 'package:customer/widget/my_separator.dart';
import 'package:dotted_border/dotted_border.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:get/get.dart' hide Trans;
class ParcelCouponScreen extends StatelessWidget {
const ParcelCouponScreen({super.key});
@@ -33,12 +33,30 @@ class ParcelCouponScreen extends StatelessWidget {
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))),
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),
Text("Coupon".tr(), style: AppThemeData.boldTextStyle(fontSize: 18, color: AppThemeData.grey900)),
Text(
"Coupon".tr(),
style: AppThemeData.boldTextStyle(
fontSize: 18,
color: AppThemeData.grey900,
),
),
],
),
),
@@ -54,17 +72,35 @@ class ParcelCouponScreen extends StatelessWidget {
itemBuilder: (context, index) {
CouponModel couponModel = controller.cabCouponList[index];
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 10),
padding: const EdgeInsets.symmetric(
horizontal: 16,
vertical: 10,
),
child: Container(
height: Responsive.height(16, context),
decoration: ShapeDecoration(color: isDark ? AppThemeData.grey900 : AppThemeData.grey50, shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10))),
decoration: ShapeDecoration(
color:
isDark
? AppThemeData.grey900
: AppThemeData.grey50,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10),
),
),
child: Row(
children: [
ClipRRect(
borderRadius: const BorderRadius.only(topLeft: Radius.circular(10), bottomLeft: Radius.circular(10)),
borderRadius: const BorderRadius.only(
topLeft: Radius.circular(10),
bottomLeft: Radius.circular(10),
),
child: Stack(
children: [
Image.asset("assets/images/ic_coupon_image.png", height: Responsive.height(16, context), fit: BoxFit.fill),
Image.asset(
"assets/images/ic_coupon_image.png",
height: Responsive.height(16, context),
fit: BoxFit.fill,
),
Padding(
padding: const EdgeInsets.only(left: 10),
child: Align(
@@ -74,7 +110,14 @@ class ParcelCouponScreen extends StatelessWidget {
child: Text(
"${couponModel.discountType == "Fix Price" ? Constant.amountShow(amount: couponModel.discount) : "${couponModel.discount}%"} ${'Off'.tr()}",
textAlign: TextAlign.start,
style: TextStyle(fontFamily: AppThemeData.semiBold, fontSize: 16, color: isDark ? AppThemeData.grey50 : AppThemeData.grey50),
style: TextStyle(
fontFamily: AppThemeData.semiBold,
fontSize: 16,
color:
isDark
? AppThemeData.grey50
: AppThemeData.grey50,
),
),
),
),
@@ -84,24 +127,53 @@ class ParcelCouponScreen extends StatelessWidget {
),
Expanded(
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 18),
padding: const EdgeInsets.symmetric(
horizontal: 16,
vertical: 18,
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
Row(
children: [
DottedBorder(
options: RoundedRectDottedBorderOptions(strokeWidth: 1, radius: const Radius.circular(6), color: isDark ? AppThemeData.grey400 : AppThemeData.grey500),
options:
RoundedRectDottedBorderOptions(
strokeWidth: 1,
radius: const Radius.circular(
6,
),
color:
isDark
? AppThemeData.grey400
: AppThemeData
.grey500,
),
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 16),
padding:
const EdgeInsets.symmetric(
horizontal: 16,
),
child: Text(
"${couponModel.code}",
textAlign: TextAlign.start,
style: TextStyle(fontFamily: AppThemeData.semiBold, fontSize: 16, color: isDark ? AppThemeData.grey400 : AppThemeData.grey500),
style: TextStyle(
fontFamily:
AppThemeData.semiBold,
fontSize: 16,
color:
isDark
? AppThemeData.grey400
: AppThemeData
.grey500,
),
),
),
),
const Expanded(child: SizedBox(height: 10)),
const Expanded(
child: SizedBox(height: 10),
),
InkWell(
onTap: () {
Get.back(result: couponModel);
@@ -109,18 +181,38 @@ class ParcelCouponScreen extends StatelessWidget {
child: Text(
"Tap To Apply".tr(),
textAlign: TextAlign.start,
style: TextStyle(fontFamily: AppThemeData.medium, color: isDark ? AppThemeData.primary300 : AppThemeData.primary300),
style: TextStyle(
fontFamily: AppThemeData.medium,
color:
isDark
? AppThemeData
.primary300
: AppThemeData
.primary300,
),
),
),
],
),
const SizedBox(height: 20),
MySeparator(color: isDark ? AppThemeData.grey700 : AppThemeData.grey200),
MySeparator(
color:
isDark
? AppThemeData.grey700
: AppThemeData.grey200,
),
const SizedBox(height: 20),
Text(
"${couponModel.description}",
textAlign: TextAlign.start,
style: TextStyle(fontFamily: AppThemeData.medium, fontSize: 16, color: isDark ? AppThemeData.grey50 : AppThemeData.grey900),
style: TextStyle(
fontFamily: AppThemeData.medium,
fontSize: 16,
color:
isDark
? AppThemeData.grey50
: AppThemeData.grey900,
),
),
],
),

View File

@@ -5,7 +5,7 @@ import 'package:customer/themes/app_them_data.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:get/get.dart';
import 'package:get/get.dart' hide Trans;
class ParcelDashboardScreen extends StatelessWidget {
const ParcelDashboardScreen({super.key});
@@ -25,12 +25,21 @@ class ParcelDashboardScreen extends StatelessWidget {
showUnselectedLabels: true,
showSelectedLabels: true,
selectedFontSize: 12,
selectedLabelStyle: const TextStyle(fontFamily: AppThemeData.bold),
unselectedLabelStyle: const TextStyle(fontFamily: AppThemeData.bold),
selectedLabelStyle: const TextStyle(
fontFamily: AppThemeData.bold,
),
unselectedLabelStyle: const TextStyle(
fontFamily: AppThemeData.bold,
),
currentIndex: controller.selectedIndex.value,
backgroundColor: isDark ? AppThemeData.grey900 : AppThemeData.grey50,
selectedItemColor: isDark ? AppThemeData.parcelServiceDark300 : AppThemeData.primary300,
unselectedItemColor: isDark ? AppThemeData.greyDark500 : AppThemeData.grey500,
backgroundColor:
isDark ? AppThemeData.grey900 : AppThemeData.grey50,
selectedItemColor:
isDark
? AppThemeData.parcelServiceDark300
: AppThemeData.primary300,
unselectedItemColor:
isDark ? AppThemeData.greyDark500 : AppThemeData.grey500,
onTap: (int index) {
if (index == 0) {
Get.put(ParcelDashboardController());
@@ -40,15 +49,57 @@ class ParcelDashboardScreen extends StatelessWidget {
items:
Constant.walletSetting == false
? [
navigationBarItem(isDark, index: 0, assetIcon: "assets/icons/ic_home_parcel.svg", label: 'Home'.tr(), controller: controller),
navigationBarItem(isDark, index: 1, assetIcon: "assets/icons/ic_mybooking_parcel.svg", label: 'My Bookings'.tr(), controller: controller),
navigationBarItem(isDark, index: 2, assetIcon: "assets/icons/ic_profile_parcel.svg", label: 'Profile'.tr(), controller: controller),
navigationBarItem(
isDark,
index: 0,
assetIcon: "assets/icons/ic_home_parcel.svg",
label: 'Home'.tr(),
controller: controller,
),
navigationBarItem(
isDark,
index: 1,
assetIcon: "assets/icons/ic_mybooking_parcel.svg",
label: 'My Bookings'.tr(),
controller: controller,
),
navigationBarItem(
isDark,
index: 2,
assetIcon: "assets/icons/ic_profile_parcel.svg",
label: 'Profile'.tr(),
controller: controller,
),
]
: [
navigationBarItem(isDark, index: 0, assetIcon: "assets/icons/ic_home_parcel.svg", label: 'Home'.tr(), controller: controller),
navigationBarItem(isDark, index: 1, assetIcon: "assets/icons/ic_mybooking_parcel.svg", label: 'My Bookings'.tr(), controller: controller),
navigationBarItem(isDark, index: 2, assetIcon: "assets/icons/ic_wallet_parcel.svg", label: 'Wallet'.tr(), controller: controller),
navigationBarItem(isDark, index: 3, assetIcon: "assets/icons/ic_profile_parcel.svg", label: 'Profile'.tr(), controller: controller),
navigationBarItem(
isDark,
index: 0,
assetIcon: "assets/icons/ic_home_parcel.svg",
label: 'Home'.tr(),
controller: controller,
),
navigationBarItem(
isDark,
index: 1,
assetIcon: "assets/icons/ic_mybooking_parcel.svg",
label: 'My Bookings'.tr(),
controller: controller,
),
navigationBarItem(
isDark,
index: 2,
assetIcon: "assets/icons/ic_wallet_parcel.svg",
label: 'Wallet'.tr(),
controller: controller,
),
navigationBarItem(
isDark,
index: 3,
assetIcon: "assets/icons/ic_profile_parcel.svg",
label: 'Profile'.tr(),
controller: controller,
),
],
),
);
@@ -57,7 +108,13 @@ class ParcelDashboardScreen extends StatelessWidget {
});
}
BottomNavigationBarItem navigationBarItem(isDark, {required int index, required String label, required String assetIcon, required ParcelDashboardController controller}) {
BottomNavigationBarItem navigationBarItem(
isDark, {
required int index,
required String label,
required String assetIcon,
required ParcelDashboardController controller,
}) {
return BottomNavigationBarItem(
icon: Padding(
padding: const EdgeInsets.symmetric(vertical: 5),

File diff suppressed because it is too large Load Diff

View File

@@ -3,7 +3,7 @@ import 'package:dotted_border/dotted_border.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/svg.dart';
import 'package:get/get.dart';
import 'package:get/get.dart' hide Trans;
import '../../constant/constant.dart';
import '../../controllers/parcel_order_details_controller.dart';
import '../../controllers/theme_controller.dart';
@@ -40,8 +40,20 @@ class ParcelOrderDetails extends StatelessWidget {
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))),
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),
@@ -49,12 +61,22 @@ class ParcelOrderDetails extends StatelessWidget {
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(),
"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),
style: AppThemeData.mediumTextStyle(
fontSize: 14,
color: AppThemeData.grey900,
),
),
],
),
@@ -74,23 +96,47 @@ class ParcelOrderDetails extends StatelessWidget {
Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(15),
color: isDark ? AppThemeData.greyDark50 : AppThemeData.grey50,
border: Border.all(color: isDark ? AppThemeData.greyDark200 : AppThemeData.grey200),
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(),
"${'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),
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),
color:
isDark
? AppThemeData.greyDark50
: AppThemeData.grey50,
border: Border.all(
color:
isDark
? AppThemeData.greyDark200
: AppThemeData.grey200,
),
),
padding: const EdgeInsets.all(16),
child: Column(
@@ -102,7 +148,11 @@ class ParcelOrderDetails extends StatelessWidget {
// Timeline with icons and line
Column(
children: [
Image.asset("assets/images/image_parcel.png", height: 32, width: 32),
Image.asset(
"assets/images/image_parcel.png",
height: 32,
width: 32,
),
DottedBorder(
options: CustomPathDottedBorderOptions(
color: Colors.grey.shade400,
@@ -112,24 +162,50 @@ class ParcelOrderDetails extends StatelessWidget {
(size) =>
Path()
..moveTo(size.width / 2, 0)
..lineTo(size.width / 2, size.height),
..lineTo(
size.width / 2,
size.height,
),
),
child: const SizedBox(
width: 20,
height: 95,
),
child: const SizedBox(width: 20, height: 95),
),
Image.asset("assets/images/image_parcel.png", height: 32, width: 32),
Image.asset(
"assets/images/image_parcel.png",
height: 32,
width: 32,
),
],
),
const SizedBox(width: 12),
// Address Details
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
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
.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!)}"
// : '',
@@ -138,9 +214,24 @@ class ParcelOrderDetails extends StatelessWidget {
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
.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!)}"
// : '',
@@ -154,12 +245,16 @@ class ParcelOrderDetails extends StatelessWidget {
const Divider(),
if (controller.parcelOrder.value.isSchedule == true)
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),
style: AppThemeData.mediumTextStyle(
fontSize: 14,
color: AppThemeData.info400,
),
),
),
@@ -167,23 +262,61 @@ class ParcelOrderDetails extends StatelessWidget {
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),
style: AppThemeData.mediumTextStyle(
fontSize: 14,
color: AppThemeData.info400,
),
),
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [
Text("Parcel Type:".tr(), style: AppThemeData.semiBoldTextStyle(fontSize: 16, color: isDark ? AppThemeData.greyDark800 : AppThemeData.grey800)),
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),
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),
if (controller
.getSelectedCategory()
?.image !=
null &&
controller
.getSelectedCategory()!
.image!
.isNotEmpty)
NetworkImageWidget(
imageUrl:
controller
.getSelectedCategory()
?.image ??
'',
height: 20,
width: 20,
),
],
),
],
@@ -193,15 +326,31 @@ class ParcelOrderDetails extends StatelessWidget {
: SizedBox(
height: 120,
child: ListView.builder(
itemCount: controller.parcelOrder.value.parcelImages!.length,
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),
borderRadius: BorderRadius.circular(
10,
),
child: NetworkImageWidget(
imageUrl:
controller
.parcelOrder
.value
.parcelImages![index],
width: 100,
fit: BoxFit.cover,
borderRadius: 10,
),
),
);
},
@@ -215,16 +364,42 @@ class ParcelOrderDetails extends StatelessWidget {
Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(15),
color: isDark ? AppThemeData.greyDark50 : AppThemeData.grey50,
border: Border.all(color: isDark ? AppThemeData.greyDark200 : AppThemeData.grey200),
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),
_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,
),
],
),
),
@@ -235,18 +410,37 @@ class ParcelOrderDetails extends StatelessWidget {
Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(15),
color: isDark ? AppThemeData.greyDark50 : AppThemeData.grey50,
border: Border.all(color: isDark ? AppThemeData.greyDark200 : AppThemeData.grey200),
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)),
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,
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
crossAxisAlignment:
CrossAxisAlignment.center,
children: [
Row(
children: [
@@ -254,19 +448,48 @@ class ParcelOrderDetails extends StatelessWidget {
width: 52,
height: 52,
child: ClipRRect(
borderRadius: BorderRadiusGeometry.circular(10),
child: NetworkImageWidget(imageUrl: controller.driverUser.value?.profilePictureURL ?? '', height: 70, width: 70, borderRadius: 35),
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),
controller
.parcelOrder
.value
.driver
?.fullName() ??
'',
style: AppThemeData.boldTextStyle(
color:
isDark
? AppThemeData
.greyDark900
: AppThemeData.grey900,
fontSize: 18,
),
),
],
),
RoundedButtonBorder(
title: controller.driverUser.value!.averageRating.toStringAsFixed(1),
title: controller
.driverUser
.value!
.averageRating
.toStringAsFixed(1),
width: 20,
height: 3.5,
radius: 10,
@@ -275,72 +498,155 @@ class ParcelOrderDetails extends StatelessWidget {
textColor: AppThemeData.warning400,
borderColor: AppThemeData.warning400,
color: AppThemeData.warning50,
icon: SvgPicture.asset("assets/icons/ic_start.svg"),
icon: SvgPicture.asset(
"assets/icons/ic_start.svg",
),
onPress: () {},
),
],
),
Visibility(
visible: controller.parcelOrder.value.status == Constant.orderCompleted ? true : false,
visible:
controller.parcelOrder.value.status ==
Constant.orderCompleted
? true
: false,
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 10),
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(),
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});
final result = await Get.to(
() => ParcelReviewScreen(),
arguments: {
'order':
controller
.parcelOrder
.value,
},
);
// If review was submitted successfully
if (result == true) {
await controller.fetchDriverDetails();
await controller
.fetchDriverDetails();
}
},
height: 5,
borderRadius: 15,
color: Colors.orange,
textColor: isDark ? AppThemeData.greyDark900 : AppThemeData.grey900,
textColor:
isDark
? AppThemeData.greyDark900
: AppThemeData.grey900,
),
),
),
if (controller.parcelOrder.value.status != Constant.orderCompleted)
if (controller.parcelOrder.value.status !=
Constant.orderCompleted)
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [
InkWell(
onTap: () {
Constant.makePhoneCall(controller.parcelOrder.value.driver!.phoneNumber.toString());
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),
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",
),
),
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("Please wait...".tr());
ShowToastDialog.showLoader(
"Please wait...".tr(),
);
UserModel? customer = await FireStoreUtils.getUserProfile(controller.parcelOrder.value.authorID ?? '');
UserModel? driverUser = await FireStoreUtils.getUserProfile(controller.parcelOrder.value.driverId ?? '');
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,
"customerName":
customer?.fullName(),
"restaurantName":
driverUser?.fullName(),
"orderId":
controller
.parcelOrder
.value
.id,
"restaurantId":
driverUser?.id,
"customerId": customer?.id,
"customerProfileImage": customer?.profilePictureURL,
"restaurantProfileImage": driverUser?.profilePictureURL,
"customerProfileImage":
customer
?.profilePictureURL,
"restaurantProfileImage":
driverUser
?.profilePictureURL,
"token": driverUser?.fcmToken,
"chatType": "Driver",
},
@@ -351,11 +657,29 @@ class ParcelOrderDetails extends StatelessWidget {
height: 42,
decoration: ShapeDecoration(
shape: RoundedRectangleBorder(
side: BorderSide(width: 1, color: isDark ? AppThemeData.grey700 : AppThemeData.grey200),
borderRadius: BorderRadius.circular(120),
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",
),
),
child: Padding(padding: const EdgeInsets.all(8.0), child: SvgPicture.asset("assets/icons/ic_wechat.svg")),
),
),
],
@@ -369,43 +693,98 @@ class ParcelOrderDetails extends StatelessWidget {
Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(15),
color: isDark ? AppThemeData.greyDark50 : AppThemeData.grey50,
border: Border.all(color: isDark ? AppThemeData.greyDark200 : AppThemeData.grey200),
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)),
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),
_summaryTile(
"Subtotal".tr(),
Constant.amountShow(
amount: controller.subTotal.value.toString(),
),
isDark,
),
// Discount
_summaryTile("Discount".tr(), Constant.amountShow(amount: controller.discount.value.toString()), isDark),
_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,
);
}),
...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),
_summaryTile(
"Order Total".tr(),
Constant.amountShow(
amount:
controller.totalAmount.value.toString(),
),
isDark,
),
],
),
),
@@ -424,7 +803,10 @@ class ParcelOrderDetails extends StatelessWidget {
height: 5,
borderRadius: 15,
color: AppThemeData.primary300,
textColor: isDark ? AppThemeData.greyDark900 : AppThemeData.grey900,
textColor:
isDark
? AppThemeData.greyDark900
: AppThemeData.grey900,
),
)
: SizedBox(),
@@ -433,7 +815,11 @@ class ParcelOrderDetails extends StatelessWidget {
);
}
Widget statusBottomSheet(BuildContext context, ParcelOrderDetailsController controller, bool isDark) {
Widget statusBottomSheet(
BuildContext context,
ParcelOrderDetailsController controller,
bool isDark,
) {
return DraggableScrollableSheet(
initialChildSize: 0.30,
minChildSize: 0.20,
@@ -442,23 +828,46 @@ class ParcelOrderDetails extends StatelessWidget {
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))),
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)),
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 ?? [];
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))),
child: Center(
child: Text(
"No status updates yet".tr(),
style: AppThemeData.mediumTextStyle(
color:
isDark
? AppThemeData.greyDark900
: AppThemeData.grey900,
),
),
),
);
}
@@ -476,12 +885,26 @@ class ParcelOrderDetails extends StatelessWidget {
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Image.asset(isCompleted ? "assets/images/image_status_timeline.png" : "assets/images/image_timeline.png", height: 48, width: 48),
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),
style: AppThemeData.semiBoldTextStyle(
color:
isCompleted
? (isDark
? AppThemeData.greyDark900
: AppThemeData.grey900)
: AppThemeData.grey500,
fontSize: 18,
),
),
),
],
@@ -499,14 +922,44 @@ class ParcelOrderDetails extends StatelessWidget {
);
}
Widget _infoSection(String title, String name, String address, String phone, bool isDark) {
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(
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)),
],
);
@@ -516,11 +969,28 @@ class ParcelOrderDetails extends StatelessWidget {
return Column(
children: [
// Icon(icon, color: AppThemeData.primary300),
SvgPicture.asset(icon, height: 28, width: 28, color: isDark ? AppThemeData.greyDark800 : AppThemeData.grey800),
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)),
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)),
Text(
title,
style: AppThemeData.semiBoldTextStyle(
fontSize: 12,
color: isDark ? AppThemeData.greyDark900 : AppThemeData.grey900,
),
),
],
);
}
@@ -531,8 +1001,20 @@ class ParcelOrderDetails extends StatelessWidget {
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)),
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,
),
),
],
),
);

View File

@@ -2,7 +2,7 @@ import 'package:customer/controllers/parcel_review_controller.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:flutter_rating_bar/flutter_rating_bar.dart';
import 'package:get/get.dart';
import 'package:get/get.dart' hide Trans;
import '../../constant/constant.dart';
import '../../controllers/theme_controller.dart';
import '../../themes/app_them_data.dart';
@@ -26,10 +26,22 @@ class ParcelReviewScreen extends StatelessWidget {
centerTitle: true,
elevation: 0,
backgroundColor: AppThemeData.primary300,
leading: GestureDetector(onTap: () => Get.back(), child: Icon(Icons.arrow_back_ios, color: isDark ? Colors.white : Colors.black)),
leading: GestureDetector(
onTap: () => Get.back(),
child: Icon(
Icons.arrow_back_ios,
color: isDark ? Colors.white : Colors.black,
),
),
title: Text(
controller.ratingModel.value != null && controller.ratingModel.value!.id!.isNotEmpty ? "Update Review".tr() : "Add Review".tr(),
style: TextStyle(color: isDark ? Colors.white : Colors.black, fontSize: 16),
controller.ratingModel.value != null &&
controller.ratingModel.value!.id!.isNotEmpty
? "Update Review".tr()
: "Add Review".tr(),
style: TextStyle(
color: isDark ? Colors.white : Colors.black,
fontSize: 16,
),
),
),
body: Obx(
@@ -41,11 +53,21 @@ class ParcelReviewScreen extends StatelessWidget {
child: Stack(
children: [
Padding(
padding: const EdgeInsets.only(left: 20, right: 20, top: 50, bottom: 20),
padding: const EdgeInsets.only(
left: 20,
right: 20,
top: 50,
bottom: 20,
),
child: Card(
elevation: 2,
color: isDark ? AppThemeData.greyDark50 : AppThemeData.grey50,
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)),
color:
isDark
? AppThemeData.greyDark50
: AppThemeData.grey50,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10),
),
child: SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.only(top: 65),
@@ -53,65 +75,148 @@ class ParcelReviewScreen extends StatelessWidget {
children: [
// Driver Name
Padding(
padding: const EdgeInsets.only(top: 8.0),
padding: const EdgeInsets.only(
top: 8.0,
),
child: Text(
controller.order.value!.driver?.fullName() ?? "",
style: TextStyle(color: isDark ? Colors.white : Colors.black87, fontFamily: AppThemeData.medium, fontSize: 18),
controller.order.value!.driver
?.fullName() ??
"",
style: TextStyle(
color:
isDark
? Colors.white
: Colors.black87,
fontFamily: AppThemeData.medium,
fontSize: 18,
),
),
),
// Car info
const Padding(padding: EdgeInsets.symmetric(vertical: 12), child: Divider(color: Colors.grey)),
const Padding(
padding: EdgeInsets.symmetric(
vertical: 12,
),
child: Divider(color: Colors.grey),
),
// Title
Padding(
padding: const EdgeInsets.only(top: 16),
child: Text('How is your trip?'.tr(), style: TextStyle(fontSize: 18, color: isDark ? Colors.white : Colors.black, fontWeight: FontWeight.bold, letterSpacing: 2)),
child: Text(
'How is your trip?'.tr(),
style: TextStyle(
fontSize: 18,
color:
isDark
? Colors.white
: Colors.black,
fontWeight: FontWeight.bold,
letterSpacing: 2,
),
),
),
Padding(
padding: const EdgeInsets.only(top: 8),
child: Text(
'Your feedback will help us improve \n driving experience better'.tr(),
'Your feedback will help us improve \n driving experience better'
.tr(),
textAlign: TextAlign.center,
style: TextStyle(color: isDark ? Colors.white : Colors.black.withOpacity(0.60), letterSpacing: 0.8),
style: TextStyle(
color:
isDark
? Colors.white
: Colors.black.withOpacity(
0.60,
),
letterSpacing: 0.8,
),
),
),
// Rating
Padding(
padding: const EdgeInsets.only(top: 20),
child: Text('Rate for'.tr(), style: TextStyle(fontSize: 16, color: isDark ? Colors.white : Colors.black.withOpacity(0.60), letterSpacing: 0.8)),
child: Text(
'Rate for'.tr(),
style: TextStyle(
fontSize: 16,
color:
isDark
? Colors.white
: Colors.black.withOpacity(
0.60,
),
letterSpacing: 0.8,
),
),
),
Padding(
padding: const EdgeInsets.only(top: 8),
child: Text(
controller.order.value!.driver?.fullName() ?? "",
style: TextStyle(fontSize: 18, color: isDark ? Colors.white : Colors.black, fontWeight: FontWeight.bold, letterSpacing: 2),
controller.order.value!.driver
?.fullName() ??
"",
style: TextStyle(
fontSize: 18,
color:
isDark
? Colors.white
: Colors.black,
fontWeight: FontWeight.bold,
letterSpacing: 2,
),
),
),
Padding(
padding: const EdgeInsets.only(top: 10),
child: RatingBar.builder(
initialRating: controller.ratings.value,
initialRating:
controller.ratings.value,
minRating: 1,
direction: Axis.horizontal,
allowHalfRating: true,
itemCount: 5,
itemBuilder: (context, _) => const Icon(Icons.star, color: Colors.amber),
unratedColor: isDark ? AppThemeData.greyDark400 : AppThemeData.grey400,
onRatingUpdate: (rating) => controller.ratings.value = rating,
itemBuilder:
(context, _) => const Icon(
Icons.star,
color: Colors.amber,
),
unratedColor:
isDark
? AppThemeData.greyDark400
: AppThemeData.grey400,
onRatingUpdate:
(rating) =>
controller.ratings.value =
rating,
),
),
// Comment
Padding(padding: const EdgeInsets.all(20.0), child: TextFieldWidget(hintText: "Type comment....".tr(), controller: controller.comment.value, maxLine: 5)),
Padding(
padding: const EdgeInsets.all(20.0),
child: TextFieldWidget(
hintText: "Type comment....".tr(),
controller: controller.comment.value,
maxLine: 5,
),
),
// Submit Button
Padding(
padding: const EdgeInsets.all(20.0),
child: RoundedButtonFill(
title: controller.ratingModel.value != null ? "Update Review".tr() : "Add Review".tr(),
title:
controller.ratingModel.value !=
null
? "Update Review".tr()
: "Add Review".tr(),
color: AppThemeData.primary300,
textColor: isDark ? Colors.white : Colors.black,
textColor:
isDark
? Colors.white
: Colors.black,
onPress: controller.submitReview,
),
),
@@ -127,11 +232,28 @@ class ParcelReviewScreen extends StatelessWidget {
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(60),
color: Colors.white,
boxShadow: [BoxShadow(color: Colors.grey.withOpacity(0.15), blurRadius: 8, spreadRadius: 6)],
boxShadow: [
BoxShadow(
color: Colors.grey.withOpacity(0.15),
blurRadius: 8,
spreadRadius: 6,
),
],
),
child: ClipRRect(
borderRadius: BorderRadius.circular(60),
child: NetworkImageWidget(imageUrl: controller.order.value?.driver?.profilePictureURL ?? '', fit: BoxFit.cover, height: 110, width: 110),
child: NetworkImageWidget(
imageUrl:
controller
.order
.value
?.driver
?.profilePictureURL ??
'',
fit: BoxFit.cover,
height: 110,
width: 110,
),
),
),
),