Untitled
unknown
dart
2 years ago
68 kB
1
Indexable
Never
import 'dart:math' as math; import 'package:dotted_border/dotted_border.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:geocoding/geocoding.dart'; import 'package:get/get.dart'; import 'package:google_maps_flutter/google_maps_flutter.dart'; import 'package:iketfaa_delivery/App/Common/Models/Main/address.dart'; import 'package:iketfaa_delivery/App/Common/Modules/PickUpLocationMap/binding/pick_up_location_map_binding.dart'; import 'package:iketfaa_delivery/App/Common/Modules/PickUpLocationMap/view/pick_up_location_map_view.dart'; import 'package:iketfaa_delivery/App/Common/Widgets/myTextfield_widget.dart'; import 'package:iketfaa_delivery/App/Common/Services/translation_service.dart'; import 'package:iketfaa_delivery/App/Common/Utilities/Constants/AppColors.dart'; import 'package:iketfaa_delivery/App/Common/Widgets/CustomButton.dart'; import 'package:iketfaa_delivery/App/Common/Widgets/LocationTile.dart'; import 'package:iketfaa_delivery/App/Common/Widgets/primary_button.dart'; import 'package:iketfaa_delivery/App/Common/Widgets/radio_button_with_title.dart'; import 'package:iketfaa_delivery/App/Freelance/Modules/BrowseServices/controller/browse_services_controller.dart'; import 'package:iketfaa_delivery/App/Freelance/Modules/BrowseServices/view/choose_cities_view.dart'; import 'package:iketfaa_delivery/App/Freelance/Widgets/gender_types.dart'; class RequestServiceView extends GetView<BrowseServicesController> { final bool isArabic = TranslationService().isLocaleArabic(); @override Widget build(BuildContext context) { return GestureDetector( onTap: () { controller.authManager.commonTools.unFocusKeyboard(context); }, child: Scaffold( backgroundColor: AppColors.white, body: ListView( padding: EdgeInsets.zero, children: [ Material( color: AppColors.primary, elevation: 2.0, child: Column( children: [ SizedBox( height: MediaQuery.of(context).padding.top, ), Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, crossAxisAlignment: CrossAxisAlignment.center, children: [ IconButton( onPressed: () => Get.back(), icon: Transform.rotate( angle: isArabic ? (180 * math.pi / 180) : 0, child: SvgPicture.asset( 'assets/svg/icArrowBack.svg', color: Colors.white, ), )), Text( 'requestService'.tr, style: Get.textTheme.headline5!.copyWith( fontWeight: FontWeight.w600, height: 1.2, color: Colors.white), textScaleFactor: 1.0, overflow: TextOverflow.ellipsis, softWrap: true, maxLines: 2, textAlign: TextAlign.center, ), IconButton( onPressed: () => () {}, icon: Transform.rotate( angle: isArabic ? (180 * math.pi / 180) : 0, child: SvgPicture.asset( 'assets/svg/icArrowBack.svg', color: AppColors.primary, ), )), ], ), const SizedBox( height: 25.0, ), SvgPicture.network( controller.specialitySelected.value.imageUrl!, color: AppColors.white.withOpacity(0.7), width: 35.0, ), const SizedBox( height: 25.0, ), Text( isArabic ? controller.specialitySelected.value.nameAr! : controller.specialitySelected.value.nameEn!, style: Get.textTheme.headline5!.copyWith( fontWeight: FontWeight.w100, height: 1.2, color: Colors.white), textScaleFactor: 1.0, overflow: TextOverflow.ellipsis, softWrap: true, maxLines: 2, textAlign: TextAlign.center, ), const SizedBox( height: 20.0, ), ], ), ), Container( padding: const EdgeInsets.symmetric(horizontal: 35, vertical: 0), child: Column( children: [ const SizedBox( height: 30.0, ), Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( 'Provider\'s Gender'.tr, style: Get.textTheme.bodyText1! .copyWith(fontWeight: FontWeight.w600), ).paddingOnly(bottom: 8), Text( 'Choose provider gender'.tr, style: Get.textTheme.bodyText1! .copyWith(color: AppColors.grey), ), const SizedBox( height: 20.0, ), Obx( () => Row( mainAxisAlignment: MainAxisAlignment.center, children: [ Column( children: [ GenderType( imagepath: 'assets/svg/icFemale.svg', id: 1, currentID: controller.genderID.value, onPressed: () { controller.genderID.value = 1; }), const SizedBox( height: 15.0, ), Text( 'Male'.tr, style: Get.textTheme.headline6! .copyWith(fontWeight: FontWeight.w500), ) ], ), SizedBox( width: Get.width * 0.2, ), Column( children: [ GenderType( imagepath: 'assets/svg/icMale.svg', id: 2, currentID: controller.genderID.value, onPressed: () { controller.genderID.value = 2; }), const SizedBox( height: 15.0, ), Text('Female'.tr, style: Get.textTheme.headline6! .copyWith(fontWeight: FontWeight.w500)) ], ) ], ), ) ], ), const SizedBox( height: 25.0, ), Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( 'Request details'.tr, style: Get.textTheme.bodyText1! .copyWith(fontWeight: FontWeight.w600), ).paddingOnly(bottom: 8, top: 16), Text( 'Write a description'.tr, style: Get.textTheme.bodyText1! .copyWith(color: AppColors.grey), ).paddingOnly(bottom: 8), Container( height: Get.width * 0.3, child: TextFieldWidget( controller: controller.descriptionTF, hintText: 'Description...'.tr, maxLines: 10, svgpath: '', formatter: [ LengthLimitingTextInputFormatter(1500), ], padding: const EdgeInsets.all(10.0), ), ), ], ), const SizedBox( height: 15.0, ), Obx( () => Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( 'Service images'.tr, style: Get.textTheme.bodyText1! .copyWith(fontWeight: FontWeight.w600), ).paddingOnly(bottom: 8, top: 16), Text( 'Upload images of your service'.tr, style: Get.textTheme.bodyText1! .copyWith(color: AppColors.grey), ).paddingOnly(bottom: 16), Container( height: Get.height * 0.15, width: Get.width, margin: const EdgeInsets.only(bottom: 16.0), child: ListView( shrinkWrap: true, scrollDirection: Axis.horizontal, children: [ Container( height: Get.width * 0.38, child: ListView.builder( scrollDirection: Axis.horizontal, itemCount: controller.serviceImages.length, shrinkWrap: true, physics: const NeverScrollableScrollPhysics(), itemBuilder: (context, index) { return Stack( children: [ Container( width: Get.width * 0.3, height: Get.height * 0.15, margin: const EdgeInsets.only( right: 10.0), child: ClipRRect( borderRadius: BorderRadius.circular(10.0), child: Image.file( controller.serviceImages[index], height: double.infinity, width: double.infinity, fit: BoxFit.cover, ), ), ), Container( width: Get.width * 0.3, height: Get.height * 0.15, margin: const EdgeInsets.only( right: 10.0), decoration: BoxDecoration( borderRadius: BorderRadius.circular(10.0), color: AppColors.black .withOpacity(0.4)), ), Positioned.fill( child: Align( alignment: Alignment.bottomCenter, child: Row( mainAxisAlignment: MainAxisAlignment .spaceBetween, children: [ Container( margin: const EdgeInsets .symmetric( horizontal: 5.0), child: InkWell( onTap: () async { controller .serviceImages .removeAt(index); controller .serviceAssets .removeAt(index); controller .noOfImagescanAdd += 1; }, child: Container( width: 40, height: 40, margin: const EdgeInsets .all(5.0), padding: const EdgeInsets .all(5.0), child: CircleAvatar( backgroundColor: AppColors .darkGrey .withOpacity( 0.5), radius: 40, child: Icon( Icons.delete, color: AppColors.red, ), ), ), ), ), Container( margin: const EdgeInsets .symmetric( horizontal: 5.0), child: InkWell( onTap: () async { controller .serviceImages[ index] = (await controller .authManager .commonTools .cropImage(controller .serviceImages[ index])) ?? controller .serviceImages[ index]; }, child: Container( width: 40, height: 40, margin: const EdgeInsets .all(5.0), padding: const EdgeInsets .all(5.0), child: CircleAvatar( backgroundColor: AppColors .darkGrey .withOpacity( 0.5), radius: 40, child: Icon( Icons.crop, color: AppColors .white, ), ), ), ), ), ], )), ) ], ); }, ), ), const SizedBox( width: 10.0, ), GetBuilder<BrowseServicesController>( builder: (_) { return Visibility( visible: controller.noOfImagescanAdd > 0, child: InkWell( child: Container( margin: const EdgeInsets.only( right: 5.0, left: 5.0), width: Get.width * 0.3, height: Get.height * 0.1, decoration: const BoxDecoration( color: Color.fromRGBO( 238, 238, 238, 1), borderRadius: BorderRadius.all( Radius.circular( 10, ), ), ), child: DottedBorder( borderType: BorderType.RRect, radius: const Radius.circular(10), dashPattern: [5, 5], color: Get.theme.focusColor, strokeWidth: 2, child: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Icon( Icons.add, color: Get.theme.focusColor, ), Text( 'Upload Image'.tr, style: Get .textTheme.bodyMedium! .copyWith( color: Get.theme .focusColor, fontWeight: FontWeight .bold), ), ], ), ), )), onTap: () async { FocusScopeNode currentFocus = FocusScope.of(context); if (!currentFocus.hasPrimaryFocus) { currentFocus.unfocus(); } await controller .loadPostsAssets(context); }, ), ); }, ), ], )), ], ), ), const SizedBox( height: 15.0, ), Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( crossAxisAlignment: CrossAxisAlignment.center, children: [ Text( 'My Budget'.tr + ' ', style: Get.textTheme.bodyText1! .copyWith(fontWeight: FontWeight.w600), ), Text( '(SAR)'.tr, style: Get.textTheme.bodyText1!.copyWith( fontWeight: FontWeight.w600, fontSize: 11), ), ], ).paddingOnly(bottom: 8, top: 16), Text( 'Your budget might not be the final price'.tr, style: Get.textTheme.bodyText1! .copyWith(color: AppColors.grey), ).paddingOnly(bottom: 8), TextFieldWidget( controller: controller.budgetTF, margin: const EdgeInsets.symmetric(vertical: 10), hintText: 'Enter price..'.tr, keyboardType: const TextInputType.numberWithOptions( decimal: true), formatter: [ LengthLimitingTextInputFormatter(8), FilteringTextInputFormatter.allow( RegExp(r'^\d+\.?\d*')), ], svgpath: '', ), ], ), const SizedBox( height: 15.0, ), Obx( () => Column( mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( 'Deliver Service to'.tr, style: Get.textTheme.bodyText1! .copyWith(fontWeight: FontWeight.w600), ).paddingOnly(bottom: 8, top: 16), Text( 'Set your location'.tr, style: Get.textTheme.bodyText1! .copyWith(color: AppColors.grey), ).paddingOnly(bottom: 16), Align( alignment: Alignment.center, child: CustomButton( onTap: () { controller.authManager.commonTools .showCustomBottomSheet( context, '', Container( margin: const EdgeInsets.all(10.0), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ ListView.builder( padding: EdgeInsets.zero, shrinkWrap: true, physics: const NeverScrollableScrollPhysics(), itemCount: controller .freelanceHomeController .dashboardController .userAddresses .length, itemBuilder: (context, index) { return Obx( () => LocationTile( withCricle: true, translate: true, address: controller .freelanceHomeController .dashboardController .userAddresses[index], active: controller .freelanceHomeController .dashboardController .selectedAddress .value .id == controller .freelanceHomeController .dashboardController .userAddresses[index] .id, onTap: () { controller.destinationAddress .value = controller .freelanceHomeController .dashboardController .selectedAddress .value = controller .freelanceHomeController .dashboardController .userAddresses[index]; }, ), ); }, ), Obx( () => ListTile( horizontalTitleGap: 0.0, minVerticalPadding: 0.0, onTap: () async { controller.authManager.commonTools .showLoading(); Placemark placemark = await controller .authManager.deliveryTools .getAddressPlacemark(LatLng( controller .authManager .appUser .value .locationData! .localPosition! .latitude, controller .authManager .appUser .value .locationData! .localPosition! .longitude)); controller .freelanceHomeController .dashboardController .selectedAddress .value = controller.destinationAddress .value = Address( id: '-1', street: placemark.street, city: placemark.subLocality, latitude: controller .authManager .appUser .value .locationData! .localPosition! .latitude .toString(), longitude: controller .authManager .appUser .value .locationData! .localPosition! .longitude .toString(), ); Get.back(); }, title: Text( 'currentLocation'.tr, style: Get.textTheme.headline6! .copyWith( fontWeight: FontWeight.w600), ), leading: SvgPicture.asset( 'assets/svg/currentLocation.svg', width: 25, ), trailing: Container( height: 20, width: 20, padding: const EdgeInsets.all(2), decoration: BoxDecoration( color: Colors.transparent, shape: BoxShape.circle, border: Border.all( color: AppColors.primary), ), child: Container( height: 16, width: 16, decoration: BoxDecoration( color: (controller .destinationAddress .value .id == '-1') ? AppColors.primary : AppColors.white, shape: BoxShape.circle, ), ), ), ), ), ListTile( horizontalTitleGap: 0.0, minVerticalPadding: 0.0, onTap: () { Get.back(); Get.to( () => PickUpLocationMapView( title: 'location', buttonText: 'pickUpMyLocation', function: (latlng, placemark) { controller .destinationAddress .value = Address( id: '-2', street: placemark .street, city: placemark .subLocality, latitude: latlng .latitude .toString(), longitude: latlng .longitude .toString()); }, ), binding: PickUpLocationMapBinding()); }, title: Text( 'Set location on map'.tr, style: Get.textTheme.headline6! .copyWith( fontWeight: FontWeight.w600), ), leading: SvgPicture.asset( 'assets/svg/gen011-021.svg', width: 20, ), ), const SizedBox( height: 10.0, ), ListTile( horizontalTitleGap: 0.0, minVerticalPadding: 0.0, title: Text( 'prefferedLocationReqServiceFL' .tr, style: Get.textTheme.headline6! .copyWith( fontWeight: FontWeight.w600)), ), Obx( () => Column( children: controller .prefferedLocations .map((e) => Column( crossAxisAlignment: CrossAxisAlignment .start, children: [ ListTile( horizontalTitleGap: 0.0, minLeadingWidth: 0.0, minVerticalPadding: 0.0, leading: RadioButtonWithTitle( radioValue: controller .prefferedLocations .indexOf( e), radioCurrentValue: controller .prefferedLocation .value, title: e.tr, function: (value) { controller .prefferedLocation .value = value; }), ), Container( margin: const EdgeInsets .symmetric( horizontal: 40.0), child: Text( 'Based on your location' .tr), ), const SizedBox( height: 10.0, ), ], )) .toList(), ), ), const SizedBox( height: 15.0, ), Obx(() => Visibility( visible: controller .prefferedLocation.value == 1, child: Container( margin: const EdgeInsets.symmetric( horizontal: 30.0), child: CustomButton( icon: Icon( Icons .arrow_drop_down_outlined, color: AppColors.black .withOpacity(0.8), ), background: AppColors .greyWhite .withOpacity(0.5), text: Text('chooseCity'.tr, textAlign: TextAlign.center, style: Get .textTheme.bodyText1! .copyWith( fontWeight: FontWeight .w600, color: AppColors .black .withOpacity( 0.8))), borderRadius: 5.0, padding: const EdgeInsets .symmetric( horizontal: 18, vertical: 12.0), shadow: false, spaceBetween: true, iconFirst: false, onTap: () { controller.cityTemp.clear(); controller.cityTemp.addAll( controller.cityIds); Get.to(() => ChooseCitiesView()); }), ))), const SizedBox( height: 30.0, ), Obx( () => Center( child: Wrap( children: controller.cityIds .map( (i) => GestureDetector( onTap: () { controller.cityIds .removeWhere( (element) => element == i); controller.cityTemp .removeWhere( (element) => element == i); }, child: Container( padding: const EdgeInsets .all(10.0), margin: const EdgeInsets .all(10.0), decoration: BoxDecoration( color: AppColors .greyWhite .withOpacity( 0.5), borderRadius: BorderRadius .circular( 20.0)), child: Row( mainAxisSize: MainAxisSize.min, children: [ SvgPicture.asset( 'assets/svg/cancel.svg'), const SizedBox( width: 10.0, ), Text( isArabic ? controller .citiesItems .where((p0) => p0.id == i) .first .nameAr! : controller .citiesItems .where((p0) => p0.id == i) .first .nameEn!, style: Get .textTheme .headline5, ), ], ), ), ), ) .toList(), ), ), ), const SizedBox( height: 30.0, ), Center( child: PrimaryButton( text: 'Done', function: () { Get.back(); }), ), ], ), ), ); }, width: Get.width, background: controller.destinationAddress.value.id == null ? AppColors.lightGreen.withOpacity(0.3) : AppColors.lightGreen, icon: controller.destinationAddress.value.id == null || controller.destinationAddress.value.id == '-2' ? SvgPicture.asset( 'assets/svg/icLocation.svg') : controller.destinationAddress.value.id == '-1' ? SvgPicture.asset( 'assets/svg/currentLocation.svg', ) : SvgPicture.asset( 'assets/svg/address.svg', ), text: Text( controller.destinationAddress.value.id == null ? 'Choose your default location'.tr : '${controller.destinationAddress.value.street ?? ''}, ${controller.destinationAddress.value.city}', textAlign: TextAlign.center, style: Get.textTheme.bodyText1!.copyWith( fontWeight: FontWeight.w600, fontSize: 14)), borderRadius: 5.0, padding: const EdgeInsets.symmetric(vertical: 16), shadow: false), ).paddingOnly(bottom: 16), ], ), ), const SizedBox( height: 15.0, ), Container( width: Get.width, child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( 'When to Deliver'.tr, style: Get.textTheme.bodyText1! .copyWith(fontWeight: FontWeight.w600), ).paddingOnly(bottom: 8, top: 16), Text( 'When would you like to have your service'.tr, style: Get.textTheme.bodyText1! .copyWith(color: AppColors.grey), ).paddingOnly(bottom: 12), ], ), ), Obx( () => Column( crossAxisAlignment: CrossAxisAlignment.start, children: controller.schedules .map((e) => Container( margin: const EdgeInsets.symmetric(vertical: 5.0), child: Row( children: [ RadioButtonWithTitle( radioValue: controller.schedules.indexOf(e), radioCurrentValue: controller.currentSchedule.value, title: e.tr, function: (value) { controller.currentSchedule.value = value; }), const SizedBox( width: 10.0, ), Visibility( visible: controller .currentSchedule.value != 0 && controller.schedules.indexOf(e) != 0, child: Row( children: [ InkWell( onTap: () { print(controller .currentSchedule.value); print(controller.schedules .indexOf(e)); chooseScheduleDate(context); }, child: const Icon( Icons.date_range_rounded, color: AppColors.primary, ), ), const SizedBox( width: 10.0, ), Text( controller.scheduleDateString.value != '' ? controller .scheduleDateString.value : '', style: Get.textTheme.headline5! .copyWith( color: AppColors.primary), ), ], ), ) ], ), )) .toList(), ), ), Align( alignment: Alignment.center, child: CustomButton( onTap: () async { controller.authManager.commonTools .unFocusKeyboard(context); if (controller.genderID.value == 0) return controller.authManager.commonTools .showFailedSnackBar('pleaseSelectGender'); if (controller.descriptionTF.text.isEmpty) return controller.authManager.commonTools .showFailedSnackBar('pleaseWriteDescription'); if (controller.budgetTF.text.isEmpty) return controller.authManager.commonTools .showFailedSnackBar('pleaseEnterBugdet'); if (double.tryParse(controller.budgetTF.text) == null) return controller.authManager.commonTools .showFailedSnackBar('pleaseEnterValidBudget'); if (controller.destinationAddress.value.id == null) return controller.authManager.commonTools .showFailedSnackBar('pleaseSetYourLocation'); if (controller.currentSchedule.value == (-1)) return controller.authManager.commonTools .showFailedSnackBar( 'pleaseSelectTimeToDeliverService'); if (controller.prefferedLocation.value == 1 && controller.cityIds.isEmpty) return controller.authManager.commonTools .showFailedSnackBar('pleaseSelectCities'); if (controller.currentSchedule.value == 1 && controller.scheduleDateString == null) return controller.authManager.commonTools .showFailedSnackBar( 'pleaseSelectSpecificDateToDeliverService'); if (controller.serviceImages.isEmpty) { controller.authManager.commonTools .ShowWarningDialogMutliButtons( context, 'warning'.tr, 'noImagesFreelanceServiceMess'.tr, 'ok'.tr, 'cancel'.tr, CupertinoColors.activeBlue, CupertinoColors.systemRed, () async { Get.back(); controller.sendRequest(); }, () { Get.back(); return; }); } else { controller.sendRequest(); } }, width: Get.width, background: AppColors.primary, text: Text('Send request'.tr, textAlign: TextAlign.center, style: Get.textTheme.bodyText1!.copyWith( fontWeight: FontWeight.w600, color: Colors.white)), borderRadius: 5.0, padding: const EdgeInsets.symmetric(vertical: 16), shadow: true), ).paddingOnly(top: Get.height * 0.05), const SizedBox( height: 30.0, ), ], ), ), ], ), ), ); } void chooseScheduleDate(context) { showModalBottomSheet( isScrollControlled: true, elevation: 5, backgroundColor: AppColors.white.withOpacity(0), context: context, builder: (BuildContext bc) { return Container( padding: EdgeInsets.only( bottom: MediaQuery.of(context).viewInsets.bottom), decoration: const BoxDecoration( borderRadius: BorderRadius.only( topLeft: Radius.circular(15), topRight: Radius.circular(15), ), ), child: Column( mainAxisAlignment: MainAxisAlignment.end, children: [ Container( width: Get.width, padding: const EdgeInsets.all(10.0), decoration: BoxDecoration( color: AppColors.white, borderRadius: const BorderRadius.only( topLeft: Radius.circular(20.0), topRight: Radius.circular(20.0), ), ), child: const Center( child: Text( '', ), ), ), Container( color: AppColors.white, height: Get.width * 0.5, child: CupertinoDatePicker( dateOrder: DatePickerDateOrder.dmy, initialDateTime: controller.scheduleDate.value, maximumYear: 2023, minimumYear: 2022, minimumDate: controller.minimumDate.value, mode: CupertinoDatePickerMode.date, onDateTimeChanged: (datetime) { controller.scheduleDate.value = datetime; }), ), Container( color: AppColors.white, width: Get.width, child: Container( child: Material( color: Colors.transparent, child: InkWell( onTap: () { if (controller.scheduleDate.value .difference(controller.minimumDate.value) .inSeconds >= 0) { controller.scheduleDateString.value = '${controller.scheduleDate.value.day}/${controller.scheduleDate.value.month}/${controller.scheduleDate.value.year}' ; Get.back(); } else controller.authManager.commonTools .showFailedSnackBar('selectValidDate'); }, child: Container( padding: const EdgeInsets.all(30.0), child: Center( child: Text( 'ok'.tr, style: Get.textTheme.headline5, ), ), ), ), ), ), ), ], ), ); }); } }