From a5796ad2dbdedc47ead0db18fb4fa392e310eeae Mon Sep 17 00:00:00 2001 From: Sikander Saleem Date: Wed, 20 May 2026 17:37:35 +0300 Subject: [PATCH] improvements --- .../views/components/history_log_view.dart | 4 +- .../service_request_detail_view.dart | 32 +-- .../utils/swipe_general_utils.dart | 187 ++++++++++++++++-- .../multiple_selection_fullscreen_dialog.dart | 2 +- 4 files changed, 186 insertions(+), 39 deletions(-) diff --git a/lib/modules/cm_module/views/components/history_log_view.dart b/lib/modules/cm_module/views/components/history_log_view.dart index bae88867..e549f02f 100644 --- a/lib/modules/cm_module/views/components/history_log_view.dart +++ b/lib/modules/cm_module/views/components/history_log_view.dart @@ -32,8 +32,8 @@ class HistoryLogView extends StatelessWidget { children: [ Padding( padding: EdgeInsets.only(left: 122.toScreenWidth), - child: const VerticalDivider( - color: AppColor.white40, + child: VerticalDivider( + color: AppColor.background(context), thickness: 2, width: 20, indent: 10, diff --git a/lib/modules/cm_module/views/components/service_request_detail_view.dart b/lib/modules/cm_module/views/components/service_request_detail_view.dart index fee7bb28..f38790a9 100644 --- a/lib/modules/cm_module/views/components/service_request_detail_view.dart +++ b/lib/modules/cm_module/views/components/service_request_detail_view.dart @@ -238,7 +238,7 @@ class _ServiceRequestDetailViewState extends State { 8.height, Text( workOrder.comments!, - style: AppTextStyles.bodyText2.copyWith(color: AppColor.labelTextStyleColor(context)), + style: AppTextStyles.bodyText2.copyWith(color: AppColor.labelTextStyleColor(context)), ), ], if (userProvider.user?.type == UsersTypes.engineer) ...[ @@ -274,13 +274,16 @@ class _ServiceRequestDetailViewState extends State { ASoundPlayer(audio: URLs.getFileUrl(workOrder.voiceNote!)!), ], ], - ).paddingAll(16), + ), if ((workOrder.nextStep!.workOrderNextStepEnum == WorkOrderNextStepEnum.verifyAssetDetail || workOrder.nextStep!.workOrderNextStepEnum == WorkOrderNextStepEnum.activity) && userProvider.user?.type == UsersTypes.engineer) ...[ + 8.height, assetRetiredButton(context: context), ] ], - ).toShadowContainer(context, padding: 0); + ).toShadowContainer( + context, + ); } Widget contactInfoCard(BuildContext context, WorkOrderData workOrder) { @@ -307,7 +310,7 @@ class _ServiceRequestDetailViewState extends State { separatorBuilder: (cxt, index) => const Divider().defaultStyle(context), itemCount: workOrder.workOrderContactPerson.length), ], - ).toShadowContainer(context, padding: 16); + ).toShadowContainer(context); } Widget costCard(BuildContext context, CMDetailProvider provider) { @@ -340,18 +343,15 @@ class _ServiceRequestDetailViewState extends State { } Widget assetRetiredButton({required BuildContext context}) { - return Padding( - padding: EdgeInsets.symmetric(horizontal: 16.toScreenHeight, vertical: 12.toScreenWidth), - child: AppFilledButton( - label: context.translation.assetToBeRetired, - maxWidth: true, - buttonColor: AppColor.background(context), - textColor: AppColor.red30, - showBorder: true, - onPressed: () async { - Navigator.push(context, MaterialPageRoute(builder: (context) => const AssetRetired())); - }), - ); + return AppFilledButton( + label: context.translation.assetToBeRetired, + maxWidth: true, + buttonColor: AppColor.background(context), + textColor: AppColor.red30, + showBorder: true, + onPressed: () async { + Navigator.push(context, MaterialPageRoute(builder: (context) => const AssetRetired())); + }); } Widget initialVisitCard({required CMDetailProvider requestDetailProvider, required UserProvider userProvider}) { diff --git a/lib/new_views/swipe_module/utils/swipe_general_utils.dart b/lib/new_views/swipe_module/utils/swipe_general_utils.dart index b5b71ae8..a24834e0 100644 --- a/lib/new_views/swipe_module/utils/swipe_general_utils.dart +++ b/lib/new_views/swipe_module/utils/swipe_general_utils.dart @@ -618,26 +618,9 @@ class SwipeGeneralUtils { ), backgroundColor: AppColor.bottomSheetColor(context), clipBehavior: Clip.antiAliasWithSaveLayer, - builder: (BuildContext context) => Padding( - padding: EdgeInsets.only( - bottom: MediaQuery.of(context).viewInsets.bottom + MediaQuery.of(context).padding.bottom, - ), - child: Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - context.translation.markAttendance.heading4(context).custom(color: context.isDark ? AppColor.white50 : AppColor.white936), - 8.height, - context.translation.selectMethodToMarkAttendance.bodyText2(context).custom(color: AppColor.lightTextColor(context)), - 12.height, - GridView( - padding: const EdgeInsets.all(0), - shrinkWrap: true, - physics: const NeverScrollableScrollPhysics(), - gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 3, childAspectRatio: 1, crossAxisSpacing: 12, mainAxisSpacing: 12), - children: availableAttendanceMethodList(context: context, userProvider: _userProvider, isNfcSupported: isNfcSupported)), - ], - ).paddingAll(16), + builder: (BuildContext context) => _SwipeTypeBottomSheetContent( + userProvider: _userProvider, + isNfcSupported: isNfcSupported, ), ); } @@ -764,3 +747,167 @@ class SwipeGeneralUtils { return await WiFiForIoTPlugin.disconnect(); } } + +class _SwipeTypeBottomSheetContent extends StatefulWidget { + final UserProvider userProvider; + final bool isNfcSupported; + + const _SwipeTypeBottomSheetContent({ + required this.userProvider, + required this.isNfcSupported, + }); + + @override + State<_SwipeTypeBottomSheetContent> createState() => _SwipeTypeBottomSheetContentState(); +} + +class _SwipeTypeBottomSheetContentState extends State<_SwipeTypeBottomSheetContent> with SingleTickerProviderStateMixin { + late AnimationController _animationController; + + @override + void initState() { + super.initState(); + _animationController = AnimationController( + duration: const Duration(milliseconds: 1200), + vsync: this, + ); + _animationController.forward(); + } + + @override + void dispose() { + _animationController.dispose(); + super.dispose(); + } + + List<_SwipeTypeItem> _getAvailableSwipeMethods() { + List<_SwipeTypeItem> availableMethods = []; + + if (widget.userProvider.user!.enableNFC!) { + availableMethods.add(_SwipeTypeItem( + type: SwipeTypeEnum.NFC, + icon: 'nfc_icon', + isEnabled: widget.isNfcSupported, + )); + } + + if (widget.userProvider.user!.enableQR!) { + availableMethods.add(_SwipeTypeItem( + type: SwipeTypeEnum.QR, + icon: 'qr', + isEnabled: widget.userProvider.user!.enableQR!, + )); + } + + if (kDebugMode) { + widget.userProvider.user!.enableWifi = true; + } + + if (widget.userProvider.user!.enableWifi!) { + availableMethods.add(_SwipeTypeItem( + type: SwipeTypeEnum.Wifi, + icon: 'wifi_icon', + isEnabled: widget.userProvider.user!.enableWifi!, + )); + } + + return availableMethods; + } + + @override + Widget build(BuildContext context) { + final availableMethods = _getAvailableSwipeMethods(); + + return Padding( + padding: EdgeInsets.only( + bottom: MediaQuery.of(context).viewInsets.bottom + MediaQuery.of(context).padding.bottom, + ), + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + context.translation.markAttendance.heading5(context).custom(color: AppColor.headingTextColor(context)), + 8.height, + context.translation.selectMethodToMarkAttendance.bodyText2(context).custom(color: AppColor.lightTextColor(context)), + 12.height, + GridView.builder( + padding: const EdgeInsets.all(0), + shrinkWrap: true, + physics: const NeverScrollableScrollPhysics(), + gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount( + crossAxisCount: 3, + childAspectRatio: 1, + crossAxisSpacing: 12, + mainAxisSpacing: 12, + ), + itemCount: availableMethods.length, + itemBuilder: (context, index) { + // Calculate staggered animation delay + final delay = index * 0.08; + final animation = Tween(begin: 0.0, end: 1.0).animate( + CurvedAnimation( + parent: _animationController, + curve: Interval( + delay.clamp(0.0, 0.8), + (delay + 0.3).clamp(0.0, 1.0), + curve: Curves.easeOut, + ), + ), + ); + + final slideAnimation = Tween( + begin: const Offset(0.0, 0.3), + end: Offset.zero, + ).animate( + CurvedAnimation( + parent: _animationController, + curve: Interval( + delay.clamp(0.0, 0.8), + (delay + 0.3).clamp(0.0, 1.0), + curve: Curves.easeOutCubic, + ), + ), + ); + + final item = availableMethods[index]; + + return FadeTransition( + opacity: animation, + child: SlideTransition( + position: slideAnimation, + child: SwipeGeneralUtils.instance.attendanceTypeCard( + item.type.name, + item.icon, + item.isEnabled, + () { + Navigator.pop(context); + SwipeGeneralUtils.instance.handleSwipe( + swipeType: item.type, + isEnable: item.isEnabled, + context: navigatorKey.currentState!.overlay!.context, + ); + }, + context, + ), + ), + ); + }, + ), + ], + ).paddingAll(16), + ); + } +} + +class _SwipeTypeItem { + final SwipeTypeEnum type; + final String icon; + final bool isEnabled; + + _SwipeTypeItem({ + required this.type, + required this.icon, + required this.isEnabled, + }); +} + diff --git a/lib/views/widgets/fullscreen_dialogs/multiple_selection_fullscreen_dialog.dart b/lib/views/widgets/fullscreen_dialogs/multiple_selection_fullscreen_dialog.dart index 17dc2b58..5adeb69e 100644 --- a/lib/views/widgets/fullscreen_dialogs/multiple_selection_fullscreen_dialog.dart +++ b/lib/views/widgets/fullscreen_dialogs/multiple_selection_fullscreen_dialog.dart @@ -151,7 +151,7 @@ class _SelectionBottomSheetState extends State