feat: integrate Google Maps Places Autocomplete for hub address validation

This commit is contained in:
Achintha Isuru
2026-01-29 03:01:14 -05:00
parent 8f55e3f758
commit c212e8be00
7 changed files with 106 additions and 11 deletions

View File

@@ -6,7 +6,7 @@
/// Locales: 2
/// Strings: 1038 (519 per locale)
///
/// Built on 2026-01-29 at 04:15 UTC
/// Built on 2026-01-29 at 06:58 UTC
// coverage:ignore-file
// ignore_for_file: type=lint, unused_import

View File

@@ -2,6 +2,8 @@ import 'package:design_system/design_system.dart';
import 'package:flutter/material.dart';
import 'package:core_localization/core_localization.dart';
import 'hub_address_autocomplete.dart';
/// A dialog for adding a new hub.
class AddHubDialog extends StatefulWidget {
/// Callback when the "Create Hub" button is pressed.
@@ -74,12 +76,9 @@ class _AddHubDialogState extends State<AddHubDialog> {
),
const SizedBox(height: UiConstants.space4),
_buildFieldLabel(t.client_hubs.add_hub_dialog.address_label),
TextField(
HubAddressAutocomplete(
controller: _addressController,
style: UiTypography.body1r.textPrimary,
decoration: _buildInputDecoration(
t.client_hubs.add_hub_dialog.address_hint,
),
hintText: t.client_hubs.add_hub_dialog.address_hint,
),
const SizedBox(height: UiConstants.space8),
Row(

View File

@@ -0,0 +1,55 @@
import 'package:design_system/design_system.dart';
import 'package:flutter/material.dart';
import 'package:google_places_flutter/google_places_flutter.dart';
import 'package:google_places_flutter/model/prediction.dart';
import '../../util/hubs_constants.dart';
class HubAddressAutocomplete extends StatelessWidget {
const HubAddressAutocomplete({
required this.controller,
required this.hintText,
super.key,
});
final TextEditingController controller;
final String hintText;
@override
Widget build(BuildContext context) {
return GooglePlaceAutoCompleteTextField(
textEditingController: controller,
googleAPIKey: HubsConstants.googlePlacesApiKey,
debounceTime: 500,
countries: HubsConstants.supportedCountries,
isLatLngRequired: false,
getPlaceDetailWithLatLng: (Prediction prediction) {
// Handle lat/lng if needed in the future
},
itemClick: (Prediction prediction) {
controller.text = prediction.description ?? '';
controller.selection = TextSelection.fromPosition(
TextPosition(offset: controller.text.length),
);
},
itemBuilder: (_, _, Prediction prediction) {
return Padding(
padding: const EdgeInsets.all(UiConstants.space2),
child: Row(
spacing: UiConstants.space1,
children: <Widget>[
const Icon(UiIcons.mapPin, color: UiColors.iconSecondary),
Expanded(
child: Text(
prediction.description ?? "",
style: UiTypography.body1r.textSecondary,
),
),
],
),
);
},
textStyle: UiTypography.body1r.textPrimary,
);
}
}

View File

@@ -0,0 +1,4 @@
class HubsConstants {
static const String googlePlacesApiKey = String.fromEnvironment('GOOGLE_PLACES_API_KEY');
static const List<String> supportedCountries = <String>['us'];
}

View File

@@ -11,11 +11,7 @@ environment:
dependencies:
flutter:
sdk: flutter
flutter_bloc: ^8.1.0
flutter_modular: ^6.3.2
equatable: ^2.0.5
lucide_icons: ^0.257.0
# Architecture Packages
krow_core:
path: ../../../core
@@ -27,8 +23,14 @@ dependencies:
path: ../../../design_system
core_localization:
path: ../../../core_localization
flutter_bloc: ^8.1.0
flutter_modular: ^6.3.2
equatable: ^2.0.5
lucide_icons: ^0.257.0
firebase_auth: ^6.1.4
firebase_data_connect: ^0.2.2+2
google_places_flutter: ^2.1.1
dev_dependencies:
flutter_test: