import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'package:test_sa/controllers/api_routes/api_manager.dart'; import 'package:test_sa/controllers/providers/settings/setting_provider.dart'; import 'package:test_sa/dashboard_latest/dashboard_provider.dart'; import 'package:test_sa/extensions/context_extension.dart'; import 'package:test_sa/extensions/int_extensions.dart'; import 'package:test_sa/extensions/text_extensions.dart'; import 'package:test_sa/extensions/widget_extensions.dart'; import 'package:test_sa/helper/utils.dart'; import 'package:test_sa/new_views/app_style/app_color.dart'; import 'package:test_sa/views/pages/user/notifications/notifications_page.dart'; import 'package:test_sa/views/pages/user/notifications/unread_chat_list.dart'; import '../../controllers/providers/api/user_provider.dart'; import '../../models/user.dart'; class AppBarWidget extends StatefulWidget { final VoidCallback onDrawerPress; const AppBarWidget({Key? key, required this.onDrawerPress}) : super(key: key); @override State createState() => _AppBarWidgetState(); } class _AppBarWidgetState extends State with TickerProviderStateMixin { late AnimationController _leftController; late AnimationController _rightController; late Animation _leftSlideAnimation; late Animation _leftFadeAnimation; late Animation _rightSlideAnimation; late Animation _rightFadeAnimation; @override void initState() { super.initState(); // Profile section animation (left to right with fade) _leftController = AnimationController( duration: const Duration(milliseconds: 600), vsync: this, ); _leftSlideAnimation = Tween( begin: const Offset(-0.3, 0.0), end: Offset.zero, ).animate(CurvedAnimation( parent: _leftController, curve: Curves.easeOutCubic, )); _leftFadeAnimation = Tween( begin: 0.0, end: 1.0, ).animate(CurvedAnimation( parent: _leftController, curve: Curves.easeIn, )); // Action icons animation (right to left with fade) _rightController = AnimationController( duration: const Duration(milliseconds: 600), vsync: this, ); _rightSlideAnimation = Tween( begin: const Offset(0.3, 0.0), end: Offset.zero, ).animate(CurvedAnimation( parent: _rightController, curve: Curves.easeOutCubic, )); _rightFadeAnimation = Tween( begin: 0.0, end: 1.0, ).animate(CurvedAnimation( parent: _rightController, curve: Curves.easeIn, )); // Start animations with slight delay between them _leftController.forward(); Future.delayed(const Duration(milliseconds: 100), () { if (mounted) _rightController.forward(); }); } @override void dispose() { _leftController.dispose(); _rightController.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return AppBar( automaticallyImplyLeading: false, backgroundColor: Theme.of(context).scaffoldBackgroundColor, titleSpacing: 0, title: Consumer(builder: (context, snapshot, _) { return Row( // mainAxisAlignment: MainAxisAlignment.spaceBetween, crossAxisAlignment: CrossAxisAlignment.center, children: [ // Profile section with left-to-right fade animation SlideTransition( position: _leftSlideAnimation, child: FadeTransition( opacity: _leftFadeAnimation, child: CircleAvatar( radius: 24, backgroundColor: context.isDark ? AppColor.neutral50 : AppColor.neutral40, child: Padding( padding: const EdgeInsets.all(1), // Border radius child: ClipOval( child: snapshot.profileImage != null ? Image.file(snapshot.profileImage!) // Added null check : (snapshot.user?.profilePhotoName?.isNotEmpty ?? false) ? Image.network(snapshot.user!.profilePhotoName!) // Added null check : const Icon(Icons.person, size: 24, color: Colors.white), ), ), ).onPress(widget.onDrawerPress), ), ), 8.width, SlideTransition( position: _leftSlideAnimation, child: FadeTransition( opacity: _leftFadeAnimation, child: Column( crossAxisAlignment: CrossAxisAlignment.start, spacing: 4, children: [ Text( snapshot.user?.username ?? "", style: AppTextStyles.heading6.copyWith(color: AppColor.headingTextColor(context), fontSize: context.isTablet() ? 14 : null), ), Text( snapshot.user?.type?.name.toCamelCase ?? "", style: AppTextStyles.bodyText.copyWith(color: AppColor.lightTextColor(context), fontSize: context.isTablet() ? 12 : null), ), ], ).expanded, ), ), const Spacer(), // Action icons with right-to-left fade animation SlideTransition( position: _rightSlideAnimation, child: FadeTransition( opacity: _rightFadeAnimation, child: Consumer(builder: (context, settingProvider, child) { return MenuAnchor( style: MenuStyle( backgroundColor: WidgetStateProperty.all(AppColor.background(context)), shape: WidgetStateProperty.all( RoundedRectangleBorder( borderRadius: const BorderRadius.all(Radius.circular(20.0)), side: BorderSide(color: AppColor.borderColor(context), width: 1), ), ), padding: WidgetStateProperty.all( EdgeInsets.symmetric( horizontal: 0.toScreenWidth, vertical: 8.toScreenHeight, ), ), elevation: WidgetStateProperty.all(0), ), menuChildren: Provider.of(context, listen: false).user?.assetGroups?.map((value) { return MenuItemButton( onPressed: () async { if (settingProvider.assetGroup != value) { AssetGroup? tempGroup = ApiManager.instance.assetGroup; ApiManager.instance.assetGroup = value; Utils.showLoading(context); bool isSuccess = await context.userProvider.userChangeAssetGroup(); Utils.hideLoading(context); if (isSuccess) { await context.userProvider.getMobilePermissionByUser(); settingProvider.setAssetGroup(value); WidgetsBinding.instance.addPostFrameCallback((_) { context.settingProvider.setUser(ApiManager.instance.user!); context.userProvider.setUser(ApiManager.instance.user!); DashBoardProvider dashBoardProvider = Provider.of(context, listen: false); dashBoardProvider.setTabs(userType: settingProvider.user!.type!, context: context); dashBoardProvider.getDashBoardCount(usersType: settingProvider.user!.type!); dashBoardProvider.resetRequestDataList(); dashBoardProvider.getRequestDetail(usersType: settingProvider.user!.type!, status: dashBoardProvider.tabs[dashBoardProvider.currentListIndex].tag); }); } else { ApiManager.instance.assetGroup = tempGroup; context.showConfirmDialog("Failed, Please Try again"); } } }, child: Text(value.name ?? "", style: AppTextStyles.bodyText2.copyWith(color: AppColor.headingTextColor(context))), ); }).toList() ?? [], builder: (_, MenuController controller, Widget? child) { return Container( padding: const EdgeInsets.all(10), decoration: BoxDecoration( borderRadius: BorderRadius.circular(8), color: AppColor.assetGroupBackground(context), border: Border.all(color: AppColor.white936.withValues(alpha: .03), width: 1), boxShadow: [ BoxShadow(color: Colors.black.withValues(alpha: 0.03), blurRadius: 4, offset: const Offset(0, 0), spreadRadius: 0), ], ), child: Row( mainAxisSize: MainAxisSize.min, spacing: 16, children: [ Text(settingProvider.assetGroup?.name ?? "", style: AppTextStyles.bodyText2.copyWith(color: AppColor.headingTextColor(context))), Icon(Icons.keyboard_arrow_down, color: AppColor.headingTextColor(context)), ], ), ).onPress(() { if (controller.isOpen) { controller.close(); } else { controller.open(); } }); }, ); return Container( padding: const EdgeInsets.all(10), decoration: BoxDecoration( borderRadius: BorderRadius.circular(8), color: AppColor.assetGroupBackground(context), border: Border.all(color: AppColor.white936.withValues(alpha: .03), width: 1), boxShadow: [ BoxShadow(color: Colors.black.withValues(alpha: 0.03), blurRadius: 4, offset: const Offset(0, 0), spreadRadius: 0), ], ), child: Row( mainAxisSize: MainAxisSize.min, spacing: 16, children: [ Text(settingProvider.assetGroup?.name ?? "", style: AppTextStyles.bodyText2.copyWith(color: AppColor.headingTextColor(context))), Icon(Icons.keyboard_arrow_down, color: AppColor.headingTextColor(context)), ], ), ); return Container( padding: const EdgeInsets.fromLTRB(12, 6, 6, 6), decoration: BoxDecoration( borderRadius: BorderRadius.circular(8), color: AppColor.background(context), boxShadow: const [ BoxShadow( color: Color(0x07000000), blurRadius: 14, offset: Offset(0, 0), spreadRadius: 0, ) ], ), child: DropdownButton( // Made AssetGroup nullable value: settingProvider.assetGroup, //iconSize: 24, isDense: true, icon: Icon(Icons.keyboard_arrow_down, color: AppColor.headingTextColor(context)), elevation: 8, // dropdownColor: Colors.amber, borderRadius: BorderRadius.circular(8), style: AppTextStyles.tinyFont.copyWith(color: AppColor.headingTextColor(context)), underline: const SizedBox.shrink(), onChanged: (newValue) async { if (settingProvider.assetGroup != newValue) { AssetGroup? tempGroup = ApiManager.instance.assetGroup; ApiManager.instance.assetGroup = newValue; Utils.showLoading(context); bool isSuccess = await context.userProvider.userChangeAssetGroup(); Utils.hideLoading(context); if (isSuccess) { await context.userProvider.getMobilePermissionByUser(); settingProvider.setAssetGroup(newValue); WidgetsBinding.instance.addPostFrameCallback((_) { context.settingProvider.setUser(ApiManager.instance.user!); context.userProvider.setUser(ApiManager.instance.user!); DashBoardProvider dashBoardProvider = Provider.of(context, listen: false); dashBoardProvider.setTabs(userType: settingProvider.user!.type!, context: context); dashBoardProvider.getDashBoardCount(usersType: settingProvider.user!.type!); dashBoardProvider.resetRequestDataList(); dashBoardProvider.getRequestDetail(usersType: settingProvider.user!.type!, status: dashBoardProvider.tabs[dashBoardProvider.currentListIndex].tag); }); } else { ApiManager.instance.assetGroup = tempGroup; context.showConfirmDialog("Failed, Please Try again"); } } }, items: Provider.of(context, listen: false).user?.assetGroups?.map>((value) { // Added null check and made AssetGroup nullable return DropdownMenuItem( value: value, child: Text( value.name ?? "", style: Theme.of(context).textTheme.bodyLarge, ), ); }).toList() ?? [], // Added null check and empty list default ), ); }), ), ), 16.width, SlideTransition( position: _rightSlideAnimation, child: FadeTransition( opacity: _rightFadeAnimation, child: Row( children: [ if (context.settingProvider.isUserFlowMedical) ...[ ("dashboard/chat").toSvgAsset(height: 24, width: 24, color: AppColor.icon2Color(context)).paddingOnly(top: 0, end: 0).onPress(() { Navigator.of(context).push(CupertinoPageRoute(builder: (_) => UnReadChatList())); }), 16.width, ], ("dashboard/notification").toSvgAsset(height: 24, width: 24, color: AppColor.icon2Color(context)).paddingOnly(top: 0, end: 0).onPress(() { Navigator.of(context).pushNamed(NotificationsPage.id); }), ], ), ), ), ], ).paddingOnly(start: 16, end: 16); }), ); } }