From fe52726f6eb18f9e2735b9c724caa6207b9d6d00 Mon Sep 17 00:00:00 2001 From: mohammad Date: Wed, 26 Feb 2025 12:00:30 +0300 Subject: [PATCH] WebAppBar ResponsiveLayout --- .../view/access_management.dart | 54 ++- lib/pages/auth/view/forget_password_page.dart | 4 +- lib/pages/auth/view/login_page.dart | 4 +- .../view/device_managment_page.dart | 39 +- .../widgets/device_managment_body.dart | 2 +- .../bloc/living_room_bloc.dart | 3 + .../bloc/two_gang_glass_switch_bloc.dart | 36 +- lib/pages/home/bloc/home_bloc.dart | 5 +- .../view/roles_and_permission_page.dart | 10 +- .../view/spaces_management_page.dart | 7 +- lib/utils/responsive_layout.dart | 31 +- lib/utils/theme/responsive_text_theme.dart | 30 ++ lib/web_layout/web_app_bar.dart | 394 ++++++++++-------- 13 files changed, 368 insertions(+), 251 deletions(-) create mode 100644 lib/utils/theme/responsive_text_theme.dart diff --git a/lib/pages/access_management/view/access_management.dart b/lib/pages/access_management/view/access_management.dart index 9fe3a722..d7c7a9dd 100644 --- a/lib/pages/access_management/view/access_management.dart +++ b/lib/pages/access_management/view/access_management.dart @@ -17,6 +17,7 @@ import 'package:syncrow_web/utils/constants/assets.dart'; import 'package:syncrow_web/utils/extension/build_context_x.dart'; import 'package:syncrow_web/utils/helpers/responsice_layout_helper/responsive_layout_helper.dart'; import 'package:syncrow_web/utils/style.dart'; +import 'package:syncrow_web/utils/theme/responsive_text_theme.dart'; import 'package:syncrow_web/web_layout/web_scaffold.dart'; class AccessManagementPage extends StatelessWidget with HelperResponsiveLayout { @@ -27,19 +28,19 @@ class AccessManagementPage extends StatelessWidget with HelperResponsiveLayout { final isLargeScreen = isLargeScreenSize(context); final isSmallScreen = isSmallScreenSize(context); final isHalfMediumScreen = isHafMediumScreenSize(context); - final padding = isLargeScreen ? const EdgeInsets.all(30) : const EdgeInsets.all(15); + final padding = + isLargeScreen ? const EdgeInsets.all(30) : const EdgeInsets.all(15); return WebScaffold( enableMenuSidebar: false, - appBarTitle: FittedBox( - child: Text( - 'Access Management', - style: Theme.of(context).textTheme.headlineLarge, - ), + appBarTitle: Text( + 'Access Management', + style: ResponsiveTextTheme.of(context).deviceManagementTitle, ), rightBody: const NavigateHomeGridView(), scaffoldBody: BlocProvider( - create: (BuildContext context) => AccessBloc()..add(FetchTableData()), + create: (BuildContext context) => + AccessBloc()..add(FetchTableData()), child: BlocConsumer( listener: (context, state) {}, builder: (context, state) { @@ -93,11 +94,14 @@ class AccessManagementPage extends StatelessWidget with HelperResponsiveLayout { return [ item.passwordName, item.passwordType.value, - accessBloc.timestampToDate(item.effectiveTime), - accessBloc.timestampToDate(item.invalidTime), + accessBloc + .timestampToDate(item.effectiveTime), + accessBloc + .timestampToDate(item.invalidTime), item.deviceName.toString(), item.authorizerEmail.toString(), - accessBloc.timestampToDate(item.invalidTime), + accessBloc + .timestampToDate(item.invalidTime), item.passwordStatus.value, ]; }).toList(), @@ -108,7 +112,8 @@ class AccessManagementPage extends StatelessWidget with HelperResponsiveLayout { }))); } - Wrap _buildVisitorAdminPasswords(BuildContext context, AccessBloc accessBloc) { + Wrap _buildVisitorAdminPasswords( + BuildContext context, AccessBloc accessBloc) { return Wrap( spacing: 10, runSpacing: 10, @@ -134,7 +139,8 @@ class AccessManagementPage extends StatelessWidget with HelperResponsiveLayout { borderRadius: 8, child: Text( 'Create Visitor Password ', - style: context.textTheme.titleSmall!.copyWith(color: Colors.white, fontSize: 12), + style: context.textTheme.titleSmall! + .copyWith(color: Colors.white, fontSize: 12), )), ), // Container( @@ -172,8 +178,10 @@ class AccessManagementPage extends StatelessWidget with HelperResponsiveLayout { description: '', onSubmitted: (value) { accessBloc.add(FilterDataEvent( - emailAuthorizer: accessBloc.emailAuthorizer.text.toLowerCase(), - selectedTabIndex: BlocProvider.of(context).selectedIndex, + emailAuthorizer: + accessBloc.emailAuthorizer.text.toLowerCase(), + selectedTabIndex: + BlocProvider.of(context).selectedIndex, passwordName: accessBloc.passwordName.text.toLowerCase(), startTime: accessBloc.effectiveTimeTimeStamp, endTime: accessBloc.expirationTimeTimeStamp)); @@ -191,8 +199,10 @@ class AccessManagementPage extends StatelessWidget with HelperResponsiveLayout { description: '', onSubmitted: (value) { accessBloc.add(FilterDataEvent( - emailAuthorizer: accessBloc.emailAuthorizer.text.toLowerCase(), - selectedTabIndex: BlocProvider.of(context).selectedIndex, + emailAuthorizer: + accessBloc.emailAuthorizer.text.toLowerCase(), + selectedTabIndex: + BlocProvider.of(context).selectedIndex, passwordName: accessBloc.passwordName.text.toLowerCase(), startTime: accessBloc.effectiveTimeTimeStamp, endTime: accessBloc.expirationTimeTimeStamp)); @@ -221,7 +231,8 @@ class AccessManagementPage extends StatelessWidget with HelperResponsiveLayout { onSearch: () { accessBloc.add(FilterDataEvent( emailAuthorizer: accessBloc.emailAuthorizer.text.toLowerCase(), - selectedTabIndex: BlocProvider.of(context).selectedIndex, + selectedTabIndex: + BlocProvider.of(context).selectedIndex, passwordName: accessBloc.passwordName.text.toLowerCase(), startTime: accessBloc.effectiveTimeTimeStamp, endTime: accessBloc.expirationTimeTimeStamp)); @@ -249,8 +260,10 @@ class AccessManagementPage extends StatelessWidget with HelperResponsiveLayout { description: '', onSubmitted: (value) { accessBloc.add(FilterDataEvent( - emailAuthorizer: accessBloc.emailAuthorizer.text.toLowerCase(), - selectedTabIndex: BlocProvider.of(context).selectedIndex, + emailAuthorizer: + accessBloc.emailAuthorizer.text.toLowerCase(), + selectedTabIndex: + BlocProvider.of(context).selectedIndex, passwordName: accessBloc.passwordName.text.toLowerCase(), startTime: accessBloc.effectiveTimeTimeStamp, endTime: accessBloc.expirationTimeTimeStamp)); @@ -274,7 +287,8 @@ class AccessManagementPage extends StatelessWidget with HelperResponsiveLayout { onSearch: () { accessBloc.add(FilterDataEvent( emailAuthorizer: accessBloc.emailAuthorizer.text.toLowerCase(), - selectedTabIndex: BlocProvider.of(context).selectedIndex, + selectedTabIndex: + BlocProvider.of(context).selectedIndex, passwordName: accessBloc.passwordName.text.toLowerCase(), startTime: accessBloc.effectiveTimeTimeStamp, endTime: accessBloc.expirationTimeTimeStamp)); diff --git a/lib/pages/auth/view/forget_password_page.dart b/lib/pages/auth/view/forget_password_page.dart index 0ab2c2df..5ec7e4a7 100644 --- a/lib/pages/auth/view/forget_password_page.dart +++ b/lib/pages/auth/view/forget_password_page.dart @@ -8,6 +8,8 @@ class ForgetPasswordPage extends StatelessWidget { @override Widget build(BuildContext context) { return const ResponsiveLayout( - desktopBody: ForgetPasswordWebPage(), mobileBody: ForgetPasswordWebPage()); + tablet: ForgetPasswordWebPage(), + desktopBody: ForgetPasswordWebPage(), + mobileBody: ForgetPasswordWebPage()); } } diff --git a/lib/pages/auth/view/login_page.dart b/lib/pages/auth/view/login_page.dart index 31907c68..6f302eeb 100644 --- a/lib/pages/auth/view/login_page.dart +++ b/lib/pages/auth/view/login_page.dart @@ -9,6 +9,8 @@ class LoginPage extends StatelessWidget { @override Widget build(BuildContext context) { return const ResponsiveLayout( - desktopBody: LoginWebPage(), mobileBody: LoginWebPage()); + tablet: LoginWebPage(), + desktopBody: LoginWebPage(), + mobileBody: LoginWebPage()); } } diff --git a/lib/pages/device_managment/all_devices/view/device_managment_page.dart b/lib/pages/device_managment/all_devices/view/device_managment_page.dart index d29246ad..ab71c4b7 100644 --- a/lib/pages/device_managment/all_devices/view/device_managment_page.dart +++ b/lib/pages/device_managment/all_devices/view/device_managment_page.dart @@ -9,6 +9,7 @@ import 'package:syncrow_web/pages/routines/view/routines_view.dart'; import 'package:syncrow_web/utils/color_manager.dart'; import 'package:syncrow_web/utils/extension/build_context_x.dart'; import 'package:syncrow_web/utils/helpers/responsice_layout_helper/responsive_layout_helper.dart'; +import 'package:syncrow_web/utils/theme/responsive_text_theme.dart'; import 'package:syncrow_web/web_layout/web_scaffold.dart'; class DeviceManagementPage extends StatelessWidget with HelperResponsiveLayout { @@ -19,17 +20,17 @@ class DeviceManagementPage extends StatelessWidget with HelperResponsiveLayout { return MultiBlocProvider( providers: [ BlocProvider( - create: (context) => DeviceManagementBloc()..add(FetchDevices(context)), + create: (context) => + DeviceManagementBloc()..add(FetchDevices(context)), ), ], child: WebScaffold( - appBarTitle: FittedBox( - child: Text( - 'Device Management', - style: Theme.of(context).textTheme.headlineLarge, - ), + appBarTitle: Text( + 'Device Management', + style: ResponsiveTextTheme.of(context).deviceManagementTitle, ), - centerBody: BlocBuilder(builder: (context, state) { + centerBody: + BlocBuilder(builder: (context, state) { return Row( mainAxisSize: MainAxisSize.min, children: [ @@ -45,8 +46,11 @@ class DeviceManagementPage extends StatelessWidget with HelperResponsiveLayout { child: Text( 'Devices', style: context.textTheme.titleMedium?.copyWith( - color: !state.routineTab ? ColorsManager.whiteColors : ColorsManager.grayColor, - fontWeight: !state.routineTab ? FontWeight.w700 : FontWeight.w400, + color: !state.routineTab + ? ColorsManager.whiteColors + : ColorsManager.grayColor, + fontWeight: + !state.routineTab ? FontWeight.w700 : FontWeight.w400, ), ), ), @@ -55,13 +59,18 @@ class DeviceManagementPage extends StatelessWidget with HelperResponsiveLayout { backgroundColor: null, ), onPressed: () { - context.read().add(const TriggerSwitchTabsEvent(isRoutineTab: true)); + context + .read() + .add(const TriggerSwitchTabsEvent(isRoutineTab: true)); }, child: Text( 'Routines', style: context.textTheme.titleMedium?.copyWith( - color: state.routineTab ? ColorsManager.whiteColors : ColorsManager.grayColor, - fontWeight: state.routineTab ? FontWeight.w700 : FontWeight.w400, + color: state.routineTab + ? ColorsManager.whiteColors + : ColorsManager.grayColor, + fontWeight: + state.routineTab ? FontWeight.w700 : FontWeight.w400, ), ), ), @@ -69,7 +78,8 @@ class DeviceManagementPage extends StatelessWidget with HelperResponsiveLayout { ); }), rightBody: const NavigateHomeGridView(), - scaffoldBody: BlocBuilder(builder: (context, state) { + scaffoldBody: + BlocBuilder(builder: (context, state) { if (state.routineTab) { return const RoutinesView(); } @@ -84,7 +94,8 @@ class DeviceManagementPage extends StatelessWidget with HelperResponsiveLayout { } else if (deviceState is DeviceManagementLoaded) { return DeviceManagementBody(devices: deviceState.devices); } else if (deviceState is DeviceManagementFiltered) { - return DeviceManagementBody(devices: deviceState.filteredDevices); + return DeviceManagementBody( + devices: deviceState.filteredDevices); } else { return const Center(child: Text('Error fetching Devices')); } diff --git a/lib/pages/device_managment/all_devices/widgets/device_managment_body.dart b/lib/pages/device_managment/all_devices/widgets/device_managment_body.dart index 52b2321c..b49e5086 100644 --- a/lib/pages/device_managment/all_devices/widgets/device_managment_body.dart +++ b/lib/pages/device_managment/all_devices/widgets/device_managment_body.dart @@ -95,7 +95,7 @@ class DeviceManagementBody extends StatelessWidget with HelperResponsiveLayout { const DeviceSearchFilters(), const SizedBox(height: 12), Container( - height: 45, + // height: 45, width: 125, decoration: containerDecoration, child: Center( diff --git a/lib/pages/device_managment/three_gang_switch/bloc/living_room_bloc.dart b/lib/pages/device_managment/three_gang_switch/bloc/living_room_bloc.dart index f64ef314..a7a03a7f 100644 --- a/lib/pages/device_managment/three_gang_switch/bloc/living_room_bloc.dart +++ b/lib/pages/device_managment/three_gang_switch/bloc/living_room_bloc.dart @@ -147,6 +147,9 @@ class LivingRoomBloc extends Bloc { await DevicesManagementApi().getBatchStatus(event.devicesIds); deviceStatus = LivingRoomStatusModel.fromJson(event.devicesIds.first, status.status); + // for (var deviceId in event.devicesIds) { + // _listenToChanges(deviceId); + // } emit(LivingRoomDeviceStatusLoaded(deviceStatus)); } catch (e) { emit(LivingRoomDeviceManagementError(e.toString())); diff --git a/lib/pages/device_managment/two_g_glass_switch/bloc/two_gang_glass_switch_bloc.dart b/lib/pages/device_managment/two_g_glass_switch/bloc/two_gang_glass_switch_bloc.dart index eece65a1..90afaacb 100644 --- a/lib/pages/device_managment/two_g_glass_switch/bloc/two_gang_glass_switch_bloc.dart +++ b/lib/pages/device_managment/two_g_glass_switch/bloc/two_gang_glass_switch_bloc.dart @@ -1,5 +1,4 @@ import 'dart:async'; - import 'package:bloc/bloc.dart'; import 'package:firebase_database/firebase_database.dart'; import 'package:meta/meta.dart'; @@ -7,7 +6,6 @@ import 'package:syncrow_web/pages/device_managment/all_devices/models/device_sta import 'package:syncrow_web/pages/device_managment/all_devices/models/factory_reset_model.dart'; import 'package:syncrow_web/pages/device_managment/two_g_glass_switch/models/two_gang_glass_status_model.dart'; import 'package:syncrow_web/services/devices_mang_api.dart'; - part 'two_gang_glass_switch_event.dart'; part 'two_gang_glass_switch_state.dart'; @@ -15,7 +13,6 @@ class TwoGangGlassSwitchBloc extends Bloc { TwoGangGlassStatusModel deviceStatus; Timer? _timer; - TwoGangGlassSwitchBloc({required String deviceId}) : deviceStatus = TwoGangGlassStatusModel( uuid: deviceId, @@ -29,6 +26,7 @@ class TwoGangGlassSwitchBloc on(_onBatchControl); on(_onFetchBatchStatus); on(_onFactoryReset); + on(_onStatusUpdated); } Future _onFetchDeviceStatus(TwoGangGlassSwitchFetchDeviceEvent event, @@ -181,7 +179,7 @@ class TwoGangGlassSwitchBloc return super.close(); } - _listenToChanges(deviceId) { + _listenToChanges(deviceId) { try { DatabaseReference ref = FirebaseDatabase.instance.ref('device-status/$deviceId'); @@ -197,8 +195,8 @@ class TwoGangGlassSwitchBloc .add(Status(code: element['code'], value: element['value'])); }); - deviceStatus = - TwoGangGlassStatusModel.fromJson(usersMap['productUuid'], statusList); + deviceStatus = TwoGangGlassStatusModel.fromJson( + usersMap['productUuid'], statusList); if (!isClosed) { add(StatusUpdated(deviceStatus)); } @@ -206,31 +204,9 @@ class TwoGangGlassSwitchBloc } catch (_) {} } - void _onStatusUpdated(StatusUpdated event, Emitter emit) { + void _onStatusUpdated( + StatusUpdated event, Emitter emit) { deviceStatus = event.deviceStatus; emit(TwoGangGlassSwitchBatchStatusLoaded(deviceStatus)); } - - - // _listenToChanges(deviceId, Emitter emit) { - // try { - // DatabaseReference ref = - // FirebaseDatabase.instance.ref('device-status/$deviceId'); - // Stream stream = ref.onValue; - - // stream.listen((DatabaseEvent event) { - // Map usersMap = - // event.snapshot.value as Map; - // List statusList = []; - - // usersMap['status'].forEach((element) { - // statusList - // .add(Status(code: element['code'], value: element['value'])); - // }); - - // deviceStatus = TwoGangGlassStatusModel.fromJson(deviceId, statusList); - // emit(TwoGangGlassSwitchBatchStatusLoaded(deviceStatus)); - // }); - // } catch (_) {} - // } } diff --git a/lib/pages/home/bloc/home_bloc.dart b/lib/pages/home/bloc/home_bloc.dart index 042a91d1..f80f3c0a 100644 --- a/lib/pages/home/bloc/home_bloc.dart +++ b/lib/pages/home/bloc/home_bloc.dart @@ -106,7 +106,7 @@ class HomeBloc extends Bloc { List homeItems = [ HomeItemModel( - title: 'Access', + title: 'Access Management', icon: Assets.accessIcon, active: true, onPress: (context) { @@ -124,7 +124,7 @@ class HomeBloc extends Bloc { color: ColorsManager.primaryColor, ), HomeItemModel( - title: 'Devices', + title: 'Devices Management', icon: Assets.devicesIcon, active: true, onPress: (context) { @@ -134,6 +134,7 @@ class HomeBloc extends Bloc { }, color: ColorsManager.primaryColor, ), + // HomeItemModel( // title: 'Move in', // icon: Assets.moveinIcon, diff --git a/lib/pages/roles_and_permission/view/roles_and_permission_page.dart b/lib/pages/roles_and_permission/view/roles_and_permission_page.dart index 44944ed3..c128558b 100644 --- a/lib/pages/roles_and_permission/view/roles_and_permission_page.dart +++ b/lib/pages/roles_and_permission/view/roles_and_permission_page.dart @@ -8,6 +8,7 @@ import 'package:syncrow_web/pages/roles_and_permission/users_page/users_table/bl import 'package:syncrow_web/pages/roles_and_permission/users_page/users_table/view/users_page.dart'; import 'package:syncrow_web/utils/color_manager.dart'; import 'package:syncrow_web/utils/extension/build_context_x.dart'; +import 'package:syncrow_web/utils/theme/responsive_text_theme.dart'; import 'package:syncrow_web/web_layout/web_scaffold.dart'; class RolesAndPermissionPage extends StatelessWidget { @@ -26,11 +27,10 @@ class RolesAndPermissionPage extends StatelessWidget { ? const Center(child: CircularProgressIndicator()) : WebScaffold( enableMenuSidebar: false, - appBarTitle: FittedBox( - child: Text( - 'Roles & Permissions', - style: Theme.of(context).textTheme.headlineLarge, - ), + appBarTitle: Text( + 'Roles & Permissions', + style: + ResponsiveTextTheme.of(context).deviceManagementTitle, ), rightBody: const NavigateHomeGridView(), centerBody: Row( diff --git a/lib/pages/spaces_management/all_spaces/view/spaces_management_page.dart b/lib/pages/spaces_management/all_spaces/view/spaces_management_page.dart index 3abab9cc..c2a9fc2e 100644 --- a/lib/pages/spaces_management/all_spaces/view/spaces_management_page.dart +++ b/lib/pages/spaces_management/all_spaces/view/spaces_management_page.dart @@ -10,6 +10,7 @@ import 'package:syncrow_web/pages/spaces_management/structure_selector/view/cent import 'package:syncrow_web/services/product_api.dart'; import 'package:syncrow_web/services/space_mana_api.dart'; import 'package:syncrow_web/services/space_model_mang_api.dart'; +import 'package:syncrow_web/utils/theme/responsive_text_theme.dart'; import 'package:syncrow_web/web_layout/web_scaffold.dart'; class SpaceManagementPage extends StatefulWidget { @@ -36,8 +37,10 @@ class SpaceManagementPageState extends State { ), ], child: WebScaffold( - appBarTitle: Text('Space Management', - style: Theme.of(context).textTheme.headlineLarge), + appBarTitle: Text( + 'Space Management', + style: ResponsiveTextTheme.of(context).deviceManagementTitle, + ), enableMenuSidebar: false, centerBody: CenterBodyWidget(), rightBody: const NavigateHomeGridView(), diff --git a/lib/utils/responsive_layout.dart b/lib/utils/responsive_layout.dart index efc1600b..c49fa0d9 100644 --- a/lib/utils/responsive_layout.dart +++ b/lib/utils/responsive_layout.dart @@ -1,18 +1,37 @@ import 'package:flutter/material.dart'; class ResponsiveLayout extends StatelessWidget { - final Widget desktopBody; final Widget mobileBody; - const ResponsiveLayout( - {super.key, required this.desktopBody, required this.mobileBody}); + final Widget? tablet; + final Widget desktopBody; + + const ResponsiveLayout({ + super.key, + required this.mobileBody, + this.tablet, + required this.desktopBody, + }); + + static bool isMobile(BuildContext context) => + MediaQuery.of(context).size.width < 650; + + static bool isTablet(BuildContext context) => + MediaQuery.of(context).size.width < 1100 && + MediaQuery.of(context).size.width >= 650; + + static bool isDesktop(BuildContext context) => + MediaQuery.of(context).size.width >= 1100; + @override Widget build(BuildContext context) { return LayoutBuilder( builder: (context, constraints) { - if (constraints.maxWidth < 600) { - return mobileBody; - } else { + if (constraints.maxWidth >= 1100) { return desktopBody; + } else if (constraints.maxWidth >= 650) { + return tablet!; + } else { + return mobileBody; } }, ); diff --git a/lib/utils/theme/responsive_text_theme.dart b/lib/utils/theme/responsive_text_theme.dart new file mode 100644 index 00000000..f5daed7f --- /dev/null +++ b/lib/utils/theme/responsive_text_theme.dart @@ -0,0 +1,30 @@ +import 'package:flutter/material.dart'; +import 'package:syncrow_web/utils/color_manager.dart'; +import 'package:syncrow_web/utils/responsive_layout.dart'; + +class ResponsiveTextTheme extends ThemeExtension { + final TextStyle deviceManagementTitle; + + ResponsiveTextTheme({ + required this.deviceManagementTitle, + }); + + @override + ThemeExtension copyWith() => this; + + @override + ThemeExtension lerp( + ThemeExtension? other, double t) => + this; + + static ResponsiveTextTheme of(BuildContext context) { + final isMobile = ResponsiveLayout.isMobile(context); + return Theme.of(context).extension() ?? + ResponsiveTextTheme( + deviceManagementTitle: TextStyle( + fontSize: isMobile ? 20 : 30, + fontWeight: FontWeight.w700, + color: ColorsManager.whiteColors), + ); + } +} diff --git a/lib/web_layout/web_app_bar.dart b/lib/web_layout/web_app_bar.dart index 777b0931..02b81522 100644 --- a/lib/web_layout/web_app_bar.dart +++ b/lib/web_layout/web_app_bar.dart @@ -5,10 +5,10 @@ import 'package:syncrow_web/pages/home/bloc/home_bloc.dart'; import 'package:syncrow_web/pages/home/bloc/home_state.dart'; import 'package:syncrow_web/utils/color_manager.dart'; import 'package:syncrow_web/utils/constants/assets.dart'; -import 'package:syncrow_web/utils/helpers/responsice_layout_helper/responsive_layout_helper.dart'; +import 'package:syncrow_web/utils/responsive_layout.dart'; import 'package:syncrow_web/utils/user_drop_down_menu.dart'; -class WebAppBar extends StatefulWidget { +class WebAppBar extends StatelessWidget { final Widget? title; final Widget? centerBody; final Widget? rightBody; @@ -16,178 +16,234 @@ class WebAppBar extends StatefulWidget { const WebAppBar({super.key, this.title, this.centerBody, this.rightBody}); @override - State createState() => _WebAppBarState(); + Widget build(BuildContext context) { + return BlocBuilder( + builder: (context, state) { + final user = context.read().user; + return ResponsiveLayout( + mobileBody: MobileAppBar( + title: title, + centerBody: centerBody, + rightBody: rightBody, + user: user, + ), + tablet: TabletAppBar( + title: title, + centerBody: centerBody, + rightBody: rightBody, + user: user, + ), + desktopBody: DesktopAppBar( + title: title, + centerBody: centerBody, + rightBody: rightBody, + user: user, + ), + ); + }, + ); + } } -class _WebAppBarState extends State with HelperResponsiveLayout { - @override - void initState() { - super.initState(); - } +class DesktopAppBar extends StatelessWidget { + final Widget? title; + final Widget? centerBody; + final Widget? rightBody; + final dynamic user; + + const DesktopAppBar({ + super.key, + this.title, + this.centerBody, + this.rightBody, + required this.user, + }); @override Widget build(BuildContext context) { - bool isSmallScreen = isSmallScreenSize(context); - bool isHalfMediumScreen = isHafMediumScreenSize(context); - return BlocBuilder(builder: (context, state) { - final user = context.read().user; - return Container( - height: (isSmallScreen || isHalfMediumScreen) ? 130 : 100, - decoration: const BoxDecoration(color: ColorsManager.secondaryColor), - padding: const EdgeInsets.all(10), - child: isSmallScreen || isHalfMediumScreen - ? Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - if (widget.title != null) - Align( - alignment: Alignment.centerLeft, - child: widget.title!, - ), - if (widget.centerBody != null) - Padding( - padding: const EdgeInsets.only(top: 8.0), - child: widget.centerBody, - ), - if (widget.rightBody != null || user != null) - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - if (widget.rightBody != null) widget.rightBody!, - Row( - children: [ - SizedBox.square( - dimension: 40, - child: CircleAvatar( - backgroundColor: ColorsManager.whiteColors, - child: SizedBox.square( - dimension: 35, - child: SvgPicture.asset( - Assets.logoGrey, - fit: BoxFit.cover, - ), - ), - ), - ), - const SizedBox( - width: 10, - ), - if (user != null) - Text( - '${user.firstName} ${user.lastName}', - style: Theme.of(context).textTheme.bodyLarge, - ), - ], - ), - ], - ), - ], - ) - : Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - Expanded( - child: Row( - children: [ - widget.title!, - if (widget.centerBody != null) - Padding( - padding: const EdgeInsets.only(left: 80), - child: widget.centerBody!, - ), - ], - ), + return Container( + height: 100, + decoration: const BoxDecoration(color: ColorsManager.secondaryColor), + padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 10), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Expanded( + child: Row( + children: [ + if (title != null) title!, + if (centerBody != null) + Padding( + padding: const EdgeInsets.only(left: 80), + child: centerBody!, ), - Row( - mainAxisSize: MainAxisSize.min, - children: [ - if (widget.rightBody != null) - Align( - alignment: Alignment.centerRight, - child: widget.rightBody, - ), - const SizedBox( - width: 10, - ), - SizedBox.square( - dimension: 40, - child: CircleAvatar( - backgroundColor: ColorsManager.whiteColors, - child: SizedBox.square( - dimension: 35, - child: SvgPicture.asset( - Assets.logoGrey, - fit: BoxFit.cover, - ), - ), - ), - ), - const SizedBox( - width: 10, - ), - if (user != null) - Text( - '${user.firstName} ${user.lastName}', - style: Theme.of(context).textTheme.bodyLarge, - ), - const SizedBox( - width: 10, - ), - UserDropdownMenu(user: user), - // GestureDetector( - // onTap: () { - // showCustomDialog( - // context: context, - // barrierDismissible: true, - // title: 'Logout', - // message: 'Are you sure you want to logout?', - // actions: [ - // GestureDetector( - // onTap: () { - // AuthBloc.logout(); - // context.go(RoutesConst.auth); - // }, - // child: DefaultButton( - // child: Text( - // 'Ok', - // style: Theme.of(context) - // .textTheme - // .bodyMedium! - // .copyWith(fontSize: 12, color: Colors.white), - // ), - // ), - // ), - // const SizedBox( - // height: 10, - // ), - // GestureDetector( - // onTap: () { - // context.pop(); - // }, - // child: DefaultButton( - // child: Text( - // 'Cancel', - // style: Theme.of(context) - // .textTheme - // .bodyMedium! - // .copyWith(fontSize: 12, color: Colors.white), - // ), - // ), - // ), - // ], - // ); - // }, - // child: const Icon( - // Icons.logout, - // color: ColorsManager.whiteColors, - // ), - // ) - ], - ), - ], - ), - ); - }); + ], + ), + ), + _buildUserSection(context), + ], + ), + ); + } + + Widget _buildUserSection(BuildContext context) { + return Row( + children: [ + if (rightBody != null) rightBody!, + const SizedBox(width: 24), + _UserAvatar(), + const SizedBox(width: 12), + if (user != null) + Text( + '${user.firstName} ${user.lastName}', + style: Theme.of(context).textTheme.bodyLarge, + ), + const SizedBox(width: 12), + UserDropdownMenu(user: user), + ], + ); + } +} + +class TabletAppBar extends StatelessWidget { + final Widget? title; + final Widget? centerBody; + final Widget? rightBody; + final dynamic user; + + const TabletAppBar({ + super.key, + this.title, + this.centerBody, + this.rightBody, + required this.user, + }); + + @override + Widget build(BuildContext context) { + return Container( + height: 100, + decoration: const BoxDecoration(color: ColorsManager.secondaryColor), + padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 10), + child: Column( + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + if (title != null) Expanded(child: title!), + _buildUserSection(context), + ], + ), + if (centerBody != null) Expanded(child: centerBody!), + ], + ), + ); + } + + Widget _buildUserSection(BuildContext context) { + return Row( + children: [ + if (rightBody != null) rightBody!, + const SizedBox(width: 16), + _UserAvatar(), + if (user != null) ...[ + const SizedBox(width: 8), + Text( + '${user.firstName} ${user.lastName}', + style: + Theme.of(context).textTheme.bodyLarge?.copyWith(fontSize: 14), + ), + ], + UserDropdownMenu(user: user), + ], + ); + } +} + +class MobileAppBar extends StatelessWidget { + final Widget? title; + final Widget? centerBody; + final Widget? rightBody; + final dynamic user; + + const MobileAppBar({ + super.key, + this.title, + this.centerBody, + this.rightBody, + required this.user, + }); + + @override + Widget build(BuildContext context) { + return Container( + height: 135, + decoration: const BoxDecoration(color: ColorsManager.secondaryColor), + padding: const EdgeInsets.all(12), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + if (title != null) title!, + _buildUserSection(context), + ], + ), + Row( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + if (centerBody != null) + Padding( + padding: const EdgeInsets.only(top: 8), + child: centerBody!, + ), + if (rightBody != null) + Padding( + padding: const EdgeInsets.only(top: 8), + child: rightBody!, + ), + ], + ), + ], + ), + ); + } + + Widget _buildUserSection(BuildContext context) { + return Row( + children: [ + _UserAvatar(), + if (user != null) ...[ + const SizedBox(width: 8), + Text( + '${user.firstName} ${user.lastName}', + style: + Theme.of(context).textTheme.bodyLarge?.copyWith(fontSize: 14), + ), + ], + UserDropdownMenu(user: user), + ], + ); + } +} + +class _UserAvatar extends StatelessWidget { + @override + Widget build(BuildContext context) { + return SizedBox.square( + dimension: 40, + child: CircleAvatar( + backgroundColor: ColorsManager.whiteColors, + child: SizedBox.square( + dimension: 35, + child: SvgPicture.asset( + Assets.logoGrey, + fit: BoxFit.cover, + ), + ), + ), + ); } }