feat: Google Maps location picker in dashboard
- LocationPickerDialog: detecta ubicación del dispositivo, pin draggable, reverse geocoding para obtener dirección y ciudad - Dashboard: campo de dirección abre el mapa al tocar - index.html: carga Maps JS API (key pendiente de configurar) - pubspec: google_maps_flutter + geolocator Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 4.6
parent
77f44ac43a
commit
863546f0fc
@@ -1,5 +1,6 @@
|
||||
import 'dart:async';
|
||||
import 'dart:convert';
|
||||
import 'package:google_maps_flutter/google_maps_flutter.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:prosapp_web_app/services/api_service.dart';
|
||||
import 'package:prosapp_web_app/models/schedules_entity.dart';
|
||||
@@ -15,6 +16,7 @@ import 'package:prosapp_web_app/services/navigation_service.dart';
|
||||
import 'package:prosapp_web_app/services/notifications_service.dart';
|
||||
import 'package:prosapp_web_app/ui/cards/white_card.dart';
|
||||
import 'package:prosapp_web_app/ui/inputs/custom_inputs.dart';
|
||||
import 'package:prosapp_web_app/ui/widgets/location_picker.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:prosapp_web_app/utils/local_notifications.dart';
|
||||
import 'package:prosapp_web_app/utils/network_utility.dart';
|
||||
@@ -37,6 +39,8 @@ class _DashboardViewState extends State<DashboardView> {
|
||||
String? selectedProfessionalName;
|
||||
DateTime? selectedDay;
|
||||
TimeOfDay? selectedHour;
|
||||
LatLng? _selectedLatLng;
|
||||
String? _selectedCity;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
@@ -94,6 +98,20 @@ class _DashboardViewState extends State<DashboardView> {
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
Future<void> _openLocationPicker() async {
|
||||
final result = await LocationPickerDialog.show(
|
||||
context,
|
||||
initialPosition: _selectedLatLng,
|
||||
);
|
||||
if (result != null && mounted) {
|
||||
setState(() {
|
||||
_addressController.text = result.address;
|
||||
_selectedLatLng = result.position;
|
||||
_selectedCity = result.city;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
if (user == null) {
|
||||
@@ -194,39 +212,20 @@ class _DashboardViewState extends State<DashboardView> {
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
const SizedBox(height: 10),
|
||||
isUserComplete()
|
||||
? TextFormField(
|
||||
controller: _addressController,
|
||||
onChanged: (value) {
|
||||
if (_debounce?.isActive ?? false)
|
||||
_debounce?.cancel();
|
||||
|
||||
_debounce = Timer(
|
||||
const Duration(milliseconds: 500), () {
|
||||
String modifiedValue =
|
||||
value.replaceAll(' ', '_');
|
||||
placeAutoComplete(modifiedValue, _coords);
|
||||
});
|
||||
},
|
||||
decoration: CustomInputs.formInputDecoration(
|
||||
hint: 'Ingresa tu dirección',
|
||||
label: 'Dirección',
|
||||
icon: Icons.location_on,
|
||||
),
|
||||
)
|
||||
: GestureDetector(
|
||||
onTap: () => NotificationsService.showSnackBarError(
|
||||
'Completa tu perfil para solicitar un servicio'),
|
||||
child: AbsorbPointer(
|
||||
child: TextFormField(
|
||||
decoration: CustomInputs.formInputDecoration(
|
||||
hint: 'Ingresa tu dirección',
|
||||
label: 'Dirección',
|
||||
icon: Icons.location_on,
|
||||
),
|
||||
),
|
||||
),
|
||||
GestureDetector(
|
||||
onTap: isUserComplete() ? _openLocationPicker : () =>
|
||||
NotificationsService.showSnackBarError('Completa tu perfil para solicitar un servicio'),
|
||||
child: AbsorbPointer(
|
||||
child: TextFormField(
|
||||
controller: _addressController,
|
||||
decoration: CustomInputs.formInputDecoration(
|
||||
hint: 'Toca para seleccionar tu dirección',
|
||||
label: 'Dirección',
|
||||
icon: Icons.location_on,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
GestureDetector(
|
||||
onTap: () => isUserComplete()
|
||||
|
||||
Reference in New Issue
Block a user