diff --git a/apps/mobile/apps/staff/android/app/src/main/java/io/flutter/plugins/GeneratedPluginRegistrant.java b/apps/mobile/apps/staff/android/app/src/main/java/io/flutter/plugins/GeneratedPluginRegistrant.java index 2b40a2eb..05f7bbac 100644 --- a/apps/mobile/apps/staff/android/app/src/main/java/io/flutter/plugins/GeneratedPluginRegistrant.java +++ b/apps/mobile/apps/staff/android/app/src/main/java/io/flutter/plugins/GeneratedPluginRegistrant.java @@ -45,6 +45,11 @@ public final class GeneratedPluginRegistrant { } catch (Exception e) { Log.e(TAG, "Error registering plugin geolocator_android, com.baseflow.geolocator.GeolocatorPlugin", e); } + try { + flutterEngine.getPlugins().add(new io.flutter.plugins.googlemaps.GoogleMapsPlugin()); + } catch (Exception e) { + Log.e(TAG, "Error registering plugin google_maps_flutter_android, io.flutter.plugins.googlemaps.GoogleMapsPlugin", e); + } try { flutterEngine.getPlugins().add(new io.flutter.plugins.imagepicker.ImagePickerPlugin()); } catch (Exception e) { diff --git a/apps/mobile/apps/staff/ios/Runner/GeneratedPluginRegistrant.m b/apps/mobile/apps/staff/ios/Runner/GeneratedPluginRegistrant.m index 0285454c..89cde2bb 100644 --- a/apps/mobile/apps/staff/ios/Runner/GeneratedPluginRegistrant.m +++ b/apps/mobile/apps/staff/ios/Runner/GeneratedPluginRegistrant.m @@ -36,6 +36,12 @@ @import geolocator_apple; #endif +#if __has_include() +#import +#else +@import google_maps_flutter_ios; +#endif + #if __has_include() #import #else @@ -80,6 +86,7 @@ [FLTFirebaseCorePlugin registerWithRegistrar:[registry registrarForPlugin:@"FLTFirebaseCorePlugin"]]; [FlutterLocalNotificationsPlugin registerWithRegistrar:[registry registrarForPlugin:@"FlutterLocalNotificationsPlugin"]]; [GeolocatorPlugin registerWithRegistrar:[registry registrarForPlugin:@"GeolocatorPlugin"]]; + [FGMGoogleMapsPlugin registerWithRegistrar:[registry registrarForPlugin:@"FGMGoogleMapsPlugin"]]; [FLTImagePickerPlugin registerWithRegistrar:[registry registrarForPlugin:@"FLTImagePickerPlugin"]]; [FPPPackageInfoPlusPlugin registerWithRegistrar:[registry registrarForPlugin:@"FPPPackageInfoPlusPlugin"]]; [RecordIosPlugin registerWithRegistrar:[registry registrarForPlugin:@"RecordIosPlugin"]]; diff --git a/apps/mobile/packages/features/staff/shifts/lib/src/presentation/pages/shift_details_page.dart b/apps/mobile/packages/features/staff/shifts/lib/src/presentation/pages/shift_details_page.dart index cb238376..f0f9a27a 100644 --- a/apps/mobile/packages/features/staff/shifts/lib/src/presentation/pages/shift_details_page.dart +++ b/apps/mobile/packages/features/staff/shifts/lib/src/presentation/pages/shift_details_page.dart @@ -140,6 +140,8 @@ class _ShiftDetailsPageState extends State { ShiftLocationSection( location: detail.location, address: detail.address ?? '', + latitude: detail.latitude, + longitude: detail.longitude, locationLabel: context.t.staff_shifts.shift_details.location, tbdLabel: context.t.staff_shifts.shift_details.tbd, getDirectionLabel: context.t.staff_shifts.shift_details.get_direction, diff --git a/apps/mobile/packages/features/staff/shifts/lib/src/presentation/widgets/shift_details/shift_date_time_section.dart b/apps/mobile/packages/features/staff/shifts/lib/src/presentation/widgets/shift_details/shift_date_time_section.dart index 3e38f151..08ce36e2 100644 --- a/apps/mobile/packages/features/staff/shifts/lib/src/presentation/widgets/shift_details/shift_date_time_section.dart +++ b/apps/mobile/packages/features/staff/shifts/lib/src/presentation/widgets/shift_details/shift_date_time_section.dart @@ -57,7 +57,7 @@ class ShiftDateTimeSection extends StatelessWidget { const Icon( UiIcons.calendar, size: 20, - color: UiColors.primary, + color: UiColors.textPrimary, ), const SizedBox(width: UiConstants.space2), Text( diff --git a/apps/mobile/packages/features/staff/shifts/lib/src/presentation/widgets/shift_details/shift_description_section.dart b/apps/mobile/packages/features/staff/shifts/lib/src/presentation/widgets/shift_details/shift_description_section.dart index 770fc3f9..41731764 100644 --- a/apps/mobile/packages/features/staff/shifts/lib/src/presentation/widgets/shift_details/shift_description_section.dart +++ b/apps/mobile/packages/features/staff/shifts/lib/src/presentation/widgets/shift_details/shift_description_section.dart @@ -32,7 +32,7 @@ class ShiftDescriptionSection extends StatelessWidget { const SizedBox(height: UiConstants.space2), Text( description, - style: UiTypography.body2r.textSecondary, + style: UiTypography.body2r, ), ], ), diff --git a/apps/mobile/packages/features/staff/shifts/lib/src/presentation/widgets/shift_details/shift_details_header.dart b/apps/mobile/packages/features/staff/shifts/lib/src/presentation/widgets/shift_details/shift_details_header.dart index c822d5e2..a225243e 100644 --- a/apps/mobile/packages/features/staff/shifts/lib/src/presentation/widgets/shift_details/shift_details_header.dart +++ b/apps/mobile/packages/features/staff/shifts/lib/src/presentation/widgets/shift_details/shift_details_header.dart @@ -45,8 +45,8 @@ class ShiftDetailsHeader extends StatelessWidget { child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - Text(detail.title, style: UiTypography.headline1b.textPrimary), - Text(detail.roleName, style: UiTypography.body1m.textSecondary), + Text(detail.roleName, style: UiTypography.headline1b.textPrimary), + Text(detail.clientName, style: UiTypography.body1m.textSecondary), ], ), ), diff --git a/apps/mobile/packages/features/staff/shifts/lib/src/presentation/widgets/shift_details/shift_location_section.dart b/apps/mobile/packages/features/staff/shifts/lib/src/presentation/widgets/shift_details/shift_location_section.dart index e85910b6..18e3786d 100644 --- a/apps/mobile/packages/features/staff/shifts/lib/src/presentation/widgets/shift_details/shift_location_section.dart +++ b/apps/mobile/packages/features/staff/shifts/lib/src/presentation/widgets/shift_details/shift_location_section.dart @@ -1,6 +1,7 @@ import 'package:core_localization/core_localization.dart'; import 'package:design_system/design_system.dart'; import 'package:flutter/material.dart'; +import 'package:google_maps_flutter/google_maps_flutter.dart'; import 'package:url_launcher/url_launcher.dart'; /// A section displaying the shift's location, address, and "Get direction" action. @@ -10,6 +11,8 @@ class ShiftLocationSection extends StatelessWidget { super.key, required this.location, required this.address, + this.latitude, + this.longitude, required this.locationLabel, required this.tbdLabel, required this.getDirectionLabel, @@ -21,6 +24,12 @@ class ShiftLocationSection extends StatelessWidget { /// Street address. final String address; + /// Latitude coordinate for map preview. + final double? latitude; + + /// Longitude coordinate for map preview. + final double? longitude; + /// Localization string for location section title. final String locationLabel; @@ -97,15 +106,53 @@ class ShiftLocationSection extends StatelessWidget { ), ], ), + + if (latitude != null && longitude != null) ...[ + ClipRRect( + borderRadius: BorderRadius.circular(UiConstants.radiusBase), + child: SizedBox( + height: 180, + width: double.infinity, + child: GoogleMap( + initialCameraPosition: CameraPosition( + target: LatLng(latitude!, longitude!), + zoom: 15, + ), + markers: { + Marker( + markerId: const MarkerId('shift_location'), + position: LatLng(latitude!, longitude!), + ), + }, + liteModeEnabled: true, + myLocationButtonEnabled: false, + myLocationEnabled: false, + zoomControlsEnabled: false, + mapToolbarEnabled: false, + compassEnabled: false, + rotateGesturesEnabled: false, + scrollGesturesEnabled: false, + tiltGesturesEnabled: false, + zoomGesturesEnabled: false, + ), + ), + ), + const SizedBox(height: UiConstants.space3), + ], ], ), ); } Future _openDirections(BuildContext context) async { - final String destination = Uri.encodeComponent( - address.isNotEmpty ? address : location, - ); + String destination; + if (latitude != null && longitude != null) { + destination = '$latitude,$longitude'; + } else { + destination = Uri.encodeComponent( + address.isNotEmpty ? address : location, + ); + } final String url = 'https://www.google.com/maps/dir/?api=1&destination=$destination'; diff --git a/apps/mobile/packages/features/staff/shifts/pubspec.yaml b/apps/mobile/packages/features/staff/shifts/pubspec.yaml index a05c568e..d478f4f9 100644 --- a/apps/mobile/packages/features/staff/shifts/pubspec.yaml +++ b/apps/mobile/packages/features/staff/shifts/pubspec.yaml @@ -29,6 +29,7 @@ dependencies: url_launcher: ^6.3.1 bloc: ^8.1.4 meta: ^1.17.0 + google_maps_flutter: ^2.10.0 dev_dependencies: flutter_test: diff --git a/apps/mobile/pubspec.lock b/apps/mobile/pubspec.lock index 8a97848c..53a17dd0 100644 --- a/apps/mobile/pubspec.lock +++ b/apps/mobile/pubspec.lock @@ -257,6 +257,14 @@ packages: url: "https://pub.dev" source: hosted version: "3.0.7" + csslib: + dependency: transitive + description: + name: csslib + sha256: "09bad715f418841f976c77db72d5398dc1253c21fb9c0c7f0b0b985860b2d58e" + url: "https://pub.dev" + source: hosted + version: "1.0.2" csv: dependency: transitive description: @@ -637,6 +645,54 @@ packages: url: "https://pub.dev" source: hosted version: "7.0.2" + google_maps: + dependency: transitive + description: + name: google_maps + sha256: "5d410c32112d7c6eb7858d359275b2aa04778eed3e36c745aeae905fb2fa6468" + url: "https://pub.dev" + source: hosted + version: "8.2.0" + google_maps_flutter: + dependency: transitive + description: + name: google_maps_flutter + sha256: "0114a31e177f650f0972347d93122c42661a75b869561ff6a374cc42ff3af886" + url: "https://pub.dev" + source: hosted + version: "2.16.0" + google_maps_flutter_android: + dependency: transitive + description: + name: google_maps_flutter_android + sha256: "68a3907c90dc37caffbcfc1093541ef2c18d6ebb53296fdb9f04822d16269353" + url: "https://pub.dev" + source: hosted + version: "2.19.3" + google_maps_flutter_ios: + dependency: transitive + description: + name: google_maps_flutter_ios + sha256: c855600dce17e77e8af96edcf85cb68501675bb77a72f85009d08c17a8805ace + url: "https://pub.dev" + source: hosted + version: "2.18.0" + google_maps_flutter_platform_interface: + dependency: transitive + description: + name: google_maps_flutter_platform_interface + sha256: ddbe34435dfb34e83fca295c6a8dcc53c3b51487e9eec3c737ce4ae605574347 + url: "https://pub.dev" + source: hosted + version: "2.15.0" + google_maps_flutter_web: + dependency: transitive + description: + name: google_maps_flutter_web + sha256: "6cefe4ef4cc61dc0dfba4c413dec4bd105cb6b9461bfbe1465ddd09f80af377d" + url: "https://pub.dev" + source: hosted + version: "0.6.2" google_places_flutter: dependency: transitive description: @@ -669,6 +725,14 @@ packages: url: "https://pub.dev" source: hosted version: "0.20.5" + html: + dependency: transitive + description: + name: html + sha256: "6d1264f2dffa1b1101c25a91dff0dc2daee4c18e87cd8538729773c073dbf602" + url: "https://pub.dev" + source: hosted + version: "0.15.6" http: dependency: transitive description: @@ -1189,6 +1253,14 @@ packages: url: "https://pub.dev" source: hosted version: "0.28.0" + sanitize_html: + dependency: transitive + description: + name: sanitize_html + sha256: "12669c4a913688a26555323fb9cec373d8f9fbe091f2d01c40c723b33caa8989" + url: "https://pub.dev" + source: hosted + version: "2.1.0" shared_preferences: dependency: transitive description: