feat(maps): Integrate Google Maps plugin for shift location display and refactor related components

This commit is contained in:
Achintha Isuru
2026-02-16 13:55:32 -05:00
parent 888cf83c18
commit e1e255f8f0
6 changed files with 175 additions and 52 deletions

View File

@@ -1,19 +1,19 @@
import 'package:design_system/design_system.dart';
import 'package:flutter/material.dart';
import 'package:krow_domain/krow_domain.dart';
import '../shift_location_map.dart';
import 'shift_location_map.dart';
/// A section displaying the shift's location, address, map, and "Get direction" action.
class ShiftLocationSection extends StatelessWidget {
/// The shift entity containing location data.
final Shift shift;
/// Localization string for location section title.
final String locationLabel;
/// Localization string for "TBD".
final String tbdLabel;
/// Localization string for "Get direction".
final String getDirectionLabel;
@@ -32,56 +32,80 @@ class ShiftLocationSection extends StatelessWidget {
padding: const EdgeInsets.all(UiConstants.space5),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
spacing: UiConstants.space4,
children: [
Text(
locationLabel,
style: UiTypography.titleUppercase4b.textSecondary,
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
Column(
spacing: UiConstants.space2,
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
Expanded(
child: Text(
shift.location.isEmpty ? tbdLabel : shift.location,
style: UiTypography.title1m.textPrimary,
overflow: TextOverflow.ellipsis,
),
Text(
locationLabel,
style: UiTypography.titleUppercase4b.textSecondary,
),
const SizedBox(width: UiConstants.space3),
OutlinedButton.icon(
onPressed: () {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(
shift.locationAddress.isNotEmpty
? shift.locationAddress
: shift.location,
),
duration: const Duration(seconds: 3),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
spacing: UiConstants.space4,
children: [
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
shift.location.isEmpty ? tbdLabel : shift.location,
style: UiTypography.title1m.textPrimary,
overflow: TextOverflow.ellipsis,
),
if (shift.locationAddress.isNotEmpty)
Text(
shift.locationAddress,
style: UiTypography.body2r.textSecondary,
maxLines: 2,
overflow: TextOverflow.ellipsis,
),
],
),
);
},
icon: const Icon(
UiIcons.navigation,
size: UiConstants.iconXs,
),
label: Text(getDirectionLabel),
style: OutlinedButton.styleFrom(
foregroundColor: UiColors.textPrimary,
side: const BorderSide(color: UiColors.border),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(UiConstants.radiusBase),
),
padding: const EdgeInsets.symmetric(
horizontal: UiConstants.space3,
vertical: 0,
OutlinedButton.icon(
onPressed: () {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(
shift.locationAddress.isNotEmpty
? shift.locationAddress
: shift.location,
),
duration: const Duration(seconds: 3),
),
);
},
icon: const Icon(
UiIcons.navigation,
size: UiConstants.iconXs,
),
label: Text(getDirectionLabel),
style: OutlinedButton.styleFrom(
foregroundColor: UiColors.textPrimary,
side: const BorderSide(color: UiColors.border),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(
UiConstants.radiusBase,
),
),
padding: const EdgeInsets.symmetric(
horizontal: UiConstants.space3,
vertical: 0,
),
minimumSize: const Size(0, 32),
),
),
minimumSize: const Size(0, 32),
),
],
),
],
),
const SizedBox(height: UiConstants.space3),
ShiftLocationMap(
shift: shift,
height: 160,