diff --git a/lib/classes/utils.dart b/lib/classes/utils.dart index af9e340..2bb9135 100644 --- a/lib/classes/utils.dart +++ b/lib/classes/utils.dart @@ -17,6 +17,8 @@ import 'package:mohem_flutter_app/extensions/widget_extensions.dart'; import 'package:mohem_flutter_app/generated/locale_keys.g.dart'; import 'package:mohem_flutter_app/widgets/dialogs/confirm_dialog.dart'; import 'package:mohem_flutter_app/widgets/loading_dialog.dart'; +import 'package:nfc_manager/nfc_manager.dart'; +import 'package:nfc_manager/platform_tags.dart'; import 'package:shared_preferences/shared_preferences.dart'; // ignore_for_file: avoid_annotating_with_dynamic @@ -321,4 +323,23 @@ class Utils { } return selectedDate; } + + static void readNFc({required Function(String) onRead}) { + var instance = NfcManager.instance; + + NfcManager.instance.startSession(onDiscovered: (NfcTag tag) async { + print(tag.data); + var f; + if (Platform.isAndroid) { + f = MifareUltralight(tag: tag, identifier: tag.data["nfca"]["identifier"], type: 2, maxTransceiveLength: 252, timeout: 22); + } else { + f = MifareUltralight(tag: tag, identifier: tag.data["mifare"]["identifier"], type: 2, maxTransceiveLength: 252, timeout: 22); + } + String identifier = f.identifier.map((e) => e.toRadixString(16).padLeft(2, '0')).join(''); + NfcManager.instance.stopSession(); + onRead(identifier); + }).catchError((err) { + print(err); + }); + } } diff --git a/lib/config/routes.dart b/lib/config/routes.dart index 9823082..1fcbf2e 100644 --- a/lib/config/routes.dart +++ b/lib/config/routes.dart @@ -8,6 +8,7 @@ import 'package:mohem_flutter_app/ui/chat/chat_home.dart'; import 'package:mohem_flutter_app/ui/landing/dashboard_screen.dart'; import 'package:mohem_flutter_app/ui/landing/itg/survey_screen.dart'; import 'package:mohem_flutter_app/ui/landing/today_attendance_screen.dart'; +import 'package:mohem_flutter_app/ui/landing/today_attendance_screen2.dart'; import 'package:mohem_flutter_app/ui/leave_balance/add_leave_balance_screen.dart'; import 'package:mohem_flutter_app/ui/leave_balance/leave_balance_screen.dart'; import 'package:mohem_flutter_app/ui/login/change_password_screen.dart'; @@ -193,7 +194,7 @@ class AppRoutes { subMenuScreen: (BuildContext context) => SubMenuScreen(), newPassword: (BuildContext context) => NewPasswordScreen(), forgotPassword: (BuildContext context) => ForgotPasswordScreen(), - todayAttendance: (BuildContext context) => TodayAttendanceScreen(), + todayAttendance: (BuildContext context) => TodayAttendanceScreen2(), //eit addEitScreen: (BuildContext context) => AddEITScreen(), diff --git a/lib/extensions/string_extensions.dart b/lib/extensions/string_extensions.dart index 9bcc984..37f41ae 100644 --- a/lib/extensions/string_extensions.dart +++ b/lib/extensions/string_extensions.dart @@ -74,7 +74,7 @@ extension EmailValidator on String { this, textAlign: isCenter ? TextAlign.center : null, maxLines: (maxLine > 0) ? maxLine : null, - minFontSize: 8, + minFontSize: 5, style: TextStyle( fontSize: fontSize, fontWeight: isBold ? FontWeight.bold : FontWeight.w600, diff --git a/lib/extensions/widget_extensions.dart b/lib/extensions/widget_extensions.dart index ad41cfb..64aaae8 100644 --- a/lib/extensions/widget_extensions.dart +++ b/lib/extensions/widget_extensions.dart @@ -12,21 +12,14 @@ extension WidgetExtensions on Widget { Widget get center => Center(child: this); - Widget circle(double _value) => - ClipRRect(borderRadius: BorderRadius.circular(_value), child: this); + Widget circle(double _value) => ClipRRect(borderRadius: BorderRadius.circular(_value), child: this); - Widget paddingAll(double _value) => - Padding(padding: EdgeInsets.all(_value), child: this); + Widget paddingAll(double _value) => Padding(padding: EdgeInsets.all(_value), child: this); - Widget paddingOnly( - {double left = 0.0, - double right = 0.0, - double top = 0.0, - double bottom = 0.0}) => - Padding( - padding: EdgeInsets.only( - left: left, right: right, top: top, bottom: bottom), - child: this); + Widget paddingOnly({double left = 0.0, double right = 0.0, double top = 0.0, double bottom = 0.0}) => + Padding(padding: EdgeInsets.only(left: left, right: right, top: top, bottom: bottom), child: this); + + Widget toExpanded({int flex = 1}) => Expanded(flex: flex, child: this); Widget toShimmer({bool isShow = true}) => isShow ? Shimmer.fromColors( @@ -51,15 +44,9 @@ extension WidgetExtensions on Widget { child: this, ); - Widget objectContainerView( - {String title = "", - String note = "", - bool disablePadding = false, - double radius = 15}) { + Widget objectContainerView({String title = "", String note = "", bool disablePadding = false, double radius = 15}) { return Container( - padding: disablePadding - ? EdgeInsets.zero - : const EdgeInsets.only(top: 15, bottom: 15, left: 14, right: 14), + padding: disablePadding ? EdgeInsets.zero : const EdgeInsets.only(top: 15, bottom: 15, left: 14, right: 14), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(radius), @@ -95,9 +82,7 @@ extension WidgetExtensions on Widget { bool disableWidth = false, bool isAlignment = false}) { return Container( - padding: disablePadding - ? EdgeInsets.zero - : const EdgeInsets.only(top: 15, bottom: 15, left: 14, right: 14), + padding: disablePadding ? EdgeInsets.zero : const EdgeInsets.only(top: 15, bottom: 15, left: 14, right: 14), decoration: BoxDecoration( borderRadius: BorderRadius.circular(radius), color: color, diff --git a/lib/ui/landing/today_attendance_screen.dart b/lib/ui/landing/today_attendance_screen.dart index 22c4df9..d23fa10 100644 --- a/lib/ui/landing/today_attendance_screen.dart +++ b/lib/ui/landing/today_attendance_screen.dart @@ -95,64 +95,76 @@ class _TodayAttendanceScreenState extends State { ? Center(child: CircularProgressIndicator()) : Column( children: [ - Container( - width: double.infinity, - color: MyColors.backgroundBlackColor, - padding: EdgeInsets.only(top: 4, left: 21, right: 21, bottom: 21), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - DateUtil.getWeekDayMonthDayYearDateFormatted(DateTime.now(), "en").toText24(isBold: true, color: Colors.white), - LocaleKeys.timeLeftToday.tr().toText16(color: Color(0xffACACAC)), - //21.height, - Center( - 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), + Expanded( + flex: 2, + child: Container( + width: double.infinity, + color: MyColors.backgroundBlackColor, + padding: EdgeInsets.only(top: 4, left: 21, right: 21, bottom: 21), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + DateUtil.getWeekDayMonthDayYearDateFormatted(DateTime.now(), "en").toText24(isBold: true, color: Colors.white), + LocaleKeys.timeLeftToday.tr().toText16(color: Color(0xffACACAC)), + Center( + child: AspectRatio( + aspectRatio: 265 / 265, + child: CircularStepProgressBar( + totalSteps: 16 * 4, + currentStep: (model.progress * 100).toInt(), + selectedColor: MyColors.gradiantEndColor, + unselectedColor: MyColors.grey70Color, + child: Center( + child: Padding( + padding: const EdgeInsets.all(21.0), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + CountdownTimer( + endTime: model.endTime, + widgetBuilder: (context, v) { + return AutoSizeText( + getValue(v?.hours) + " : " + getValue(v?.min) + " : " + getValue(v?.sec), + maxLines: 1, + style: TextStyle(color: Colors.white, fontSize: 42, letterSpacing: -1.92, fontWeight: FontWeight.bold, height: 1), + ); + }, + onEnd: null, + endWidget: "00:00:00".toTextAuto(color: Colors.white, isBold: true, fontSize: 30, letterSpacing: -1.92), + textStyle: TextStyle(color: Colors.white, fontSize: 30, letterSpacing: -1.92, fontWeight: FontWeight.bold, height: 1), + ).center.expanded, + LocaleKeys.shiftTime.tr().tr().toTextAuto(color: MyColors.greyACColor, fontSize: 18, maxLine: 1), + (model.attendanceTracking!.pShtName ?? "00:00:00").toString().toTextAuto(color: Colors.white, isBold: true, fontSize: 26, maxLine: 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, - - ], + ).paddingAll(12), + ).expanded, + ], + ), ), - ).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, - ]), + 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), + padding: const EdgeInsets.only(left: 21, right: 21, top: 21, 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: [ @@ -179,80 +191,7 @@ class _TodayAttendanceScreenState extends State { ), ), //.expanded, - MarkAttendanceWidget(model, topPadding: 24), - // 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")], - // ), - // ], - // ), - // ), - // ), + MarkAttendanceWidget(model, topPadding: 21), ], ), ), @@ -265,60 +204,6 @@ class _TodayAttendanceScreenState extends State { ); } - // 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()); - // } - // } - String getValue(int? v) { if (v == null) { return "00"; @@ -335,63 +220,6 @@ class _TodayAttendanceScreenState extends State { 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: [ - // SvgPicture.asset( - // image, - // color: Colors.white, - // ).expanded, - // title.toText17(isBold: true, color: Colors.white), - // ], - // ), - // ), - // if (!isEnabled) - // Container( - // width: double.infinity, - // height: double.infinity, - // color: Colors.grey.withOpacity(0.7), - // ) - // ], - // ), - // ).onPress(onPress); - Widget commonStatusView(String title, String time) => Expanded( child: Column(mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, children: [ title.toText12(color: Colors.white.withOpacity(.69)), diff --git a/lib/widgets/mark_attendance_widget.dart b/lib/widgets/mark_attendance_widget.dart index 1780d68..6a5b4d8 100644 --- a/lib/widgets/mark_attendance_widget.dart +++ b/lib/widgets/mark_attendance_widget.dart @@ -75,21 +75,23 @@ class _MarkAttendanceWidgetState extends State { @override Widget build(BuildContext context) { + print(MediaQuery.of(context).size.width); return Container( padding: EdgeInsets.only(left: 21, right: 21, bottom: 21, top: widget.topPadding), decoration: const BoxDecoration(borderRadius: BorderRadius.only(topLeft: Radius.circular(25), topRight: Radius.circular(25)), color: Colors.white), width: double.infinity, child: Column( crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, 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), + padding: const EdgeInsets.only(bottom: 0, top: 21), gridDelegate: - SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: (MediaQuery.of(context).size.width < 400) ? 3 : 5, childAspectRatio: 1 / 1, crossAxisSpacing: 8, mainAxisSpacing: 8), + SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: (MediaQuery.of(context).size.width < 550) ? 3 : 5, childAspectRatio: 1 / 1, crossAxisSpacing: 8, mainAxisSpacing: 8), children: [ // if (isNfcEnabled) attendanceMethod("NFC", "assets/images/nfc.svg", isNfcEnabled, () { @@ -137,27 +139,50 @@ class _MarkAttendanceWidgetState extends State { 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); - showMDialog( - context, - backgroundColor: Colors.transparent, - isDismissable: false, - child: SuccessDialog(widget.isFromDashboard), - ); - } catch (ex) { - print(ex); - Utils.hideLoading(context); - Utils.handleException(ex, context, (msg) { - Utils.confirmDialog(context, msg); - }); - } - }); + if (Platform.isIOS) { + Utils.readNFc(onRead: (String nfcId) async { + 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); + showMDialog( + context, + backgroundColor: Colors.transparent, + isDismissable: false, + child: SuccessDialog(widget.isFromDashboard), + ); + } catch (ex) { + print(ex); + Utils.hideLoading(context); + Utils.handleException(ex, context, (msg) { + Utils.confirmDialog(context, msg); + }); + } + }); + } else { + 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); + showMDialog( + context, + backgroundColor: Colors.transparent, + isDismissable: false, + child: SuccessDialog(widget.isFromDashboard), + ); + } 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 { @@ -199,6 +224,7 @@ class _MarkAttendanceWidgetState extends State { }); } } else { + Utils.hideLoading(context); Utils.confirmDialog(context, LocaleKeys.comeNearHMGWifi.tr()); } } @@ -264,8 +290,10 @@ class _MarkAttendanceWidgetState extends State { title.toText17(isBold: true, color: Colors.white), ], ), - ).onPress(() { - if (!isEnabled) return; - onPress(); - }); + ).onPress( + () { + if (!isEnabled) return; + onPress(); + }, + ); }