286 lines
9.5 KiB
Dart
286 lines
9.5 KiB
Dart
import 'dart:math' as math;
|
|
import 'package:flutter/material.dart';
|
|
import 'package:flutter/services.dart';
|
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
|
import 'package:get/get.dart';
|
|
import 'package:taxglide/consts/app_asstes.dart';
|
|
import 'package:taxglide/consts/local_store.dart';
|
|
import 'package:taxglide/controller/api_contoller.dart'; // ✅ Needed for providers
|
|
import 'package:taxglide/view/Main_controller/comman_chat_box.dart';
|
|
import 'package:taxglide/view/screens/history/serivces_status_screen.dart'
|
|
show ServicesStatusScreen;
|
|
import 'package:taxglide/view/screens/home_screen.dart';
|
|
import 'package:taxglide/view/screens/list_service_screen.dart';
|
|
import 'package:taxglide/view/screens/profile/employee_profile/employee_profile_screen.dart';
|
|
import 'package:taxglide/view/screens/profile/profile_screen.dart';
|
|
import 'package:curved_labeled_navigation_bar/curved_navigation_bar.dart';
|
|
import 'package:curved_labeled_navigation_bar/curved_navigation_bar_item.dart';
|
|
import 'package:taxglide/consts/app_style.dart';
|
|
|
|
class MainController extends ConsumerStatefulWidget {
|
|
final Widget? child; // Optional child (like ServiceRequestScreen)
|
|
final int? initialIndex; // Which tab to show initially
|
|
final int? sourceTabIndex; // Source tab (Home=0, Services=1)
|
|
|
|
const MainController({
|
|
Key? key,
|
|
this.child,
|
|
this.initialIndex,
|
|
this.sourceTabIndex,
|
|
}) : super(key: key);
|
|
|
|
@override
|
|
ConsumerState<MainController> createState() => _MainControllerState();
|
|
}
|
|
|
|
class _MainControllerState extends ConsumerState<MainController> {
|
|
int currentIndex = 0;
|
|
DateTime? lastBackPressed;
|
|
String? userRole;
|
|
|
|
/// 📌 Bottom bar labels
|
|
final List<String> _labels = [
|
|
'Home',
|
|
'Services',
|
|
'Task Status',
|
|
'Profile',
|
|
];
|
|
|
|
/// 📌 Screens list
|
|
List<Widget> _screens = [];
|
|
|
|
@override
|
|
void initState() {
|
|
super.initState();
|
|
currentIndex = widget.initialIndex ?? 0;
|
|
_loadRole();
|
|
}
|
|
|
|
/// 🔹 Load user role from local storage
|
|
Future<void> _loadRole() async {
|
|
userRole = await LocalStore().getRole(); // "employee" or "user"
|
|
_initScreens();
|
|
setState(() {});
|
|
}
|
|
|
|
/// 🔹 Initialize screens based on role
|
|
void _initScreens() {
|
|
_screens = [
|
|
const HomeScreen(),
|
|
ListServiceScreen(key: UniqueKey()),
|
|
ServicesStatusScreen(),
|
|
_getProfileScreen(), // ✅ role based
|
|
];
|
|
}
|
|
|
|
/// 🔹 Role based profile screen
|
|
Widget _getProfileScreen() {
|
|
if (userRole == "employee") {
|
|
return const EmployeeProfileScreen(); // 👈 employee profile
|
|
}
|
|
return const ProfileScreen(); // 👈 normal user profile
|
|
}
|
|
|
|
/// 🔄 Change tab index
|
|
void setBottomBarIndex(int index) {
|
|
setState(() {
|
|
currentIndex = index;
|
|
});
|
|
_refreshTab(index);
|
|
}
|
|
|
|
/// ✅ Refresh API data based on the current tab
|
|
void _refreshTab(int index) {
|
|
final container = ProviderScope.containerOf(context, listen: false);
|
|
|
|
switch (index) {
|
|
case 0:
|
|
// 🔁 Refresh Home screen APIs
|
|
container.refresh(profileProvider);
|
|
container.refresh(serviceListProvider);
|
|
ref.invalidate(chatMessagesProvider);
|
|
ref.invalidate(notificationCountProvider);
|
|
ref.invalidate(dashboardProvider);
|
|
break;
|
|
case 1:
|
|
// 🔁 Refresh ListServiceScreen APIs
|
|
container.refresh(serviceListProvider);
|
|
ref.invalidate(chatMessagesProvider);
|
|
ref.invalidate(dashboardProvider);
|
|
break;
|
|
case 2:
|
|
// 🔁 Refresh Service Status APIs
|
|
try {
|
|
ref.invalidate(serviceHistoryNotifierProvider);
|
|
ref.invalidate(serviceDetailProvider);
|
|
ref.invalidate(chatMessagesProvider);
|
|
ref.invalidate(dashboardProvider);
|
|
} catch (_) {}
|
|
break;
|
|
case 3:
|
|
// 🔁 Refresh Profile screen APIs
|
|
ref.invalidate(chatMessagesProvider);
|
|
container.refresh(profileProvider);
|
|
ref.invalidate(staffListProvider);
|
|
ref.invalidate(dashboardProvider);
|
|
break;
|
|
}
|
|
}
|
|
|
|
/// ✅ Handle Back button presses
|
|
Future<bool> _onWillPop() async {
|
|
// If inside ServiceRequestScreen → go back to originating tab
|
|
if (widget.child != null) {
|
|
Get.offAll(
|
|
() => MainController(initialIndex: widget.sourceTabIndex ?? 0),
|
|
);
|
|
return false;
|
|
}
|
|
|
|
// If not in Home tab, go back to Home
|
|
if (currentIndex != 0) {
|
|
setState(() => currentIndex = 0);
|
|
return false;
|
|
}
|
|
|
|
// Double back press to exit
|
|
DateTime now = DateTime.now();
|
|
if (lastBackPressed == null ||
|
|
now.difference(lastBackPressed!) > const Duration(seconds: 2)) {
|
|
lastBackPressed = now;
|
|
ScaffoldMessenger.of(context).showSnackBar(
|
|
const SnackBar(
|
|
content: Text("Press back again to exit"),
|
|
duration: Duration(seconds: 2),
|
|
),
|
|
);
|
|
return false;
|
|
}
|
|
|
|
await SystemNavigator.pop();
|
|
return true;
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
final Size size = MediaQuery.of(context).size;
|
|
|
|
// ✅ Show loading while screens are being initialized
|
|
if (_screens.isEmpty) {
|
|
return const Scaffold(body: Center(child: CircularProgressIndicator()));
|
|
}
|
|
|
|
final Widget mainContent = widget.child ?? _screens[currentIndex];
|
|
final dashboardAsync = ref.watch(dashboardProvider);
|
|
|
|
return WillPopScope(
|
|
onWillPop: _onWillPop,
|
|
child: Scaffold(
|
|
backgroundColor: Colors.white.withAlpha(55),
|
|
body: Stack(
|
|
children: [
|
|
mainContent,
|
|
dashboardAsync.when(
|
|
data: (dashboard) {
|
|
final int? chatIdInt = dashboard.generalChatId;
|
|
|
|
if (chatIdInt == null || chatIdInt == 0) {
|
|
return const SizedBox(); // ❌ No chat box
|
|
}
|
|
|
|
return CommanChatBox(
|
|
chatId: chatIdInt.toString(), // ✅ INT → STRING
|
|
);
|
|
},
|
|
loading: () => const SizedBox(),
|
|
error: (e, _) => const SizedBox(),
|
|
),
|
|
],
|
|
),
|
|
bottomNavigationBar: SafeArea(
|
|
top: false,
|
|
child: CurvedNavigationBar(
|
|
backgroundColor: Color(0xFF61277A),
|
|
buttonBackgroundColor: Colors.white,
|
|
color: Colors.white,
|
|
animationDuration: const Duration(milliseconds: 300),
|
|
index: currentIndex,
|
|
items: [
|
|
CurvedNavigationBarItem(
|
|
child: Icon(
|
|
Icons.home,
|
|
color: currentIndex == 0 ? Colors.black : const Color(0xFF6C7278),
|
|
),
|
|
label: _labels[0],
|
|
labelStyle: (currentIndex == 0 ? AppTextStyles.bold : AppTextStyles.bold).copyWith(
|
|
color: currentIndex == 0 ? const Color(0xFF61277A) : const Color(0xFF6C7278),
|
|
fontSize: 12,
|
|
),
|
|
),
|
|
CurvedNavigationBarItem(
|
|
child: Icon(
|
|
Icons.list_alt_sharp,
|
|
color: currentIndex == 1 ? Colors.black : const Color(0xFF6C7278),
|
|
),
|
|
label: _labels[1],
|
|
labelStyle: (currentIndex == 0 ? AppTextStyles.bold : AppTextStyles.bold).copyWith(
|
|
color: currentIndex == 1 ? const Color(0xFF61277A) : const Color(0xFF6C7278),
|
|
fontSize: 12,
|
|
),
|
|
),
|
|
CurvedNavigationBarItem(
|
|
child: Icon(
|
|
Icons.history_edu,
|
|
color: currentIndex == 2 ? Colors.black : const Color(0xFF6C7278),
|
|
),
|
|
label: _labels[2],
|
|
labelStyle: (currentIndex == 0 ? AppTextStyles.bold : AppTextStyles.bold).copyWith(
|
|
color: currentIndex == 2 ? const Color(0xFF61277A) : const Color(0xFF6C7278),
|
|
fontSize: 12,
|
|
),
|
|
),
|
|
CurvedNavigationBarItem(
|
|
child: Icon(
|
|
Icons.person_2,
|
|
color: currentIndex == 3 ? Colors.black : const Color(0xFF6C7278),
|
|
),
|
|
label: _labels[3],
|
|
labelStyle: (currentIndex == 0 ? AppTextStyles.bold : AppTextStyles.bold).copyWith(
|
|
color: currentIndex == 3 ? const Color(0xFF61277A) : const Color(0xFF6C7278),
|
|
fontSize: 12,
|
|
),
|
|
),
|
|
],
|
|
onTap: (index) {
|
|
// 🔹 If inside ServiceRequestScreen
|
|
if (widget.child != null) {
|
|
if (widget.initialIndex == index) return;
|
|
|
|
if (widget.sourceTabIndex == 0 && index == 1) {
|
|
Get.offAll(() => const MainController(initialIndex: 1));
|
|
return;
|
|
}
|
|
|
|
if (widget.sourceTabIndex == 1 && index == 1) return;
|
|
|
|
Get.offAll(() => MainController(initialIndex: index));
|
|
return;
|
|
}
|
|
|
|
// 🔹 If same tab tapped again → refresh
|
|
if (currentIndex == index) {
|
|
_refreshTab(index);
|
|
return;
|
|
}
|
|
|
|
// 🔹 Switch to a different tab
|
|
setBottomBarIndex(index);
|
|
},
|
|
),
|
|
),
|
|
),
|
|
);
|
|
}
|
|
|
|
}
|