diff --git a/lib/features/bottom_navigation_bar/presentation/widgets/bottom_navigation_bar_widget.dart b/lib/features/bottom_navigation_bar/presentation/widgets/bottom_navigation_bar_widget.dart index f177d57a..efac96bf 100644 --- a/lib/features/bottom_navigation_bar/presentation/widgets/bottom_navigation_bar_widget.dart +++ b/lib/features/bottom_navigation_bar/presentation/widgets/bottom_navigation_bar_widget.dart @@ -1,5 +1,6 @@ import 'package:badges/badges.dart' as badges; import 'package:eatvio_app/core/app_config.dart'; +import 'package:eatvio_app/core/env_config.dart'; import 'package:eatvio_app/core/locator_service.dart'; import 'package:eatvio_app/core/utils/image_constant.dart'; import 'package:eatvio_app/features/dev_tools/presentation/dev_tools_screen.dart'; @@ -19,10 +20,7 @@ import 'package:go_router/go_router.dart'; class BottomNavigationBarWidget extends StatefulWidget { final Widget child; - const BottomNavigationBarWidget({ - super.key, - required this.child, - }); + const BottomNavigationBarWidget({super.key, required this.child}); @override State createState() => _BottomNavigationBarWidgetState(); @@ -35,24 +33,9 @@ class _BottomNavigationBarWidgetState extends State { List _getPages(bool isConsultant) { if (isConsultant) { - return [ - '/my-profile-screen', - '/feed-screen', - '/diary-screen', - '/consultations-screen', - '/chat-select-screen', - '/notifications-screen', - '/menu-screen', - ]; + return ['/my-profile-screen', '/feed-screen', '/diary-screen', '/consultations-screen', '/chat-select-screen', '/notifications-screen', '/menu-screen']; } else { - return [ - '/my-profile-screen', - '/feed-screen', - '/diary-screen', - '/chat-select-screen', - '/notifications-screen', - '/menu-screen', - ]; + return ['/my-profile-screen', '/feed-screen', '/diary-screen', '/chat-select-screen', '/notifications-screen', '/menu-screen']; } } @@ -83,6 +66,49 @@ class _BottomNavigationBarWidgetState extends State { } } + static const Color _devAccentColor = Color(0xFFF59E0B); // amber-500 + + Widget _buildLogoIcon() { + final isProduction = sl().baseUrl == EnvConfig.baseUrl; + final logo = SvgPicture.asset( + ImageConstant.imgLogo, + height: 32, + colorFilter: isProduction ? null : const ColorFilter.mode(_devAccentColor, BlendMode.srcIn), + ); + if (isProduction) return logo; + return Stack( + clipBehavior: Clip.none, + alignment: Alignment.center, + children: [ + Container( + padding: const EdgeInsets.symmetric(horizontal: 6, vertical: 4), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(8), + border: Border.all(color: _devAccentColor.withValues(alpha: 0.6), width: 1.5), + color: _devAccentColor.withValues(alpha: 0.08), + ), + child: logo, + ), + Positioned( + top: -6, + right: -4, + child: Container( + padding: const EdgeInsets.symmetric(horizontal: 4, vertical: 1), + decoration: BoxDecoration( + color: _devAccentColor, + borderRadius: BorderRadius.circular(4), + boxShadow: [BoxShadow(color: _devAccentColor.withValues(alpha: 0.4), blurRadius: 4, offset: const Offset(0, 1))], + ), + child: const Text( + 'DEV', + style: TextStyle(fontSize: 8, fontWeight: FontWeight.w700, color: Colors.white, letterSpacing: 0.3, height: 1.0), + ), + ), + ), + ], + ); + } + @override Widget build(BuildContext context) { final s = S.of(context); @@ -91,10 +117,10 @@ class _BottomNavigationBarWidgetState extends State { if (state is ProfileAvatarStateLoaded) { final profileModel = state.profile; final isConsultant = profileModel.roles.contains('consultant'); - + // Инициализируем pages на основе profileModel pages ??= _getPages(isConsultant); - + return Scaffold( body: widget.child, bottomNavigationBar: BottomNavigationBar( @@ -117,52 +143,26 @@ class _BottomNavigationBarWidgetState extends State { ), BottomNavigationBarItem( label: 'Лента', - icon: Padding( - padding: const EdgeInsets.only(bottom: 2), - child: SvgPicture.asset( - colorFilter: const ColorFilter.mode(Colors.grey, BlendMode.srcIn), - width: 20, - height: 20, - ImageConstant.icnFeed, - ), - ), - activeIcon: Padding( - padding: const EdgeInsets.only(bottom: 2), - child: SvgPicture.asset( - ImageConstant.icnFeed, - width: 20, - height: 20, - colorFilter: ColorFilter.mode( - appTheme.blueA400, - BlendMode.srcIn, - ), - ), - ), + icon: Padding( + padding: const EdgeInsets.only(bottom: 2), + child: SvgPicture.asset(colorFilter: const ColorFilter.mode(Colors.grey, BlendMode.srcIn), width: 20, height: 20, ImageConstant.icnFeed), + ), + activeIcon: Padding( + padding: const EdgeInsets.only(bottom: 2), + child: SvgPicture.asset(ImageConstant.icnFeed, width: 20, height: 20, colorFilter: ColorFilter.mode(appTheme.blueA400, BlendMode.srcIn)), + ), ), BottomNavigationBarItem( label: s.diary, - icon: Padding( - padding: const EdgeInsets.only(bottom: 2), - child: SvgPicture.asset( - colorFilter: const ColorFilter.mode(Colors.grey, BlendMode.srcIn), - ImageConstant.icnDiary, - width: 20, - height: 20, - ), - ), - activeIcon: Padding( - padding: const EdgeInsets.only(bottom: 2), - child: SvgPicture.asset( - ImageConstant.icnDiary, - width: 20, - height: 20, - colorFilter: ColorFilter.mode( - appTheme.blueA400, - BlendMode.srcIn, + icon: Padding( + padding: const EdgeInsets.only(bottom: 2), + child: SvgPicture.asset(colorFilter: const ColorFilter.mode(Colors.grey, BlendMode.srcIn), ImageConstant.icnDiary, width: 20, height: 20), + ), + activeIcon: Padding( + padding: const EdgeInsets.only(bottom: 2), + child: SvgPicture.asset(ImageConstant.icnDiary, width: 20, height: 20, colorFilter: ColorFilter.mode(appTheme.blueA400, BlendMode.srcIn)), + ), ), - ), - ), - ), if (profileModel.roles.contains('consultant')) BottomNavigationBarItem( label: 'Консультации', @@ -181,97 +181,69 @@ class _BottomNavigationBarWidgetState extends State { 'assets/icons/consultations.svg', width: 20, height: 20, - colorFilter: ColorFilter.mode( - appTheme.blueA400, - BlendMode.srcIn, - ), - ), - ), - ), + colorFilter: ColorFilter.mode(appTheme.blueA400, BlendMode.srcIn), + ), + ), + ), BottomNavigationBarItem( label: s.chat, - icon: BlocBuilder( - builder: (BuildContext context, ChatsState state) { - final hasUnreadMessages = state.chatsWithUnreadMessagesCount > 0; - return badges.Badge( - position: badges.BadgePosition.topEnd(), - badgeAnimation: const badges.BadgeAnimation.fade(), - badgeStyle: badges.BadgeStyle( - badgeColor: hasUnreadMessages ? Colors.red : Colors.transparent, + icon: BlocBuilder( + builder: (BuildContext context, ChatsState state) { + final hasUnreadMessages = state.chatsWithUnreadMessagesCount > 0; + return badges.Badge( + position: badges.BadgePosition.topEnd(), + badgeAnimation: const badges.BadgeAnimation.fade(), + badgeStyle: badges.BadgeStyle(badgeColor: hasUnreadMessages ? Colors.red : Colors.transparent), + badgeContent: Text( + hasUnreadMessages ? state.chatsWithUnreadMessagesCount.toString() : '', + style: TextStyle(color: hasUnreadMessages ? Colors.white : Colors.transparent, fontSize: 8), + ), + child: Padding( + padding: const EdgeInsets.only(bottom: 2), + child: SvgPicture.asset( + ImageConstant.icnChat, + width: 20, + height: 20, + colorFilter: pages![currentBottomNavBarIndex] == '/chat-select-screen' + ? ColorFilter.mode(appTheme.blueA400, BlendMode.srcIn) + : const ColorFilter.mode(Colors.grey, BlendMode.srcIn), + ), + ), + ); + }, ), - badgeContent: Text( - hasUnreadMessages ? state.chatsWithUnreadMessagesCount.toString() : '', - style: TextStyle( - color: hasUnreadMessages ? Colors.white : Colors.transparent, - fontSize: 8, - ), - ), - child: Padding( - padding: const EdgeInsets.only(bottom: 2), - child: SvgPicture.asset( - ImageConstant.icnChat, - width: 20, - height: 20, - colorFilter: pages![currentBottomNavBarIndex] == '/chat-select-screen' - ? ColorFilter.mode( - appTheme.blueA400, - BlendMode.srcIn, - ) - : const ColorFilter.mode(Colors.grey, BlendMode.srcIn), - ), - ), - ); - }, - ), ), BottomNavigationBarItem( label: 'Уведомления', - icon: BlocBuilder( - builder: (BuildContext context, NotificationsState state) { - return badges.Badge( - position: badges.BadgePosition.topEnd(), - badgeAnimation: const badges.BadgeAnimation.fade(), - showBadge: state is NotificationsStateLoaded && state.hasUnreadNotifications, - badgeContent: const Text( - '', - style: TextStyle( - color: Colors.white, - fontSize: 8, - ), - ), - child: Padding( - padding: const EdgeInsets.only(bottom: 2), - child: SvgPicture.asset( - ImageConstant.icnBell, - colorFilter: pages![currentBottomNavBarIndex] == '/notifications-screen' - ? ColorFilter.mode( - appTheme.blueA400, - BlendMode.srcIn, - ) - : const ColorFilter.mode(Colors.grey, BlendMode.srcIn), - width: 20, - height: 20, - ), - ), - ); - }, - ), - ), - BottomNavigationBarItem( - label: '', - icon: SvgPicture.asset( - ImageConstant.imgLogo, - height: 32, + icon: BlocBuilder( + builder: (BuildContext context, NotificationsState state) { + return badges.Badge( + position: badges.BadgePosition.topEnd(), + badgeAnimation: const badges.BadgeAnimation.fade(), + showBadge: state is NotificationsStateLoaded && state.hasUnreadNotifications, + badgeContent: const Text('', style: TextStyle(color: Colors.white, fontSize: 8)), + child: Padding( + padding: const EdgeInsets.only(bottom: 2), + child: SvgPicture.asset( + ImageConstant.icnBell, + colorFilter: pages![currentBottomNavBarIndex] == '/notifications-screen' + ? ColorFilter.mode(appTheme.blueA400, BlendMode.srcIn) + : const ColorFilter.mode(Colors.grey, BlendMode.srcIn), + width: 20, + height: 20, + ), + ), + ); + }, ), ), + BottomNavigationBarItem(label: '', icon: _buildLogoIcon()), ], ), ); } // Показываем child даже когда профиль еще загружается, чтобы экраны могли инициализироваться - return Scaffold( - body: widget.child, - ); + return Scaffold(body: widget.child); }, ); }