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 @override
void onInit() { void onInit() {
// TODO: implement onInit
getTaxList(); getTaxList();
if (Constant.walletSetting == false) { if (Constant.walletSetting == false) {
pageList.value = [CabHomeScreen(), const MyCabBookingScreen(), const ProfileScreen()]; 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/controllers/theme_controller.dart';
import 'package:customer/themes/app_them_data.dart'; import 'package:customer/themes/app_them_data.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:flutter_svg/flutter_svg.dart'; import 'package:flutter_svg/flutter_svg.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
@@ -23,13 +24,19 @@ class CabDashboardScreen extends StatelessWidget {
type: BottomNavigationBarType.fixed, type: BottomNavigationBarType.fixed,
showUnselectedLabels: true, showUnselectedLabels: true,
showSelectedLabels: true, showSelectedLabels: true,
selectedFontSize: 12, selectedFontSize: 12.sp,
selectedLabelStyle: const TextStyle(fontFamily: AppThemeData.bold), selectedLabelStyle: const TextStyle(
unselectedLabelStyle: const TextStyle(fontFamily: AppThemeData.bold), fontFamily: AppThemeData.bold,
),
unselectedLabelStyle: const TextStyle(
fontFamily: AppThemeData.bold,
),
currentIndex: controller.selectedIndex.value, currentIndex: controller.selectedIndex.value,
backgroundColor: isDark ? AppThemeData.grey900 : AppThemeData.grey50, backgroundColor: AppThemeData.cardColor,
selectedItemColor: isDark ? AppThemeData.primary300 : AppThemeData.primary300, selectedItemColor:
unselectedItemColor: isDark ? AppThemeData.grey300 : AppThemeData.grey600, isDark ? AppThemeData.primary300 : AppThemeData.primary300,
unselectedItemColor:
isDark ? AppThemeData.grey300 : AppThemeData.grey600,
onTap: (int index) { onTap: (int index) {
if (index == 0) { if (index == 0) {
Get.put(CabDashboardController()); Get.put(CabDashboardController());
@@ -39,15 +46,57 @@ class CabDashboardScreen extends StatelessWidget {
items: items:
Constant.walletSetting == false Constant.walletSetting == false
? [ ? [
navigationBarItem(isDark, index: 0, assetIcon: "assets/icons/ic_home_cab.svg", label: 'Home'.tr, controller: controller), navigationBarItem(
navigationBarItem(isDark, index: 1, assetIcon: "assets/icons/ic_booking_cab.svg", label: 'My Bookings'.tr, controller: controller), isDark,
navigationBarItem(isDark, index: 2, assetIcon: "assets/icons/ic_profile.svg", label: 'Profile'.tr, controller: controller), 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(
navigationBarItem(isDark, index: 1, assetIcon: "assets/icons/ic_booking_cab.svg", label: 'My Bookings'.tr, controller: controller), isDark,
navigationBarItem(isDark, index: 2, assetIcon: "assets/icons/ic_wallet_cab.svg", label: 'Wallet'.tr, controller: controller), index: 0,
navigationBarItem(isDark, index: 3, assetIcon: "assets/icons/ic_profile.svg", label: 'Profile'.tr, controller: controller), 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( return BottomNavigationBarItem(
icon: Padding( icon: Padding(
padding: const EdgeInsets.symmetric(vertical: 5), 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/models/banner_model.dart';
import 'package:customer/screen_ui/auth_screens/login_screen.dart'; import 'package:customer/screen_ui/auth_screens/login_screen.dart';
import 'package:customer/themes/app_them_data.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:customer/utils/network_image_widget.dart';
import 'package:flutter/material.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 'package:get/get.dart';
import 'Intercity_home_screen.dart'; import 'Intercity_home_screen.dart';
import 'cab_booking_screen.dart'; import 'cab_booking_screen.dart';
class CabHomeScreen extends StatelessWidget { class CabHomeScreen extends HookWidget {
const CabHomeScreen({super.key}); const CabHomeScreen({super.key});
@override @override
@@ -26,25 +25,18 @@ class CabHomeScreen extends StatelessWidget {
return Scaffold( return Scaffold(
appBar: AppBar( appBar: AppBar(
automaticallyImplyLeading: false, automaticallyImplyLeading: false,
backgroundColor: AppThemeData.primary300, backgroundColor: AppThemeData.cardColor,
title: Padding( title: Row(
padding: const EdgeInsets.only(bottom: 10),
child: Row(
children: [ children: [
GestureDetector( SizedBox(width: 5.w),
InkWell(
onTap: () { onTap: () {
Get.back(); Get.back();
}, },
child: Container( child: Icon(
height: 42, Icons.arrow_back_ios,
width: 42, color: AppThemeData.grey900,
decoration: BoxDecoration(shape: BoxShape.circle, color: AppThemeData.grey50), size: 20,
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), const SizedBox(width: 10),
@@ -60,19 +52,29 @@ class CabHomeScreen extends StatelessWidget {
child: Text( child: Text(
"Login".tr, "Login".tr,
textAlign: TextAlign.center, textAlign: TextAlign.center,
style: AppThemeData.boldTextStyle(color: AppThemeData.grey900, fontSize: 12), style: AppThemeData.boldTextStyle(
color: AppThemeData.grey900,
fontSize: 17.sp,
),
), ),
) )
: Text( : Text(
Constant.userModel!.fullName(), Constant.userModel!.fullName(),
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.center, textAlign: TextAlign.center,
style: AppThemeData.boldTextStyle(color: AppThemeData.grey900, fontSize: 12), style: AppThemeData.boldTextStyle(
color: AppThemeData.grey900,
fontSize: 17.sp,
),
), ),
Text( Text(
Constant.selectedLocation.getFullAddress(), Constant.selectedLocation.getFullAddress(),
maxLines: 1, maxLines: 1,
overflow: TextOverflow.ellipsis, 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: body:
controller.isLoading.value controller.isLoading.value
? Constant.loader() ? Constant.loader()
: Padding( : Column(
padding: const EdgeInsets.symmetric(vertical: 20, horizontal: 15),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
BannerView(bannerList: controller.bannerTopHome), BannerView(bannerList: controller.bannerTopHome),
Column( Padding(
crossAxisAlignment: CrossAxisAlignment.start, padding: EdgeInsetsGeometry.symmetric(horizontal: 16.r),
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),
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
SvgPicture.asset("assets/icons/ic_ride.svg", height: 38, width: 38),
SizedBox(height: 20), SizedBox(height: 20),
Text( Text(
"Ride".tr, "Cab Service Type",
style: AppThemeData.semiBoldTextStyle(color: AppThemeData.taxiBooking500, fontSize: 16), style: AppThemeData.boldTextStyle(
), color:
Text( isDark
"City rides, 24x7 availability".tr, ? AppThemeData.greyDark900
style: AppThemeData.mediumTextStyle(color: AppThemeData.taxiBooking600, fontSize: 14), : AppThemeData.darkGrey,
), fontSize: 16.sp,
],
), ),
), ),
) SizedBox(height: 10.h),
: SizedBox(), // Cab Service Types Section
SizedBox(width: 20), _buildCabServiceTypesSection(),
Constant.sectionConstantModel!.rideType == "both" || Constant.sectionConstantModel!.rideType == "intercity"
? GestureDetector( SizedBox(height: 35.h),
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),
Row( Row(
children: [ children: [
Expanded( Expanded(
flex: 2, flex: 2,
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment:
CrossAxisAlignment.start,
children: [ children: [
Text( Text(
"Every Ride. Every Driver. Verified.".tr, "Every Ride. Every Driver. Verified."
.tr,
style: AppThemeData.boldTextStyle( style: AppThemeData.boldTextStyle(
color: isDark ? AppThemeData.greyDark900 : AppThemeData.grey900, color:
isDark
? AppThemeData.greyDark900
: AppThemeData.grey900,
fontSize: 22, fontSize: 22,
), ),
), ),
Text( 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( style: AppThemeData.mediumTextStyle(
color: isDark ? AppThemeData.greyDark700 : AppThemeData.grey700, color:
isDark
? AppThemeData.greyDark700
: AppThemeData.grey700,
fontSize: 14, 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 { class BannerView extends StatelessWidget {
@@ -242,43 +298,39 @@ class BannerView extends StatelessWidget {
? SizedBox() ? SizedBox()
: Column( : Column(
children: [ children: [
SizedBox(height: 20), SizedBox(height: 20.h),
SizedBox( SizedBox(
height: 150, height: 150.h,
child: ListView.separated( child: ListView.builder(
controller: scrollController, controller: scrollController,
scrollDirection: Axis.horizontal, scrollDirection: Axis.horizontal,
itemCount: bannerList.length, itemCount: bannerList.length,
separatorBuilder: (context, index) => const SizedBox(width: 15),
itemBuilder: (context, index) { itemBuilder: (context, index) {
final banner = bannerList[index]; final banner = bannerList[index];
return ClipRRect( return Container(
borderRadius: BorderRadius.circular(15),
child: SizedBox(
width: MediaQuery.of(context).size.width * 0.8, 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" url: "https://pub.dev"
source: hosted source: hosted
version: "2.0.0" 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: flutter_html:
dependency: "direct main" dependency: "direct main"
description: description:

View File

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