From 9b50c2cf31245fbb750e010f6c199c8b094c6383 Mon Sep 17 00:00:00 2001 From: Sikander Saleem Date: Thu, 25 Aug 2022 09:25:47 +0300 Subject: [PATCH] mark attendance improvement. --- lib/ui/landing/dashboard_screen.dart | 6 +- lib/ui/landing/today_attendance_screen.dart | 296 ++++++++++---------- lib/widgets/mark_attendance_widget.dart | 249 ++++++++++++++++ 3 files changed, 405 insertions(+), 146 deletions(-) create mode 100644 lib/widgets/mark_attendance_widget.dart diff --git a/lib/ui/landing/dashboard_screen.dart b/lib/ui/landing/dashboard_screen.dart index 4406a4d..da9cb5f 100644 --- a/lib/ui/landing/dashboard_screen.dart +++ b/lib/ui/landing/dashboard_screen.dart @@ -17,6 +17,8 @@ import 'package:mohem_flutter_app/provider/dashboard_provider_model.dart'; import 'package:mohem_flutter_app/ui/landing/widget/app_drawer.dart'; import 'package:mohem_flutter_app/ui/landing/widget/menus_widget.dart'; import 'package:mohem_flutter_app/ui/landing/widget/services_widget.dart'; +import 'package:mohem_flutter_app/widgets/bottom_sheet.dart'; +import 'package:mohem_flutter_app/widgets/mark_attendance_widget.dart'; import 'package:mohem_flutter_app/widgets/shimmer/dashboard_shimmer_widget.dart'; import 'package:provider/provider.dart'; @@ -206,7 +208,9 @@ class _DashboardScreenState extends State { ), ), child: SvgPicture.asset(model.isTimeRemainingInSeconds == 0 ? "assets/images/play.svg" : "assets/images/stop.svg"), - ), + ).onPress(() { + showMyBottomSheet(context, child: MarkAttendanceWidget(model)); + }), ], ), ], diff --git a/lib/ui/landing/today_attendance_screen.dart b/lib/ui/landing/today_attendance_screen.dart index 9346773..83c3f06 100644 --- a/lib/ui/landing/today_attendance_screen.dart +++ b/lib/ui/landing/today_attendance_screen.dart @@ -1,6 +1,5 @@ import 'package:easy_localization/src/public_ext.dart'; import 'package:flutter/material.dart'; -import 'package:flutter/services.dart'; import 'package:flutter_countdown_timer/flutter_countdown_timer.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:google_maps_flutter/google_maps_flutter.dart'; @@ -16,17 +15,13 @@ import 'package:mohem_flutter_app/generated/locale_keys.g.dart'; import 'package:mohem_flutter_app/models/generic_response_model.dart'; import 'package:mohem_flutter_app/provider/dashboard_provider_model.dart'; import 'package:mohem_flutter_app/widgets/circular_step_progress_bar.dart'; -import 'package:mohem_flutter_app/widgets/dialogs/dialogs.dart'; import 'package:mohem_flutter_app/widgets/location/Location.dart'; import 'package:mohem_flutter_app/widgets/nfc/nfc_reader_sheet.dart'; +import 'package:mohem_flutter_app/widgets/qr_scanner_dialog.dart'; import 'package:nfc_manager/nfc_manager.dart'; import 'package:provider/provider.dart'; import 'package:wifi_iot/wifi_iot.dart'; -import 'package:mohem_flutter_app/widgets/qr_scanner_dialog.dart'; - - - class TodayAttendanceScreen extends StatefulWidget { TodayAttendanceScreen({Key? key}) : super(key: key); @@ -44,11 +39,11 @@ class _TodayAttendanceScreenState extends State { @override void initState() { super.initState(); - checkAttendanceAvailablity(); + checkAttendanceAvailability(); data = Provider.of(context, listen: false); } - void checkAttendanceAvailablity() async { + void checkAttendanceAvailability() async { bool isAvailable = await NfcManager.instance.isAvailable(); setState(() { AppState().privilegeListModel!.forEach((element) { @@ -104,7 +99,7 @@ class _TodayAttendanceScreenState extends State { builder: (context, model, child) { return (model.isAttendanceTrackingLoading ? Center(child: CircularProgressIndicator()) - : ListView( + : Column( children: [ Container( color: MyColors.backgroundBlackColor, @@ -114,144 +109,156 @@ class _TodayAttendanceScreenState extends State { children: [ DateUtil.getWeekDayMonthDayYearDateFormatted(DateTime.now(), "en").toText24(isBold: true, color: Colors.white), LocaleKeys.timeLeftToday.tr().toText16(color: Color(0xffACACAC)), - 21.height, + //21.height, Center( - child: CircularStepProgressBar( - totalSteps: 16 * 4, - currentStep: (model.progress * 100).toInt(), - width: 216, - height: 216, - selectedColor: MyColors.gradiantEndColor, - unselectedColor: MyColors.grey70Color, - child: Center( - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - CountdownTimer( - endTime: model.endTime, - onEnd: null, - endWidget: "00:00:00".toText32(color: Colors.white, isBold: true), - textStyle: TextStyle(color: Colors.white, fontSize: 32, letterSpacing: -1.92, fontWeight: FontWeight.bold, height: 1), - ), - 19.height, - LocaleKeys.shiftTime.tr().tr().toText12(color: MyColors.greyACColor), - (model.attendanceTracking!.pShtName ?? "00:00:00").toString().toText22(color: Colors.white, isBold: true), - ], + child: AspectRatio( + aspectRatio: 265 / 265, + child: CircularStepProgressBar( + totalSteps: 16 * 4, + currentStep: (model.progress * 100).toInt(), + //width: 216, + // height: 216, + selectedColor: MyColors.gradiantEndColor, + unselectedColor: MyColors.grey70Color, + child: Center( + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + CountdownTimer( + endTime: model.endTime, + onEnd: null, + endWidget: "00:00:00".toText32(color: Colors.white, isBold: true), + textStyle: TextStyle(color: Colors.white, fontSize: 32, letterSpacing: -1.92, fontWeight: FontWeight.bold, height: 1), + ), + 19.height, + LocaleKeys.shiftTime.tr().tr().toText12(color: MyColors.greyACColor), + (model.attendanceTracking!.pShtName ?? "00:00:00").toString().toText22(color: Colors.white, isBold: true), + ], + ), ), ), - ), - ), + ).paddingAll(21), + ).expanded, ], ), - ), - Container( - color: MyColors.backgroundBlackColor, - child: Stack( - children: [ - Container( - height: 187, - padding: EdgeInsets.only(left: 31, right: 31, top: 31, bottom: 16), - decoration: BoxDecoration( - borderRadius: BorderRadius.only(topLeft: Radius.circular(25), topRight: Radius.circular(25)), - gradient: const LinearGradient(transform: GradientRotation(.64), begin: Alignment.topRight, end: Alignment.bottomLeft, colors: [ - MyColors.gradiantEndColor, - MyColors.gradiantStartColor, - ]), - ), - child: Column( - children: [ - Row( - children: [ - commonStatusView(LocaleKeys.checkIn.tr(), (model.attendanceTracking!.pSwipeIn) ?? "- - : - -"), - commonStatusView(LocaleKeys.checkOut.tr(), (model.attendanceTracking!.pSwipeOut) ?? "- - : - -") - ], - ), - 21.height, - Row( - children: [ - commonStatusView(LocaleKeys.lateIn.tr(), (model.attendanceTracking!.pLateInHours) ?? "- - : - -"), - commonStatusView(LocaleKeys.regular.tr(), (model.attendanceTracking!.pScheduledHours) ?? "- - : - -") - ], - ), - ], - ), - ), - Container( - width: double.infinity, - decoration: BoxDecoration(borderRadius: BorderRadius.only(topLeft: Radius.circular(25), topRight: Radius.circular(25)), color: Colors.white), - margin: EdgeInsets.only(top: 187 - 31), - padding: EdgeInsets.only(left: 21, right: 21, top: 24, bottom: 24), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisSize: MainAxisSize.min, - children: [ - LocaleKeys.mark.tr().tr().toText12(), - LocaleKeys.attendance.tr().tr().toText24(), - LocaleKeys.selectMethodOfAttendance.tr().tr().toText12(color: Color(0xff535353)), - 24.height, - GridView( - physics: const NeverScrollableScrollPhysics(), - shrinkWrap: true, - padding: EdgeInsets.zero, - gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 3, childAspectRatio: 1 / 1, crossAxisSpacing: 8, mainAxisSpacing: 8), - children: [ - if (isNfcEnabled) - attendanceMethod("NFC", "assets/images/nfc.svg", isNfcEnabled, () { - if (isNfcLocationEnabled) { - Location.getCurrentLocation((LatLng? latlng) { - performNfcAttendance(model, lat: latlng?.latitude.toString() ?? "", lng: latlng?.longitude.toString() ?? ""); - }); - } else { - performNfcAttendance(model); - } - }), - if (isWifiEnabled) - attendanceMethod("Wifi", "assets/images/wufu.svg", isWifiEnabled, () { - if (isWifiLocationEnabled) { + ).expanded, + Center( + child: Container( + // color: MyColors.backgroundBlackColor, + decoration: const BoxDecoration( + borderRadius: BorderRadius.only(topLeft: Radius.circular(25), topRight: Radius.circular(25)), + gradient: LinearGradient(transform: GradientRotation(.64), begin: Alignment.topRight, end: Alignment.bottomLeft, colors: [ + MyColors.gradiantEndColor, + MyColors.gradiantStartColor, + ]), + ), + child: Column( + children: [ + Container( + //height: 187, + padding: const EdgeInsets.only(left: 31, right: 31, top: 31, bottom: 16), + decoration: const BoxDecoration( + borderRadius: BorderRadius.only(topLeft: Radius.circular(25), topRight: Radius.circular(25)), + gradient: LinearGradient(transform: GradientRotation(.64), begin: Alignment.topRight, end: Alignment.bottomLeft, colors: [ + MyColors.gradiantEndColor, + MyColors.gradiantStartColor, + ]), + ), + child: Column( + children: [ + Row( + children: [ + commonStatusView(LocaleKeys.checkIn.tr(), (model.attendanceTracking!.pSwipeIn) ?? "- - : - -"), + commonStatusView(LocaleKeys.checkOut.tr(), (model.attendanceTracking!.pSwipeOut) ?? "- - : - -") + ], + ), + 21.height, + Row( + children: [ + commonStatusView(LocaleKeys.lateIn.tr(), (model.attendanceTracking!.pLateInHours) ?? "- - : - -"), + commonStatusView(LocaleKeys.regular.tr(), (model.attendanceTracking!.pScheduledHours) ?? "- - : - -") + ], + ), + ], + ), + ), //.expanded, - Location.getCurrentLocation((LatLng? latlng) { - performWifiAttendance(model, lat: latlng?.latitude.toString() ?? "", lng: latlng?.longitude.toString() ?? ""); - }); - } else { - performWifiAttendance(model); - } - // connectWifi(); - }), - if (isQrEnabled) - attendanceMethod("QR", "assets/images/ic_qr.svg", isQrEnabled, () async { - if (isQrLocationEnabled) { - Location.getCurrentLocation((LatLng? latlng) { - performQrCodeAttendance(model, lat: latlng?.latitude.toString() ?? "", lng: latlng?.longitude.toString() ?? ""); - }); - } else { - performQrCodeAttendance(model); - } - // performQrCodeAttendance(model); - }), - ], - ) - ], + // MarkAttendanceWidget(model), + Container( + width: double.infinity, + decoration: BoxDecoration(borderRadius: BorderRadius.only(topLeft: Radius.circular(25), topRight: Radius.circular(25)), color: Colors.white), + // margin: EdgeInsets.only(top: 187 - 31), + padding: EdgeInsets.only(left: 21, right: 21, top: 24, bottom: 24), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + LocaleKeys.markAttendance.tr().toSectionHeading(), + LocaleKeys.selectMethodOfAttendance.tr().tr().toText11(color: Color(0xff535353)), + 24.height, + GridView( + physics: const NeverScrollableScrollPhysics(), + shrinkWrap: true, + padding: EdgeInsets.zero, + gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 3, childAspectRatio: 1 / 1, crossAxisSpacing: 8, mainAxisSpacing: 8), + children: [ + if (isNfcEnabled) + attendanceMethod("NFC", "assets/images/nfc.svg", isNfcEnabled, () { + if (isNfcLocationEnabled) { + Location.getCurrentLocation((LatLng? latlng) { + performNfcAttendance(model, lat: latlng?.latitude.toString() ?? "", lng: latlng?.longitude.toString() ?? ""); + }); + } else { + performNfcAttendance(model); + } + }), + if (isWifiEnabled) + attendanceMethod("Wifi", "assets/images/wufu.svg", isWifiEnabled, () { + if (isWifiLocationEnabled) { + Location.getCurrentLocation((LatLng? latlng) { + performWifiAttendance(model, lat: latlng?.latitude.toString() ?? "", lng: latlng?.longitude.toString() ?? ""); + }); + } else { + performWifiAttendance(model); + } + // connectWifi(); + }), + if (isQrEnabled) + attendanceMethod("QR", "assets/images/ic_qr.svg", isQrEnabled, () async { + if (isQrLocationEnabled) { + Location.getCurrentLocation((LatLng? latlng) { + performQrCodeAttendance(model, lat: latlng?.latitude.toString() ?? "", lng: latlng?.longitude.toString() ?? ""); + }); + } else { + performQrCodeAttendance(model); + } + // performQrCodeAttendance(model); + }), + ], + ) + ], + ), ), - ), - // Positioned( - // top: 187 - 21, - // child: Container( - // padding: EdgeInsets.only(left: 31, right: 31, top: 31, bottom: 16), - // decoration: BoxDecoration(borderRadius: BorderRadius.only(topLeft: Radius.circular(25), topRight: Radius.circular(25)), color: Colors.white), - // child: Column( - // children: [ - // Row( - // children: [commonStatusView("Check In", "09:27"), commonStatusView("Check Out", "- - : - -")], - // ), - // 21.height, - // Row( - // children: [commonStatusView("Late In", "00:27"), commonStatusView("Regular", "08:00")], - // ), - // ], - // ), - // ), - // ), - ], + // Positioned( + // top: 187 - 21, + // child: Container( + // padding: EdgeInsets.only(left: 31, right: 31, top: 31, bottom: 16), + // decoration: BoxDecoration(borderRadius: BorderRadius.only(topLeft: Radius.circular(25), topRight: Radius.circular(25)), color: Colors.white), + // child: Column( + // children: [ + // Row( + // children: [commonStatusView("Check In", "09:27"), commonStatusView("Check Out", "- - : - -")], + // ), + // 21.height, + // Row( + // children: [commonStatusView("Late In", "00:27"), commonStatusView("Regular", "08:00")], + // ), + // ], + // ), + // ), + // ), + ], + ), ), ) ], @@ -328,7 +335,7 @@ class _TodayAttendanceScreenState extends State { builder: (context) => QrScannerDialog(), ), ); - if(qrCodeValue!=null){ + if (qrCodeValue != null) { print("qrCode: " + qrCodeValue); Utils.showLoading(context); try { @@ -361,11 +368,10 @@ class _TodayAttendanceScreenState extends State { child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - Expanded( - child: SvgPicture.asset( + SvgPicture.asset( image, color: Colors.white, - )), + ).expanded, title.toText17(isBold: true, color: Colors.white), ], ), @@ -382,7 +388,7 @@ class _TodayAttendanceScreenState extends State { Widget commonStatusView(String title, String time) => Expanded( child: Column(mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, children: [ - title.toText12(color: Colors.white), + title.toText12(color: Colors.white.withOpacity(.69)), time.toText22(color: Colors.white, isBold: true), ]), ); diff --git a/lib/widgets/mark_attendance_widget.dart b/lib/widgets/mark_attendance_widget.dart new file mode 100644 index 0000000..c534dee --- /dev/null +++ b/lib/widgets/mark_attendance_widget.dart @@ -0,0 +1,249 @@ +import 'package:easy_localization/easy_localization.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_svg/flutter_svg.dart'; +import 'package:google_maps_flutter/google_maps_flutter.dart'; +import 'package:mohem_flutter_app/api/dashboard_api_client.dart'; +import 'package:mohem_flutter_app/app_state/app_state.dart'; +import 'package:mohem_flutter_app/classes/colors.dart'; +import 'package:mohem_flutter_app/classes/utils.dart'; +import 'package:mohem_flutter_app/extensions/string_extensions.dart'; +import 'package:mohem_flutter_app/extensions/widget_extensions.dart'; +import 'package:mohem_flutter_app/generated/locale_keys.g.dart'; +import 'package:mohem_flutter_app/models/generic_response_model.dart'; +import 'package:mohem_flutter_app/provider/dashboard_provider_model.dart'; +import 'package:mohem_flutter_app/widgets/location/Location.dart'; +import 'package:mohem_flutter_app/widgets/nfc/nfc_reader_sheet.dart'; +import 'package:mohem_flutter_app/widgets/qr_scanner_dialog.dart'; +import 'package:nfc_manager/nfc_manager.dart'; +import 'package:wifi_iot/wifi_iot.dart'; + +class MarkAttendanceWidget extends StatefulWidget { + DashboardProviderModel model; + + MarkAttendanceWidget(this.model, {Key? key}) : super(key: key); + + @override + _MarkAttendanceWidgetState createState() { + return _MarkAttendanceWidgetState(); + } +} + +class _MarkAttendanceWidgetState extends State { + bool isNfcEnabled = false, isNfcLocationEnabled = false, isQrEnabled = false, isQrLocationEnabled = false, isWifiEnabled = false, isWifiLocationEnabled = false; + + @override + void initState() { + super.initState(); + checkAttendanceAvailability(); + } + + void checkAttendanceAvailability() async { + bool isAvailable = await NfcManager.instance.isAvailable(); + setState(() { + AppState().privilegeListModel!.forEach((element) { + print(element.serviceName.toString() + " " + element.previlege.toString()); // Check availability + + if (element.serviceName == "enableNFC") { + if (isAvailable) if (element.previlege ?? false) isNfcEnabled = true; + } else if (element.serviceName == "enableQR") { + if (element.previlege ?? false) isQrEnabled = true; + } else if (element.serviceName == "enableWIFI") { + if (element.previlege ?? false) isWifiEnabled = true; + } else if (element.serviceName!.trim() == "enableLocationNFC") { + if (element.previlege ?? false) isNfcLocationEnabled = true; + } else if (element.serviceName == "enableLocationQR") { + if (element.previlege ?? false) isQrLocationEnabled = true; + } else if (element.serviceName == "enableLocationWIFI") { + if (element.previlege ?? false) isWifiLocationEnabled = true; + } + }); + }); + } + + @override + void dispose() { + super.dispose(); + // Stop Session + NfcManager.instance.stopSession(); + } + + @override + Widget build(BuildContext context) { + return Container( + padding: EdgeInsets.only(left: 21, right: 21, bottom: 21), + decoration: BoxDecoration(borderRadius: BorderRadius.only(topLeft: Radius.circular(25), topRight: Radius.circular(25)), color: Colors.white), + + width: double.infinity, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + LocaleKeys.markAttendance.tr().toSectionHeading(), + LocaleKeys.selectMethodOfAttendance.tr().tr().toText11(color: const Color(0xff535353)), + GridView( + physics: const NeverScrollableScrollPhysics(), + shrinkWrap: true, + padding: const EdgeInsets.only(bottom: 14, top: 21), + gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 3, childAspectRatio: 1 / 1, crossAxisSpacing: 8, mainAxisSpacing: 8), + children: [ + if (isNfcEnabled) + attendanceMethod("NFC", "assets/images/nfc.svg", isNfcEnabled, () { + if (isNfcLocationEnabled) { + Location.getCurrentLocation((LatLng? latlng) { + performNfcAttendance(widget.model, lat: latlng?.latitude.toString() ?? "", lng: latlng?.longitude.toString() ?? ""); + }); + } else { + performNfcAttendance(widget.model); + } + }), + if (isWifiEnabled) + attendanceMethod("Wifi", "assets/images/wufu.svg", isWifiEnabled, () { + if (isWifiLocationEnabled) { + Location.getCurrentLocation((LatLng? latlng) { + performWifiAttendance(widget.model, lat: latlng?.latitude.toString() ?? "", lng: latlng?.longitude.toString() ?? ""); + }); + } else { + performWifiAttendance(widget.model); + } + // connectWifi(); + }), + if (isQrEnabled) + attendanceMethod("QR", "assets/images/ic_qr.svg", isQrEnabled, () async { + if (isQrLocationEnabled) { + Location.getCurrentLocation((LatLng? latlng) { + performQrCodeAttendance(widget.model, lat: latlng?.latitude.toString() ?? "", lng: latlng?.longitude.toString() ?? ""); + }); + } else { + performQrCodeAttendance(widget.model); + } + // performQrCodeAttendance(model); + }), + ], + ) + ], + ), + ); + } + + Future performNfcAttendance(DashboardProviderModel model, {String lat = "0", String lng = "0"}) async { + if (isNfcLocationEnabled) { + print("nfc location enabled"); + } else { + print("nfc not location enabled"); + } + + showNfcReader(context, onNcfScan: (String? nfcId) async { + print(nfcId); + Utils.showLoading(context); + try { + GenericResponseModel? g = await DashboardApiClient().markAttendance(pointType: 2, nfcValue: nfcId ?? "", isGpsRequired: isNfcLocationEnabled, lat: lat, long: lng); + bool status = await model.fetchAttendanceTracking(context); + Utils.hideLoading(context); + } catch (ex) { + print(ex); + Utils.hideLoading(context); + Utils.handleException(ex, context, (msg) { + Utils.confirmDialog(context, msg); + }); + } + }); + } + + Future performWifiAttendance(DashboardProviderModel model, {String lat = "0", String lng = "0"}) async { + if (isWifiLocationEnabled) { + print("wifi location enabled"); + } else { + print("wifi not location enabled"); + } + + bool v = await WiFiForIoTPlugin.connect(AppState().mohemmWifiSSID ?? "", password: AppState().mohemmWifiPassword ?? "", joinOnce: true, security: NetworkSecurity.WPA, withInternet: false); + if (v) { + await WiFiForIoTPlugin.forceWifiUsage(true); + print("connected"); + Utils.showLoading(context); + try { + GenericResponseModel? g = await DashboardApiClient().markAttendance(pointType: 3, nfcValue: "", isGpsRequired: isWifiLocationEnabled, lat: lat, long: lng); + bool status = await model.fetchAttendanceTracking(context); + Utils.hideLoading(context); + await closeWifiRequest(); + } catch (ex) { + print(ex); + await closeWifiRequest(); + Utils.hideLoading(context); + Utils.handleException(ex, context, (msg) { + Utils.confirmDialog(context, msg); + }); + } + } else { + Utils.confirmDialog(context, LocaleKeys.comeNearHMGWifi.tr()); + } + } + + Future closeWifiRequest() async { + await WiFiForIoTPlugin.forceWifiUsage(false); + bool v = await WiFiForIoTPlugin.disconnect(); + return v; + } + + Future performQrCodeAttendance(DashboardProviderModel model, {String lat = "0", String lng = "0"}) async { + var qrCodeValue = await Navigator.of(context).push( + MaterialPageRoute( + builder: (context) => QrScannerDialog(), + ), + ); + if (qrCodeValue != null) { + print("qrCode: " + qrCodeValue); + Utils.showLoading(context); + try { + GenericResponseModel? g = await DashboardApiClient().markAttendance(pointType: 1, isGpsRequired: isQrLocationEnabled, lat: lat, long: lng, QRValue: qrCodeValue); + bool status = await model.fetchAttendanceTracking(context); + Utils.hideLoading(context); + } catch (ex) { + print(ex); + Utils.hideLoading(context); + Utils.handleException(ex, context, (msg) { + Utils.confirmDialog(context, msg); + }); + } + } + } + + Widget attendanceMethod(String title, String image, bool isEnabled, VoidCallback onPress) => Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(15), + gradient: const LinearGradient( + transform: GradientRotation(.64), + begin: Alignment.topRight, + end: Alignment.bottomLeft, + colors: [ + MyColors.gradiantEndColor, + MyColors.gradiantStartColor, + ], + ), + ), + clipBehavior: Clip.antiAlias, + child: Stack( + children: [ + Container( + padding: const EdgeInsets.only(left: 10, right: 10, top: 14, bottom: 14), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Expanded( + child: SvgPicture.asset( + image, + color: Colors.white, + )), + title.toText17(isBold: true, color: Colors.white), + ], + ), + ), + if (!isEnabled) + Container( + width: double.infinity, + height: double.infinity, + color: Colors.grey.withOpacity(0.7), + ) + ], + ), + ).onPress(onPress); +}