3 Commits

Author SHA1 Message Date
9dd76e1dac Merge remote-tracking branch 'origin/vinayak' into dinesh
# Conflicts:
#	lib/main.dart
2025-10-29 17:12:05 +05:30
Vinayakkadge04
c771ce335c Changed serch_city_bottomsheet navigation 2025-10-29 17:11:07 +05:30
Vinayakkadge04
f93ba6dad2 Worked on Search city bottomsheet 2025-10-29 17:07:27 +05:30
4 changed files with 242 additions and 7 deletions

View File

@@ -0,0 +1,54 @@
import 'package:flutter_bloc/flutter_bloc.dart';
abstract class LoadCityEvent {}
class LoadAllCity extends LoadCityEvent {}
class SearchCity extends LoadCityEvent {
final String query;
SearchCity(this.query);
}
// ----- State -----
class CityState {
final List<Map<String, String>> offers;
const CityState(this.offers);
}
// ----- Bloc -----
class SearchCityBloc extends Bloc<LoadCityEvent, CityState> {
SearchCityBloc() : super(const CityState([])) {
on<LoadAllCity>(_onLoadCity);
on<SearchCity>(_onSearchCity);
}
final List<Map<String, String>> _allOffers = [
{"image": "assets/images/aa1.png", "title": "Sydney"},
{"image": "assets/images/aa2.png", "title": "New York"},
{"image": "assets/images/aa3.png", "title": "Abu Dhabi"},
{"image": "assets/images/aa4.png", "title": "Dubai"},
{
"image": "assets/images/card_banner.png",
"title": "Tokyo",
},
{"image": "assets/images/city_germany.jpg", "title": "Ontario"},
{"image": "assets/images/aa2.png", "title": "Mumbai"},
{"image": "assets/images/aa3.png", "title": "Louisiana"},
];
void _onLoadCity(event, emit) {
emit(CityState(_allOffers));
}
void _onSearchCity(event, emit) {
final filtered = _allOffers
.where(
(offer) =>
offer["title"]!.toLowerCase().contains(event.query.toLowerCase()),
)
.toList();
emit(CityState(filtered));
}
}

View File

@@ -1,3 +1,4 @@
import 'package:citycards_customer/home/widgets/search_city_bottomsheet.dart';
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
@@ -120,7 +121,9 @@ class _FirstTimeUserHomePageState extends State<FirstTimeUserHomePage> {
borderRadius: BorderRadius.circular(25.r),
),
),
onPressed: () {},
onPressed: () {
},
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [

View File

@@ -0,0 +1,183 @@
import 'package:citycards_customer/common_packages/custom_text.dart';
import 'package:citycards_customer/home/bloc/search_city_bloc.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
class CitySelectionBottomSheet extends StatelessWidget {
const CitySelectionBottomSheet({super.key});
@override
Widget build(BuildContext context) {
return BlocProvider(
create: (_) => SearchCityBloc()..add(LoadAllCity()),
child: _CitySelectionView(),
);
}
}
class _CitySelectionView extends StatelessWidget {
_CitySelectionView();
final TextEditingController _controller = TextEditingController();
@override
Widget build(BuildContext context) {
return Container(
height: 620.h,
padding: EdgeInsets.symmetric(horizontal: 20.w, vertical: 20.h),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.only(
topLeft: Radius.circular(12.r),
topRight: Radius.circular(12.r),
),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// Header
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Row(
children: [
InkWell(
onTap: () => Navigator.pop(context),
child: const Icon(Icons.arrow_back, size: 18),
),
SizedBox(width: 4.w,),
CustomText(text: "Back", size: 12.sp,)
],
),
Text(
"Select a City",
style: TextStyle(
fontSize: 16.sp,
fontWeight: FontWeight.w600,
),
),
SizedBox(width: 25.w,)
],
),
SizedBox(height: 19.h),
// Search Field
SizedBox(
height: 45.h,
child: TextField(
controller: _controller,
onChanged: (value) {
if (value.isEmpty) {
context.read<SearchCityBloc>().add(LoadAllCity());
} else {
context.read<SearchCityBloc>().add(SearchCity(value));
}
},
decoration: InputDecoration(
hintText: "Search Cities",
hintStyle: TextStyle(
fontSize: 14.sp,
color: const Color(0xFF2B2B2B),
fontWeight: FontWeight.w300
),
filled: true,
fillColor: const Color(0xFFFFFFFF).withOpacity(.24),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(8.r),
borderSide: BorderSide(
color: Color(0xFFF95F62).withOpacity(.40),
width: 1,
),
),
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(8.r),
borderSide: BorderSide(
color: Color(0xFFF95F62).withOpacity(.40),
width: 1,
),
),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(8.r),
borderSide: BorderSide(
color: Color(0xFFF95F62).withOpacity(.40),
width: 1.2,
),
),
),
),
),
SizedBox(height: 19.h),
// City Grid
Expanded(
child: BlocBuilder<SearchCityBloc, CityState>(
builder: (context, state) {
if (state.offers.isEmpty) {
return const Center(child: Text("No cities found"));
}
return GridView.builder(
itemCount: state.offers.length,
physics: const BouncingScrollPhysics(),
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
mainAxisSpacing: 12.h,
crossAxisSpacing: 12.w,
childAspectRatio: 1.2,
),
itemBuilder: (context, index) {
final city = state.offers[index];
return _cityCard(city["image"]!, city["title"]!);
},
);
},
),
),
],
),
);
}
Widget _cityCard(String image, String name) {
return ClipRRect(
borderRadius: BorderRadius.circular(12.r),
child: Stack(
fit: StackFit.expand,
children: [
Image.asset(image, fit: BoxFit.cover,width: 170.w,height: 123.h,),
Container(
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [
Colors.black.withOpacity(0.5),
Colors.black.withOpacity(0.5),
Colors.transparent,
],
begin: Alignment.bottomCenter,
end: Alignment.center,
),
),
),
Align(
alignment: Alignment.bottomLeft,
child: Padding(
padding: EdgeInsets.all(8.w),
child: Text(
name,
style: TextStyle(
color: Colors.white,
fontSize: 18.sp,
fontWeight: FontWeight.w400,
),
),
),
),
],
),
);
}
}

View File

@@ -38,15 +38,10 @@ class OfferPassDetailView extends StatelessWidget {
crossAxisAlignment: CrossAxisAlignment.start,
children: [
CommonAppBar(
isWhiteLogo: true,
isWhiteLogo: false,
isProfilePage: false,
),
SizedBox(height: 10.h),
Divider(
color: Colors.white.withOpacity(0.6),
height: 1.h,
),
SizedBox(height: 8.h),
Row(