1import 'package:easy_localization/easy_localization.dart';
2import 'package:flutter/material.dart';
3import 'package:flutter_bloc/flutter_bloc.dart';
4import 'package:flutter_screenutil/flutter_screenutil.dart';
5import 'package:google_maps_flutter/google_maps_flutter.dart';
6import 'package:geolocator/geolocator.dart';
7import 'package:geocoding/geocoding.dart';
8import 'package:go_router/go_router.dart';
9import 'package:fluentui_system_icons/fluentui_system_icons.dart';
12import '../../../../../core/ui/theme/color_palette.dart';
13import '../../../../../core/ui/widgets/custom_scaffold.dart';
14import '../../../../../core/router/routes.dart';
15import '../../bloc/planning_bloc/routing_planning_bloc.dart';
16import '../../../../auth/presentation/bloc/authentication_bloc/authentication_bloc.dart';
17import 'models/saved_location.dart';
18import 'widgets/location_search_bar.dart';
19import 'widgets/saved_locations_list.dart';
20import 'widgets/custom_pin_widget.dart';
21import 'widgets/address_info_widget.dart';
22import 'widgets/map_overlay_buttons.dart';
23import 'widgets/confirm_location_button.dart';
29 State<EndLocationChooserScreen>
createState() => _EndLocationChooserScreenState();
32class _EndLocationChooserScreenState
extends State<EndLocationChooserScreen> {
49 "elementType":
"labels.icon",
57 "featureType":
"transit",
69 name:
'Dammam Warehouse',
70 address:
'Al-Dammam, Saudi Arabia',
71 latLng: LatLng(26.251011, 49.971146),
72 icon: FluentIcons.building_16_filled,
75 name:
'Jeddah Warehouse',
76 address:
'Prince Abdulmajeed, Jeddah Saudi Arabia',
77 latLng: LatLng(21.418327917324838, 39.25912328519525),
78 icon: FluentIcons.building_16_filled,
81 name:
'Riyadh Warehouse',
82 address:
'Al Misfat, Riyad Arabie saoudite',
83 latLng: LatLng(24.5518913, 46.8818212),
84 icon: FluentIcons.building_16_filled,
96 bool serviceEnabled = await Geolocator.isLocationServiceEnabled();
97 if (!serviceEnabled)
return;
99 LocationPermission permission = await Geolocator.checkPermission();
100 if (permission == LocationPermission.denied) {
101 permission = await Geolocator.requestPermission();
102 if (permission == LocationPermission.denied)
return;
105 if (permission == LocationPermission.deniedForever)
return;
107 final position = await Geolocator.getCurrentPosition(
108 locationSettings:
const LocationSettings(
109 accuracy: LocationAccuracy.high,
110 timeLimit: Duration(seconds: 10),
124 CameraUpdate.newCameraPosition(
165 List<Placemark> placemarks = await placemarkFromCoordinates(
170 if (placemarks.isNotEmpty && mounted) {
171 final placemark = placemarks.first;
174 if (placemark.street != null && placemark.street!.isNotEmpty) {
178 if (placemark.locality != null && placemark.locality!.isNotEmpty) {
180 address += placemark.locality!;
183 if (placemark.administrativeArea != null &&
184 placemark.administrativeArea!.isNotEmpty) {
186 address += placemark.administrativeArea!;
189 if (placemark.country != null && placemark.country!.isNotEmpty) {
212 CameraUpdate.newCameraPosition(
229 context.read<RoutingPlanningBloc>().add(
237 final authState = context.read<AuthenticationBloc>().state;
238 if (authState is AuthenticatedState) {
239 context.read<RoutingPlanningBloc>().add(
241 driverId: (authState.session.uid)?.toInt() ?? 0,
249 Widget
build(BuildContext context) {
250 return BlocListener<RoutingPlanningBloc, RoutingPlanningState>(
251 listener: (context, state) {
253 ScaffoldMessenger.of(context).showSnackBar(
255 content:
Text(state.failure.message),
256 backgroundColor: state.failure.color,
259 }
else if (state is RoutingPlanningSuccess) {
261 context.go(
Routes.scheduleConfirmationScreen.route);
264 child: CustomScaffold(
265 title:
'scheduling.choose_end_location'.tr(),
274 initialCameraPosition: CameraPosition(
278 onMapCreated: (GoogleMapController controller) {
286 myLocationEnabled:
true,
287 myLocationButtonEnabled:
false,
288 zoomControlsEnabled:
false,
289 zoomGesturesEnabled:
true,
290 mapToolbarEnabled:
false,
291 compassEnabled:
true,
301 child: LocationSearchBar(
307 CameraUpdate.newCameraPosition(
328 child: AddressInfoWidget(
335 color: Colors.white.withValues(alpha: 0.7),
337 child: CircularProgressIndicator(),
343 child: MapOverlayButtons(
344 onSearchPressed: () {
349 onSavedLocationsPressed: () {
363 child: BlocBuilder<RoutingPlanningBloc, RoutingPlanningState>(
364 builder: (context, state) {
365 final isLoading = state is RoutingPlanningLoading;
366 return ConfirmLocationButton(
378 duration:
const Duration(milliseconds: 300),
379 curve: Curves.easeInOut,
381 child: SavedLocationsList(
406 child: Transform.translate(
407 offset: Offset(0, -24.5.sp),
408 child: AnimatedContainer(
409 duration:
const Duration(milliseconds: 200),
412 child: CustomPinWidget(
427 decoration: BoxDecoration(
431 shape: BoxShape.circle,
435 color: Colors.black.withValues(alpha: 0.3),
436 offset:
const Offset(0, 2),
override void initState()
class App extends StatefulWidget build(BuildContext context)
static const antiFlashWhite
final List< SavedLocation > _savedLocations
void _onSavedLocationSelected(SavedLocation location) async
Future< void > _getCurrentLocationForInit() async
final TextEditingController _searchController
bool _isBottomSheetVisible
class EndLocationChooserScreen extends StatefulWidget _mapController
Future< void > _getAddressFromLocation(LatLng location) async
LatLng _currentCameraPosition
void _onCameraMove(CameraPosition position)
bool _isBottomSheetExpanded
class UpdateLocationEvent extends LocationSelectionEvent location
const SetEndLocationEvent({ required this.location, required this.address, })
const RoutingPlanningError({ required this.failure, this.startLocation, this.startAddress, this.selectedCollections, this.collectionsToSchedule, this.endLocation, this.endAddress, })
style Text( '${ 'scheduling.reference'.tr()}:${collection.internalCode}', style:Theme.of(context).textTheme.bodySmall,)
style Column(crossAxisAlignment:CrossAxisAlignment.end, children:[Container(padding:EdgeInsets.symmetric(horizontal:8.w, vertical:4.h), decoration:BoxDecoration(color:ColorPalette.tiffanyBlue.withValues(alpha:0.1), borderRadius:BorderRadius.circular(12),), child:Text(collection.type ?? '', style:Theme.of(context).textTheme.bodySmall?.copyWith(color:ColorPalette.tiffanyBlue, fontWeight:FontWeight.bold,),),),],)