BASE: Finish Cam Home Screen UI.

This commit is contained in:
2025-11-28 15:31:06 +05:00
parent 5c98705bde
commit 8c120b8984
5 changed files with 300 additions and 185 deletions

View File

@@ -13,7 +13,6 @@ class CabDashboardController extends GetxController {
@override
void onInit() {
// TODO: implement onInit
getTaxList();
if (Constant.walletSetting == false) {
pageList.value = [CabHomeScreen(), const MyCabBookingScreen(), const ProfileScreen()];

View File

@@ -3,6 +3,7 @@ import 'package:customer/controllers/cab_dashboard_controller.dart';
import 'package:customer/controllers/theme_controller.dart';
import 'package:customer/themes/app_them_data.dart';
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:get/get.dart';
@@ -23,13 +24,19 @@ class CabDashboardScreen extends StatelessWidget {
type: BottomNavigationBarType.fixed,
showUnselectedLabels: true,
showSelectedLabels: true,
selectedFontSize: 12,
selectedLabelStyle: const TextStyle(fontFamily: AppThemeData.bold),
unselectedLabelStyle: const TextStyle(fontFamily: AppThemeData.bold),
selectedFontSize: 12.sp,
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.primary300 : AppThemeData.primary300,
unselectedItemColor: isDark ? AppThemeData.grey300 : AppThemeData.grey600,
backgroundColor: AppThemeData.cardColor,
selectedItemColor:
isDark ? AppThemeData.primary300 : AppThemeData.primary300,
unselectedItemColor:
isDark ? AppThemeData.grey300 : AppThemeData.grey600,
onTap: (int index) {
if (index == 0) {
Get.put(CabDashboardController());
@@ -39,15 +46,57 @@ class CabDashboardScreen extends StatelessWidget {
items:
Constant.walletSetting == false
? [
navigationBarItem(isDark, index: 0, assetIcon: "assets/icons/ic_home_cab.svg", label: 'Home'.tr, controller: controller),
navigationBarItem(isDark, index: 1, assetIcon: "assets/icons/ic_booking_cab.svg", label: 'My Bookings'.tr, controller: controller),
navigationBarItem(isDark, index: 2, assetIcon: "assets/icons/ic_profile.svg", label: 'Profile'.tr, controller: controller),
navigationBarItem(
isDark,
index: 0,
assetIcon: "assets/icons/ic_home_cab.svg",
label: 'Home'.tr,
controller: controller,
),
navigationBarItem(
isDark,
index: 1,
assetIcon: "assets/icons/ic_booking_cab.svg",
label: 'My Bookings'.tr,
controller: controller,
),
navigationBarItem(
isDark,
index: 2,
assetIcon: "assets/icons/ic_profile.svg",
label: 'Profile'.tr,
controller: controller,
),
]
: [
navigationBarItem(isDark, index: 0, assetIcon: "assets/icons/ic_home_cab.svg", label: 'Home'.tr, controller: controller),
navigationBarItem(isDark, index: 1, assetIcon: "assets/icons/ic_booking_cab.svg", label: 'My Bookings'.tr, controller: controller),
navigationBarItem(isDark, index: 2, assetIcon: "assets/icons/ic_wallet_cab.svg", label: 'Wallet'.tr, controller: controller),
navigationBarItem(isDark, index: 3, assetIcon: "assets/icons/ic_profile.svg", label: 'Profile'.tr, controller: controller),
navigationBarItem(
isDark,
index: 0,
assetIcon: "assets/icons/ic_home_cab.svg",
label: 'Home'.tr,
controller: controller,
),
navigationBarItem(
isDark,
index: 1,
assetIcon: "assets/icons/ic_booking_cab.svg",
label: 'My Bookings'.tr,
controller: controller,
),
navigationBarItem(
isDark,
index: 2,
assetIcon: "assets/icons/ic_wallet_cab.svg",
label: 'Wallet'.tr,
controller: controller,
),
navigationBarItem(
isDark,
index: 3,
assetIcon: "assets/icons/ic_profile.svg",
label: 'Profile'.tr,
controller: controller,
),
],
),
);
@@ -56,7 +105,13 @@ class CabDashboardScreen extends StatelessWidget {
});
}
BottomNavigationBarItem navigationBarItem(isDark, {required int index, required String label, required String assetIcon, required CabDashboardController controller}) {
BottomNavigationBarItem navigationBarItem(
isDark, {
required int index,
required String label,
required String assetIcon,
required CabDashboardController controller,
}) {
return BottomNavigationBarItem(
icon: Padding(
padding: const EdgeInsets.symmetric(vertical: 5),

View File

@@ -4,16 +4,15 @@ 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/themes/responsive.dart';
import 'package:customer/utils/network_image_widget.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.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 StatelessWidget {
class CabHomeScreen extends HookWidget {
const CabHomeScreen({super.key});
@override
@@ -26,25 +25,18 @@ class CabHomeScreen extends StatelessWidget {
return Scaffold(
appBar: AppBar(
automaticallyImplyLeading: false,
backgroundColor: AppThemeData.primary300,
title: Padding(
padding: const EdgeInsets.only(bottom: 10),
child: Row(
backgroundColor: AppThemeData.cardColor,
title: Row(
children: [
GestureDetector(
SizedBox(width: 5.w),
InkWell(
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),
),
),
child: Icon(
Icons.arrow_back_ios,
color: AppThemeData.grey900,
size: 20,
),
),
const SizedBox(width: 10),
@@ -60,19 +52,29 @@ class CabHomeScreen extends StatelessWidget {
child: Text(
"Login".tr,
textAlign: TextAlign.center,
style: AppThemeData.boldTextStyle(color: AppThemeData.grey900, fontSize: 12),
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: 12),
style: AppThemeData.boldTextStyle(
color: AppThemeData.grey900,
fontSize: 17.sp,
),
),
Text(
Constant.selectedLocation.getFullAddress(),
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: AppThemeData.boldTextStyle(fontSize: 18, color: AppThemeData.grey900),
style: AppThemeData.regularTextStyle(
fontSize: 12.sp,
color: AppThemeData.grey900,
),
),
],
),
@@ -80,135 +82,189 @@ class CabHomeScreen extends StatelessWidget {
],
),
),
),
body:
controller.isLoading.value
? Constant.loader()
: Padding(
padding: const EdgeInsets.symmetric(vertical: 20, horizontal: 15),
child: Column(
: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
BannerView(bannerList: controller.bannerTopHome),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SizedBox(height: 20),
Text(
"Where are you going for?".tr,
style: AppThemeData.mediumTextStyle(
color: isDark ? AppThemeData.greyDark900 : AppThemeData.grey900,
fontSize: 18,
),
),
SizedBox(height: 20),
Row(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Constant.sectionConstantModel!.rideType == "both" || Constant.sectionConstantModel!.rideType == "ride"
? GestureDetector(
onTap: () {
Get.to(() => CabBookingScreen());
},
child: Container(
width: Responsive.width(40, context),
decoration: BoxDecoration(
color: AppThemeData.warning50,
borderRadius: BorderRadius.circular(15),
border: Border.all(color: AppThemeData.warning200),
),
padding: EdgeInsets.all(16),
Padding(
padding: EdgeInsetsGeometry.symmetric(horizontal: 16.r),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SvgPicture.asset("assets/icons/ic_ride.svg", height: 38, width: 38),
SizedBox(height: 20),
Text(
"Ride".tr,
style: AppThemeData.semiBoldTextStyle(color: AppThemeData.taxiBooking500, fontSize: 16),
),
Text(
"City rides, 24x7 availability".tr,
style: AppThemeData.mediumTextStyle(color: AppThemeData.taxiBooking600, fontSize: 14),
),
],
"Cab Service Type",
style: AppThemeData.boldTextStyle(
color:
isDark
? AppThemeData.greyDark900
: AppThemeData.darkGrey,
fontSize: 16.sp,
),
),
)
: SizedBox(),
SizedBox(width: 20),
Constant.sectionConstantModel!.rideType == "both" || Constant.sectionConstantModel!.rideType == "intercity"
? GestureDetector(
onTap: () {
Get.to(() => IntercityHomeScreen());
},
child: Container(
width: Responsive.width(44, context),
decoration: BoxDecoration(
color: AppThemeData.carRent50,
borderRadius: BorderRadius.circular(15),
border: Border.all(color: AppThemeData.carRent200),
),
padding: EdgeInsets.all(15),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SvgPicture.asset("assets/icons/ic_intercity.svg", height: 38, width: 38),
SizedBox(height: 20),
Text(
"Intercity/Outstation".tr,
style: AppThemeData.semiBoldTextStyle(color: AppThemeData.carRent500, fontSize: 16),
),
Text(
"Long trips, prepaid options".tr,
style: AppThemeData.mediumTextStyle(color: AppThemeData.parcelService600, fontSize: 14),
),
],
),
),
)
: SizedBox(),
],
),
SizedBox(height: 30),
SizedBox(height: 10.h),
// Cab Service Types Section
_buildCabServiceTypesSection(),
SizedBox(height: 35.h),
Row(
children: [
Expanded(
flex: 2,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
Text(
"Every Ride. Every Driver. Verified.".tr,
"Every Ride. Every Driver. Verified."
.tr,
style: AppThemeData.boldTextStyle(
color: isDark ? AppThemeData.greyDark900 : AppThemeData.grey900,
color:
isDark
? AppThemeData.greyDark900
: AppThemeData.grey900,
fontSize: 22,
),
),
Text(
"All drivers go through ID checks and background verification for your safety.".tr,
"All drivers go through ID checks and background verification for your safety."
.tr,
style: AppThemeData.mediumTextStyle(
color: isDark ? AppThemeData.greyDark700 : AppThemeData.grey700,
color:
isDark
? AppThemeData.greyDark700
: AppThemeData.grey700,
fontSize: 14,
),
),
],
),
),
Expanded(child: Image.asset("assets/images/img_ride_driver.png", height: 118, width: 68)),
],
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 {
@@ -242,43 +298,39 @@ class BannerView extends StatelessWidget {
? SizedBox()
: Column(
children: [
SizedBox(height: 20),
SizedBox(height: 20.h),
SizedBox(
height: 150,
child: ListView.separated(
height: 150.h,
child: ListView.builder(
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(
return Container(
width: MediaQuery.of(context).size.width * 0.8,
child: NetworkImageWidget(imageUrl: banner.photo ?? '', fit: BoxFit.cover),
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,
),
),
);
},
),
),
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),
),
),
);
}),
);
}),
],
);
}

View File

@@ -558,6 +558,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.0.0"
flutter_hooks:
dependency: "direct main"
description:
name: flutter_hooks
sha256: "8ae1f090e5f4ef5cfa6670ce1ab5dddadd33f3533a7f9ba19d9f958aa2a89f42"
url: "https://pub.dev"
source: hosted
version: "0.21.3+1"
flutter_html:
dependency: "direct main"
description:

View File

@@ -87,6 +87,7 @@ dependencies:
uuid: ^4.5.2
flutter_google_places_hoc081098: ^2.0.0
flutter_screenutil: ^5.9.3
flutter_hooks: ^0.21.3+1
dependency_overrides:
webview_flutter: ^4.9.0