import 'dart:convert'; import 'dart:ui'; import 'dart:math' as math; import 'package:bookmywages/consts_widgets/app_assets.dart'; import 'package:bookmywages/routers/consts_router.dart'; import 'package:bookmywages/viewmodel/api_controller.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; // Add this import import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:get/get.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'package:http/http.dart' as http; class MainController extends ConsumerStatefulWidget { final Widget child; final int? initialBottomIndex; const MainController({ super.key, required this.child, this.initialBottomIndex, }); @override ConsumerState createState() => _MainControllerState(); } class _MainControllerState extends ConsumerState with SingleTickerProviderStateMixin { int _selectedIndex = 0; bool _showMenu = false; late AnimationController _animationController; @override void initState() { super.initState(); // Set bottom navigation index if (widget.initialBottomIndex != null) { _selectedIndex = widget.initialBottomIndex!; } else { // Auto-detect based on current route final currentRoute = Get.currentRoute; if (currentRoute == RouterConts.homescreen) { _selectedIndex = 0; } else if (currentRoute == RouterConts.packageList) { _selectedIndex = 1; } else if (currentRoute == RouterConts.categorypage) { _selectedIndex = 2; } else if (currentRoute == RouterConts.history) { _selectedIndex = 3; } else if (currentRoute == RouterConts.profilemainscreen || currentRoute == RouterConts.editprofile || currentRoute == RouterConts.changepassword) { _selectedIndex = 0; // No tab selected } } _animationController = AnimationController( vsync: this, duration: const Duration(milliseconds: 300), ); } void _toggleMenu() { setState(() { _showMenu = !_showMenu; _showMenu ? _animationController.forward() : _animationController.reverse(); }); } // 🎯 NEW: Handle back button press Future _onWillPop() async { final currentRoute = Get.currentRoute; // If menu is open, close it first if (_showMenu) { _toggleMenu(); return false; // Don't exit } // Handle back navigation based on current route switch (currentRoute) { case RouterConts.profilemainscreen: case RouterConts.editprofile: case RouterConts.changepassword: // Navigate back to home when coming from profile screens Get.offAllNamed(RouterConts.homescreen); return false; // Don't use default back behavior case RouterConts.packageList: case RouterConts.categorypage: case RouterConts.history: // For other main tabs, go to home first Get.offAllNamed(RouterConts.homescreen); return false; case RouterConts.homescreen: // If already on home, allow default back behavior (exit app) return true; default: // For any other screens, try to go back to home try { Get.back(); } catch (e) { // If can't go back, navigate to home Get.offAllNamed(RouterConts.homescreen); } return false; } } void _onItemTapped(int index, BuildContext context) { if (_selectedIndex == index) return; switch (index) { case 0: Get.offAllNamed(RouterConts.homescreen); break; case 1: Get.offAllNamed(RouterConts.packageList); break; case 2: Get.offAllNamed(RouterConts.categorypage); break; case 3: // Navigate to history with default tab (Service Booking) Get.offAllNamed( RouterConts.history, arguments: { 'historyTab': 0, // Default to first tab }, ); break; } } void changeSelectedIndex(int index) { setState(() { _selectedIndex = index; }); } @override Widget build(BuildContext context) { final isKeyboardOpen = MediaQuery.of(context).viewInsets.bottom > 0; // 🎯 Wrap with WillPopScope to handle back button return WillPopScope( onWillPop: _onWillPop, child: Scaffold( resizeToAvoidBottomInset: false, body: Stack( children: [ InheritedIndexController( changeIndex: changeSelectedIndex, child: widget.child, ), if (_showMenu && !isKeyboardOpen) AnimatedOpacity( opacity: 1.0, duration: const Duration(milliseconds: 300), child: GestureDetector( onTap: _toggleMenu, child: Container( alignment: Alignment.center, child: BackdropFilter( filter: ImageFilter.blur(sigmaX: 2.0, sigmaY: 2.0), child: Container( color: Colors.black.withOpacity(0.2), width: double.infinity, height: double.infinity, ), ), ), ), ), if (_showMenu && !isKeyboardOpen) Positioned( bottom: 60, left: 0, right: 0, child: Padding( padding: const EdgeInsets.symmetric(horizontal: 110), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ _buildMenuOption( icon: Icons.store, label: 'Vendor', color: const Color(0xFF0066FF), onTap: () async { _toggleMenu(); try { await ref.read(getvendorIdProvider.future); Get.toNamed(RouterConts.vendorwelcome); } catch (e) { ScaffoldMessenger.of(context).showSnackBar( const SnackBar( content: Text('Failed to fetch Vendor ID'), ), ); } }, ), _buildMenuOption( icon: Icons.person, label: 'Profile', color: const Color(0xFF0066FF), onTap: () { _toggleMenu(); Get.toNamed(RouterConts.profilemainscreen); }, ), ], ), ), ), ], ), floatingActionButton: isKeyboardOpen ? null : FloatingActionButton( heroTag: "main_controller_fab", onPressed: _toggleMenu, shape: const CircleBorder(), backgroundColor: const Color(0xFF0066FF), child: AnimatedBuilder( animation: _animationController, builder: (context, child) { return Transform.rotate( angle: _animationController.value * 0.75 * math.pi, child: Icon( _animationController.value > 0.5 ? Icons.close : Icons.add, color: Colors.white, ), ); }, ), ), floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked, bottomNavigationBar: BottomAppBar( notchMargin: 8, color: Colors.white, elevation: 8, child: SizedBox( height: 60, child: Row( mainAxisAlignment: MainAxisAlignment.spaceAround, children: [ _bottomNavItem(0, AppAssets.home), _bottomNavItem(1, AppAssets.package), const Expanded(child: SizedBox()), _bottomNavItem(2, AppAssets.categories), _bottomNavItem(3, AppAssets.history), ], ), ), ), ), ); } Widget _bottomNavItem(int index, String assetPath) { return Expanded( child: InkWell( onTap: () => _onItemTapped(index, context), child: Column( mainAxisSize: MainAxisSize.min, mainAxisAlignment: MainAxisAlignment.center, children: [ Image.asset( assetPath, color: _selectedIndex == index ? const Color(0xFF0066FF) : Colors.grey, width: 26, height: 29, ), const SizedBox(height: 4), Container( height: 3, width: 30, decoration: BoxDecoration( color: _selectedIndex == index ? const Color(0xFF0066FF) : Colors.transparent, borderRadius: BorderRadius.circular(2), ), ), ], ), ), ); } Widget _buildMenuOption({ required IconData icon, required String label, required Color color, required VoidCallback onTap, }) { return ScaleTransition( scale: CurvedAnimation( parent: _animationController, curve: Curves.easeOut, ), child: Column( mainAxisSize: MainAxisSize.min, children: [ Container( width: 50, height: 50, decoration: BoxDecoration( color: color, shape: BoxShape.circle, boxShadow: [ BoxShadow( color: Colors.black.withOpacity(0.2), blurRadius: 3, spreadRadius: 1, offset: const Offset(0, 1), ), ], ), child: IconButton( icon: Icon(icon, color: Colors.white), onPressed: onTap, padding: EdgeInsets.zero, ), ), const SizedBox(height: 5), Text( label, style: const TextStyle( color: Color(0xFF0066FF), fontWeight: FontWeight.bold, fontSize: 12, ), ), ], ), ); } @override void dispose() { _animationController.dispose(); super.dispose(); } } class InheritedIndexController extends InheritedWidget { final void Function(int) changeIndex; const InheritedIndexController({ super.key, required this.changeIndex, required super.child, }); static InheritedIndexController? of(BuildContext context) { return context .dependOnInheritedWidgetOfExactType(); } @override bool updateShouldNotify(InheritedIndexController oldWidget) { return oldWidget.changeIndex != changeIndex; } }