import 'package:customer/constant/constant.dart'; import 'package:flutter/material.dart'; import 'package:geocoding/geocoding.dart'; import 'package:geolocator/geolocator.dart'; import 'package:get/get.dart'; import '../../controllers/home_parcel_controller.dart'; import '../../controllers/theme_controller.dart'; import '../../models/banner_model.dart'; import '../../models/parcel_category.dart'; import '../../models/user_model.dart'; import '../../themes/app_them_data.dart'; import '../../themes/show_toast_dialog.dart'; import '../../utils/network_image_widget.dart'; import '../../widget/osm_map/map_picker_page.dart'; import '../../widget/place_picker/location_picker_screen.dart'; import '../../widget/place_picker/selected_location_model.dart'; import '../auth_screens/login_screen.dart'; import '../location_enable_screens/address_list_screen.dart'; import 'book_parcel_screen.dart'; class HomeParcelScreen extends StatelessWidget { const HomeParcelScreen({super.key}); @override Widget build(BuildContext context) { final themeController = Get.find(); final isDark = themeController.isDark.value; return GetX( init: HomeParcelController(), builder: (controller) { return Scaffold( appBar: AppBar( automaticallyImplyLeading: false, backgroundColor: AppThemeData.primary300, title: Padding( padding: const EdgeInsets.only(bottom: 10), child: Row( children: [ InkWell( borderRadius: BorderRadius.circular(50), onTap: () { Get.back(); }, child: Container( height: 42, width: 42, decoration: BoxDecoration(shape: BoxShape.circle, color: AppThemeData.grey50), child: Center(child: Padding(padding: const EdgeInsets.only(left: 5), child: Icon(Icons.arrow_back_ios, color: AppThemeData.grey900, size: 20))), ), ), const SizedBox(width: 10), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Constant.userModel == null ? InkWell( onTap: () { Get.offAll(const LoginScreen()); }, child: Text("Login".tr, 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) { Get.to(AddressListScreen())!.then((value) { if (value != null) { ShippingAddress shippingAddress = value; Constant.selectedLocation = shippingAddress; } }); } else { Constant.checkPermission( onTap: () async { ShowToastDialog.showLoader("Please wait...".tr); ShippingAddress shippingAddress = ShippingAddress(); try { await Geolocator.requestPermission(); await Geolocator.getCurrentPosition(); ShowToastDialog.closeLoader(); if (Constant.selectedMapType == 'osm') { final result = await Get.to(() => MapPickerPage()); if (result != null) { final firstPlace = result; 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); Constant.selectedLocation = shippingAddress; Get.back(); } } else { Get.to(LocationPickerScreen())!.then((value) async { if (value != null) { SelectedLocationModel selectedLocationModel = value; shippingAddress.addressAs = "Home"; shippingAddress.location = UserLocation(latitude: selectedLocationModel.latLng!.latitude, longitude: selectedLocationModel.latLng!.longitude); shippingAddress.locality = "Picked from Map"; Constant.selectedLocation = shippingAddress; } }); } } catch (e) { await placemarkFromCoordinates(19.228825, 72.854118).then((valuePlaceMaker) { Placemark placeMark = valuePlaceMaker[0]; 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; }); Constant.selectedLocation = shippingAddress; ShowToastDialog.closeLoader(); } }, context: context, ); } }, child: Text( Constant.selectedLocation.getFullAddress(), maxLines: 1, overflow: TextOverflow.ellipsis, style: AppThemeData.boldTextStyle(fontSize: 18, color: AppThemeData.grey900), ), ), ], ), ), ], ), ), ), body: controller.isLoading.value ? Center(child: Constant.loader()) : SingleChildScrollView( child: Padding( padding: const EdgeInsets.symmetric(horizontal: 16), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ const SizedBox(height: 12), BannerView(bannerList: controller.bannerTopHome), const SizedBox(height: 12), Padding( padding: const EdgeInsets.symmetric(vertical: 15), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ 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), ), padding: const EdgeInsets.symmetric(horizontal: 20), child: ListView.builder( itemCount: controller.parcelCategory.length, shrinkWrap: true, physics: const ScrollPhysics(), padding: const EdgeInsets.symmetric(vertical: 10), itemBuilder: (context, index) { return buildItems(item: controller.parcelCategory[index], isDark: isDark); }, ), ), ], ), ), ], ), ), ), ); }, ); } Widget buildItems({required ParcelCategory item, required bool isDark}) { return Padding( padding: const EdgeInsets.symmetric(vertical: 10.0), child: InkWell( onTap: () { if (Constant.userModel == null) { Get.to(const LoginScreen()); } else { Get.to(const BookParcelScreen(), arguments: {'parcelCategory': item}); } }, child: Row( crossAxisAlignment: CrossAxisAlignment.center, children: [ 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), ], ), ), ); } } class BannerView extends StatelessWidget { final List bannerList; final RxInt currentPage = 0.obs; final ScrollController scrollController = ScrollController(); BannerView({super.key, required this.bannerList}); /// Computes the visible item index from scroll offset void onScroll(BuildContext context) { if (scrollController.hasClients && bannerList.isNotEmpty) { final screenWidth = MediaQuery.of(context).size.width; final itemWidth = screenWidth * 0.8 + 10; // banner width + spacing final offset = scrollController.offset; final index = (offset / itemWidth).round(); if (index != currentPage.value && index < bannerList.length) { currentPage.value = index; } } } @override Widget build(BuildContext context) { scrollController.addListener(() { onScroll(context); }); return Column( children: [ SizedBox( height: 150, child: ListView.separated( controller: scrollController, scrollDirection: Axis.horizontal, itemCount: bannerList.length, separatorBuilder: (context, index) => const SizedBox(width: 15), itemBuilder: (context, index) { 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)), ); }, ), ), const SizedBox(height: 8), Obx(() { 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)))); }), ); }), ], ); } }