Files
Fondex/lib/screen_ui/cab_service_screens/cab_home_screen.dart

339 lines
12 KiB
Dart

import 'package:customer/constant/const_texts.dart';
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/app_router.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<ThemeController>();
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(
ConstTexts.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(
ConstTexts.cabServiceType.tr,
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(
ConstTexts.everyRideVerified.tr,
style: AppThemeData.boldTextStyle(
color:
isDark
? AppThemeData.greyDark900
: AppThemeData.grey900,
fontSize: 22,
),
),
Text(
ConstTexts.allDriversIDCheck.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: ConstTexts.aroundTheCity.tr,
isMain: false,
image: "assets/images/taxi_option.png",
useGradient: false,
onTap: () {
Get.to(() => CabBookingScreen());
},
mainColor: AppThemeData.cardColor,
)
: Expanded(child: SizedBox()),
_cabOptionMaker(
title: ConstTexts.intercity.tr,
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<BannerModel> 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,
),
),
);
},
),
),
],
);
}
}