import 'package:manager_app/l10n/app_localizations.dart'; import 'package:flutter/material.dart'; import 'package:location_picker_flutter_map/location_picker_flutter_map.dart'; import 'package:manager_app/Components/common_loader.dart'; import 'package:manager_app/Components/message_notification.dart'; import 'package:manager_app/constants.dart'; /// Choix d'un point sur une carte. /// /// Le champ affiche les coordonnées retenues au lieu d'un simple bouton /// « Changer la localisation » : on voit ce qui est réglé sans ouvrir la carte. /// Le dialogue reprend la coquille standard, et la carte occupe la hauteur /// disponible au lieu d'un bloc de 350 px. class GeolocInputContainer extends StatefulWidget { final Color color; final String label; final LatLong? initialValue; final ValueChanged onChanged; final bool isSmall; final double fontSize; final double fontSizeText; const GeolocInputContainer({ Key? key, this.color = kSecond, required this.label, required this.initialValue, required this.onChanged, this.isSmall = false, this.fontSize = 18, this.fontSizeText = 20, }) : super(key: key); @override State createState() => _GeolocInputContainerState(); } class _GeolocInputContainerState extends State { LatLong? localisation; @override Widget build(BuildContext context) { final l = AppLocalizations.of(context)!; localisation = widget.initialValue; final current = localisation; return Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, children: [ Text(widget.label, style: kLabelField), const SizedBox(height: kSpace2), Material( color: Colors.transparent, child: InkWell( borderRadius: BorderRadius.circular(kRadiusInput), onTap: () => _openPicker(context), child: Container( padding: const EdgeInsets.symmetric( horizontal: kSpace4, vertical: kSpace3), decoration: BoxDecoration( color: kSurface2, border: Border.all(color: kLine), borderRadius: BorderRadius.circular(kRadiusInput), ), child: Row( children: [ const Icon(Icons.place_outlined, size: 15, color: kInk3), const SizedBox(width: kSpace3), Expanded( child: Text( current == null ? l.noLocationChosen : "${current.latitude.toStringAsFixed(5)}, ${current.longitude.toStringAsFixed(5)}", maxLines: 1, overflow: TextOverflow.ellipsis, style: TextStyle( fontSize: 13, color: current == null ? kInk3 : kInk, fontStyle: current == null ? FontStyle.italic : FontStyle.normal, ), ), ), const SizedBox(width: kSpace3), Text(l.change, style: const TextStyle( fontSize: 12.5, fontWeight: FontWeight.w600, color: kPrimaryColor)), ], ), ), ), ), ], ); } void _openPicker(BuildContext context) { final size = MediaQuery.of(context).size; showDialog( context: context, builder: (BuildContext context) { final l = AppLocalizations.of(context)!; return Dialog( shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(kRadiusShell), side: const BorderSide(color: kLine), ), clipBehavior: Clip.antiAlias, insetPadding: const EdgeInsets.symmetric(horizontal: kSpace7, vertical: kSpace7), child: SizedBox( width: size.width * 0.75, child: Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.stretch, children: [ Padding( padding: const EdgeInsets.fromLTRB( kSpace6, kSpace5, kSpace4, kSpace5), child: Row( children: [ Expanded(child: Text(widget.label, style: kTitleCard)), IconButton( icon: const Icon(Icons.close, size: 20, color: kInk3), tooltip: l.cancel, onPressed: () => Navigator.of(context).pop(), ), ], ), ), const Divider(height: 1, thickness: 1, color: kLineSoft), Flexible( child: FlutterLocationPicker( initZoom: 14, initPosition: localisation == null ? LatLong(50.429333, 4.891434) : LatLong(localisation!.latitude, localisation!.longitude), minZoomLevel: 0, maxZoomLevel: 17, markerIcon: const Icon( Icons.location_pin, color: kPrimaryColor, size: 50, ), loadingWidget: CommonLoader(iconSize: 40.0), searchBarHintColor: kPrimaryColor, mapLoadingBackgroundColor: kSurface2, zoomButtonsBackgroundColor: kPrimaryColor, zoomButtonsColor: kWhite, locationButtonBackgroundColor: kPrimaryColor, locationButtonsColor: kWhite, countryFilter: "be, fr", trackMyPosition: false, searchBarHintText: l.searchLocationHint, searchBarTextColor: kInk, searchBarBackgroundColor: kSurface, showSelectLocationButton: true, selectLocationButtonText: l.selectThisLocation, selectedLocationButtonTextstyle: const TextStyle(fontSize: 14, color: kPrimaryColor), mapLanguage: 'fr', onError: (e) => print(e), selectLocationButtonLeadingIcon: const Icon(Icons.check, color: kPrimaryColor), onPicked: (pickedData) { localisation = pickedData.latLong; }, showContributorBadgeForOSM: false, ), ), Container( padding: const EdgeInsets.all(kSpace4), decoration: const BoxDecoration( color: kSurface2, border: Border(top: BorderSide(color: kLineSoft)), ), child: Row( mainAxisAlignment: MainAxisAlignment.end, children: [ TextButton( onPressed: () => Navigator.of(context).pop(), child: Text(l.cancel, style: const TextStyle(fontSize: 13, color: kInk2)), ), const SizedBox(width: kSpace2), FilledButton( onPressed: () { if (localisation != null) { widget.onChanged(localisation!); Navigator.of(context).pop(); } else { showNotification(kPrimaryColor, kWhite, l.noLocationChosen, context, null); } }, style: FilledButton.styleFrom( backgroundColor: kPrimaryColor, padding: const EdgeInsets.symmetric( horizontal: kSpace5, vertical: kSpace3), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(kRadiusPill)), ), child: Text(l.validate, style: const TextStyle( fontSize: 13, fontWeight: FontWeight.w600)), ), ], ), ), ], ), ), ); }, ); } }