import 'package:customer/constant/constant.dart'; import 'package:customer/controllers/cab_home_controller.dart'; import 'package:customer/controllers/theme_controller.dart'; import 'package:customer/models/banner_model.dart'; import 'package:customer/screen_ui/auth_screens/login_screen.dart'; import 'package:customer/themes/app_them_data.dart'; import 'package:customer/utils/network_image_widget.dart'; import 'package:flutter/material.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:get/get.dart'; import 'Intercity_home_screen.dart'; import 'cab_booking_screen.dart'; class CabHomeScreen extends HookWidget { const CabHomeScreen({super.key}); @override Widget build(BuildContext context) { final themeController = Get.find(); final isDark = themeController.isDark.value; return GetX( init: CabHomeController(), builder: (controller) { return Scaffold( appBar: AppBar( automaticallyImplyLeading: false, backgroundColor: AppThemeData.cardColor, title: Row( children: [ SizedBox(width: 5.w), InkWell( onTap: () { Get.back(); }, 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, textAlign: TextAlign.center, style: AppThemeData.boldTextStyle( color: AppThemeData.grey900, fontSize: 17.sp, ), ), ) : Text( Constant.userModel!.fullName(), overflow: TextOverflow.ellipsis, textAlign: TextAlign.center, style: AppThemeData.boldTextStyle( color: AppThemeData.grey900, fontSize: 17.sp, ), ), Text( Constant.selectedLocation.getFullAddress(), maxLines: 1, overflow: TextOverflow.ellipsis, style: AppThemeData.regularTextStyle( fontSize: 12.sp, color: AppThemeData.grey900, ), ), ], ), ), ], ), ), body: controller.isLoading.value ? Constant.loader() : Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ BannerView(bannerList: controller.bannerTopHome), Padding( padding: EdgeInsetsGeometry.symmetric(horizontal: 16.r), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ SizedBox(height: 20), Text( "Cab Service Type", style: AppThemeData.boldTextStyle( color: isDark ? AppThemeData.greyDark900 : AppThemeData.darkGrey, fontSize: 16.sp, ), ), SizedBox(height: 10.h), // Cab Service Types Section _buildCabServiceTypesSection(), SizedBox(height: 35.h), Row( children: [ Expanded( flex: 2, child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( "Every Ride. Every Driver. Verified." .tr, style: AppThemeData.boldTextStyle( color: isDark ? AppThemeData.greyDark900 : AppThemeData.grey900, fontSize: 22, ), ), Text( "All drivers go through ID checks and background verification for your safety." .tr, style: AppThemeData.mediumTextStyle( color: isDark ? AppThemeData.greyDark700 : AppThemeData.grey700, fontSize: 14, ), ), ], ), ), Expanded( child: Image.asset( "assets/images/img_ride_driver.png", height: 118, width: 68, ), ), ], ), ], ), ), ], ), ); }, ); } Row _buildCabServiceTypesSection() { return Row( spacing: 10.w, children: [ Constant.sectionConstantModel!.rideType == "both" || Constant.sectionConstantModel!.rideType == "ride" ? _cabOptionMaker( title: "По городу", isMain: false, image: "assets/images/taxi_option.png", useGradient: false, onTap: () { Get.to(() => CabBookingScreen()); }, mainColor: AppThemeData.cardColor, ) : Expanded(child: SizedBox()), _cabOptionMaker( title: "Межгород", isMain: false, useGradient: false, image: "assets/images/outer_city_taxi_option.png", onTap: () { Get.to(() => IntercityHomeScreen()); }, mainColor: AppThemeData.cardColor, ), ], ); } Expanded _cabOptionMaker({ required String title, required String image, required VoidCallback onTap, required Color mainColor, required useGradient, required bool isMain, }) { return Expanded( child: InkWell( onTap: onTap, child: Container( height: 100.h, clipBehavior: Clip.hardEdge, decoration: BoxDecoration( color: mainColor, borderRadius: BorderRadius.circular(16.r), gradient: useGradient ? LinearGradient( begin: Alignment.centerLeft, end: Alignment.centerRight, colors: [Color(0xFF2E2E37), Color(0xFF6A6A9E)], ) : null, ), child: Stack( children: [ Padding( padding: EdgeInsets.only(left: 12.r, top: 12.r), child: Row( children: [ Expanded( child: Text( maxLines: 2, title, style: TextStyle( overflow: TextOverflow.ellipsis, fontFamily: AppThemeData.semiBold, fontSize: 14.sp, fontWeight: FontWeight.w700, color: isMain ? AppThemeData.grey50 : AppThemeData.darkGrey, ), ), ), Expanded(child: SizedBox()), ], ), ), Transform.translate( offset: Offset(25.w, 0), child: Align( alignment: Alignment.bottomRight, child: Image.asset( image, height: 133.h, width: 133.w, fit: BoxFit.contain, ), ), ), ], ), ), ), ); } } 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 bannerList.isEmpty ? SizedBox() : Column( children: [ SizedBox(height: 20.h), SizedBox( height: 150.h, child: ListView.builder( controller: scrollController, scrollDirection: Axis.horizontal, itemCount: bannerList.length, itemBuilder: (context, index) { final banner = bannerList[index]; return Container( width: MediaQuery.of(context).size.width * 0.8, margin: index == 0 ? EdgeInsets.only(left: 16.r, right: 10.r) : index == bannerList.length - 1 ? EdgeInsets.only(right: 16.r) : EdgeInsets.only(right: 10.r), decoration: BoxDecoration( borderRadius: BorderRadius.circular(15), ), child: ClipRRect( borderRadius: BorderRadius.circular(15), child: NetworkImageWidget( imageUrl: banner.photo ?? '', fit: BoxFit.cover, ), ), ); }, ), ), ], ); } }