diff --git a/lib/components/dark_mode_map.dart b/lib/components/dark_mode_map.dart index 856698b..b887f90 100644 --- a/lib/components/dark_mode_map.dart +++ b/lib/components/dark_mode_map.dart @@ -293,36 +293,6 @@ class _DarkModeMapComponentState extends State { } } - Future _zoomIn() async { - if (_navigationController == null) return; - try { - final currentCamera = await _navigationController!.getCameraPosition(); - await _navigationController!.animateCamera( - CameraUpdate.newLatLngZoom( - currentCamera.target, - currentCamera.zoom + 1, - ), - ); - } catch (e) { - debugPrint('Zoom in error: $e'); - } - } - - Future _zoomOut() async { - if (_navigationController == null) return; - try { - final currentCamera = await _navigationController!.getCameraPosition(); - await _navigationController!.animateCamera( - CameraUpdate.newLatLngZoom( - currentCamera.target, - currentCamera.zoom - 1, - ), - ); - } catch (e) { - debugPrint('Zoom out error: $e'); - } - } - Future _recenterMap() async { if (_navigationController == null) return; try { @@ -340,9 +310,8 @@ class _DarkModeMapComponentState extends State { // Driver's current location (defaults to Montreal if not available) final initialPosition = const LatLng(latitude: 45.5017, longitude: -73.5673); - // Calculate dynamic padding for top info panel and bottom button bar - // Increased to accommodate navigation widget info and action buttons - final topPadding = widget.selectedDelivery != null ? 110.0 : 0.0; + // Calculate dynamic padding for bottom button bar + final topPadding = 0.0; final bottomPadding = widget.selectedDelivery != null ? 110.0 : 0.0; return Stack( @@ -369,27 +338,6 @@ class _DarkModeMapComponentState extends State { ), ), ), - // Custom dark-themed controls overlay - Positioned( - top: 16, - right: 16, - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - // Zoom in button - _buildIconButton( - icon: Icons.add, - onPressed: _zoomIn, - ), - const SizedBox(height: 8), - // Zoom out button - _buildIconButton( - icon: Icons.remove, - onPressed: _zoomOut, - ), - ], - ), - ), // Navigation and action buttons (positioned above bottom button bar) Positioned( bottom: 120, @@ -415,87 +363,6 @@ class _DarkModeMapComponentState extends State { ], ), ), - // Selected delivery info panel (dark themed) - if (widget.selectedDelivery != null) - Positioned( - top: 0, - left: 0, - right: 0, - child: Container( - decoration: BoxDecoration( - color: Theme.of(context).colorScheme.surface, - boxShadow: [ - BoxShadow( - color: Colors.black.withValues(alpha: 0.2), - blurRadius: 8, - offset: const Offset(0, 2), - ), - ], - ), - padding: const EdgeInsets.symmetric( - horizontal: 16, - vertical: 12, - ), - child: Row( - children: [ - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisSize: MainAxisSize.min, - children: [ - Text( - widget.selectedDelivery!.name, - style: Theme.of(context) - .textTheme - .titleMedium - ?.copyWith(fontWeight: FontWeight.w600), - maxLines: 1, - overflow: TextOverflow.ellipsis, - ), - const SizedBox(height: 4), - Text( - widget.selectedDelivery!.deliveryAddress - ?.formattedAddress ?? - 'No address', - style: Theme.of(context) - .textTheme - .bodySmall, - maxLines: 1, - overflow: TextOverflow.ellipsis, - ), - ], - ), - ), - const SizedBox(width: 8), - // Status indicator - Container( - padding: const EdgeInsets.symmetric( - horizontal: 8, - vertical: 4, - ), - decoration: BoxDecoration( - color: widget.selectedDelivery!.delivered - ? SvrntyColors.statusCompleted - : SvrntyColors.statusPending, - borderRadius: BorderRadius.circular(4), - ), - child: Text( - widget.selectedDelivery!.delivered - ? 'Delivered' - : 'Pending', - style: Theme.of(context) - .textTheme - .labelSmall - ?.copyWith( - color: Colors.white, - fontWeight: FontWeight.w600, - ), - ), - ), - ], - ), - ), - ), // Bottom action button bar if (widget.selectedDelivery != null) Positioned( @@ -633,40 +500,6 @@ class _DarkModeMapComponentState extends State { ); } - Widget _buildIconButton({ - required IconData icon, - required VoidCallback onPressed, - }) { - return Container( - decoration: BoxDecoration( - shape: BoxShape.circle, - boxShadow: [ - BoxShadow( - color: Colors.black.withValues(alpha: 0.3), - blurRadius: 4, - offset: const Offset(0, 2), - ), - ], - ), - child: Material( - color: Theme.of(context).colorScheme.surface, - shape: const CircleBorder(), - child: InkWell( - onTap: onPressed, - customBorder: const CircleBorder(), - child: Padding( - padding: const EdgeInsets.all(12), - child: Icon( - icon, - color: Theme.of(context).colorScheme.onSurface, - size: 24, - ), - ), - ), - ), - ); - } - Widget _buildBottomActionButton({ required String label, required IconData icon, diff --git a/lib/components/delivery_map.dart b/lib/components/delivery_map.dart index 5052c94..68328f6 100644 --- a/lib/components/delivery_map.dart +++ b/lib/components/delivery_map.dart @@ -195,29 +195,6 @@ class _DeliveryMapState extends State { ), ), ), - Positioned( - top: 16, - right: 16, - child: Column( - children: [ - FloatingActionButton.small( - heroTag: 'zoom_in', - onPressed: () { - _navigationController?.animateCamera(CameraUpdate.zoomIn()); - }, - child: const Icon(Icons.add), - ), - const SizedBox(height: 8), - FloatingActionButton.small( - heroTag: 'zoom_out', - onPressed: () { - _navigationController?.animateCamera(CameraUpdate.zoomOut()); - }, - child: const Icon(Icons.remove), - ), - ], - ), - ), ], ); } diff --git a/lib/components/map_sidebar_layout.dart b/lib/components/map_sidebar_layout.dart index b1f4cea..90fb5dc 100644 --- a/lib/components/map_sidebar_layout.dart +++ b/lib/components/map_sidebar_layout.dart @@ -1,7 +1,11 @@ import 'package:flutter/material.dart'; import '../utils/breakpoints.dart'; +import '../theme/spacing_system.dart'; +import '../theme/size_system.dart'; +import '../theme/animation_system.dart'; +import '../theme/color_system.dart'; -class MapSidebarLayout extends StatelessWidget { +class MapSidebarLayout extends StatefulWidget { final Widget mapWidget; final Widget sidebarWidget; final double mapRatio; @@ -13,23 +17,119 @@ class MapSidebarLayout extends StatelessWidget { this.mapRatio = 2 / 3, }); + @override + State createState() => _MapSidebarLayoutState(); +} + +class _MapSidebarLayoutState extends State + with SingleTickerProviderStateMixin { + late AnimationController _animationController; + bool _isExpanded = true; + + @override + void initState() { + super.initState(); + _animationController = AnimationController( + duration: const Duration(milliseconds: 300), + vsync: this, + ); + if (_isExpanded) { + _animationController.forward(); + } + } + + @override + void dispose() { + _animationController.dispose(); + super.dispose(); + } + + void _toggleSidebar() { + setState(() { + _isExpanded = !_isExpanded; + }); + if (_isExpanded) { + _animationController.forward(); + } else { + _animationController.reverse(); + } + } + @override Widget build(BuildContext context) { final isMobile = MediaQuery.of(context).size.width < Breakpoints.tablet; + final isDarkMode = Theme.of(context).brightness == Brightness.dark; if (isMobile) { - return sidebarWidget; + return widget.sidebarWidget; } + // Desktop: Show map with collapsible sidebar return Row( children: [ Expanded( - flex: (mapRatio * 100).toInt(), - child: mapWidget, + flex: (widget.mapRatio * 100).toInt(), + child: widget.mapWidget, ), - Expanded( - flex: ((1 - mapRatio) * 100).toInt(), - child: sidebarWidget, + // Collapsible sidebar with toggle button + AnimatedContainer( + duration: const Duration(milliseconds: 300), + width: _isExpanded ? 280 : 64, + color: isDarkMode ? SvrntyColors.almostBlack : Colors.white, + child: Column( + children: [ + // Header with toggle button + Container( + height: kToolbarHeight, + padding: EdgeInsets.symmetric(horizontal: AppSpacing.xs), + decoration: BoxDecoration( + border: Border( + left: BorderSide( + color: isDarkMode + ? SvrntyColors.darkSlate + : SvrntyColors.slateGray.withValues(alpha: 0.2), + width: 1, + ), + ), + ), + child: Row( + mainAxisAlignment: _isExpanded + ? MainAxisAlignment.spaceBetween + : MainAxisAlignment.center, + children: [ + if (_isExpanded) + Expanded( + child: Text( + 'Deliveries', + style: Theme.of(context).textTheme.titleMedium, + overflow: TextOverflow.ellipsis, + ), + ), + SizedBox( + width: AppSizes.buttonHeightMd, + height: AppSizes.buttonHeightMd, + child: IconButton( + icon: AnimatedRotation( + turns: _isExpanded ? 0 : -0.5, + duration: Duration( + milliseconds: + AppAnimations.durationFast.inMilliseconds, + ), + child: const Icon(Icons.chevron_right), + ), + onPressed: _toggleSidebar, + iconSize: AppSizes.iconMd, + ), + ), + ], + ), + ), + // Sidebar content + Expanded( + child: _isExpanded ? widget.sidebarWidget : const SizedBox.shrink(), + ), + ], + ), ), ], );