Files
CityCards_Customer_Flutter/lib/home/widgets/search_city_bottomsheet.dart
2025-10-29 17:07:27 +05:30

184 lines
5.7 KiB
Dart

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,
),
),
),
),
],
),
);
}
}