diff --git a/assets/images/biometrics.svg b/assets/images/biometrics.svg new file mode 100644 index 0000000..5d61575 --- /dev/null +++ b/assets/images/biometrics.svg @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/lib/classes/notifications.dart b/lib/classes/notifications.dart index 8f432d7..00b732e 100644 --- a/lib/classes/notifications.dart +++ b/lib/classes/notifications.dart @@ -35,7 +35,7 @@ class AppNotifications { await flutterLocalNotificationsPlugin.resolvePlatformSpecificImplementation()?.requestPermissions(alert: true, badge: true, sound: true); } else if (Platform.isAndroid) { AndroidFlutterLocalNotificationsPlugin? androidImplementation = flutterLocalNotificationsPlugin.resolvePlatformSpecificImplementation(); - bool? granted = await androidImplementation?.requestPermission(); + bool? granted = await androidImplementation?.requestNotificationsPermission(); if (granted == false) { if (kDebugMode) { print("-------------------- Permission Granted ------------------------"); diff --git a/lib/dialogs/otp_dialog.dart b/lib/dialogs/otp_dialog.dart index 9f7c82e..7265d97 100644 --- a/lib/dialogs/otp_dialog.dart +++ b/lib/dialogs/otp_dialog.dart @@ -202,11 +202,11 @@ class OtpDialog { ), errorBorder: OutlineInputBorder( borderRadius: const BorderRadius.all(Radius.circular(10.0)), - borderSide: BorderSide(color: Theme.of(context).errorColor), + borderSide: BorderSide(color: Theme.of(context).colorScheme.error), ), focusedErrorBorder: OutlineInputBorder( borderRadius: const BorderRadius.all(Radius.circular(10.0)), - borderSide: BorderSide(color: Theme.of(context).errorColor), + borderSide: BorderSide(color: Theme.of(context).colorScheme.error), ), ); } diff --git a/lib/theme/app_theme.dart b/lib/theme/app_theme.dart index 586c3aa..b1a5570 100644 --- a/lib/theme/app_theme.dart +++ b/lib/theme/app_theme.dart @@ -1,4 +1,5 @@ import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; import 'package:mohem_flutter_app/classes/colors.dart'; import 'package:mohem_flutter_app/theme/colors.dart'; @@ -15,36 +16,84 @@ class AppTheme { }, ), hintColor: Colors.grey[400], - colorScheme: ColorScheme.fromSwatch(accentColor: MyColors.backgroundColor), + colorScheme: ColorScheme.fromSwatch( + accentColor: MyColors.backgroundColor, + errorColor: const Color.fromRGBO(235, 80, 60, 1.0), + ), disabledColor: Colors.grey[300], - errorColor: const Color.fromRGBO(235, 80, 60, 1.0), scaffoldBackgroundColor: MyColors.backgroundColor, textSelectionTheme: const TextSelectionThemeData(cursorColor: Colors.grey, selectionColor: Color.fromRGBO(80, 100, 253, 0.5), selectionHandleColor: Colors.grey), canvasColor: Colors.white, - backgroundColor: const Color.fromRGBO(255, 255, 255, 1), highlightColor: Colors.grey[100]!.withOpacity(0.4), splashColor: Colors.transparent, primaryColor: primaryColor, primaryColorDark: primaryColor, - buttonColor: Colors.black, - toggleableActiveColor: secondaryColor, + buttonTheme: ButtonThemeData( + buttonColor: Colors.black, + ), + switchTheme: SwitchThemeData( + thumbColor: MaterialStateProperty.resolveWith( + (Set states) { + if (states.contains(MaterialState.disabled)) { + return null; + } + if (states.contains(MaterialState.selected)) { + return secondaryColor; + } + return null; + }), + trackColor: MaterialStateProperty.resolveWith( + (Set states) { + if (states.contains(MaterialState.disabled)) { + return null; + } + if (states.contains(MaterialState.selected)) { + return secondaryColor; + } + return null; + }), + ), + radioTheme: RadioThemeData( + fillColor: MaterialStateProperty.resolveWith( + (Set states) { + if (states.contains(MaterialState.disabled)) { + return null; + } + if (states.contains(MaterialState.selected)) { + return secondaryColor; + } + return null; + }), + ), + checkboxTheme: CheckboxThemeData( + fillColor: MaterialStateProperty.resolveWith( + (Set states) { + if (states.contains(MaterialState.disabled)) { + return null; + } + if (states.contains(MaterialState.selected)) { + return secondaryColor; + } + return null; + }), + ), indicatorColor: secondaryColor, bottomSheetTheme: const BottomSheetThemeData( backgroundColor: Color(0xFFE0E0E0), ), - primaryTextTheme: const TextTheme( - bodyText2: TextStyle(color: Colors.white), - ), iconTheme: const IconThemeData(color: MyColors.darkIconColor), textTheme: const TextTheme( - bodyText1: TextStyle(color: Colors.black, letterSpacing: 0.6), - headline1: TextStyle(color: Colors.white, letterSpacing: 0.6), - headline2: TextStyle(color: Colors.white, letterSpacing: 0.6), + bodyMedium: TextStyle(color: Colors.black, letterSpacing: 0.6), + headlineSmall: TextStyle(color: Colors.white, letterSpacing: 0.6), + headlineMedium: TextStyle(color: Colors.white, letterSpacing: 0.6), ), floatingActionButtonTheme: const FloatingActionButtonThemeData(highlightElevation: 2, disabledElevation: 0, elevation: 2), - appBarTheme: AppBarTheme( + + appBarTheme: AppBarTheme( + systemOverlayStyle: const SystemUiOverlayStyle( + statusBarBrightness: Brightness.light, + ), color: const Color(0xff515A5D), - brightness: Brightness.light, elevation: 0.0, actionsIconTheme: IconThemeData( color: Colors.grey[800], diff --git a/lib/ui/attendance/monthly_attendance_screen.dart b/lib/ui/attendance/monthly_attendance_screen.dart index 65f101b..cb1e784 100644 --- a/lib/ui/attendance/monthly_attendance_screen.dart +++ b/lib/ui/attendance/monthly_attendance_screen.dart @@ -16,7 +16,7 @@ import 'package:mohem_flutter_app/models/get_schedule_shifts_details_list_model. import 'package:mohem_flutter_app/models/get_time_card_summary_list_model.dart'; import 'package:mohem_flutter_app/widgets/app_bar_widget.dart'; import 'package:mohem_flutter_app/widgets/circular_step_progress_bar.dart'; -import 'package:month_picker_dialog_2/month_picker_dialog_2.dart'; +import 'package:month_picker_dialog/month_picker_dialog.dart'; import 'package:pie_chart/pie_chart.dart'; import 'package:syncfusion_flutter_calendar/calendar.dart'; @@ -117,8 +117,6 @@ class _MonthlyAttendanceScreenState extends State { initialDate: formattedDate, firstDate: DateTime(searchYear - 2), lastDate: DateTime.now(), - confirmText: Text(LocaleKeys.confirm.tr()), - cancelText: Text(LocaleKeys.cancel.tr()), ).then((selectedDate) { if (selectedDate != null) { searchMonth = getMonth(selectedDate.month); diff --git a/lib/ui/chat/chat_home_screen.dart b/lib/ui/chat/chat_home_screen.dart index 04d7c2e..2f392f3 100644 --- a/lib/ui/chat/chat_home_screen.dart +++ b/lib/ui/chat/chat_home_screen.dart @@ -214,6 +214,8 @@ class _ChatHomeScreenState extends State { }, ), floatingActionButton: FloatingActionButton( + backgroundColor: Colors.transparent, + elevation: 0, child: Container( width: 60, height: 60, diff --git a/lib/ui/login/verify_last_login_screen.dart b/lib/ui/login/verify_last_login_screen.dart index 8604baf..9970206 100644 --- a/lib/ui/login/verify_last_login_screen.dart +++ b/lib/ui/login/verify_last_login_screen.dart @@ -4,8 +4,9 @@ import 'package:easy_localization/src/public_ext.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_svg/svg.dart'; -import 'package:local_auth/auth_strings.dart'; import 'package:local_auth/local_auth.dart'; +import 'package:local_auth_android/local_auth_android.dart'; +import 'package:local_auth_darwin/local_auth_darwin.dart'; import 'package:mohem_flutter_app/api/login_api_client.dart'; import 'package:mohem_flutter_app/app_state/app_state.dart'; import 'package:mohem_flutter_app/classes/colors.dart'; @@ -69,7 +70,7 @@ class _VerifyLastLoginScreenState extends State { automaticallyImplyLeading: false, title: (mobileLoginInfoListModel?.businessCardPrivilege ?? false) ? LocaleKeys.viewBusinessCard.tr().toText12(color: MyColors.textMixColor, isUnderLine: true).onPress(() { - showMDialog(context, child: BusinessCardDialog()); + showMDialog(context, child: const BusinessCardDialog()); }) : Container(), actions: [ @@ -93,7 +94,7 @@ class _VerifyLastLoginScreenState extends State { crossAxisAlignment: CrossAxisAlignment.start, children: [ LocaleKeys.welcomeBack.tr().toText12(), - mobileLoginInfoListModel!.employeeName!.toText24(isBold: true), + mobileLoginInfoListModel?.employeeName?.toText24(isBold: true) ?? const SizedBox.shrink(), 10.height, LocaleKeys.wouldYouLikeToLoginWithCurrentUsername.tr().toText16(), Container( @@ -126,7 +127,7 @@ class _VerifyLastLoginScreenState extends State { children: [ LocaleKeys.verificationType.tr().toText10(color: MyColors.grey57Color), getVerificationType(mobileLoginInfoListModel!.loginType!).toText12(), - Expanded(child: SizedBox()), + const Expanded(child: SizedBox()), DateUtil.formatDateToTime(DateUtil.convertStringToDate(mobileLoginInfoListModel!.editedOn!)).toText12(), ], ) @@ -225,7 +226,10 @@ class _VerifyLastLoginScreenState extends State { const IOSAuthMessages(cancelButton: 'cancel', goToSettingsButton: 'settings', goToSettingsDescription: 'Please set up your Touch ID.', lockOut: 'Please reenable your Touch ID'); bool authenticated = false; try { - authenticated = await auth.authenticate(localizedReason: 'Scan your fingerprint to authenticate', useErrorDialogs: true, stickyAuth: true, biometricOnly: true, iOSAuthStrings: iosStrings); + authenticated = await auth.authenticate(localizedReason: 'Scan your fingerprint to authenticate', + options: const AuthenticationOptions( + useErrorDialogs: true, stickyAuth: true, biometricOnly: true, + ),authMessages: [iosStrings,const AndroidAuthMessages(),]); } on PlatformException catch (e) { print(e); Utils.hideLoading(context); @@ -235,7 +239,8 @@ class _VerifyLastLoginScreenState extends State { } Widget _loginOptionButton(String _title, String _icon, int _flag, int? _loginIndex) { - bool isDisable = ((_flag == 3 && !checkBiometricIsAvailable(BiometricType.face)) || (_flag == 4 && !checkBiometricIsAvailable(BiometricType.fingerprint))); + bool isDisable = (_flag == 3 && !checkBiometricIsAvailable(BiometricType.face) || + _flag == 4 && !checkBiometricIsAvailable(BiometricType.fingerprint) && _flag == 4 && !checkBiometricIsAvailable(BiometricType.strong)); return InkWell( onTap: isDisable ? null diff --git a/lib/ui/login/verify_login_screen.dart b/lib/ui/login/verify_login_screen.dart index ac3c454..ea8439e 100644 --- a/lib/ui/login/verify_login_screen.dart +++ b/lib/ui/login/verify_login_screen.dart @@ -4,8 +4,9 @@ import 'package:easy_localization/src/public_ext.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_svg/svg.dart'; -import 'package:local_auth/auth_strings.dart'; import 'package:local_auth/local_auth.dart'; +import 'package:local_auth_darwin/local_auth_darwin.dart'; +import 'package:local_auth_android/local_auth_android.dart'; import 'package:mohem_flutter_app/api/login_api_client.dart'; import 'package:mohem_flutter_app/app_state/app_state.dart'; import 'package:mohem_flutter_app/classes/colors.dart'; @@ -90,6 +91,7 @@ class _VerifyLoginScreenState extends State { Future _getAvailableBiometrics() async { try { _availableBioMetricType = await auth.getAvailableBiometrics(); + print("the available biometric are ${_availableBioMetricType.length}"); } on PlatformException catch (e) { // AppToast.showErrorToast(message: e.message); print(e); @@ -516,7 +518,14 @@ class _VerifyLoginScreenState extends State { const IOSAuthMessages(cancelButton: 'cancel', goToSettingsButton: 'settings', goToSettingsDescription: 'Please set up your Touch ID.', lockOut: 'Please reenable your Touch ID'); bool authenticated = false; try { - authenticated = await auth.authenticate(localizedReason: 'Scan your fingerprint to authenticate', useErrorDialogs: true, stickyAuth: true, biometricOnly: true, iOSAuthStrings: iosStrings); + authenticated = await auth.authenticate( + localizedReason: 'Scan your fingerprint to authenticate', + options: const AuthenticationOptions( + useErrorDialogs: true, + stickyAuth: true, + biometricOnly: true, + ), + authMessages: [iosStrings, const AndroidAuthMessages()]); } on PlatformException catch (e) { print(e); Utils.hideLoading(context); @@ -526,7 +535,25 @@ class _VerifyLoginScreenState extends State { } Widget _loginOptionButton(String _title, String _icon, int _flag, int? _loginIndex) { - bool isDisable = ((_flag == 3 && !checkBiometricIsAvailable(BiometricType.face)) || (_flag == 4 && !checkBiometricIsAvailable(BiometricType.fingerprint))); + bool isDisable = (_flag == 3 && !checkBiometricIsAvailable(BiometricType.face) || + _flag == 4 && !checkBiometricIsAvailable(BiometricType.fingerprint) && _flag == 4 && !checkBiometricIsAvailable(BiometricType.strong)); + // bool isDisable = false; + // switch (_flag) { + // case 3: + // isDisable = !(checkBiometricIsAvailable(BiometricType.face) || + // checkBiometricIsAvailable(BiometricType.weak)); + // break; + // case 4: + // isDisable = !(checkBiometricIsAvailable(BiometricType.fingerprint) || + // checkBiometricIsAvailable(BiometricType.strong)); + // break; + // } + // // bool isDisable = ((_flag == 3 && + // // (!checkBiometricIsAvailable(BiometricType.face) || + // // !checkBiometricIsAvailable(BiometricType.weak))) || + // // (_flag == 4 && + // // (!checkBiometricIsAvailable(BiometricType.fingerprint) || + // // !checkBiometricIsAvailable(BiometricType.strong)))); return InkWell( onTap: isDisable ? null @@ -596,8 +623,13 @@ class _VerifyLoginScreenState extends State { bool checkBiometricIsAvailable(BiometricType biometricType) { bool isAvailable = false; + print("the given biometric is $biometricType"); + for (int i = 0; i < _availableBioMetricType.length; i++) { + print("the current biometric is ${_availableBioMetricType[i]}"); + if (biometricType == _availableBioMetricType[i]) { + print("the data is available $biometricType"); isAvailable = true; break; } diff --git a/lib/ui/my_team/view_attendance.dart b/lib/ui/my_team/view_attendance.dart index a45f35c..96e673d 100644 --- a/lib/ui/my_team/view_attendance.dart +++ b/lib/ui/my_team/view_attendance.dart @@ -15,7 +15,7 @@ import 'package:mohem_flutter_app/models/get_time_card_summary_list_model.dart'; import 'package:mohem_flutter_app/models/my_team/get_employee_subordinates_list.dart'; import 'package:mohem_flutter_app/widgets/app_bar_widget.dart'; import 'package:mohem_flutter_app/widgets/circular_step_progress_bar.dart'; -import 'package:month_picker_dialog_2/month_picker_dialog_2.dart'; +import 'package:month_picker_dialog/month_picker_dialog.dart'; import 'package:pie_chart/pie_chart.dart'; import 'package:syncfusion_flutter_calendar/calendar.dart'; @@ -169,8 +169,6 @@ class _ViewAttendanceState extends State { initialDate: formattedDate, firstDate: DateTime(searchYear - 2), lastDate: DateTime.now(), - confirmText: Text(LocaleKeys.confirm.tr()), - cancelText: Text(LocaleKeys.cancel.tr()), ).then( (selectedDate) { if (selectedDate != null) { diff --git a/lib/ui/profile/delete_family_member.dart b/lib/ui/profile/delete_family_member.dart index 3b73512..f478b53 100644 --- a/lib/ui/profile/delete_family_member.dart +++ b/lib/ui/profile/delete_family_member.dart @@ -115,8 +115,8 @@ class _DeleteFamilyMemberState extends State { padding: EdgeInsets.only(left: 50, right: 50), child: TextButton( style: TextButton.styleFrom( - primary: MyColors.white, - onSurface: MyColors.white, + foregroundColor: MyColors.white, + surfaceTintColor: MyColors.white, backgroundColor: MyColors.gradiantEndColor, ), onPressed: () { diff --git a/lib/ui/screens/offers_and_discounts/offers_and_discounts_details.dart b/lib/ui/screens/offers_and_discounts/offers_and_discounts_details.dart index b4cb242..30a9fa2 100644 --- a/lib/ui/screens/offers_and_discounts/offers_and_discounts_details.dart +++ b/lib/ui/screens/offers_and_discounts/offers_and_discounts_details.dart @@ -76,7 +76,7 @@ class _OffersAndDiscountsDetailsState extends State { : getOffersList[0].titleEn!.toText22(isBold: true, color: const Color(0xff2B353E)).center, Html( data: AppState().isArabic(context) ? getOffersList[0].descriptionAr! : getOffersList[0].descriptionEn ?? "", - onLinkTap: (String? url, RenderContext context, Map attributes, _) { + onLinkTap: (String? url, Map attributes, _) { launchUrl(Uri.parse(url!)); }, ), diff --git a/lib/ui/work_list/item_history_screen.dart b/lib/ui/work_list/item_history_screen.dart index 71cea08..92516e8 100644 --- a/lib/ui/work_list/item_history_screen.dart +++ b/lib/ui/work_list/item_history_screen.dart @@ -188,7 +188,7 @@ class _ItemHistoryScreenState extends State { LineChartData drawLineChart(List spots, List reversedList) { return LineChartData( - lineTouchData: LineTouchData(enabled: true, touchTooltipData: LineTouchTooltipData(tooltipBgColor: Colors.grey[300])), + lineTouchData: LineTouchData(enabled: true, touchTooltipData: LineTouchTooltipData()), gridData: FlGridData( show: true, drawHorizontalLine: true, @@ -211,7 +211,7 @@ class _ItemHistoryScreenState extends State { interval: 1, getTitlesWidget: (double value, TitleMeta meta) { return SideTitleWidget( - axisSide: meta.axisSide, + meta: meta, child: Text(reversedList[int.parse(meta.formattedValue)].cREATIONDATE!, style: TextStyle(fontSize: 10)), ); })), @@ -222,7 +222,7 @@ class _ItemHistoryScreenState extends State { interval: 1, getTitlesWidget: (double value, TitleMeta meta) { return SideTitleWidget( - axisSide: meta.axisSide, + meta: meta, child: Text(meta.formattedValue, style: TextStyle(fontSize: 10)), ); })), @@ -233,7 +233,7 @@ class _ItemHistoryScreenState extends State { reservedSize: 15, getTitlesWidget: (double value, TitleMeta meta) { return SideTitleWidget( - axisSide: meta.axisSide, + meta: meta, child: Text("", style: TextStyle(fontSize: 10)), ); })), diff --git a/lib/widgets/app_bar_widget.dart b/lib/widgets/app_bar_widget.dart index 6f9898e..744b7eb 100644 --- a/lib/widgets/app_bar_widget.dart +++ b/lib/widgets/app_bar_widget.dart @@ -15,6 +15,8 @@ AppBar AppBarWidget(BuildContext context, void Function()? onBackTapped}) { return AppBar( leadingWidth: 0, + + automaticallyImplyLeading: false, title: Row( children: [ GestureDetector( diff --git a/lib/widgets/image_picker.dart b/lib/widgets/image_picker.dart index 943d68e..f808d6e 100644 --- a/lib/widgets/image_picker.dart +++ b/lib/widgets/image_picker.dart @@ -159,7 +159,7 @@ class _BottomSheet extends StatelessWidget { Widget build(BuildContext context) { return Container( padding: const EdgeInsets.symmetric(vertical: 12.0), - decoration: BoxDecoration(color: Theme.of(context).backgroundColor, borderRadius: const BorderRadius.only(topLeft: Radius.circular(16.0), topRight: Radius.circular(16.0))), + decoration: BoxDecoration(color: Theme.of(context).scaffoldBackgroundColor, borderRadius: const BorderRadius.only(topLeft: Radius.circular(16.0), topRight: Radius.circular(16.0))), child: SafeArea( top: false, child: Column( diff --git a/lib/widgets/nfc/nfc_reader_sheet.dart b/lib/widgets/nfc/nfc_reader_sheet.dart index b7b97a7..0ecc5e8 100644 --- a/lib/widgets/nfc/nfc_reader_sheet.dart +++ b/lib/widgets/nfc/nfc_reader_sheet.dart @@ -78,9 +78,11 @@ class _NfcLayoutState extends State { } Widget scanNfc() { - return Container( - key: ValueKey(1), + return SizedBox( + width: MediaQuery.sizeOf(context).width, child: Column( + key: ValueKey(1), + mainAxisSize: MainAxisSize.min, children: [ SizedBox( @@ -138,8 +140,9 @@ class _NfcLayoutState extends State { Widget doneNfc() { return Container( - key: ValueKey(2), + width: MediaQuery.sizeOf(context).width, child: Column( + key: ValueKey(2), mainAxisSize: MainAxisSize.min, children: [ SizedBox( diff --git a/pubspec.yaml b/pubspec.yaml index 9740e7d..08a6251 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -20,7 +20,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev version: 3.7.98+3 environment: - sdk: ">=2.16.0 <3.0.0" + sdk: ">=2.16.0 <3.7.0" # Dependencies specify other packages that your package needs in order to work. # To automatically upgrade your package dependencies to the latest versions @@ -40,13 +40,13 @@ dependencies: injector: ^2.0.0 provider: ^6.0.1 easy_localization: ^3.0.0 - http: ^0.13.4 + http: ^1.3.0 permission_handler: ^10.2.0 flutter_svg: any sizer: ^2.0.15 - local_auth: ^1.1.9 + local_auth: ^2.3.0 fluttertoast: ^8.0.8 - syncfusion_flutter_calendar: ^19.4.48 + syncfusion_flutter_calendar: ^28.2.4 # flutter_calendar_carousel: ^2.1.0 pie_chart: ^5.1.0 shared_preferences: ^2.0.12 @@ -60,12 +60,12 @@ dependencies: # android_id: ^0.1.3+1 platform_device_id: ^1.0.1 image_picker: ^0.8.5+3 - file_picker: 5.2.5 + file_picker: ^8.3.1 geolocator: ^9.0.2 - month_year_picker: ^0.2.0+1 - month_picker_dialog_2: ^0.5.5 + month_year_picker: ^0.4.0+1 + month_picker_dialog: ^6.0.3 # open_file: ^3.2.1 - open_filex: ^4.4.0 + open_filex: ^4.6.0 wifi_iot: ^0.3.19+1 flutter_html: ^3.0.0-alpha.6 # flutter_barcode_scanner: ^2.0.0 @@ -76,7 +76,7 @@ dependencies: flutter_rating_bar: ^4.0.1 auto_size_text: ^3.0.0 pull_to_refresh: ^2.0.0 - fl_chart: ^0.62.0 + fl_chart: ^0.70.2 # lottie json animations lottie: any # Marathon Card Swipe @@ -93,7 +93,7 @@ dependencies: swipe_to: ^1.0.2 flutter_webrtc: ^0.9.17 camera: ^0.10.3 - flutter_local_notifications: ^10.0.0 + flutter_local_notifications: ^18.0.1 #firebase_analytics: any #Chat Voice Message Recoding & Play @@ -116,7 +116,7 @@ dependencies: firebase_crashlytics: ^2.9.0 #Items for sale Image Carousel Slider - carousel_slider: ^4.2.1 + carousel_slider: ^5.0.0 #Huawei Specified # store_checker: ^1.1.0