From 01c3af5280d38cc5a7690f26e70d7c0f878c051a Mon Sep 17 00:00:00 2001 From: Sikander Saleem Date: Mon, 20 Dec 2021 17:11:35 +0300 Subject: [PATCH 1/7] confirm login screen added & structure improvement. --- assets/images/bn_map.png | Bin 43970 -> 0 bytes assets/images/verify_face.svg | 9 + assets/images/verify_sms.svg | 11 + assets/images/verify_thumb.svg | 9 + assets/images/verify_whatsapp.svg | 12 + assets/langs/ar-SA.json | 12 + assets/langs/en-US.json | 12 + .../api/api_client.dart | 2 +- .../api/tangheem_user_api_client.dart | 8 +- .../app_state/app_state.dart | 4 +- .../classes/colors.dart | 0 .../classes/consts.dart | 0 .../classes/utils.dart | 2 +- lib/config/app_provider.dart | 4 +- lib/config/background_loader.dart | 34 - lib/config/constants.dart | 8 - lib/config/dependencies.dart | 36 - lib/config/routes.dart | 7 +- lib/dialogs/otp_dialog.dart | 235 ++++++ .../exceptions/api_exception.dart | 2 +- .../extensions/int_extensions.dart | 0 lib/extensions/string_extensions.dart | 72 ++ lib/extensions/widget_extensions.dart | 11 + lib/generated/codegen_loader.g.dart | 24 + lib/main.dart | 3 +- lib/models/account.dart | 43 -- lib/models/config_model.dart | 12 - .../models/content_info_model.dart | 0 .../models/member_model.dart | 0 lib/models/parent_list.dart | 26 - lib/models/response_models.dart | 34 - .../models/surah_model.dart | 0 lib/models/user.dart | 9 - lib/pages/a.dart | 0 lib/pages/user/splash_page.dart | 48 -- lib/provider/counter.dart | 20 - lib/repo/account_repository.dart | 49 -- lib/services/backend_service.dart | 127 ---- lib/services/firebase_service.dart | 180 ----- lib/services/http_service.dart | 34 - lib/services/media_service.dart | 26 - lib/services/network_service.dart | 25 - lib/services/secure_storage.dart | 33 - lib/services/shared_preferences.dart | 119 --- .../extensions/string_extensions.dart | 46 -- .../extensions/widget_extensions.dart | 9 - .../widgets/otp_widget.dart | 373 ---------- lib/theme/app_theme.dart | 4 +- .../country_selection_bottom_sheet.dart | 0 .../ui/common_appbar.dart | 0 lib/ui/dashboard.dart | 27 + .../ui/dialogs/change_password_dialog.dart | 0 .../ui/dialogs/general_dialog.dart | 0 .../ui/dialogs/loading_dialog.dart | 0 .../ui/dialogs/otp_dialog.dart | 0 lib/{pages => ui}/login/login_screen.dart | 14 +- lib/ui/login/verify_login_screen.dart | 700 ++++++++++++++++++ .../ui/misc/no_data_ui.dart | 2 +- .../ui/screens/tangheem_detail_screen.dart | 0 lib/utils/AppPermissionHandler.dart | 36 - lib/utils/dialogs.dart | 35 - lib/utils/navigator.dart | 9 - lib/utils/utils.dart | 311 -------- lib/widgets/app_bar.dart | 28 - lib/widgets/blurry_container.dart | 62 -- lib/widgets/button/show_circular_button.dart | 23 - lib/widgets/button/show_image_button.dart | 43 -- lib/widgets/dialog/dialogs.dart | 16 - lib/widgets/dialog/message_dialog.dart | 38 - lib/widgets/dialog/otp_dialog.dart | 74 -- lib/widgets/dragable_sheet.dart | 26 - lib/widgets/dropdown/dropdow_field.dart | 78 -- lib/widgets/dropdown/dropdown_text.dart | 33 - lib/widgets/extensions/extensions_widget.dart | 235 ------ lib/widgets/gradient_app_bar.dart | 63 -- lib/widgets/images/circular_image.dart | 30 - .../widgets/input_widget.dart | 2 +- lib/widgets/otp_widget.dart | 373 ++++++++++ lib/widgets/show_card_buttton.dart | 32 - lib/widgets/show_fill_button.dart | 41 - lib/widgets/txt.dart | 170 ----- lib/widgets/txt_field.dart | 155 ---- lib/widgets/user_image.dart | 26 - pubspec.lock | 21 + pubspec.yaml | 2 + 85 files changed, 1560 insertions(+), 2879 deletions(-) delete mode 100644 assets/images/bn_map.png create mode 100644 assets/images/verify_face.svg create mode 100644 assets/images/verify_sms.svg create mode 100644 assets/images/verify_thumb.svg create mode 100644 assets/images/verify_whatsapp.svg rename lib/{sikander_later_will_remove_to_parent_directory => }/api/api_client.dart (98%) rename lib/{sikander_later_will_remove_to_parent_directory => }/api/tangheem_user_api_client.dart (70%) rename lib/{sikander_later_will_remove_to_parent_directory => }/app_state/app_state.dart (69%) rename lib/{sikander_later_will_remove_to_parent_directory => }/classes/colors.dart (100%) rename lib/{sikander_later_will_remove_to_parent_directory => }/classes/consts.dart (100%) rename lib/{sikander_later_will_remove_to_parent_directory => }/classes/utils.dart (94%) delete mode 100644 lib/config/background_loader.dart delete mode 100644 lib/config/constants.dart delete mode 100644 lib/config/dependencies.dart create mode 100644 lib/dialogs/otp_dialog.dart rename lib/{sikander_later_will_remove_to_parent_directory => }/exceptions/api_exception.dart (90%) rename lib/{sikander_later_will_remove_to_parent_directory => }/extensions/int_extensions.dart (100%) create mode 100644 lib/extensions/string_extensions.dart create mode 100644 lib/extensions/widget_extensions.dart delete mode 100644 lib/models/account.dart delete mode 100644 lib/models/config_model.dart rename lib/{sikander_later_will_remove_to_parent_directory => }/models/content_info_model.dart (100%) rename lib/{sikander_later_will_remove_to_parent_directory => }/models/member_model.dart (100%) delete mode 100644 lib/models/parent_list.dart delete mode 100644 lib/models/response_models.dart rename lib/{sikander_later_will_remove_to_parent_directory => }/models/surah_model.dart (100%) delete mode 100644 lib/models/user.dart delete mode 100644 lib/pages/a.dart delete mode 100644 lib/pages/user/splash_page.dart delete mode 100644 lib/provider/counter.dart delete mode 100644 lib/repo/account_repository.dart delete mode 100644 lib/services/backend_service.dart delete mode 100644 lib/services/firebase_service.dart delete mode 100644 lib/services/http_service.dart delete mode 100644 lib/services/media_service.dart delete mode 100644 lib/services/network_service.dart delete mode 100644 lib/services/secure_storage.dart delete mode 100644 lib/services/shared_preferences.dart delete mode 100644 lib/sikander_later_will_remove_to_parent_directory/extensions/string_extensions.dart delete mode 100644 lib/sikander_later_will_remove_to_parent_directory/extensions/widget_extensions.dart delete mode 100644 lib/sikander_later_will_remove_to_parent_directory/widgets/otp_widget.dart rename lib/{sikander_later_will_remove_to_parent_directory => }/ui/bottom_sheets/country_selection_bottom_sheet.dart (100%) rename lib/{sikander_later_will_remove_to_parent_directory => }/ui/common_appbar.dart (100%) create mode 100644 lib/ui/dashboard.dart rename lib/{sikander_later_will_remove_to_parent_directory => }/ui/dialogs/change_password_dialog.dart (100%) rename lib/{sikander_later_will_remove_to_parent_directory => }/ui/dialogs/general_dialog.dart (100%) rename lib/{sikander_later_will_remove_to_parent_directory => }/ui/dialogs/loading_dialog.dart (100%) rename lib/{sikander_later_will_remove_to_parent_directory => }/ui/dialogs/otp_dialog.dart (100%) rename lib/{pages => ui}/login/login_screen.dart (88%) create mode 100644 lib/ui/login/verify_login_screen.dart rename lib/{sikander_later_will_remove_to_parent_directory => }/ui/misc/no_data_ui.dart (87%) rename lib/{sikander_later_will_remove_to_parent_directory => }/ui/screens/tangheem_detail_screen.dart (100%) delete mode 100644 lib/utils/AppPermissionHandler.dart delete mode 100644 lib/utils/dialogs.dart delete mode 100644 lib/utils/navigator.dart delete mode 100644 lib/utils/utils.dart delete mode 100644 lib/widgets/app_bar.dart delete mode 100644 lib/widgets/blurry_container.dart delete mode 100644 lib/widgets/button/show_circular_button.dart delete mode 100644 lib/widgets/button/show_image_button.dart delete mode 100644 lib/widgets/dialog/dialogs.dart delete mode 100644 lib/widgets/dialog/message_dialog.dart delete mode 100644 lib/widgets/dialog/otp_dialog.dart delete mode 100644 lib/widgets/dragable_sheet.dart delete mode 100644 lib/widgets/dropdown/dropdow_field.dart delete mode 100644 lib/widgets/dropdown/dropdown_text.dart delete mode 100644 lib/widgets/extensions/extensions_widget.dart delete mode 100644 lib/widgets/gradient_app_bar.dart delete mode 100644 lib/widgets/images/circular_image.dart rename lib/{sikander_later_will_remove_to_parent_directory => }/widgets/input_widget.dart (97%) create mode 100644 lib/widgets/otp_widget.dart delete mode 100644 lib/widgets/show_card_buttton.dart delete mode 100644 lib/widgets/show_fill_button.dart delete mode 100644 lib/widgets/txt.dart delete mode 100644 lib/widgets/txt_field.dart delete mode 100644 lib/widgets/user_image.dart diff --git a/assets/images/bn_map.png b/assets/images/bn_map.png deleted file mode 100644 index b04b5aa34b49f37ab94d59b80b0866a9b5991d29..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 43970 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 diff --git a/assets/images/verify_face.svg b/assets/images/verify_face.svg new file mode 100644 index 0000000..e50d1a6 --- /dev/null +++ b/assets/images/verify_face.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/assets/images/verify_sms.svg b/assets/images/verify_sms.svg new file mode 100644 index 0000000..ae5fa9f --- /dev/null +++ b/assets/images/verify_sms.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/assets/images/verify_thumb.svg b/assets/images/verify_thumb.svg new file mode 100644 index 0000000..e626baf --- /dev/null +++ b/assets/images/verify_thumb.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/assets/images/verify_whatsapp.svg b/assets/images/verify_whatsapp.svg new file mode 100644 index 0000000..09ac85c --- /dev/null +++ b/assets/images/verify_whatsapp.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/assets/langs/ar-SA.json b/assets/langs/ar-SA.json index 55e73b0..bfa680d 100644 --- a/assets/langs/ar-SA.json +++ b/assets/langs/ar-SA.json @@ -6,6 +6,18 @@ "pleaseEnterLoginDetails": "Please enter the detail below to login", "username": "Username", "password": "Password", + "welcomeBack": "Welcome back", + "wouldYouLikeToLoginWithCurrentUsername": "Would you like to login with current Username?", + "lastLoginDetails": "Last Login Details:", + "verificationType": "Verification Type:", + "pleaseVerify": "Please Verify", + "verifyThroughFace": "Verify Through Face", + "verifyThroughFingerprint": "Verify Through Fingerprint", + "verifyThroughSMS": "Verify Through SMS", + "verifyThroughWhatsapp": "Verify Through Whatsapp", + "useAnotherAccount": "Use Another Account", + "pleaseEnterTheVerificationCodeSentTo": "Please enter the verification code sent to ", + "theVerificationCodeWillExpireIn": "The verification code will expire in ", "title": "Hello", "forgotPassword": "Forgot Password", "msg": "Hello {} in the {} world ", diff --git a/assets/langs/en-US.json b/assets/langs/en-US.json index 55e73b0..bfa680d 100644 --- a/assets/langs/en-US.json +++ b/assets/langs/en-US.json @@ -6,6 +6,18 @@ "pleaseEnterLoginDetails": "Please enter the detail below to login", "username": "Username", "password": "Password", + "welcomeBack": "Welcome back", + "wouldYouLikeToLoginWithCurrentUsername": "Would you like to login with current Username?", + "lastLoginDetails": "Last Login Details:", + "verificationType": "Verification Type:", + "pleaseVerify": "Please Verify", + "verifyThroughFace": "Verify Through Face", + "verifyThroughFingerprint": "Verify Through Fingerprint", + "verifyThroughSMS": "Verify Through SMS", + "verifyThroughWhatsapp": "Verify Through Whatsapp", + "useAnotherAccount": "Use Another Account", + "pleaseEnterTheVerificationCodeSentTo": "Please enter the verification code sent to ", + "theVerificationCodeWillExpireIn": "The verification code will expire in ", "title": "Hello", "forgotPassword": "Forgot Password", "msg": "Hello {} in the {} world ", diff --git a/lib/sikander_later_will_remove_to_parent_directory/api/api_client.dart b/lib/api/api_client.dart similarity index 98% rename from lib/sikander_later_will_remove_to_parent_directory/api/api_client.dart rename to lib/api/api_client.dart index 66828ee..afba61e 100644 --- a/lib/sikander_later_will_remove_to_parent_directory/api/api_client.dart +++ b/lib/api/api_client.dart @@ -5,7 +5,7 @@ import 'dart:io'; import 'package:flutter/foundation.dart'; import 'package:http/http.dart'; import 'package:http/io_client.dart'; -import 'package:mohem_flutter_app/sikander_later_will_remove_to_parent_directory/exceptions/api_exception.dart'; +import 'package:mohem_flutter_app/exceptions/api_exception.dart'; typedef FactoryConstructor = U Function(dynamic); diff --git a/lib/sikander_later_will_remove_to_parent_directory/api/tangheem_user_api_client.dart b/lib/api/tangheem_user_api_client.dart similarity index 70% rename from lib/sikander_later_will_remove_to_parent_directory/api/tangheem_user_api_client.dart rename to lib/api/tangheem_user_api_client.dart index 429902f..b849141 100644 --- a/lib/sikander_later_will_remove_to_parent_directory/api/tangheem_user_api_client.dart +++ b/lib/api/tangheem_user_api_client.dart @@ -1,9 +1,9 @@ import 'dart:async'; -import 'package:mohem_flutter_app/sikander_later_will_remove_to_parent_directory/classes/consts.dart'; -import 'package:mohem_flutter_app/sikander_later_will_remove_to_parent_directory/models/content_info_model.dart'; -import 'package:mohem_flutter_app/sikander_later_will_remove_to_parent_directory/models/member_model.dart'; -import 'package:mohem_flutter_app/sikander_later_will_remove_to_parent_directory/models/surah_model.dart'; +import 'package:mohem_flutter_app/classes/consts.dart'; +import 'package:mohem_flutter_app/models/content_info_model.dart'; +import 'package:mohem_flutter_app/models/member_model.dart'; +import 'package:mohem_flutter_app/models/surah_model.dart'; import 'api_client.dart'; diff --git a/lib/sikander_later_will_remove_to_parent_directory/app_state/app_state.dart b/lib/app_state/app_state.dart similarity index 69% rename from lib/sikander_later_will_remove_to_parent_directory/app_state/app_state.dart rename to lib/app_state/app_state.dart index bbc6403..9303802 100644 --- a/lib/sikander_later_will_remove_to_parent_directory/app_state/app_state.dart +++ b/lib/app_state/app_state.dart @@ -1,5 +1,5 @@ -import 'package:mohem_flutter_app/sikander_later_will_remove_to_parent_directory/models/content_info_model.dart'; -import 'package:mohem_flutter_app/sikander_later_will_remove_to_parent_directory/models/surah_model.dart'; +import 'package:mohem_flutter_app/models/content_info_model.dart'; +import 'package:mohem_flutter_app/models/surah_model.dart'; class AppState { static final AppState _instance = AppState._internal(); diff --git a/lib/sikander_later_will_remove_to_parent_directory/classes/colors.dart b/lib/classes/colors.dart similarity index 100% rename from lib/sikander_later_will_remove_to_parent_directory/classes/colors.dart rename to lib/classes/colors.dart diff --git a/lib/sikander_later_will_remove_to_parent_directory/classes/consts.dart b/lib/classes/consts.dart similarity index 100% rename from lib/sikander_later_will_remove_to_parent_directory/classes/consts.dart rename to lib/classes/consts.dart diff --git a/lib/sikander_later_will_remove_to_parent_directory/classes/utils.dart b/lib/classes/utils.dart similarity index 94% rename from lib/sikander_later_will_remove_to_parent_directory/classes/utils.dart rename to lib/classes/utils.dart index 3aafdb1..4d26ed6 100644 --- a/lib/sikander_later_will_remove_to_parent_directory/classes/utils.dart +++ b/lib/classes/utils.dart @@ -1,7 +1,7 @@ import 'package:flutter/material.dart'; // import 'package:fluttertoast/fluttertoast.dart'; -import 'package:mohem_flutter_app/sikander_later_will_remove_to_parent_directory/exceptions/api_exception.dart'; +import 'package:mohem_flutter_app/exceptions/api_exception.dart'; class Utils { static bool _isLoadingVisible = false; diff --git a/lib/config/app_provider.dart b/lib/config/app_provider.dart index 6f11d24..9ccf065 100644 --- a/lib/config/app_provider.dart +++ b/lib/config/app_provider.dart @@ -1,4 +1,3 @@ -import 'package:mohem_flutter_app/provider/counter.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; @@ -9,9 +8,10 @@ class AppProvider extends StatelessWidget { @override Widget build(BuildContext context) { + return child; return MultiProvider( providers: [ - ChangeNotifierProvider(create: (_) => Counter()), + // ChangeNotifierProvider(create: (_) => Counter()), ], child: child, ); diff --git a/lib/config/background_loader.dart b/lib/config/background_loader.dart deleted file mode 100644 index 0683157..0000000 --- a/lib/config/background_loader.dart +++ /dev/null @@ -1,34 +0,0 @@ -//class which loads components "in the background", i.e. ui does not depend on it - -import 'package:mohem_flutter_app/services/shared_preferences.dart'; -import 'package:injector/injector.dart'; -//import 'package:revocheckapp/services/firebase_service.dart'; - - -class BackgroundLoader { - Future loadBackgroundData() async { - //init notification setting - try { - /* - final isPromotionNotificationEnabled = await Injector.appInstance - .getDependency() - .promotionNotificationsEnabled; - if (isPromotionNotificationEnabled == null) { - await Injector.appInstance - .getDependency() - .setPromotionNotificationEnabled(true); - Injector.appInstance - .getDependency() - .subscribeForPromotions(); - } */ - } catch (_) { - //something wend wrong, set it to true - await Injector.appInstance - .getDependency() - .setPromotionNotificationEnabled(true); - /*Injector.appInstance - .getDependency() - .subscribeForPromotions();*/ - } - } -} diff --git a/lib/config/constants.dart b/lib/config/constants.dart deleted file mode 100644 index 87c2c46..0000000 --- a/lib/config/constants.dart +++ /dev/null @@ -1,8 +0,0 @@ -enum YesOrNo { - no, - yes, -} - -const String icons = "assets/icons/"; -const String categorySvgIcons = "assets/category/svg/"; -const String svgIcons = "assets/svg/"; diff --git a/lib/config/dependencies.dart b/lib/config/dependencies.dart deleted file mode 100644 index 937ebc6..0000000 --- a/lib/config/dependencies.dart +++ /dev/null @@ -1,36 +0,0 @@ -// import 'package:firebase_crashlytics/firebase_crashlytics.dart'; -// import 'package:flutter/material.dart'; - -import 'package:mohem_flutter_app/config/background_loader.dart'; -import 'package:mohem_flutter_app/repo/account_repository.dart'; -import 'package:injector/injector.dart'; - -class AppDependencies { - static void addDependencies() { - Injector injector = Injector.appInstance; - - //add dependencies as needed - injector.registerSingleton(() => AcRepository()); - - // injector.registerSingleton((injector) => AcRepository()); - - _addCrashlytics(); - _loadBackgroundTasksNonBlocking(); - } - - static void _addCrashlytics() { - // Set `enableInDevMode` to true to see reports while in debug mode - // This is only to be used for confirming that reports are being - // submitted as expected. It is not intended to be used for everyday - // development. - //Crashlytics.instance.enableInDevMode = true; - - // Pass all uncaught errors from the framework to Crashlytics. - // FlutterError.onError = Crashlytics.instance.recordFlutterError; - } - - static void _loadBackgroundTasksNonBlocking() { - final backgroundLoader = BackgroundLoader(); - backgroundLoader.loadBackgroundData(); - } -} diff --git a/lib/config/routes.dart b/lib/config/routes.dart index 34505d0..d60f2b8 100644 --- a/lib/config/routes.dart +++ b/lib/config/routes.dart @@ -1,11 +1,14 @@ import 'package:flutter/material.dart'; -import 'package:mohem_flutter_app/pages/login/login_screen.dart'; +import 'package:mohem_flutter_app/ui/dashboard.dart'; +import 'package:mohem_flutter_app/ui/login/login_screen.dart'; +import 'package:mohem_flutter_app/ui/login/verify_login_screen.dart'; class AppRoutes { static const String splash = "/splash"; static const String registerSelection = "/registerSelection"; static const String loginVerifyAccount = "/loginVerifyAccount"; static const String login = "/login"; + static const String verifyLogin = "/verifyLogin"; static const String forgetPassword = "/forgetPassword"; static const String loginVerification = "/loginVerification"; static const String dashboard = "/dashboard"; @@ -13,5 +16,7 @@ class AppRoutes { static final Map routes = { login: (context) => LoginScreen(), + verifyLogin: (context) => VerifyLoginScreen(), + dashboard: (context) => Dashboard(), }; } diff --git a/lib/dialogs/otp_dialog.dart b/lib/dialogs/otp_dialog.dart new file mode 100644 index 0000000..3d625bf --- /dev/null +++ b/lib/dialogs/otp_dialog.dart @@ -0,0 +1,235 @@ +import 'dart:async'; + +import 'package:easy_localization/src/public_ext.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_svg/svg.dart'; +import 'package:mohem_flutter_app/generated/locale_keys.g.dart'; +import 'package:mohem_flutter_app/classes/colors.dart'; +import 'package:mohem_flutter_app/extensions/int_extensions.dart'; +import 'package:mohem_flutter_app/extensions/string_extensions.dart'; +import 'package:mohem_flutter_app/widgets/otp_widget.dart'; + +class OtpDialog { + final int type; + final int mobileNo; + final Function(String) onSuccess; + final Function onFailure; + final BuildContext context; + + int remainingTime = 120; + + Future? timer; + + static BuildContext? _context; + + static bool? _loading; + + OtpDialog( + this.context, + this.type, + this.mobileNo, + this.onSuccess, + this.onFailure, + ); + + GlobalKey? verifyAccountForm = GlobalKey(); + + final TextEditingController _pinPutController = TextEditingController(); + + TextEditingController digit1 = TextEditingController(text: ""); + TextEditingController digit2 = TextEditingController(text: ""); + TextEditingController digit3 = TextEditingController(text: ""); + TextEditingController digit4 = TextEditingController(text: ""); + + Map verifyAccountFormValue = { + 'digit1': '', + 'digit2': '', + 'digit3': '', + 'digit4': '', + }; + final focusD1 = FocusNode(); + final focusD2 = FocusNode(); + final focusD3 = FocusNode(); + final focusD4 = FocusNode(); + String? errorMsg; + + // ProjectViewModel projectProvider; + String displayTime = ''; + String? _code; + dynamic setState; + + // static String signature; + + displayDialog(BuildContext context) async { + return showDialog( + context: context, + barrierColor: Colors.black.withOpacity(0.63), + builder: (context) { + // projectProvider = Provider.of(context); + return Dialog( + backgroundColor: Colors.white, + shape: RoundedRectangleBorder(), + insetPadding: EdgeInsets.only(left: 21, right: 21), + child: StatefulBuilder(builder: (context, setState) { + if (displayTime == '') { + startTimer(setState); + } + + return Container( + padding: EdgeInsets.only(left: 21, right: 18, top: 39, bottom: 59), + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + SvgPicture.asset( + type == 1 ? "assets/images/verify_sms.svg" : "assets/images/verify_whatsapp.svg", + height: 50, + width: 50, + ), + IconButton( + padding: EdgeInsets.zero, + icon: const Icon(Icons.close), + constraints: const BoxConstraints(), + onPressed: () { + Navigator.pop(context); + this.onFailure(); + }, + ) + ], + ), + 22.height, + (LocaleKeys.pleaseEnterTheVerificationCodeSentTo.tr() + ' xxxxxxxx' + mobileNo.toString().substring(mobileNo.toString().length - 3)).toText16, + 18.height, + Directionality( + textDirection: TextDirection.ltr, + child: Center( + child: OTPWidget( + autoFocus: true, + controller: _pinPutController, + defaultBorderColor: const Color(0xffD8D8D8), + maxLength: 4, + onTextChanged: (text) {}, + pinBoxColor: Colors.white, + onDone: (code) => _onOtpCallBack(code, null), + textBorderColor: const Color(0xffD8D8D8), + pinBoxWidth: 60, + pinBoxHeight: 60, + pinTextStyle: const TextStyle(fontSize: 24.0, color: MyColors.darkTextColor), + pinTextAnimatedSwitcherTransition: ProvidedPinBoxTextAnimation.scalingTransition, + pinTextAnimatedSwitcherDuration: const Duration(milliseconds: 300), + pinBoxRadius: 10, + keyboardType: TextInputType.number, + ), + ), + ), + 30.height, + RichText( + text: TextSpan( + text: LocaleKeys.theVerificationCodeWillExpireIn.tr() + '\n', + style: const TextStyle(fontSize: 16, fontWeight: FontWeight.w600, color: MyColors.darkTextColor, letterSpacing: -0.48), + children: [ + TextSpan( + text: displayTime, + style: const TextStyle(fontSize: 16, fontWeight: FontWeight.w600, color: MyColors.textMixColor, letterSpacing: -0.48), + ), + ], + ), + ), + ], + ), + ); + }), + ); + }); + } + + InputDecoration buildInputDecoration(BuildContext context) { + return InputDecoration( + counterText: " ", + // ts/images/password_icon.png + // contentPadding: EdgeInsets.only(top: 20, bottom: 20), + enabledBorder: OutlineInputBorder( + borderRadius: BorderRadius.all(Radius.circular(10)), + borderSide: BorderSide(color: Colors.black), + ), + focusedBorder: OutlineInputBorder( + borderRadius: BorderRadius.all(Radius.circular(10.0)), + borderSide: BorderSide(color: Theme.of(context).primaryColor), + ), + errorBorder: OutlineInputBorder( + borderRadius: BorderRadius.all(Radius.circular(10.0)), + borderSide: BorderSide(color: Theme.of(context).errorColor), + ), + focusedErrorBorder: OutlineInputBorder( + borderRadius: BorderRadius.all(Radius.circular(10.0)), + borderSide: BorderSide(color: Theme.of(context).errorColor), + ), + ); + } + + // String validateCodeDigit(value) { + // if (value.isEmpty) { + // return ' '; + // } else if (value.length == 3) { + // print(value); + // } else { + // return null; + // } + // } + + checkValue() { + //print(verifyAccountFormValue); + // if (verifyAccountForm?.currentState!.validate()) { + // onSuccess(digit1.text.toString() + digit2.text.toString() + digit3.text.toString() + digit4.text.toString()); + // } + } + + getSecondsAsDigitalClock(int inputSeconds) { + var sec_num = int.parse(inputSeconds.toString()); // don't forget the second param + var hours = (sec_num / 3600).floor(); + var minutes = ((sec_num - hours * 3600) / 60).floor(); + var seconds = sec_num - hours * 3600 - minutes * 60; + var minutesString = ""; + var secondsString = ""; + minutesString = minutes < 10 ? "0" + minutes.toString() : minutes.toString(); + secondsString = seconds < 10 ? "0" + seconds.toString() : seconds.toString(); + return minutesString + ":" + secondsString; + } + + startTimer(setState) { + this.remainingTime--; + setState(() { + displayTime = this.getSecondsAsDigitalClock(this.remainingTime); + }); + + timer = Future.delayed(Duration(seconds: 1), () { + if (this.remainingTime > 0) { + startTimer(setState); + } else { + Navigator.pop(context); + } + }); + } + + static void hideSMSBox(context) { + Navigator.pop(context); + } + + _onOtpCallBack(String otpCode, bool? isAutofill) { + if (otpCode.length == 4) { + onSuccess(otpCode); + } + } + + static getSignature() async { + // if (Platform.isAndroid) { + // return await SmsRetriever.getAppSignature(); + // } else { + // return null; + // } + } +} diff --git a/lib/sikander_later_will_remove_to_parent_directory/exceptions/api_exception.dart b/lib/exceptions/api_exception.dart similarity index 90% rename from lib/sikander_later_will_remove_to_parent_directory/exceptions/api_exception.dart rename to lib/exceptions/api_exception.dart index fa2b22c..e3046ca 100644 --- a/lib/sikander_later_will_remove_to_parent_directory/exceptions/api_exception.dart +++ b/lib/exceptions/api_exception.dart @@ -1,6 +1,6 @@ import 'dart:convert'; -import 'package:mohem_flutter_app/sikander_later_will_remove_to_parent_directory/api/api_client.dart'; +import 'package:mohem_flutter_app/api/api_client.dart'; class APIException implements Exception { static const String BAD_REQUEST = 'api_common_bad_request'; diff --git a/lib/sikander_later_will_remove_to_parent_directory/extensions/int_extensions.dart b/lib/extensions/int_extensions.dart similarity index 100% rename from lib/sikander_later_will_remove_to_parent_directory/extensions/int_extensions.dart rename to lib/extensions/int_extensions.dart diff --git a/lib/extensions/string_extensions.dart b/lib/extensions/string_extensions.dart new file mode 100644 index 0000000..bd52c85 --- /dev/null +++ b/lib/extensions/string_extensions.dart @@ -0,0 +1,72 @@ +import 'package:flutter/cupertino.dart'; +import 'package:intl/intl.dart'; +import 'package:mohem_flutter_app/classes/colors.dart'; + +extension EmailValidator on String { + Widget get toWidget => Text(this); + + Widget toText10({Color? color}) => Text( + this, + style: TextStyle(fontSize: 10, fontWeight: FontWeight.w600, color: color ?? MyColors.darkTextColor, letterSpacing: -0.4), + ); + + Widget toText12({Color? color, bool isUnderLine = false}) => Text( + this, + style: TextStyle(fontSize: 12, fontWeight: FontWeight.w600, color: color ?? MyColors.darkTextColor, letterSpacing: -0.72, decoration: isUnderLine ? TextDecoration.underline : null), + ); + + Widget get toText14 => Text( + this, + style: const TextStyle(color: MyColors.darkTextColor, fontSize: 14, letterSpacing: -0.48, fontWeight: FontWeight.w600), + ); + + Widget get toText16 => Text( + this, + style: const TextStyle(color: MyColors.darkTextColor, fontSize: 16, letterSpacing: -0.64, fontWeight: FontWeight.w600), + ); + + Widget toText24({bool isBold = false}) => Text( + this, + style: TextStyle(color: MyColors.darkTextColor, fontSize: 24, letterSpacing: -1.44, fontWeight: isBold ? FontWeight.bold : FontWeight.w600), + ); + + bool isValidEmail() { + return RegExp(r'^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$').hasMatch(this); + } + + String toFormattedDate() { + String date = this.split("T")[0]; + String time = this.split("T")[1]; + var dates = date.split("-"); + return "${dates[2]} ${getMonth(int.parse(dates[1]))} ${dates[0]} ${DateFormat('hh:mm a').format(DateFormat('hh:mm:ss').parse(time))}"; + } + + getMonth(int month) { + switch (month) { + case 1: + return "January"; + case 2: + return "February"; + case 3: + return "March"; + case 4: + return "April"; + case 5: + return "May"; + case 6: + return "June"; + case 7: + return "July"; + case 8: + return "August"; + case 9: + return "September"; + case 10: + return "October"; + case 11: + return "November"; + case 12: + return "December"; + } + } +} diff --git a/lib/extensions/widget_extensions.dart b/lib/extensions/widget_extensions.dart new file mode 100644 index 0000000..787894d --- /dev/null +++ b/lib/extensions/widget_extensions.dart @@ -0,0 +1,11 @@ +import 'package:flutter/material.dart'; +import 'package:flutter/widgets.dart'; + +extension WidgetExtensions on Widget { + Widget onPress(VoidCallback onTap) => InkWell(onTap: onTap, 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); +} diff --git a/lib/generated/codegen_loader.g.dart b/lib/generated/codegen_loader.g.dart index 6d49427..c0810e9 100644 --- a/lib/generated/codegen_loader.g.dart +++ b/lib/generated/codegen_loader.g.dart @@ -22,6 +22,18 @@ class CodegenLoader extends AssetLoader{ "pleaseEnterLoginDetails": "Please enter the detail below to login", "username": "Username", "password": "Password", + "welcomeBack": "Welcome back", + "wouldYouLikeToLoginWithCurrentUsername": "Would you like to login with current Username?", + "lastLoginDetails": "Last Login Details:", + "verificationType": "Verification Type:", + "pleaseVerify": "Please Verify", + "verifyThroughFace": "Verify Through Face", + "verifyThroughFingerprint": "Verify Through Fingerprint", + "verifyThroughSMS": "Verify Through SMS", + "verifyThroughWhatsapp": "Verify Through Whatsapp", + "useAnotherAccount": "Use Another Account", + "pleaseEnterTheVerificationCodeSentTo": "Please enter the verification code sent to ", + "theVerificationCodeWillExpireIn": "The verification code will expire in ", "title": "Hello", "forgotPassword": "Forgot Password", "msg": "Hello {} in the {} world ", @@ -68,6 +80,18 @@ static const Map en_US = { "pleaseEnterLoginDetails": "Please enter the detail below to login", "username": "Username", "password": "Password", + "welcomeBack": "Welcome back", + "wouldYouLikeToLoginWithCurrentUsername": "Would you like to login with current Username?", + "lastLoginDetails": "Last Login Details:", + "verificationType": "Verification Type:", + "pleaseVerify": "Please Verify", + "verifyThroughFace": "Verify Through Face", + "verifyThroughFingerprint": "Verify Through Fingerprint", + "verifyThroughSMS": "Verify Through SMS", + "verifyThroughWhatsapp": "Verify Through Whatsapp", + "useAnotherAccount": "Use Another Account", + "pleaseEnterTheVerificationCodeSentTo": "Please enter the verification code sent to ", + "theVerificationCodeWillExpireIn": "The verification code will expire in ", "title": "Hello", "forgotPassword": "Forgot Password", "msg": "Hello {} in the {} world ", diff --git a/lib/main.dart b/lib/main.dart index 5964efe..b118397 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,7 +1,6 @@ import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:mohem_flutter_app/config/app_provider.dart'; -import 'package:mohem_flutter_app/config/dependencies.dart'; import 'package:mohem_flutter_app/generated/codegen_loader.g.dart'; import 'package:mohem_flutter_app/theme/app_theme.dart'; import 'package:sizer/sizer.dart'; @@ -32,7 +31,7 @@ Future main() async { class MyApp extends StatelessWidget { MyApp() { - AppDependencies.addDependencies(); +// AppDependencies.addDependencies(); } @override diff --git a/lib/models/account.dart b/lib/models/account.dart deleted file mode 100644 index 830b62f..0000000 --- a/lib/models/account.dart +++ /dev/null @@ -1,43 +0,0 @@ -// To parse this JSON data, do -// -// final account = accountFromJson(jsonString); - -import 'dart:convert'; - -import 'package:mohem_flutter_app/models/parent_list.dart'; - - - -Account accountFromJson(String str) => Account.fromJson(json.decode(str)); - -String accountToJson(Account data) => json.encode(data.toJson()); - -class Account { - Account({ - required this.parentList, - required this.selectedItem, - }); - - List? parentList; - int selectedItem; - - factory Account.fromJson(Map json) => Account( - parentList: json["parentList"] == null - ? null - : List.from( - json["parentList"].map((x) => ParentList.fromJson(x))), - selectedItem: - json["selectedItem"] == null ? null : json["selectedItem"], - ); - - Map toJson() => { - "parentList": parentList == null - ? null - : List.from(parentList!.map((x) => x.toJson())), - "selectedItem": selectedItem == null ? null : selectedItem, - }; - - Map toJsonData() => { - "selectedItem": selectedItem == null ? null : selectedItem, - }; -} diff --git a/lib/models/config_model.dart b/lib/models/config_model.dart deleted file mode 100644 index 0245ede..0000000 --- a/lib/models/config_model.dart +++ /dev/null @@ -1,12 +0,0 @@ -class ConfigModel { - ConfigModel(this.endpoint, this.organizationName); - - String endpoint; - - String organizationName; - - factory ConfigModel.fromJson(Map json) => - ConfigModel("", ""); - -// Map toJson() => _$ConfigModelToJson(this); -} diff --git a/lib/sikander_later_will_remove_to_parent_directory/models/content_info_model.dart b/lib/models/content_info_model.dart similarity index 100% rename from lib/sikander_later_will_remove_to_parent_directory/models/content_info_model.dart rename to lib/models/content_info_model.dart diff --git a/lib/sikander_later_will_remove_to_parent_directory/models/member_model.dart b/lib/models/member_model.dart similarity index 100% rename from lib/sikander_later_will_remove_to_parent_directory/models/member_model.dart rename to lib/models/member_model.dart diff --git a/lib/models/parent_list.dart b/lib/models/parent_list.dart deleted file mode 100644 index 3f2286f..0000000 --- a/lib/models/parent_list.dart +++ /dev/null @@ -1,26 +0,0 @@ -class ParentList { - ParentList({ - required this.dbId, - required this.text, - required this.path, - required this.isSelected, - }); - - int dbId; - String text; - String path; - bool isSelected; - - factory ParentList.fromJson(Map json) => ParentList( - dbId: json["dbId"] == null ? null : json["dbId"], - text: json["text"] == null ? null : json["text"], - path: json["path"] == null ? null : json["path"], - isSelected: false, - ); - - Map toJson() => { - "dbId": dbId == null ? null : dbId, - "text": text == null ? null : text, - "path": path == null ? null : path, - }; -} diff --git a/lib/models/response_models.dart b/lib/models/response_models.dart deleted file mode 100644 index 872893b..0000000 --- a/lib/models/response_models.dart +++ /dev/null @@ -1,34 +0,0 @@ -/// -/// This example was taken from -/// https://flutter.dev/docs/development/data-and-backend/json -/// - -/// This allows the `User` class to access private members in -/// the generated file. The value for this is *.g.dart, where -/// the star denotes the source file name. - -/// An annotation for the code generator to know that this class needs the -/// JSON serialization logic to be generated. - -class BackendResponse { - BackendResponse({required this.id, required this.isOk, required this.result}); - - int id; - bool isOk; - dynamic result; - - /// A necessary factory constructor for creating a new User instance - /// from a map. Pass the map to the generated `_$UserFromJson()` constructor. - /// The constructor is named after the source class, in this case, User. - factory BackendResponse.fromJson(Map json) => - BackendResponse( - id: 1, - isOk: false, - result: null, - ); -// -// /// `toJson` is the convention for a class to declare support for serialization -// /// to JSON. The implementation simply calls the private, generated -// /// helper method `_$UserToJson`. -// Map toJson() => _$BackendResponseToJson(this); -} diff --git a/lib/sikander_later_will_remove_to_parent_directory/models/surah_model.dart b/lib/models/surah_model.dart similarity index 100% rename from lib/sikander_later_will_remove_to_parent_directory/models/surah_model.dart rename to lib/models/surah_model.dart diff --git a/lib/models/user.dart b/lib/models/user.dart deleted file mode 100644 index e09c282..0000000 --- a/lib/models/user.dart +++ /dev/null @@ -1,9 +0,0 @@ -class User { - int id; - - User(this.id, this.userName, this.userImage, this.createdDate); - - String userName; - String userImage; - String createdDate; -} diff --git a/lib/pages/a.dart b/lib/pages/a.dart deleted file mode 100644 index e69de29..0000000 diff --git a/lib/pages/user/splash_page.dart b/lib/pages/user/splash_page.dart deleted file mode 100644 index c593f56..0000000 --- a/lib/pages/user/splash_page.dart +++ /dev/null @@ -1,48 +0,0 @@ -import 'dart:async'; - -import 'package:mohem_flutter_app/config/routes.dart'; -import 'package:mohem_flutter_app/utils/navigator.dart'; -import 'package:mohem_flutter_app/utils/utils.dart'; -import 'package:mohem_flutter_app/widgets/txt.dart'; -import 'package:flutter/material.dart'; - -class SplashPage extends StatelessWidget { - @override - Widget build(BuildContext context) { - return Scaffold( - body: Container( - width: double.infinity, - height: double.infinity, - child: Column( - children: [ - mFlex(5), - Txt( - "Logo", - fontSize: 45, - bold: true, - ), - mFlex(3), - Txt( - "First Time Log In", - txtType: TxtType.heading1, - isFlatButton: true, - onTap: () { - navigateWithName(context, AppRoutes.registerSelection); - }, - ), - mFlex(1), - Txt( - "Already Signed Up and Logged In", - txtType: TxtType.heading1, - isFlatButton: true, - onTap: () { - navigateWithName(context, AppRoutes.loginVerification); - }, - ), - mFlex(5), - ], - ), - ), - ); - } -} diff --git a/lib/provider/counter.dart b/lib/provider/counter.dart deleted file mode 100644 index 0272327..0000000 --- a/lib/provider/counter.dart +++ /dev/null @@ -1,20 +0,0 @@ -import 'package:flutter/foundation.dart'; -import 'package:flutter/material.dart'; - -class Counter with ChangeNotifier, DiagnosticableTreeMixin { - int _count = 0; - - int get count => _count; - - void increment() { - _count++; - notifyListeners(); - } - - /// Makes `Counter` readable inside the devtools by listing all of its properties - @override - void debugFillProperties(DiagnosticPropertiesBuilder properties) { - super.debugFillProperties(properties); - properties.add(IntProperty('count', count)); - } -} \ No newline at end of file diff --git a/lib/repo/account_repository.dart b/lib/repo/account_repository.dart deleted file mode 100644 index 770cbb4..0000000 --- a/lib/repo/account_repository.dart +++ /dev/null @@ -1,49 +0,0 @@ -import 'dart:convert'; -import 'dart:io'; - -import 'package:mohem_flutter_app/models/account.dart'; -import 'package:mohem_flutter_app/models/response_models.dart'; -import 'package:mohem_flutter_app/services/backend_service.dart'; -import 'package:injector/injector.dart'; - -abstract class IAcRepository { - Future getAccountList(); - - Future updateAccount(String dataAsJson); -} - -class AcRepository implements IAcRepository { - static const String ACCOUNT_API_CONTROLLER_MOBILE = - "AccountApiControllerMobile/"; - - static const String ACCOUNT_LIST = ACCOUNT_API_CONTROLLER_MOBILE + "list"; - static const String UPDATE_LIST = - ACCOUNT_API_CONTROLLER_MOBILE + "saveaccountselected"; - - @override - Future getAccountList() async { - BackendResponse response = await Injector.appInstance - .getDependency() - .getAuthenticatedAPI(ACCOUNT_LIST); - - if (response != null && response.isOk) { - return Account.fromJson(response.result); - } else { - throw Exception(); - } - } - - @override - Future updateAccount(String dataAsJson) async { - BackendResponse response = await Injector.appInstance - .getDependency() - .postAuthenticatedAPI(UPDATE_LIST, dataAsJson); - - if (response != null && response.isOk) { - //if parsing failed, throw exception - return response; - } else { - throw Exception(); - } - } -} diff --git a/lib/services/backend_service.dart b/lib/services/backend_service.dart deleted file mode 100644 index b2e4de0..0000000 --- a/lib/services/backend_service.dart +++ /dev/null @@ -1,127 +0,0 @@ -import 'dart:convert'; -import 'dart:io'; -import 'package:mohem_flutter_app/models/response_models.dart'; -import 'package:mohem_flutter_app/services/secure_storage.dart'; -import 'package:http/http.dart'; -import 'package:injector/injector.dart'; - -import 'http_service.dart'; -import 'network_service.dart'; - -abstract class IBackendApiService { - Future getUnauthenticatedAPI(String route); - - Future getAuthenticatedAPI(String route); - - Future postUnauthenticatedAPI( - String route, String dataAsJson); - - Future postAuthenticatedAPI(String route, String dataAsJson); - - Future deleteAuthenticatedAPI(String route, String id); -} - -class BackendApiService implements IBackendApiService { - static String _homeUrl = "https://check.revotec.eu/check2/"; - static String _serverApiBaseUrl = _homeUrl + "mapi/v1/"; - - static String get homeUrl => _homeUrl; - - final ISecureStorage _secureStorage = - Injector.appInstance.getDependency(); - final IHttpService _httpService = - Injector.appInstance.getDependency(); - - ///internal helper functions which executes the given api call - ///and wraps the response - Future _callApi(Future callback) async { - Response response; - try { - //execute future - response = await callback; - //check response code, and if not ok return isOk = false - //200 for Get - //201 for Post - - // print("res121: " + - // response.statusCode.toString() + - // " Body:" + - // response.body.toString()); - //if delete request sent so server is returning 204 in case of success. - if (response.statusCode == 204) - return BackendResponse(id: 1, isOk: true, result: null); - - if (response.statusCode != 200 && response.statusCode != 201) - return BackendResponse(id: -1, isOk: false, result: null); - //if response code is good then parse message and return parsed response - return BackendResponse.fromJson(json.decode(response.body)); - //return BackendResponse.fromJson(dioResponse.body); - } catch (e) { - return BackendResponse(id: -1, isOk: false, result: null); - // try { - // return BackendResponse.fromJson(json.decode(response.body)); - // } catch (e) { - // return BackendResponse(id:-1, isOk:false,result: null); - // } - } - } - - @override - Future getAuthenticatedAPI(String route) async { - await checkConnection(); - final token = await _secureStorage.readBearerToken(); - return _callApi(_httpService.get(_serverApiBaseUrl + route, headers: { - 'Content-Type': 'application/json', - 'Accept': '*/*', - HttpHeaders.authorizationHeader: "Bearer $token" - })); - } - - @override - Future getUnauthenticatedAPI(String route) async { - await checkConnection(); - return _callApi(_httpService.get(_serverApiBaseUrl + route, - headers: {'Content-Type': 'application/json', 'Accept': '*/*'})); - } - - @override - Future postAuthenticatedAPI( - String route, String dataAsJson) async { - await checkConnection(); - final token = await _secureStorage.readBearerToken(); - // print("res121: " + _serverApiBaseUrl + route); - return _callApi(_httpService - .post(_serverApiBaseUrl + route, body: dataAsJson, headers: { - 'Content-Type': 'application/json', - 'Accept': '*/*', - HttpHeaders.authorizationHeader: "Bearer $token" - })); - } - - @override - Future postUnauthenticatedAPI( - String route, String dataAsJson) async { - await checkConnection(); - return _callApi(_httpService.post(_serverApiBaseUrl + route, - body: dataAsJson, headers: {'Content-Type': 'application/json'})); - } - - Future checkConnection() async { - if (!(await Injector.appInstance - .getDependency() - .isHostAvailable(_homeUrl))) throw NetworkException(); - } - - @override - Future deleteAuthenticatedAPI( - String route, String id) async { - await checkConnection(); - final token = await _secureStorage.readBearerToken(); - return _callApi( - _httpService.delete(_serverApiBaseUrl + route + "/" + id, headers: { - 'Content-Type': 'application/json', - 'Accept': '*/*', - HttpHeaders.authorizationHeader: "Bearer $token" - })); - } -} diff --git a/lib/services/firebase_service.dart b/lib/services/firebase_service.dart deleted file mode 100644 index ad76959..0000000 --- a/lib/services/firebase_service.dart +++ /dev/null @@ -1,180 +0,0 @@ -/* -import 'dart:io' show Platform; -import 'package:firebase_messaging/firebase_messaging.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter_local_notifications/flutter_local_notifications.dart'; - -abstract class IFirebaseService { - Future get token; - - Future backgroundMessageHandler(Map message); - - Future messageHandler(Map message); - - Future onLaunch(Map message); - - Future onResume(Map message); - - void subscribeForPromotions(); - - void unsubscribeFromPromotions(); -} - -//https://medium.com/@SebastianEngel/easy-push-notifications-with-flutter-and-firebase-cloud-messaging-d96084f5954f -class FirebaseService implements IFirebaseService { - FirebaseMessaging _firebaseMessaging; - - FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin; - - FirebaseService() {. - _firebaseMessaging = FirebaseMessaging(); - - //https://github.com/FirebaseExtended/flutterfire/issues/1695 - _firebaseMessaging.configure( - onMessage: messageHandler, - onBackgroundMessage: - Platform.isAndroid ? myBackgroundMessageHandler : null, - onLaunch: onLaunch, - onResume: onResume, - ); - - //monitor firebase token changes - //https://firebase.google.com/docs/cloud-messaging/android/client#sample-register - ///The registration token may change when: - // - //The app deletes Instance ID - //The app is restored on a new device - //The user uninstalls/reinstall the app - //The user clears app data. - /// - - //for the first release we don't care about token refreshes - /*Stream fcmStream = _firebaseMessaging.onTokenRefresh; - fcmStream.listen((token) { - - });*/ - - //ios specific settings - //taken from https://github.com/FirebaseExtended/flutterfire/blob/master/packages/firebase_messaging/example/lib/main.dart - _firebaseMessaging.requestNotificationPermissions( - const IosNotificationSettings( - sound: true, badge: true, alert: true, provisional: true)); - _firebaseMessaging.onIosSettingsRegistered - .listen((IosNotificationSettings settings) { - print("Settings registered: $settings"); - }); - - var initializationSettingsAndroid = - AndroidInitializationSettings('app_icon'); - var initializationSettingsIOS = - IOSInitializationSettings(onDidReceiveLocalNotification: onDidReceiveLocalNotification); - var initializationSettings = InitializationSettings( - initializationSettingsAndroid, initializationSettingsIOS); - flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin(); - flutterLocalNotificationsPlugin.initialize(initializationSettings, - onSelectNotification: selectNotification); - } - - Future onDidReceiveLocalNotification(int id, String title, String body, String payload) async{ - var androidPlatformChannelSpecifics = AndroidNotificationDetails( - 'new_message_channel_id', - 'Neue Nachricht', - 'Channel für neue Nachrichten', - importance: Importance.Max, - priority: Priority.High, - ticker: 'ticker'); - var iOSPlatformChannelSpecifics = IOSNotificationDetails(); - var platformChannelSpecifics = NotificationDetails( - androidPlatformChannelSpecifics, iOSPlatformChannelSpecifics); - await flutterLocalNotificationsPlugin.show( - 0, - title, - body, - platformChannelSpecifics); - } - - @override - Future backgroundMessageHandler(Map message) async { - await myBackgroundMessageHandler(message); - } - - @override - Future messageHandler(Map message) async { - print("onMessage: $message"); - -// initialise the plugin. app_icon needs to be a added as a drawable resource to the Android head project - - var androidPlatformChannelSpecifics = AndroidNotificationDetails( - 'new_message_channel_id', - 'Neue Nachricht', - 'Channel für neue Nachrichten', - importance: Importance.Max, - priority: Priority.High, - ticker: 'ticker'); - var iOSPlatformChannelSpecifics = IOSNotificationDetails(); - var platformChannelSpecifics = NotificationDetails( - androidPlatformChannelSpecifics, iOSPlatformChannelSpecifics); - - if(Platform.isAndroid) { - await flutterLocalNotificationsPlugin.show( - 0, - message["notification"]["title"], - message["notification"]["body"], - platformChannelSpecifics); - }else if(Platform.isIOS){ - await flutterLocalNotificationsPlugin.show( - 0, - message["aps"]["alert"]["title"], - message["aps"]["alert"]["body"], - platformChannelSpecifics); - } - } - - Future selectNotification(String payload) async { - if (payload != null) { - debugPrint('notification payload: ' + payload); - } - } - - @override - Future onLaunch(Map message) async { - print("onLaunch: $message"); - } - - @override - Future onResume(Map message) async { - print("onResume: $message"); - } - - @override - Future get token => _firebaseMessaging.getToken(); - - @override - void subscribeForPromotions() { - _firebaseMessaging.subscribeToTopic("promotions"); - } - - @override - void unsubscribeFromPromotions() { - _firebaseMessaging.unsubscribeFromTopic("promotions"); - } -} - -Future myBackgroundMessageHandler(Map message) { - debugPrint("BACKGROUND MESSAGE RECEIVED"); - print("BACKGROUND MESSAGE RECEIVED"); - return Future.value(() => true); - - /*if (message.containsKey('data')) { - // Handle data message - final dynamic data = message['data']; - } - - if (message.containsKey('notification')) { - // Handle notification message - final dynamic notification = message['notification']; - }*/ - - // Or do other work. -} -*/ \ No newline at end of file diff --git a/lib/services/http_service.dart b/lib/services/http_service.dart deleted file mode 100644 index b2cb73a..0000000 --- a/lib/services/http_service.dart +++ /dev/null @@ -1,34 +0,0 @@ -import 'dart:convert'; -import 'dart:io'; -import 'dart:async'; - - -import 'package:http/http.dart' as http; -import 'package:http/http.dart'; - -abstract class IHttpService { - Future post(url, - {Map headers, body, Encoding encoding}); - - Future get(url, {Map headers}); - - Future delete(url, {Map headers}); -} - -class HttpService implements IHttpService { - @override - Future delete(url, {Map? headers}) { - return http.delete(url, headers: headers); - } - - @override - Future get(url, {Map? headers}) { - return http.get(url, headers: headers); - } - - @override - Future post(url, - {Map? headers, body, Encoding? encoding}) { - return http.post(url, headers: headers, body: body, encoding: encoding); - } -} diff --git a/lib/services/media_service.dart b/lib/services/media_service.dart deleted file mode 100644 index 0762d7f..0000000 --- a/lib/services/media_service.dart +++ /dev/null @@ -1,26 +0,0 @@ -// import 'dart:io'; -// -// import 'package:image_picker/image_picker.dart'; -// -// abstract class IMediaService { -// Future takePicture(); -// -// Future openImageFromGallery(); -// } -// -// class MediaService implements IMediaService { -// @override -// Future openImageFromGallery() async { -// final pickedFile = -// await ImagePicker().getImage(source: ImageSource.gallery); -// if (pickedFile == null) return null; -// return File(pickedFile.path); -// } -// -// @override -// Future takePicture() async { -// final pickedFile = await ImagePicker().getImage(source: ImageSource.camera); -// if (pickedFile == null) return null; -// return File(pickedFile.path); -// } -// } diff --git a/lib/services/network_service.dart b/lib/services/network_service.dart deleted file mode 100644 index 50a861d..0000000 --- a/lib/services/network_service.dart +++ /dev/null @@ -1,25 +0,0 @@ - -import 'dart:io'; - -abstract class INetworkService { - Future isHostAvailable(String endpoint); -} - -class NetworkService implements INetworkService{ - @override - Future isHostAvailable(String endpoint) async { - try { - final result = await InternetAddress.lookup(endpoint.substring(endpoint.indexOf('//')+2).substring(0,endpoint.substring(endpoint.indexOf('//')+2).indexOf('/'))); - if (result.isNotEmpty && result[0].rawAddress.isNotEmpty) { - return true; - } else{ - return false; - } - } on SocketException catch (_) { - return false; - } - } -} - -class NetworkException implements Exception { -} diff --git a/lib/services/secure_storage.dart b/lib/services/secure_storage.dart deleted file mode 100644 index 7622f7f..0000000 --- a/lib/services/secure_storage.dart +++ /dev/null @@ -1,33 +0,0 @@ -abstract class ISecureStorage { - Future readBearerToken(); - - Future clearUserCredentials(); -} - -class SecureStorage implements ISecureStorage { - ///return bearer token if present, or null if not - @override - Future readBearerToken() async { - try { - return ""; - } catch (_) { - //an error occured returning null - return ""; - } - } - - ///returns true if write was successful, false otherwise - @override - Future writeBearerToken(String token) async { - try { - await ""; - return true; - } catch (_) { - //an error occured returning false - return false; - } - } - - @override - Future clearUserCredentials() async {} -} diff --git a/lib/services/shared_preferences.dart b/lib/services/shared_preferences.dart deleted file mode 100644 index 890a616..0000000 --- a/lib/services/shared_preferences.dart +++ /dev/null @@ -1,119 +0,0 @@ -import 'dart:convert'; - -import 'package:mohem_flutter_app/models/config_model.dart'; - -import 'package:shared_preferences/shared_preferences.dart' -as SharedPrefsPlugin; - -/// -/// Taken from AlarmGuide Project -/// - -abstract class ISharedPreferences { - Future get authState; - - Future setAuthState(int authState); - - Future get configState; - - Future setConfigState(int confState); - - Future get config; - - Future setConfig(ConfigModel config); - - Future get promotionNotificationsEnabled; - - Future setPromotionNotificationEnabled(bool newSetting); - - Future get helpAlreadyShown; - - Future setHelpAlreadyShown(); - - Future get useS3; - - Future setUseS3(int value); -} - -class SharedPreferences implements ISharedPreferences { - static const String _AUTH_STATE_KEY = "auth_key"; - static const String _CONFIG_KEY = "config"; - static const String _CONFIG_STATE_KEY = "config_key"; - static const String _PROMOTION_NOTIFICATION_KEY = "promotion"; - static const String _HELP_ALREADY_SHOWN = "help_shown"; - static const String _USE_S3 = "s3"; - - @override - Future get authState async { - final sharedPrefs = await SharedPrefsPlugin.SharedPreferences.getInstance(); - return sharedPrefs.getInt(_AUTH_STATE_KEY); - } - - @override - Future setAuthState(int authState) async { - final sharedPrefs = await SharedPrefsPlugin.SharedPreferences.getInstance(); - sharedPrefs.setInt(_AUTH_STATE_KEY, authState); - } - - @override - Future get config async { - final sharedPrefs = await SharedPrefsPlugin.SharedPreferences.getInstance(); - final configAsJson = sharedPrefs.getString(_CONFIG_KEY); - return ConfigModel.fromJson(jsonDecode(configAsJson!)); - } - - @override - Future setConfig(ConfigModel config) async { - final sharedPrefs = await SharedPrefsPlugin.SharedPreferences.getInstance(); - sharedPrefs.setString(_CONFIG_KEY, jsonEncode(config)); - setConfigState(1); - } - - @override - Future get promotionNotificationsEnabled async { - final sharedPrefs = await SharedPrefsPlugin.SharedPreferences.getInstance(); - return sharedPrefs.getBool(_PROMOTION_NOTIFICATION_KEY); - } - - @override - Future setPromotionNotificationEnabled(bool newSetting) async { - final sharedPrefs = await SharedPrefsPlugin.SharedPreferences.getInstance(); - sharedPrefs.setBool(_PROMOTION_NOTIFICATION_KEY, newSetting); - } - - @override - Future get helpAlreadyShown async { - final sharedPrefs = await SharedPrefsPlugin.SharedPreferences.getInstance(); - return sharedPrefs.getBool(_HELP_ALREADY_SHOWN); - } - - @override - Future setHelpAlreadyShown() async { - final sharedPrefs = await SharedPrefsPlugin.SharedPreferences.getInstance(); - sharedPrefs.setBool(_HELP_ALREADY_SHOWN, true); - } - - @override - Future get configState async { - final sharedPrefs = await SharedPrefsPlugin.SharedPreferences.getInstance(); - return sharedPrefs.getInt(_CONFIG_STATE_KEY); - } - - @override - Future setConfigState(int confState) async { - final sharedPrefs = await SharedPrefsPlugin.SharedPreferences.getInstance(); - sharedPrefs.setInt(_CONFIG_STATE_KEY, confState); - } - - @override - Future setUseS3(int value) async { - final sharedPrefs = await SharedPrefsPlugin.SharedPreferences.getInstance(); - sharedPrefs.setInt(_USE_S3, value); - } - - @override - Future get useS3 async { - final sharedPrefs = await SharedPrefsPlugin.SharedPreferences.getInstance(); - return sharedPrefs.getInt(_USE_S3); - } -} diff --git a/lib/sikander_later_will_remove_to_parent_directory/extensions/string_extensions.dart b/lib/sikander_later_will_remove_to_parent_directory/extensions/string_extensions.dart deleted file mode 100644 index db84adf..0000000 --- a/lib/sikander_later_will_remove_to_parent_directory/extensions/string_extensions.dart +++ /dev/null @@ -1,46 +0,0 @@ -import 'package:flutter/cupertino.dart'; -import 'package:intl/intl.dart'; - -extension EmailValidator on String { - Widget toWidget() => Text(this); - - bool isValidEmail() { - return RegExp(r'^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$').hasMatch(this); - } - - String toFormattedDate() { - String date = this.split("T")[0]; - String time = this.split("T")[1]; - var dates = date.split("-"); - return "${dates[2]} ${getMonth(int.parse(dates[1]))} ${dates[0]} ${DateFormat('hh:mm a').format(DateFormat('hh:mm:ss').parse(time))}"; - } - - getMonth(int month) { - switch (month) { - case 1: - return "January"; - case 2: - return "February"; - case 3: - return "March"; - case 4: - return "April"; - case 5: - return "May"; - case 6: - return "June"; - case 7: - return "July"; - case 8: - return "August"; - case 9: - return "September"; - case 10: - return "October"; - case 11: - return "November"; - case 12: - return "December"; - } - } -} diff --git a/lib/sikander_later_will_remove_to_parent_directory/extensions/widget_extensions.dart b/lib/sikander_later_will_remove_to_parent_directory/extensions/widget_extensions.dart deleted file mode 100644 index 6f5e013..0000000 --- a/lib/sikander_later_will_remove_to_parent_directory/extensions/widget_extensions.dart +++ /dev/null @@ -1,9 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:flutter/widgets.dart'; - -extension WidgetExtensions on Widget { - Widget onPress(VoidCallback onTap) => InkWell( - onTap: onTap, - child: this, - ); -} diff --git a/lib/sikander_later_will_remove_to_parent_directory/widgets/otp_widget.dart b/lib/sikander_later_will_remove_to_parent_directory/widgets/otp_widget.dart deleted file mode 100644 index bf03b72..0000000 --- a/lib/sikander_later_will_remove_to_parent_directory/widgets/otp_widget.dart +++ /dev/null @@ -1,373 +0,0 @@ -// import 'dart:async'; -// -// import 'package:flutter/animation.dart'; -// import 'package:flutter/foundation.dart'; -// import 'package:flutter/material.dart'; -// import 'package:flutter/rendering.dart'; -// import 'package:flutter/services.dart'; -// -// typedef OnDone = void Function(String text); -// -// class ProvidedPinBoxTextAnimation { -// static AnimatedSwitcherTransitionBuilder scalingTransition = (child, animation) { -// return ScaleTransition( -// child: child, -// scale: animation, -// ); -// }; -// -// static AnimatedSwitcherTransitionBuilder defaultNoTransition = (Widget child, Animation animation) { -// return child; -// }; -// } -// -// class OTPWidget extends StatefulWidget { -// final int maxLength; -// final TextEditingController controller; -// -// final Color defaultBorderColor; -// final Color pinBoxColor; -// final double pinBoxBorderWidth; -// final double pinBoxRadius; -// final bool hideDefaultKeyboard; -// -// final TextStyle pinTextStyle; -// final double pinBoxHeight; -// final double pinBoxWidth; -// final OnDone onDone; -// final bool hasError; -// final Color errorBorderColor; -// final Color textBorderColor; -// final Function(String) onTextChanged; -// final bool autoFocus; -// final FocusNode focusNode; -// final AnimatedSwitcherTransitionBuilder pinTextAnimatedSwitcherTransition; -// final Duration pinTextAnimatedSwitcherDuration; -// final TextDirection textDirection; -// final TextInputType keyboardType; -// final EdgeInsets pinBoxOuterPadding; -// -// const OTPWidget({ -// Key key, -// this.maxLength: 4, -// this.controller, -// this.pinBoxWidth: 70.0, -// this.pinBoxHeight: 70.0, -// this.pinTextStyle, -// this.onDone, -// this.defaultBorderColor: Colors.black, -// this.textBorderColor: Colors.black, -// this.pinTextAnimatedSwitcherTransition, -// this.pinTextAnimatedSwitcherDuration: const Duration(), -// this.hasError: false, -// this.errorBorderColor: Colors.red, -// this.onTextChanged, -// this.autoFocus: false, -// this.focusNode, -// this.textDirection: TextDirection.ltr, -// this.keyboardType: TextInputType.number, -// this.pinBoxOuterPadding = const EdgeInsets.symmetric(horizontal: 4.0), -// this.pinBoxColor = Colors.white, -// this.pinBoxBorderWidth = 2.0, -// this.pinBoxRadius = 0, -// this.hideDefaultKeyboard = false, -// }) : super(key: key); -// -// @override -// State createState() { -// return OTPWidgetState(); -// } -// } -// -// class OTPWidgetState extends State with SingleTickerProviderStateMixin { -// AnimationController _highlightAnimationController; -// FocusNode focusNode; -// String text = ""; -// int currentIndex = 0; -// List strList = []; -// bool hasFocus = false; -// -// @override -// void didUpdateWidget(OTPWidget oldWidget) { -// super.didUpdateWidget(oldWidget); -// focusNode = widget.focusNode ?? focusNode; -// -// if (oldWidget.maxLength < widget.maxLength) { -// setState(() { -// currentIndex = text.length; -// }); -// widget.controller?.text = text; -// widget.controller?.selection = TextSelection.collapsed(offset: text.length); -// } else if (oldWidget.maxLength > widget.maxLength && widget.maxLength > 0 && text.length > 0 && text.length > widget.maxLength) { -// setState(() { -// text = text.substring(0, widget.maxLength); -// currentIndex = text.length; -// }); -// widget.controller?.text = text; -// widget.controller?.selection = TextSelection.collapsed(offset: text.length); -// } -// } -// -// _calculateStrList() { -// if (strList.length > widget.maxLength) { -// strList.length = widget.maxLength; -// } -// while (strList.length < widget.maxLength) { -// strList.add(""); -// } -// } -// -// @override -// void initState() { -// super.initState(); -// focusNode = widget.focusNode ?? FocusNode(); -// -// _initTextController(); -// _calculateStrList(); -// widget.controller?.addListener(_controllerListener); -// focusNode?.addListener(_focusListener); -// } -// -// void _controllerListener() { -// if (mounted == true) { -// setState(() { -// _initTextController(); -// }); -// var onTextChanged = widget.onTextChanged; -// if (onTextChanged != null) { -// onTextChanged(widget.controller?.text ?? ""); -// } -// } -// } -// -// void _focusListener() { -// if (mounted == true) { -// setState(() { -// hasFocus = focusNode?.hasFocus ?? false; -// }); -// } -// } -// -// void _initTextController() { -// if (widget.controller == null) { -// return; -// } -// strList.clear(); -// var text = widget.controller?.text ?? ""; -// if (text.isNotEmpty) { -// if (text.length > widget.maxLength) { -// throw Exception("TextEditingController length exceeded maxLength!"); -// } -// } -// for (var i = 0; i < text.length; i++) { -// strList.add(text[i]); -// } -// } -// -// double get _width { -// var width = 0.0; -// for (var i = 0; i < widget.maxLength; i++) { -// width += widget.pinBoxWidth; -// if (i == 0) { -// width += widget.pinBoxOuterPadding.left; -// } else if (i + 1 == widget.maxLength) { -// width += widget.pinBoxOuterPadding.right; -// } else { -// width += widget.pinBoxOuterPadding.left; -// } -// } -// return width; -// } -// -// @override -// void dispose() { -// if (widget.focusNode == null) { -// focusNode?.dispose(); -// } else { -// focusNode?.removeListener(_focusListener); -// } -// _highlightAnimationController?.dispose(); -// widget.controller?.removeListener(_controllerListener); -// -// super.dispose(); -// } -// -// @override -// Widget build(BuildContext context) { -// return Stack( -// children: [ -// _otpTextInput(), -// _touchPinBoxRow(), -// ], -// ); -// } -// -// Widget _touchPinBoxRow() { -// return widget.hideDefaultKeyboard -// ? _pinBoxRow(context) -// : GestureDetector( -// behavior: HitTestBehavior.opaque, -// onTap: () { -// if (hasFocus) { -// FocusScope.of(context).requestFocus(FocusNode()); -// Future.delayed(Duration(milliseconds: 100), () { -// FocusScope.of(context).requestFocus(focusNode); -// }); -// } else { -// FocusScope.of(context).requestFocus(focusNode); -// } -// }, -// child: _pinBoxRow(context), -// ); -// } -// -// Widget _otpTextInput() { -// var transparentBorder = OutlineInputBorder( -// borderSide: BorderSide( -// color: Colors.transparent, -// width: 0.0, -// ), -// ); -// return Container( -// width: _width, -// height: widget.pinBoxHeight, -// child: TextField( -// autofocus: !kIsWeb ? widget.autoFocus : false, -// enableInteractiveSelection: false, -// focusNode: focusNode, -// controller: widget.controller, -// keyboardType: widget.keyboardType, -// inputFormatters: widget.keyboardType == TextInputType.number ? [FilteringTextInputFormatter.digitsOnly] : null, -// style: TextStyle( -// height: 0.1, -// color: Colors.transparent, -// ), -// decoration: InputDecoration( -// contentPadding: EdgeInsets.all(0), -// focusedErrorBorder: transparentBorder, -// errorBorder: transparentBorder, -// disabledBorder: transparentBorder, -// enabledBorder: transparentBorder, -// focusedBorder: transparentBorder, -// counterText: null, -// counterStyle: null, -// helperStyle: TextStyle( -// height: 0.0, -// color: Colors.transparent, -// ), -// labelStyle: TextStyle(height: 0.1), -// fillColor: Colors.transparent, -// border: InputBorder.none, -// ), -// cursorColor: Colors.transparent, -// showCursor: false, -// maxLength: widget.maxLength, -// onChanged: _onTextChanged, -// ), -// ); -// } -// -// void _onTextChanged(text) { -// var onTextChanged = widget.onTextChanged; -// if (onTextChanged != null) { -// onTextChanged(text); -// } -// setState(() { -// this.text = text; -// if (text.length >= currentIndex) { -// for (int i = currentIndex; i < text.length; i++) { -// strList[i] = text[i]; -// } -// } -// currentIndex = text.length; -// }); -// if (text.length == widget.maxLength) { -// FocusScope.of(context).requestFocus(FocusNode()); -// var onDone = widget.onDone; -// if (onDone != null) { -// onDone(text); -// } -// } -// } -// -// Widget _pinBoxRow(BuildContext context) { -// _calculateStrList(); -// List pinCodes = List.generate(widget.maxLength, (int i) { -// return _buildPinCode(i, context); -// }); -// return Row(children: pinCodes, mainAxisSize: MainAxisSize.min); -// } -// -// Widget _buildPinCode(int i, BuildContext context) { -// Color borderColor; -// Color pinBoxColor = widget.pinBoxColor; -// -// if (widget.hasError) { -// borderColor = widget.errorBorderColor; -// } else if (i < text.length) { -// borderColor = widget.textBorderColor; -// } else { -// borderColor = widget.defaultBorderColor; -// pinBoxColor = widget.pinBoxColor; -// } -// -// EdgeInsets insets; -// if (i == 0) { -// insets = EdgeInsets.only( -// left: 0, -// top: widget.pinBoxOuterPadding.top, -// right: widget.pinBoxOuterPadding.right, -// bottom: widget.pinBoxOuterPadding.bottom, -// ); -// } else if (i == strList.length - 1) { -// insets = EdgeInsets.only( -// left: widget.pinBoxOuterPadding.left, -// top: widget.pinBoxOuterPadding.top, -// right: 0, -// bottom: widget.pinBoxOuterPadding.bottom, -// ); -// } else { -// insets = widget.pinBoxOuterPadding; -// } -// return Container( -// key: ValueKey("container$i"), -// alignment: Alignment.center, -// padding: EdgeInsets.symmetric(vertical: 4.0, horizontal: 1.0), -// margin: insets, -// child: _animatedTextBox(strList[i], i), -// decoration: BoxDecoration( -// border: Border.all( -// color: borderColor, -// width: widget.pinBoxBorderWidth, -// ), -// color: pinBoxColor, -// borderRadius: BorderRadius.circular(widget.pinBoxRadius), -// ), -// width: widget.pinBoxWidth, -// height: widget.pinBoxHeight, -// ); -// } -// -// Widget _animatedTextBox(String text, int i) { -// if (widget.pinTextAnimatedSwitcherTransition != null) { -// return AnimatedSwitcher( -// duration: widget.pinTextAnimatedSwitcherDuration, -// transitionBuilder: widget.pinTextAnimatedSwitcherTransition ?? -// (Widget child, Animation animation) { -// return child; -// }, -// child: Text( -// text, -// key: ValueKey("$text$i"), -// style: widget.pinTextStyle, -// ), -// ); -// } else { -// return Text( -// text, -// key: ValueKey("${strList[i]}$i"), -// style: widget.pinTextStyle, -// ); -// } -// } -// } diff --git a/lib/theme/app_theme.dart b/lib/theme/app_theme.dart index e081009..aed8437 100644 --- a/lib/theme/app_theme.dart +++ b/lib/theme/app_theme.dart @@ -1,5 +1,5 @@ import 'package:flutter/material.dart'; -import 'package:mohem_flutter_app/sikander_later_will_remove_to_parent_directory/classes/colors.dart'; +import 'package:mohem_flutter_app/classes/colors.dart'; import 'package:mohem_flutter_app/theme/colors.dart'; class AppTheme { @@ -34,7 +34,7 @@ class AppTheme { primaryTextTheme: const TextTheme( bodyText2: TextStyle(color: Colors.white), ), - iconTheme: const IconThemeData(), + 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), diff --git a/lib/sikander_later_will_remove_to_parent_directory/ui/bottom_sheets/country_selection_bottom_sheet.dart b/lib/ui/bottom_sheets/country_selection_bottom_sheet.dart similarity index 100% rename from lib/sikander_later_will_remove_to_parent_directory/ui/bottom_sheets/country_selection_bottom_sheet.dart rename to lib/ui/bottom_sheets/country_selection_bottom_sheet.dart diff --git a/lib/sikander_later_will_remove_to_parent_directory/ui/common_appbar.dart b/lib/ui/common_appbar.dart similarity index 100% rename from lib/sikander_later_will_remove_to_parent_directory/ui/common_appbar.dart rename to lib/ui/common_appbar.dart diff --git a/lib/ui/dashboard.dart b/lib/ui/dashboard.dart new file mode 100644 index 0000000..f6699ae --- /dev/null +++ b/lib/ui/dashboard.dart @@ -0,0 +1,27 @@ +import 'package:flutter/material.dart'; + +class Dashboard extends StatefulWidget { + Dashboard({Key? key}) : super(key: key); + + @override + _DashboardState createState() { + return _DashboardState(); + } +} + +class _DashboardState extends State { + @override + void initState() { + super.initState(); + } + + @override + void dispose() { + super.dispose(); + } + + @override + Widget build(BuildContext context) { + return Scaffold(); + } +} \ No newline at end of file diff --git a/lib/sikander_later_will_remove_to_parent_directory/ui/dialogs/change_password_dialog.dart b/lib/ui/dialogs/change_password_dialog.dart similarity index 100% rename from lib/sikander_later_will_remove_to_parent_directory/ui/dialogs/change_password_dialog.dart rename to lib/ui/dialogs/change_password_dialog.dart diff --git a/lib/sikander_later_will_remove_to_parent_directory/ui/dialogs/general_dialog.dart b/lib/ui/dialogs/general_dialog.dart similarity index 100% rename from lib/sikander_later_will_remove_to_parent_directory/ui/dialogs/general_dialog.dart rename to lib/ui/dialogs/general_dialog.dart diff --git a/lib/sikander_later_will_remove_to_parent_directory/ui/dialogs/loading_dialog.dart b/lib/ui/dialogs/loading_dialog.dart similarity index 100% rename from lib/sikander_later_will_remove_to_parent_directory/ui/dialogs/loading_dialog.dart rename to lib/ui/dialogs/loading_dialog.dart diff --git a/lib/sikander_later_will_remove_to_parent_directory/ui/dialogs/otp_dialog.dart b/lib/ui/dialogs/otp_dialog.dart similarity index 100% rename from lib/sikander_later_will_remove_to_parent_directory/ui/dialogs/otp_dialog.dart rename to lib/ui/dialogs/otp_dialog.dart diff --git a/lib/pages/login/login_screen.dart b/lib/ui/login/login_screen.dart similarity index 88% rename from lib/pages/login/login_screen.dart rename to lib/ui/login/login_screen.dart index 8fd0244..6e043bd 100644 --- a/lib/pages/login/login_screen.dart +++ b/lib/ui/login/login_screen.dart @@ -2,11 +2,12 @@ import 'package:easy_localization/easy_localization.dart'; import 'package:easy_localization/src/public_ext.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; +import 'package:mohem_flutter_app/config/routes.dart'; import 'package:mohem_flutter_app/generated/locale_keys.g.dart'; -import 'package:mohem_flutter_app/sikander_later_will_remove_to_parent_directory/classes/colors.dart'; -import 'package:mohem_flutter_app/sikander_later_will_remove_to_parent_directory/extensions/int_extensions.dart'; -import 'package:mohem_flutter_app/sikander_later_will_remove_to_parent_directory/extensions/widget_extensions.dart'; -import 'package:mohem_flutter_app/sikander_later_will_remove_to_parent_directory/widgets/input_widget.dart'; +import 'package:mohem_flutter_app/classes/colors.dart'; +import 'package:mohem_flutter_app/extensions/int_extensions.dart'; +import 'package:mohem_flutter_app/extensions/widget_extensions.dart'; +import 'package:mohem_flutter_app/widgets/input_widget.dart'; import 'package:mohem_flutter_app/widgets/button/default_button.dart'; class LoginScreen extends StatefulWidget { @@ -94,8 +95,9 @@ class _LoginScreenState extends State { ), DefaultButton(LocaleKeys.login.tr(), () async { // context.setLocale(const Locale("en", "US")); // to change Loacle - }) - .insideContainer + + Navigator.pushNamed(context, AppRoutes.verifyLogin); + }).insideContainer ], ), ); diff --git a/lib/ui/login/verify_login_screen.dart b/lib/ui/login/verify_login_screen.dart new file mode 100644 index 0000000..e661456 --- /dev/null +++ b/lib/ui/login/verify_login_screen.dart @@ -0,0 +1,700 @@ +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/local_auth.dart'; +import 'package:mohem_flutter_app/classes/colors.dart'; +import 'package:mohem_flutter_app/config/routes.dart'; +import 'package:mohem_flutter_app/dialogs/otp_dialog.dart'; +import 'package:mohem_flutter_app/extensions/int_extensions.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/widgets/button/default_button.dart'; + +class VerifyLoginScreen extends StatefulWidget { + VerifyLoginScreen({Key? key}) : super(key: key); + + @override + _VerifyLoginScreenState createState() { + return _VerifyLoginScreenState(); + } +} + +class _VerifyLoginScreenState extends State { + final LocalAuthentication auth = LocalAuthentication(); + List _availableBioMetricType = []; + + @override + void initState() { + _getAvailableBiometrics(); + // setDefault(); + super.initState(); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + backgroundColor: Colors.transparent, + leading: IconButton( + icon: const Icon(Icons.arrow_back_ios, color: MyColors.darkIconColor), + onPressed: () => Navigator.pop(context), + ), + actions: [Center(child: "Employee Digital ID".toText12(color: MyColors.textMixColor, isUnderLine: true).onPress(() {})), 21.width], + ), + body: Column( + children: [ + Expanded( + child: ListView( + padding: const EdgeInsets.all(21), + physics: const BouncingScrollPhysics(), + children: [ + //12.height, + if (true) + Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + LocaleKeys.welcomeBack.tr().toText12(), + "Mohammad Hussain".toText24(isBold: true), + 10.height, + LocaleKeys.wouldYouLikeToLoginWithCurrentUsername.tr().toText16, + Container( + height: 72, + margin: const EdgeInsets.only(top: 23, bottom: 23), + alignment: Alignment.center, + padding: EdgeInsets.only(left: 17, right: 12), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(10), + color: Colors.white, + border: Border.all( + color: Color(0xffefefef), + width: 1, + ), + ), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + LocaleKeys.lastLoginDetails.tr().toText16, + // Text( + // user.editedOn != null + // ? DateUtil.getDayMonthYearDateFormatted(DateUtil.convertStringToDate(user.editedOn)) + // : user.createdOn != null + // ? DateUtil.getDayMonthYearDateFormatted(DateUtil.convertStringToDate(user.createdOn)) + // : '--', + // style: TextStyle(fontSize: 12, fontWeight: FontWeight.w600, color: Color(0xff2B353E), letterSpacing: -0.48), + // ), + ], + ), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + LocaleKeys.verificationType.tr().toText10(color: MyColors.greyColor), + Text( + "SMS", + // " " + getType(user.logInType, context), + style: TextStyle( + fontSize: 12, + fontWeight: FontWeight.w600, + color: Color(0xff2B353E), + ), + ), + Expanded(child: SizedBox()), + // Text( + // user.editedOn != null + // ? DateUtil.formatDateToTimeLang(DateUtil.convertStringToDate(user.editedOn), false) + // : user.createdOn != null + // ? DateUtil.formatDateToTimeLang(DateUtil.convertStringToDate(user.createdOn), false) + // : '--', + // style: TextStyle(fontSize: 12, fontWeight: FontWeight.w600, color: Color(0xff575757), letterSpacing: -0.48), + // ), + ], + ) + ], + ), + ), + LocaleKeys.pleaseVerify.tr().toText16, + GridView( + gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2, crossAxisSpacing: 13, mainAxisSpacing: 9), + physics: const NeverScrollableScrollPhysics(), + padding: const EdgeInsets.only(top: 9), + shrinkWrap: true, + children: [ + getButton(3), + getButton(2), + getButton(1), + getButton(4), + ], + ) + ], + ) + // else + // Column(mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start, children: [ + // Image.asset( + // 'assets/images/habib-logo.png', + // height: 90, + // width: 90, + // ), + // SizedBox(height: 23), + // this.onlySMSBox == false + // ? Text( + // TranslationBase.of(context).verifyLoginWith, + // style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600, color: Color(0xff2B353E), letterSpacing: -0.64, height: 25 / 16), + // ) + // : Text( + // TranslationBase.of(context).verifyFingerprint2, + // style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600, color: Color(0xff2B353E), letterSpacing: -0.64, height: 25 / 16), + // ), + // SizedBox(height: 23), + // Text( + // TranslationBase.of(context).pleaseVerify, + // style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600, color: Color(0xff2E303A), letterSpacing: -0.64), + // ), + // GridView( + // gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2, crossAxisSpacing: 13, mainAxisSpacing: 9), + // physics: NeverScrollableScrollPhysics(), + // padding: EdgeInsets.only(top: 9), + // shrinkWrap: true, + // children: [ + // if (onlySMSBox == false) getButton(3), + // if (onlySMSBox == false) getButton(2), + // getButton(1), + // getButton(4), + // ], + // ), + // ]), + ], + ), + ), + 12.height, + DefaultButton( + LocaleKeys.useAnotherAccount.tr(), + () => { + //Navigator.of(context).pushNamed(LOGIN_TYPE) + }, + ).insideContainer, + ], + ), + ); + } + + Future _getAvailableBiometrics() async { + try { + _availableBioMetricType = await auth.getAvailableBiometrics(); + } on PlatformException catch (e) { + // AppToast.showErrorToast(message: e.message); + print(e); + } + if (mounted) setState(() {}); + } + + // authenticateUser(int type, {int isActive}) { + // GifLoaderDialogUtils.showMyDialog(context); + // if (type == 2 || type == 3) { + // fingrePrintBefore = type; + // } + // this.selectedOption = fingrePrintBefore != null ? fingrePrintBefore : type; + // + // switch (type) { + // case 1: + // this.loginWithSMS(type); + // break; + // case 2: + // this.loginWithFingurePrintFace(type, isActive); + // break; + // case 3: + // this.loginWithFingurePrintFace(type, isActive); + // break; + // case 4: + // this.loginWithSMS(type); + // break; + // default: + // break; + // } + // sharedPref.setInt(LAST_LOGIN, this.selectedOption); //this.cs.sharedService.setStorage(this.selectedOption, AuthenticationService.LAST_LOGIN); + // } +// +// loginWithSMS(type) { +// //if (!el.disabled) { +// if (this.user != null && this.registerd_data == null) { +// this.checkUserAuthentication(type); +// } else { +// if (this.loginTokenID != null) { +// // Future.delayed(Duration(seconds: 1), () { +// this.sendActivationCode(type); +// // }); +// } else { +// this.checkUserAuthentication(type); +// } +// } +// } +// +// checkUserAuthentication(type) { +// showLoader(true); +// var req = getCommonRequest(type: type); +// req.logInTokenID = ""; +// +// var request = CheckPatientAuthenticationReq.fromJson(req.toJson()); +// +// sharedPref.setObject(REGISTER_DATA_FOR_REGISTER, request); +// authService +// .checkPatientAuthentication(request) +// .then((value) => { +// GifLoaderDialogUtils.hideDialog(context), +// if (value['isSMSSent']) +// { +// sharedPref.setString(LOGIN_TOKEN_ID, value['LogInTokenID']), +// this.loginTokenID = value['LogInTokenID'], +// sharedPref.setObject(REGISTER_DATA_FOR_LOGIIN, request), +// // Future.delayed(Duration(seconds: 1), () { +// this.sendActivationCode(type) +// // }) +// } +// else +// { +// if (value['IsAuthenticated']) {this.checkActivationCode()} +// } +// }) +// .catchError((err) { +// print(err); +// GifLoaderDialogUtils.hideDialog(context); +// }); +// } +// +// sendActivationCode(type) async { +// var request = this.getCommonRequest(type: type); +// request.sMSSignature = await SMSOTP.getSignature(); +// GifLoaderDialogUtils.showMyDialog(context); +// if (healthId != null) { +// // final DateFormat dateFormat = DateFormat('MM/dd/yyyy'); +// // final DateFormat dateFormat2 = DateFormat('dd/MM/yyyy'); +// request.dob = dob; //isHijri == 1 ? dob : dateFormat2.format(dateFormat.parse(dob)); +// request.healthId = healthId; +// request.isHijri = isHijri; +// await this.authService.sendActivationCodeRegister(request).then((result) { +// GifLoaderDialogUtils.hideDialog(context); +// if (result != null && result['isSMSSent'] == true) { +// this.startSMSService(type); +// } +// }).catchError((r) { +// GifLoaderDialogUtils.hideDialog(context); +// }); +// } else { +// request.dob = ""; +// request.healthId = ""; +// request.isHijri = 0; +// await this.authService.sendActivationCode(request).then((result) { +// GifLoaderDialogUtils.hideDialog(context); +// if (result != null && result['isSMSSent'] == true) { +// this.startSMSService(type); +// } +// }).catchError((r) { +// GifLoaderDialogUtils.hideDialog(context); +// }); +// } +// } +// +// var tempType; +// +// startSMSService(type) { +// tempType = type; +// new SMSOTP( +// context, +// type, +// this.mobileNumber, +// (value) { +// this.checkActivationCode(value: value); +// }, +// () => { +// Navigator.pop(context), +// }, +// ).displayDialog(context); +// } +// +// loginWithFingurePrintFace(type, int isActive) async { +// if (isActive == 1 || isActive == 0) { +// const iosStrings = +// const IOSAuthMessages(cancelButton: 'cancel', goToSettingsButton: 'settings', goToSettingsDescription: 'Please set up your Touch ID.', lockOut: 'Please reenable your Touch ID'); +// +// try { +// authenticated = await auth.authenticateWithBiometrics(localizedReason: 'Scan your fingerprint to authenticate', useErrorDialogs: true, stickyAuth: true, iOSAuthStrings: iosStrings); +// } on PlatformException catch (e) { +// GifLoaderDialogUtils.hideDialog(context); +// AppToast.showErrorToast(message: 'Please enable your Touch or Face ID'); +// } +// +// if (authenticated == true) { +// // if (user != null && (user.logInType == 2 || user.logInType == 3)) { +// // this.checkActivationCode(); +// // } else { +// +// var request = this.getCommonRequest(type: type); +// this.getMobileInfo(request); +// //} +// } +// } +// } +// +// getMobileInfo(request) { +// // GifLoaderDialogUtils.showMyDialog(context); +// this.authService.getLoginInfo(request).then((result) { +// GifLoaderDialogUtils.hideDialog(context); +// if (result['SMSLoginRequired'] == false) { +// this.loginTokenID = result['LogInTokenID']; +// this.patientOutSA = result['PatientOutSA']; +// // sms for register the biometric +// if (result['isSMSSent']) { +// setState(() { +// isMoreOption = true; +// this.onlySMSBox = true; +// // this.fingrePrintBefore = true; +// }); +// //this.button(); +// } else { +// setDefault(); +// checkActivationCode(); +// } +// } else { +// if (result['IsAuthenticated'] == true) { +// setState(() { +// isMoreOption = true; +// this.onlySMSBox = true; +// // this.fingrePrintBefore = true; +// }); +// } +// } +// }).catchError((err) { +// GifLoaderDialogUtils.hideDialog(context); +// print(err); +// }); +// } +// +// setDefault() async { +// if (await sharedPref.getObject(IMEI_USER_DATA) != null) user = SelectDeviceIMEIRES.fromJson(await sharedPref.getObject(IMEI_USER_DATA)); +// +// if (await sharedPref.getObject(REGISTER_DATA_FOR_LOGIIN) != null) { +// isMoreOption = true; +// this.registerd_data = CheckPatientAuthenticationReq.fromJson(await sharedPref.getObject(REGISTER_DATA_FOR_LOGIIN)); +// } +// +// this.mobileNumber = this.registerd_data != null ? this.registerd_data.patientMobileNumber : int.parse(this.user.mobile); +// this.zipCode = this.registerd_data != null +// ? this.registerd_data.zipCode +// : this.user.outSA == true +// ? "971" +// : "966"; +// this.patientOutSA = this.registerd_data != null +// ? this.registerd_data.zipCode == "966" +// ? 0 +// : 1 +// : this.user.outSA; +// if (this.registerd_data != null) { +// this.loginTokenID = await sharedPref.getString(LOGIN_TOKEN_ID); +// this.loginType = this.registerd_data.searchType; +// } +// var nhic = await sharedPref.getObject(NHIC_DATA); +// if (nhic != null) { +// final DateFormat dateFormat = DateFormat('MM/dd/yyyy'); +// final DateFormat dateFormat2 = DateFormat('dd/MM/yyyy'); +// dob = nhic['IsHijri'] ? nhic['DateOfBirth'] : dateFormat2.format(dateFormat.parse(nhic['DateOfBirth'])); +// +// isHijri = nhic['IsHijri'] ? 1 : 0; +// healthId = nhic['HealthId']; +// } +// this.deviceToken = await sharedPref.getString(PUSH_TOKEN); +// this.lastLogin = await sharedPref.getInt(LAST_LOGIN) != null +// ? await sharedPref.getInt(LAST_LOGIN) +// : user != null +// ? user.logInType +// : null; +// +// //this.cs.sharedService.getStorage(AuthenticationService.LAST_LOGIN); +// } +// +// getCommonRequest({type}) { +// var request = SendActivationRequest(); +// request.patientMobileNumber = this.mobileNumber; +// request.mobileNo = '0' + this.mobileNumber.toString(); +// request.deviceToken = this.deviceToken; +// request.projectOutSA = this.patientOutSA == true ? true : false; +// request.loginType = this.selectedOption; +// request.oTPSendType = type == 1 ? type : 2; //this.selectedOption == 1 ? 1 : 2; +// request.zipCode = this.zipCode; +// +// request.logInTokenID = this.loginTokenID ?? ""; +// +// if (this.registerd_data != null) { +// request.searchType = this.registerd_data.searchType != null ? this.registerd_data.searchType : 1; +// request.patientID = this.registerd_data.patientID != null ? this.registerd_data.patientID : 0; +// request.patientIdentificationID = request.nationalID = this.registerd_data.patientIdentificationID != null ? this.registerd_data.patientIdentificationID : '0'; +// +// request.isRegister = this.registerd_data.isRegister; +// } else { +// request.searchType = request.searchType != null ? request.searchType : 2; +// request.patientID = this.user.patientID != null ? this.user.patientID : 0; +// request.nationalID = request.nationalID != null ? request.nationalID : '0'; +// request.patientIdentificationID = request.patientIdentificationID != null ? request.patientIdentificationID : '0'; +// request.isRegister = false; +// } +// request.deviceTypeID = request.searchType; +// return request; +// } +// +// // checkActivationCode({value}) async { +// // // Navigator.pop(context); +// // GifLoaderDialogUtils.showMyDialog(context); +// // var request = this.getCommonRequest().toJson(); +// // dynamic res; +// // if (healthId != null) { +// // request['DOB'] = dob; +// // request['HealthId'] = healthId; +// // request['IsHijri'] = isHijri; +// // +// // authService +// // .checkActivationCodeRegister(request, value) +// // .then((result) => { +// // res = result, +// // if (result is Map) +// // { +// // result = CheckActivationCode.fromJson(result), +// // if (this.registerd_data != null && this.registerd_data.isRegister == true) +// // { +// // widget.changePageViewIndex(1), +// // Navigator.popUntil(context, (route) => Utils.route(route, equalsTo: RegisterNew)), +// // } +// // } +// // else +// // { +// // // Navigator.of(context).pop(), +// // GifLoaderDialogUtils.hideDialog(context), +// // Future.delayed(Duration(seconds: 1), () { +// // AppToast.showErrorToast(message: result); +// // }), +// // } +// // }) +// // .catchError((err) { +// // print(err); +// // GifLoaderDialogUtils.hideDialog(context); +// // Future.delayed(Duration(seconds: 1), () { +// // AppToast.showErrorToast(message: err); +// // startSMSService(tempType); +// // }); +// // }); +// // } else { +// // authService +// // .checkActivationCode(request, value) +// // .then((result) => { +// // res = result, +// // if (result is Map) +// // { +// // result = CheckActivationCode.fromJson(result), +// // if (this.registerd_data != null && this.registerd_data.isRegister == true) +// // { +// // widget.changePageViewIndex(1), +// // Navigator.popUntil(context, (route) => Utils.route(route, equalsTo: RegisterNew)), +// // } +// // else +// // { +// // sharedPref.remove(FAMILY_FILE), +// // result.list.isFamily = false, +// // userData = result.list, +// // sharedPref.setString(BLOOD_TYPE, result.patientBloodType), +// // authenticatedUserObject.user = result.list, +// // projectViewModel.setPrivilege(privilegeList: res), +// // sharedPref.setObject(MAIN_USER, result.list), +// // sharedPref.setObject(USER_PROFILE, result.list), +// // loginTokenID = result.logInTokenID, +// // sharedPref.setObject(LOGIN_TOKEN_ID, result.logInTokenID), +// // sharedPref.setString(TOKEN, result.authenticationTokenID), +// // checkIfUserAgreedBefore(result), +// // } +// // } +// // else +// // { +// // // // Navigator.of(context).pop(), +// // // GifLoaderDialogUtils.hideDialog(context), +// // // Future.delayed(Duration(seconds: 1), () { +// // // AppToast.showErrorToast(message: result); +// // // startSMSService(tempType); +// // // }), +// // } +// // }) +// // .catchError((err) { +// // // print(err); +// // // GifLoaderDialogUtils.hideDialog(context); +// // // Future.delayed(Duration(seconds: 1), () { +// // // AppToast.showErrorToast(message: err); +// // // startSMSService(tempType); +// // // }); +// // }); +// // } +// // } +// +// // checkIfUserAgreedBefore(CheckActivationCode result) { +// // if (result.isNeedUserAgreement == true) { +// // //move to agreement page. +// // } else { +// // goToHome(); +// // } +// // } +// +// insertIMEI() { +// authService.insertDeviceImei(selectedOption).then((value) => {}).catchError((err) { +// print(err); +// }); +// } +// +// // getToDoCount() { +// // toDoProvider.setState(0, true, "0"); +// // ClinicListService service = new ClinicListService(); +// // service.getActiveAppointmentNo(context).then((res) { +// // if (res['MessageStatus'] == 1) { +// // toDoProvider.setState(res['AppointmentActiveNumber'], true, "0"); +// // } else {} +// // }).catchError((err) { +// // print(err); +// // }); +// // } +// +// // goToHome() async { +// // authenticatedUserObject.isLogin = true; +// // appointmentRateViewModel.isLogin = true; +// // projectViewModel.isLogin = true; +// // projectViewModel.user = authenticatedUserObject.user; +// // await authenticatedUserObject.getUser(getUser: true); +// // +// // // getToDoCount(); +// // +// // appointmentRateViewModel +// // .getIsLastAppointmentRatedList() +// // .then((value) => { +// // getToDoCount(), +// // GifLoaderDialogUtils.hideDialog(AppGlobal.context), +// // if (appointmentRateViewModel.isHaveAppointmentNotRate) +// // { +// // Navigator.pushAndRemoveUntil( +// // context, +// // FadePage( +// // page: RateAppointmentDoctor(), +// // ), +// // (r) => false) +// // } +// // else +// // { +// // Navigator.pushAndRemoveUntil( +// // context, +// // FadePage( +// // page: LandingPage(), +// // ), +// // (r) => false) +// // }, +// // insertIMEI() +// // }) +// // .catchError((err) { +// // print(err); +// // }); +// // } +// +// loading(flag) { +// // setState(() { +// // isLoading = flag; +// // }); +// } +// + Widget _loginOptionButton(String _title, String _icon, int _flag, int? _loginIndex) { + bool isDisable = ((_flag == 3 && !checkBiometricIsAvailable(BiometricType.face)) || (_flag == 2 && !checkBiometricIsAvailable(BiometricType.fingerprint))); + print("$_title:$isDisable"); + return InkWell( + onTap: isDisable + ? null + : () { + if (_flag == 0) { + setState(() { + // isMoreOption = true; + }); + } else { + OtpDialog( + context, + _flag, + //this.mobileNumber + 0554870506, + (value) { + Navigator.pushReplacementNamed(context, AppRoutes.dashboard); + // this.checkActivationCode(value: value); + }, + () => { + Navigator.pop(context), + }, + ).displayDialog(context); + + // authenticateUser(_flag, isActive: _loginIndex); + } + }, + child: Container( + padding: const EdgeInsets.only(left: 20, right: 20, bottom: 15, top: 28), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(15), + color: isDisable ? Colors.grey.withOpacity(0.3) : Colors.white, + border: Border.all(color: MyColors.lightGreyColor, width: 1), + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + SvgPicture.asset( + _icon, + height: 38, + width: 38, + color: isDisable ? MyColors.darkTextColor.withOpacity(0.7) : null, + ), + _title.toText16 + ], + ), + ), + ); + } + + Widget getButton(int flag) { + switch (flag) { + case 4: + return _loginOptionButton(LocaleKeys.verifyThroughWhatsapp.tr(), 'assets/images/verify_whatsapp.svg', flag, null); + case 1: + return _loginOptionButton(LocaleKeys.verifyThroughSMS.tr(), 'assets/images/verify_sms.svg', flag, null); + case 2: + return _loginOptionButton(LocaleKeys.verifyThroughFingerprint.tr(), 'assets/images/verify_thumb.svg', flag, BiometricType.fingerprint.index); + case 3: + return _loginOptionButton(LocaleKeys.verifyThroughFace.tr(), 'assets/images/verify_face.svg', flag, BiometricType.face.index); + default: + return const SizedBox(); + } + } + + bool checkBiometricIsAvailable(BiometricType biometricType) { + bool isAvailable = false; + for (int i = 0; i < _availableBioMetricType.length; i++) { + if (biometricType == _availableBioMetricType[i]) { + isAvailable = true; + break; + } + } + return isAvailable; + } +// +// formatDate(date) { +// return date; +// return DateFormat('MMM dd, yyy, kk:mm').format(date); +// } +// +// showLoader(bool isTrue) { +// setState(() { +// // isLoading = isTrue; +// }); +// } + +} diff --git a/lib/sikander_later_will_remove_to_parent_directory/ui/misc/no_data_ui.dart b/lib/ui/misc/no_data_ui.dart similarity index 87% rename from lib/sikander_later_will_remove_to_parent_directory/ui/misc/no_data_ui.dart rename to lib/ui/misc/no_data_ui.dart index d7110ed..5af6af7 100644 --- a/lib/sikander_later_will_remove_to_parent_directory/ui/misc/no_data_ui.dart +++ b/lib/ui/misc/no_data_ui.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; import 'package:flutter_svg/svg.dart'; -import 'package:mohem_flutter_app/sikander_later_will_remove_to_parent_directory/classes/colors.dart'; +import 'package:mohem_flutter_app/classes/colors.dart'; class NoDataUI extends StatelessWidget { NoDataUI({Key? key}) : super(key: key); diff --git a/lib/sikander_later_will_remove_to_parent_directory/ui/screens/tangheem_detail_screen.dart b/lib/ui/screens/tangheem_detail_screen.dart similarity index 100% rename from lib/sikander_later_will_remove_to_parent_directory/ui/screens/tangheem_detail_screen.dart rename to lib/ui/screens/tangheem_detail_screen.dart diff --git a/lib/utils/AppPermissionHandler.dart b/lib/utils/AppPermissionHandler.dart deleted file mode 100644 index 3e3877e..0000000 --- a/lib/utils/AppPermissionHandler.dart +++ /dev/null @@ -1,36 +0,0 @@ -import 'package:permission_handler/permission_handler.dart'; - -import 'dialogs.dart'; - -enum ConfirmAction { CANCEL, ACCEPT } - -Future requestPermissionGranted( - context, Permission requestPermissions) async { - var result = await requestPermissions.request(); - - switch (result) { - case PermissionStatus.granted: - // Application has been given permission to use the feature. - return true; - case PermissionStatus.denied: - // Application has been denied permission to use the feature. - return false; - case PermissionStatus.permanentlyDenied: - ConfirmAction? res = await showConfirmDialogs( - context, - 'You was denied Permission. You have give manual permission from app setting. ', - 'Open App Setting', - 'Cancel'); - if (res == ConfirmAction.ACCEPT) { - return false; - } else if (res == ConfirmAction.CANCEL) { - return false; - } - return false; - case PermissionStatus.restricted: - // iOS has restricted access to a specific feature. - return false; - default: - return false; - } -} diff --git a/lib/utils/dialogs.dart b/lib/utils/dialogs.dart deleted file mode 100644 index a6bff7e..0000000 --- a/lib/utils/dialogs.dart +++ /dev/null @@ -1,35 +0,0 @@ -import 'package:flutter/material.dart'; - -import 'AppPermissionHandler.dart'; - -Future showConfirmDialogs( - context, msg, positiveText, negativeText) async { - return showDialog( - context: context, - barrierDismissible: false, - builder: (context) { - return AlertDialog( - backgroundColor: Colors.white, - title: Text(msg, style: TextStyle(fontSize: 16)), - actions: [ - TextButton( - child: Text( - negativeText, - ), - onPressed: () { - Navigator.of(context).pop(ConfirmAction.CANCEL); - }, - ), - TextButton( - child: Text( - positiveText, - ), - onPressed: () { - Navigator.of(context).pop(ConfirmAction.ACCEPT); - }, - ) - ], - ); - }, - ); -} diff --git a/lib/utils/navigator.dart b/lib/utils/navigator.dart deleted file mode 100644 index f9855a9..0000000 --- a/lib/utils/navigator.dart +++ /dev/null @@ -1,9 +0,0 @@ -import 'package:flutter/material.dart'; - -navigateWithName(BuildContext context, String routeName, {Object? arguments}) { - Navigator.pushNamed(context, routeName, arguments: arguments); -} - -pop(BuildContext context) { - Navigator.of(context).pop(); -} diff --git a/lib/utils/utils.dart b/lib/utils/utils.dart deleted file mode 100644 index a599b3a..0000000 --- a/lib/utils/utils.dart +++ /dev/null @@ -1,311 +0,0 @@ -import 'dart:convert'; -import 'dart:io'; -import 'dart:typed_data'; -import 'dart:ui'; - -import 'package:mohem_flutter_app/config/constants.dart'; -import 'package:mohem_flutter_app/theme/colors.dart'; -import 'package:mohem_flutter_app/widgets/txt.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter_svg/svg.dart'; - -import 'package:sizer/sizer.dart'; - -Color getColorFromHex(String hexColor) { - hexColor = hexColor.toUpperCase().replaceAll('#', ''); - - if (hexColor.length == 6) { - hexColor = 'FF' + hexColor; - } - - return Color(int.parse(hexColor, radix: 16)); -} - -Widget spacerVertical(double v) { - return Container( - height: v, - width: double.infinity, - ); -} -Future delay(int millis) async { - return await Future.delayed(Duration(milliseconds: millis)); -} - -inkWellCorner({double? r}) { - return RoundedRectangleBorder( - borderRadius: BorderRadius.circular(r ?? 4), - ); -} - -Widget spacerHorizontal(double v) { - return Container( - height: v, - width: v, - ); -} - -Widget mHeight(double f) { - return Container( - width: f, - height: f, - ); -} - -Widget mDivider(Color color, {double? h}) { - return Container( - width: double.infinity, - height: h ?? 1, - color: color, - ); -} - -Widget mDivider3({double? h}) { - return Container( - width: double.infinity, - height: h ?? 1, - color: borderLightColor!.withOpacity(0.7) - ); -} - -Widget mDivider2(Color color, double w) { - return Container( - width: w, - height: 1, - color: color, - ); -} - -InputDecoration txtField(String label) { - return new InputDecoration( - border: InputBorder.none, - focusedBorder: InputBorder.none, - enabledBorder: InputBorder.none, - errorBorder: InputBorder.none, - hintText: label, - hintStyle: TextStyle(color: Colors.grey), - disabledBorder: InputBorder.none, - isDense: false, - contentPadding: EdgeInsets.only(left: 15, right: 15), - ); -} - -Widget mWidth(double f) { - return Container( - width: f, - height: f, - ); -} - -Widget mFlex(int f) { - return Flexible( - flex: f, - child: Container( - width: double.infinity, - height: double.infinity, - ), - ); -} -Widget mExp(int f) { - return Expanded( - flex: f, - child: Container( - width: double.infinity, - ), - ); -} - -spacer() { - return SizedBox( - height: 8, - ); -} - -Widget floatButton(String icon, {Color? color, required Function onClick, String? title}) { - return Padding( - padding: const EdgeInsets.only(top: 12, bottom: 12), - child: Column( - crossAxisAlignment: CrossAxisAlignment.center, - mainAxisAlignment: MainAxisAlignment.center, - children: [ - FloatingActionButton( - onPressed: () { - onClick(); - }, - heroTag: icon, - backgroundColor: accentColor, - elevation: 4, - child: Container( - child: SvgPicture.asset( - categorySvgIcons + icon, - color: color, - ), - width: double.infinity, - height: double.infinity, - decoration: containerRadius(Colors.white, 200), - clipBehavior: Clip.antiAlias, - padding: EdgeInsets.all(15), - margin: EdgeInsets.all(1), - ), - ), - if (title != null) mHeight(2.w), - if (title != null) - Txt( - title, - fontSize: 12.sp, - bold: true, - color: headingColor, - ) - ], - ), - ); -} - -navigateTo(context, page) { - Navigator.push(context, MaterialPageRoute(builder: (context) => page)); -} - -circularImage(String im, double width, double height) { - return new Container(width: 190.0, height: 190.0, decoration: new BoxDecoration(shape: BoxShape.circle, image: new DecorationImage(fit: BoxFit.fill, image: new AssetImage(im)))); -} - -circularImage2(String im, double width, double height) { - return new Container(width: width, height: height, decoration: new BoxDecoration(shape: BoxShape.circle, image: new DecorationImage(fit: BoxFit.fill, image: new AssetImage(im)))); -} - -cardRadius(double radius) { - return RoundedRectangleBorder( - side: BorderSide(color: Colors.transparent, width: 1), - borderRadius: BorderRadius.circular(radius), - ); -} - -cardRadiusWithoutBorder(double radius) { - return RoundedRectangleBorder( - side: BorderSide(color: Colors.transparent, width: 1), - borderRadius: BorderRadius.circular(radius), - ); -} - -Image imageFromBase64String(String base64String) { - return Image.memory(base64Decode(base64String)); -} - -Uint8List dataFromBase64String(String base64String) { - return base64Decode(base64String); -} - -String base64String(Uint8List data) { - return base64Encode(data); -} - -Widget overLayWidget({double? width, double? height,List? color}) { - return Container( - width: width ?? double.infinity, - height: height ?? 60, - decoration: BoxDecoration( - gradient: LinearGradient( - colors: color!=null?color:[ - Colors.black.withOpacity(0.2), - Colors.black.withOpacity(0.1), - Colors.black.withOpacity(0.004), - ], - begin: Alignment.topCenter, - end: Alignment.bottomCenter, - tileMode: TileMode.clamp, - ), - ), - ); -} - -Decoration containerRadius(Color color, double r) { - return BoxDecoration( - color: color, - borderRadius: BorderRadius.all(Radius.circular(r)), - ); -} - -Decoration containerRadiusTop({Color? color, double? r}) { - return BoxDecoration( - color: color ?? Colors.white, - borderRadius: BorderRadius.only(topRight: Radius.circular(r ?? 12), topLeft: Radius.circular(r ?? 12)), - ); -} - -Decoration containerRadiusBorder(Color color, double r) { - return BoxDecoration( - color: Colors.transparent, - border: Border.all(color: color, width: 1), - borderRadius: BorderRadius.all(Radius.circular(r)), - ); -} - -Decoration containerRadiusBottom(Color color, double r) { - return BoxDecoration( - color: color, - borderRadius: BorderRadius.only(bottomLeft: Radius.circular(r), bottomRight: Radius.circular(r)), - ); -} - -ShapeBorder cardRadiusTop(double radius) { - return RoundedRectangleBorder( - side: BorderSide(color: Colors.transparent, width: 0), - borderRadius: BorderRadius.only(topLeft: Radius.circular(radius), topRight: Radius.circular(radius)), - ); -} - -Decoration containerColorRadiusBorderWidth(Color background, double radius, Color color, double w) { - return BoxDecoration( - color: background, - border: Border.all( - width: w, // - color: color // <--- border width here - ), - borderRadius: BorderRadius.circular(radius), - ); -} - -ShapeBorder cardRadiusTop2(double radius) { - return RoundedRectangleBorder( - borderRadius: BorderRadius.only(topLeft: Radius.circular(radius), topRight: Radius.circular(radius)), - ); -} - -ShapeBorder cardRadiusBottom(double radius) { - return RoundedRectangleBorder( - borderRadius: BorderRadius.only(bottomLeft: Radius.circular(radius), bottomRight: Radius.circular(radius)), - ); -} - -Decoration containerColorRadiusBorder(Color background, double radius, Color color) { - return BoxDecoration( - color: background, - border: Border.all( - width: 1, // - color: color // <--- border width here - ), - borderRadius: BorderRadius.circular(radius), - ); -} - - - - - - -//Decoration appGradient = BoxDecoration( -// gradient: LinearGradient( -// colors: [ -// Colors.green[200], -// Colors.green, -// ], -// begin: Alignment.topCenter, -// end: Alignment.bottomCenter, -// ), -//); -// launchURL(String url) async { -// if (await canLaunch(url)) { -// await launch(url); -// } else { -// throw 'Could not launch $url'; -// } -// } diff --git a/lib/widgets/app_bar.dart b/lib/widgets/app_bar.dart deleted file mode 100644 index 3ad0b80..0000000 --- a/lib/widgets/app_bar.dart +++ /dev/null @@ -1,28 +0,0 @@ -import 'package:mohem_flutter_app/theme/colors.dart'; -import 'package:mohem_flutter_app/widgets/txt.dart'; -import 'package:flutter/material.dart'; -import 'package:sizer/sizer.dart'; - -AppBar appBar({ - Color? backgroundColor, - double? elevation, - String? title, - Color? titleColor, - bool? isTitleCenter, - Color? backIconColor, - List? actions, -}) { - return AppBar( - backgroundColor: backgroundColor ?? appBackgroundColor, - elevation: elevation ?? 0, - centerTitle: isTitleCenter ?? true, - iconTheme: IconThemeData( - color: backIconColor ?? Colors.black, //change your color here - ), - actions: actions, - title: Txt( - title ?? "", - txtType: TxtType.appBar, - ), - ); -} diff --git a/lib/widgets/blurry_container.dart b/lib/widgets/blurry_container.dart deleted file mode 100644 index 8bebc4a..0000000 --- a/lib/widgets/blurry_container.dart +++ /dev/null @@ -1,62 +0,0 @@ -import 'dart:ui'; - -import 'package:flutter/material.dart'; - -const kDemoText = Center( - child: Text( - '', - style: TextStyle( - fontSize: 25, - color: Colors.white, - letterSpacing: 2, - ), - textAlign: TextAlign.center, - ), -); -const double kBlur = 1.0; -const EdgeInsetsGeometry kDefaultPadding = EdgeInsets.all(16); -const Color kDefaultColor = Colors.transparent; -const BorderRadius kBorderRadius = BorderRadius.all(Radius.circular(20)); -const double kColorOpacity = 0.0; - -class BlurryContainer extends StatelessWidget { - final Widget child; - final double blur; - final double? height, width; - final EdgeInsetsGeometry padding; - final Color bgColor; - - final BorderRadius borderRadius; - - //final double colorOpacity; - - BlurryContainer({ - this.child = kDemoText, - this.blur = 5, - required this.height, - required this.width, - this.padding = kDefaultPadding, - this.bgColor = kDefaultColor, - this.borderRadius = kBorderRadius, - //this.colorOpacity = kColorOpacity, - }); - - @override - Widget build(BuildContext context) { - return ClipRRect( - borderRadius: borderRadius, - child: BackdropFilter( - filter: ImageFilter.blur(sigmaX: blur, sigmaY: blur), - child: Container( - height: height!, - width: width!, - padding: padding, - color: bgColor == Colors.transparent - ? bgColor - : bgColor.withOpacity(0.5), - child: child, - ), - ), - ); - } -} diff --git a/lib/widgets/button/show_circular_button.dart b/lib/widgets/button/show_circular_button.dart deleted file mode 100644 index c2bd90c..0000000 --- a/lib/widgets/button/show_circular_button.dart +++ /dev/null @@ -1,23 +0,0 @@ -import 'package:mohem_flutter_app/utils/utils.dart'; -import 'package:flutter/material.dart'; - -class ShowCircularButton extends StatelessWidget { - VoidCallback onPressed; - IconData? iconData; - ShowCircularButton({this.iconData,required this.onPressed}); - @override - Widget build(BuildContext context) { - return Card( - shape: cardRadius(1000), - color: Colors.black.withOpacity(0.2), - margin: EdgeInsets.all(12), - child: IconButton( - onPressed: onPressed, - icon: Icon( - iconData?? Icons.amp_stories_outlined, - color: Colors.white, - ), - ), - ); - } -} diff --git a/lib/widgets/button/show_image_button.dart b/lib/widgets/button/show_image_button.dart deleted file mode 100644 index 8e60d11..0000000 --- a/lib/widgets/button/show_image_button.dart +++ /dev/null @@ -1,43 +0,0 @@ -import 'package:mohem_flutter_app/theme/colors.dart'; -import 'package:mohem_flutter_app/utils/utils.dart'; -import 'package:flutter/material.dart'; - -import '../txt.dart'; - -class ShowImageButton extends StatelessWidget { - String icon, title; - VoidCallback onClick; - - ShowImageButton( - {required this.icon, required this.title, required this.onClick}); - - @override - Widget build(BuildContext context) { - return InkWell( - onTap: onClick, - child: Container( - width: double.infinity, - child: Column( - children: [ - Container( - width: double.infinity, - height: 120, - color: accentColor, - padding: EdgeInsets.all(30), - child: Image.asset( - icon, - color: Colors.white, - ), - ), - mHeight(12), - Txt( - title, - txtType: TxtType.heading2, - color: Colors.blue, - ) - ], - ), - ), - ); - } -} diff --git a/lib/widgets/dialog/dialogs.dart b/lib/widgets/dialog/dialogs.dart deleted file mode 100644 index 9a5a822..0000000 --- a/lib/widgets/dialog/dialogs.dart +++ /dev/null @@ -1,16 +0,0 @@ -import 'package:flutter/material.dart'; - -void showMDialog( - context, { - Widget? child, -}) async { - return showDialog( - context: context, - barrierDismissible: true, - builder: (context) { - return Dialog( - child: child, - ); - }, - ); -} diff --git a/lib/widgets/dialog/message_dialog.dart b/lib/widgets/dialog/message_dialog.dart deleted file mode 100644 index 4181370..0000000 --- a/lib/widgets/dialog/message_dialog.dart +++ /dev/null @@ -1,38 +0,0 @@ -import 'package:mohem_flutter_app/theme/colors.dart'; -import 'package:mohem_flutter_app/utils/navigator.dart'; -import 'package:mohem_flutter_app/utils/utils.dart'; -import 'package:mohem_flutter_app/widgets/show_fill_button.dart'; -import 'package:mohem_flutter_app/widgets/txt.dart'; -import 'package:flutter/material.dart'; - -class MessageDialog extends StatelessWidget { - String? title, buttonTitle; - VoidCallback? onClick; - MessageDialog({this.title, this.buttonTitle,this.onClick}); - - @override - Widget build(BuildContext context) { - return Container( - color: Colors.white, - padding: EdgeInsets.all(30), - child: Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Txt( - title ?? "message", - txtType: TxtType.heading3, - ), - mHeight(40), - ShowFillButton( - title: buttonTitle ?? "Continue", - width: double.infinity, - onPressed: () { - onClick!(); - }, - ) - ], - ), - ); - } -} diff --git a/lib/widgets/dialog/otp_dialog.dart b/lib/widgets/dialog/otp_dialog.dart deleted file mode 100644 index 3790c44..0000000 --- a/lib/widgets/dialog/otp_dialog.dart +++ /dev/null @@ -1,74 +0,0 @@ -import 'package:mohem_flutter_app/theme/colors.dart'; -import 'package:mohem_flutter_app/utils/navigator.dart'; -import 'package:mohem_flutter_app/utils/utils.dart'; -import 'package:mohem_flutter_app/widgets/show_fill_button.dart'; -import 'package:mohem_flutter_app/widgets/txt.dart'; -import 'package:flutter/material.dart'; - -class OtpDialog extends StatelessWidget { - VoidCallback onClick; - - OtpDialog({required this.onClick}); - - @override - Widget build(BuildContext context) { - return Container( - color: Colors.white, - padding: EdgeInsets.all(30), - child: Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Txt( - "Please insert OTP Code", - txtType: TxtType.heading3, - ), - mHeight(20), - Row( - children: [ - Expanded( - child: Container( - width: double.infinity, - height: 60, - color: accentColor.withOpacity(0.3), - ), - ), - mWidth(12), - Expanded( - child: Container( - width: double.infinity, - height: 60, - color: accentColor.withOpacity(0.3), - ), - ), - mWidth(12), - Expanded( - child: Container( - width: double.infinity, - height: 60, - color: accentColor.withOpacity(0.3), - ), - ), - mWidth(12), - Expanded( - child: Container( - width: double.infinity, - height: 60, - color: accentColor.withOpacity(0.3), - ), - ), - ], - ), - mHeight(40), - ShowFillButton( - title: "Check Code", - width: double.infinity, - onPressed: () { - onClick(); - }, - ) - ], - ), - ); - } -} diff --git a/lib/widgets/dragable_sheet.dart b/lib/widgets/dragable_sheet.dart deleted file mode 100644 index 4d91118..0000000 --- a/lib/widgets/dragable_sheet.dart +++ /dev/null @@ -1,26 +0,0 @@ -import 'package:flutter/cupertino.dart'; -import 'package:flutter/material.dart'; - -showDraggableDialog(BuildContext context, Widget child) { - showGeneralDialog( - barrierLabel: "Label", - barrierDismissible: false, - barrierColor: Colors.black.withOpacity(0.2), - transitionDuration: Duration(milliseconds: 200), - context: context, - pageBuilder: (context, anim1, anim2) { - return Dismissible( - direction: DismissDirection.vertical, - key: const Key('key'), - onDismissed: (_) => Navigator.of(context).pop(), - child: child, - ); - }, - transitionBuilder: (context, anim1, anim2, child) { - return SlideTransition( - position: Tween(begin: Offset(0, 1), end: Offset(0, 0)).animate(anim1), - child: child, - ); - }, - ); -} diff --git a/lib/widgets/dropdown/dropdow_field.dart b/lib/widgets/dropdown/dropdow_field.dart deleted file mode 100644 index 091b6f6..0000000 --- a/lib/widgets/dropdown/dropdow_field.dart +++ /dev/null @@ -1,78 +0,0 @@ -import 'package:mohem_flutter_app/theme/colors.dart'; -import 'package:mohem_flutter_app/utils/utils.dart'; -import 'package:flutter/material.dart'; -import 'package:mohem_flutter_app/theme/colors.dart'; -import 'package:mohem_flutter_app/utils/utils.dart'; - -import '../txt.dart'; - -class DropdownField extends StatefulWidget { - String? hint; - List? list; - - DropdownField({this.hint, this.list}); - - @override - State createState() => _DropdownFieldState(); -} - -class _DropdownFieldState extends State { - String? dropdownValue; - - @override - Widget build(BuildContext context) { - return Container( - decoration: containerColorRadiusBorderWidth( - Colors.transparent, - 4, - borderColor, - 0.5, - ), - margin: EdgeInsets.all(2), - padding: EdgeInsets.only(left: 8, right: 8), - child: DropdownButton( - value: dropdownValue, - icon: const Icon(Icons.keyboard_arrow_down_sharp), - elevation: 16, - iconSize: 16, - iconEnabledColor: borderColor, - iconDisabledColor: borderColor, - isExpanded: true, - style: const TextStyle(color: Colors.black), - hint: Txt( - widget.hint ?? "", - txtType: TxtType.heading1, - bold: false, - color: borderColor, - ), - underline: Container( - height: 0, - ), - onChanged: (String? newValue) { - setState(() { - dropdownValue = newValue!; - }); - }, - items: (widget.list ?? - [ - 'One', - 'Two', - 'Free', - 'Four', - ]) - .map>( - (String value) { - return DropdownMenuItem( - value: value, - child: Txt( - value, - txtType: TxtType.heading1, - bold: false, - ), - ); - }, - ).toList(), - ), - ); - } -} diff --git a/lib/widgets/dropdown/dropdown_text.dart b/lib/widgets/dropdown/dropdown_text.dart deleted file mode 100644 index 4031a98..0000000 --- a/lib/widgets/dropdown/dropdown_text.dart +++ /dev/null @@ -1,33 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:flutter_svg/flutter_svg.dart'; -import 'package:mohem_flutter_app/config/constants.dart'; -import 'package:mohem_flutter_app/theme/colors.dart'; -import 'package:mohem_flutter_app/utils/utils.dart'; -import 'package:mohem_flutter_app/widgets/txt.dart'; - -class DropDownText extends StatelessWidget { - String title; - - DropDownText(this.title); - - @override - Widget build(BuildContext context) { - return Row( - crossAxisAlignment: CrossAxisAlignment.center, - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Txt( - title, - txtType: TxtType.heading3, - color: accentColor, - ), - mWidth(16), - SvgPicture.asset( - svgIcons + "ic_arrow_down.svg", - width: 10, - height: 10, - ), - ], - ); - } -} diff --git a/lib/widgets/extensions/extensions_widget.dart b/lib/widgets/extensions/extensions_widget.dart deleted file mode 100644 index caaaba9..0000000 --- a/lib/widgets/extensions/extensions_widget.dart +++ /dev/null @@ -1,235 +0,0 @@ -import 'dart:math'; - -import 'package:flutter/material.dart'; - -extension ExtendedText on Widget { - showOverlay({double? width, double? height}){ - return Container( - width: width ?? double.infinity, - height: height ?? 60, - decoration: BoxDecoration( - gradient: LinearGradient(colors: [ - Colors.black.withOpacity(0.2), - Colors.black.withOpacity(0.1), - Colors.black.withOpacity(0.004), - ], begin: Alignment.topCenter, end: Alignment.bottomCenter, tileMode: TileMode.clamp), - ), - child: this, - ); - } -} - - - - - -extension ImageExt on Image { - Widget circular() { - return ClipRRect( - clipBehavior: Clip.hardEdge, - borderRadius: BorderRadius.circular(100), - child: this, - ); - } -} - -extension WidgetExt on Widget { - Widget toWidget() { - return this as Widget; - } - - Widget sized({double? width, double? height}) { - return SizedBox( - width: width, - height: height, - child: this, - ); - } - Widget inkWell({required VoidCallback onTap,double radius=0}){ - return InkWell( - child: Material(child: this,color: Colors.transparent,), - onTap: onTap, - ); - } - Widget sizeSq(double size) { - return SizedBox( - width: size, - height: size, - child: this, - ); - } - - Widget fillParent({double hFactor = 1, double? vFactor}) { - return FractionallySizedBox( - heightFactor: null, - widthFactor: hFactor, - child: this, - ); - } - - Widget margin( - {double top = 0, double bottom = 0, double left = 0, double right = 0}) { - var pad = - EdgeInsets.only(top: top, left: left, bottom: bottom, right: right); - try { - (this as dynamic).margin = pad; - } catch (err) { - return Padding( - padding: pad, - child: this, - ); - } - return this; - } - - Widget toClip({double r = 40}) { - return ClipRRect( - borderRadius: BorderRadius.all( - Radius.circular(r), - ), - clipBehavior: Clip.antiAlias, - child: this, - ); - } - - // Widget scrollable({Axis? direction, bool fadingEdge = true}) { - // var scrollview = SingleChildScrollView( - // child: this, - // controller: ScrollController(), - // scrollDirection: direction ?? Axis.vertical, - // ); - // return fadingEdge ? scrollview.fadingEdge() : scrollview; - // } - - Widget expand() { - return Expanded( - child: this, - ); - } - - Widget align(Alignment alignment) { - return Align( - alignment: alignment, - child: this, - ); - } - - Widget center() { - return Center( - child: this, - ); - } - - Widget padding(EdgeInsets padding) { - return Padding( - padding: padding, - child: this, - ); - } - - Widget paddingAll(double padding) { - return Padding( - padding: EdgeInsets.all(padding), - child: this, - ); - } - - // Widget onTap(VoidCallback onTap, {double corners = 0}) { - // return Clickable.widget(child: this, corners: corners, onTap: onTap); - // } - - Widget ignoreInteraction() { - return IgnorePointer( - child: this, - ); - } -} - -// extension xScrollView on ScrollView { -// Widget fadingEdge() => FadingEdgeScrollView.fromScrollView( -// child: this, -// gradientFractionOnEnd: 0.08, -// gradientFractionOnStart: 0.08, -// shouldDisposeScrollController: true, -// ); -// } -// -// extension x2ScrollView on SingleChildScrollView { -// Widget fadingEdge() => FadingEdgeScrollView.fromSingleChildScrollView( -// child: this, -// gradientFractionOnEnd: 0.08, -// gradientFractionOnStart: 0.08, -// shouldDisposeScrollController: true, -// ); -// } - -class Position { - final double x, y, w, h; - - Position(this.x, this.y, this.w, this.h); -} - -extension KeyExt on GlobalKey { - Position globalPosition() { - RenderBox box = currentContext!.findRenderObject() as RenderBox; - Offset xy = box.localToGlobal(Offset.zero); - Size wh = box.size; - return Position(xy.dx, xy.dy, wh.width, wh.height); - } -} - -extension StateExt on State { - reload({VoidCallback? b}) { - setState(b ?? () {}); - } -} - -// extension LocatiionExt on Location { -// LatLng toLatLng() { -// return LatLng(lat!, lng!); -// } -// } - -// extension xList on List { -// T randomItem() { -// final random = new Random(); -// var i = random.nextInt(this.length); -// return this[i]; -// } -// -// List append(List items) { -// this.addAll(items); -// return this; -// } -// -// bool isFirst(T item) => first == item; -// -// bool isLast(T item) => last == item; -// -// getOneByOne( -// {required int delayMillis, -// required Function(T) callback, VoidCallback? complete}) async { -// for (var i in this) { -// await delay(delayMillis); -// callback(i); -// } -// complete!(); -// } -// } - -extension xFuture on Future { - thenWithDelay(int millis, Function(T) thenBlock) { - then((value) { - Future.delayed(Duration(milliseconds: millis)) - .then((value) => thenBlock(value)); - }); - } -} - -extension xDouble on int { - Duration durationMillis() => Duration(milliseconds: this); - - Duration durationSec() => Duration(seconds: this); - - Duration durationHour() => Duration(hours: this); -} diff --git a/lib/widgets/gradient_app_bar.dart b/lib/widgets/gradient_app_bar.dart deleted file mode 100644 index c3ded30..0000000 --- a/lib/widgets/gradient_app_bar.dart +++ /dev/null @@ -1,63 +0,0 @@ -import 'package:flutter/material.dart'; - -class GradientAppBar extends StatelessWidget { - final String title; - final double barHeight = 50.0; - IconData? iconData; - - GradientAppBar(this.title, {this.iconData}); - - @override - Widget build(BuildContext context) { - final double statusbarHeight = MediaQuery.of(context).padding.top; - - return new Container( - padding: EdgeInsets.only(top: statusbarHeight), - height: statusbarHeight + barHeight, - child: Row( - children: [ - IconButton( - onPressed: () { - Navigator.pop(context); - }, - icon: Icon( - Icons.arrow_back_ios, - color: Colors.white, - ), - ), - Expanded( - child: Center( - child: Text( - title, - style: TextStyle( - fontSize: 20.0, - color: Colors.white, - fontWeight: FontWeight.bold), - ), - ), - ), - if (iconData != null) - IconButton( - onPressed: () {}, - icon: Icon( - iconData, - color: Colors.white, - ), - ), - ], - ), - decoration: BoxDecoration( - gradient: LinearGradient( - colors: [ - Colors.black.withOpacity(0.4), - Colors.black.withOpacity(0.2), - Colors.black.withOpacity(0.0001), - ], - begin: Alignment.topCenter, - end: Alignment.bottomCenter, - tileMode: TileMode.clamp, - ), - ), - ); - } -} diff --git a/lib/widgets/images/circular_image.dart b/lib/widgets/images/circular_image.dart deleted file mode 100644 index dd64efa..0000000 --- a/lib/widgets/images/circular_image.dart +++ /dev/null @@ -1,30 +0,0 @@ -import 'package:mohem_flutter_app/config/constants.dart'; -import 'package:mohem_flutter_app/utils/utils.dart'; -import 'package:flutter/material.dart'; - -class CircularImage extends StatelessWidget { - double? w, h, padding; - String? image; - - CircularImage({this.w, this.h, this.image, this.padding}); - - @override - Widget build(BuildContext context) { - return Container( - width: w ?? 120, - height: h ?? 120, - child: Card( - shape: cardRadius(2000), - clipBehavior: Clip.antiAlias, - elevation: 4, - child: Card( - shape: cardRadius(2000), - clipBehavior: Clip.antiAlias, - elevation: 0, - margin: EdgeInsets.all(padding ?? 0), - child: Image.asset(image ?? icons + "green.jpg"), - ), - ), - ); - } -} diff --git a/lib/sikander_later_will_remove_to_parent_directory/widgets/input_widget.dart b/lib/widgets/input_widget.dart similarity index 97% rename from lib/sikander_later_will_remove_to_parent_directory/widgets/input_widget.dart rename to lib/widgets/input_widget.dart index 162fd35..97e90a2 100644 --- a/lib/sikander_later_will_remove_to_parent_directory/widgets/input_widget.dart +++ b/lib/widgets/input_widget.dart @@ -1,5 +1,5 @@ import 'package:flutter/material.dart'; -import 'package:mohem_flutter_app/sikander_later_will_remove_to_parent_directory/classes/colors.dart'; +import 'package:mohem_flutter_app/classes/colors.dart'; class InputWidget extends StatelessWidget { final String labelText; diff --git a/lib/widgets/otp_widget.dart b/lib/widgets/otp_widget.dart new file mode 100644 index 0000000..a489e61 --- /dev/null +++ b/lib/widgets/otp_widget.dart @@ -0,0 +1,373 @@ +import 'dart:async'; + +import 'package:flutter/animation.dart'; +import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/rendering.dart'; +import 'package:flutter/services.dart'; + +typedef OnDone = void Function(String text); + +class ProvidedPinBoxTextAnimation { + static AnimatedSwitcherTransitionBuilder scalingTransition = (child, animation) { + return ScaleTransition( + child: child, + scale: animation, + ); + }; + + static AnimatedSwitcherTransitionBuilder defaultNoTransition = (Widget child, Animation animation) { + return child; + }; +} + +class OTPWidget extends StatefulWidget { + final int maxLength; + final TextEditingController? controller; + + final Color defaultBorderColor; + final Color pinBoxColor; + final double pinBoxBorderWidth; + final double pinBoxRadius; + final bool hideDefaultKeyboard; + + final TextStyle? pinTextStyle; + final double pinBoxHeight; + final double pinBoxWidth; + final OnDone? onDone; + final bool hasError; + final Color errorBorderColor; + final Color textBorderColor; + final Function(String)? onTextChanged; + final bool autoFocus; + final FocusNode? focusNode; + final AnimatedSwitcherTransitionBuilder? pinTextAnimatedSwitcherTransition; + final Duration pinTextAnimatedSwitcherDuration; + final TextDirection textDirection; + final TextInputType keyboardType; + final EdgeInsets pinBoxOuterPadding; + + const OTPWidget({ + Key? key, + this.maxLength: 4, + this.controller, + this.pinBoxWidth: 70.0, + this.pinBoxHeight: 70.0, + this.pinTextStyle, + this.onDone, + this.defaultBorderColor: Colors.black, + this.textBorderColor: Colors.black, + this.pinTextAnimatedSwitcherTransition, + this.pinTextAnimatedSwitcherDuration: const Duration(), + this.hasError: false, + this.errorBorderColor: Colors.red, + this.onTextChanged, + this.autoFocus: false, + this.focusNode, + this.textDirection: TextDirection.ltr, + this.keyboardType: TextInputType.number, + this.pinBoxOuterPadding = const EdgeInsets.symmetric(horizontal: 4.0), + this.pinBoxColor = Colors.white, + this.pinBoxBorderWidth = 2.0, + this.pinBoxRadius = 0, + this.hideDefaultKeyboard = false, + }) : super(key: key); + + @override + State createState() { + return OTPWidgetState(); + } +} + +class OTPWidgetState extends State with SingleTickerProviderStateMixin { + AnimationController? _highlightAnimationController; + FocusNode? focusNode; + String text = ""; + int currentIndex = 0; + List strList = []; + bool hasFocus = false; + + @override + void didUpdateWidget(OTPWidget oldWidget) { + super.didUpdateWidget(oldWidget); + focusNode = widget.focusNode ?? focusNode; + + if (oldWidget.maxLength < widget.maxLength) { + setState(() { + currentIndex = text.length; + }); + widget.controller?.text = text; + widget.controller?.selection = TextSelection.collapsed(offset: text.length); + } else if (oldWidget.maxLength > widget.maxLength && widget.maxLength > 0 && text.length > 0 && text.length > widget.maxLength) { + setState(() { + text = text.substring(0, widget.maxLength); + currentIndex = text.length; + }); + widget.controller?.text = text; + widget.controller?.selection = TextSelection.collapsed(offset: text.length); + } + } + + _calculateStrList() { + if (strList.length > widget.maxLength) { + strList.length = widget.maxLength; + } + while (strList.length < widget.maxLength) { + strList.add(""); + } + } + + @override + void initState() { + super.initState(); + focusNode = widget.focusNode ?? FocusNode(); + + _initTextController(); + _calculateStrList(); + widget.controller?.addListener(_controllerListener); + focusNode?.addListener(_focusListener); + } + + void _controllerListener() { + if (mounted == true) { + setState(() { + _initTextController(); + }); + var onTextChanged = widget.onTextChanged; + if (onTextChanged != null) { + onTextChanged(widget.controller?.text ?? ""); + } + } + } + + void _focusListener() { + if (mounted == true) { + setState(() { + hasFocus = focusNode?.hasFocus ?? false; + }); + } + } + + void _initTextController() { + if (widget.controller == null) { + return; + } + strList.clear(); + var text = widget.controller?.text ?? ""; + if (text.isNotEmpty) { + if (text.length > widget.maxLength) { + throw Exception("TextEditingController length exceeded maxLength!"); + } + } + for (var i = 0; i < text.length; i++) { + strList.add(text[i]); + } + } + + double get _width { + var width = 0.0; + for (var i = 0; i < widget.maxLength; i++) { + width += widget.pinBoxWidth; + if (i == 0) { + width += widget.pinBoxOuterPadding.left; + } else if (i + 1 == widget.maxLength) { + width += widget.pinBoxOuterPadding.right; + } else { + width += widget.pinBoxOuterPadding.left; + } + } + return width; + } + + @override + void dispose() { + if (widget.focusNode == null) { + focusNode?.dispose(); + } else { + focusNode?.removeListener(_focusListener); + } + _highlightAnimationController?.dispose(); + widget.controller?.removeListener(_controllerListener); + + super.dispose(); + } + + @override + Widget build(BuildContext context) { + return Stack( + children: [ + _otpTextInput(), + _touchPinBoxRow(), + ], + ); + } + + Widget _touchPinBoxRow() { + return widget.hideDefaultKeyboard + ? _pinBoxRow(context) + : GestureDetector( + behavior: HitTestBehavior.opaque, + onTap: () { + if (hasFocus) { + FocusScope.of(context).requestFocus(FocusNode()); + Future.delayed(Duration(milliseconds: 100), () { + FocusScope.of(context).requestFocus(focusNode); + }); + } else { + FocusScope.of(context).requestFocus(focusNode); + } + }, + child: _pinBoxRow(context), + ); + } + + Widget _otpTextInput() { + var transparentBorder = OutlineInputBorder( + borderSide: BorderSide( + color: Colors.transparent, + width: 0.0, + ), + ); + return Container( + width: _width, + height: widget.pinBoxHeight, + child: TextField( + autofocus: !kIsWeb ? widget.autoFocus : false, + enableInteractiveSelection: false, + focusNode: focusNode, + controller: widget.controller, + keyboardType: widget.keyboardType, + inputFormatters: widget.keyboardType == TextInputType.number ? [FilteringTextInputFormatter.digitsOnly] : null, + style: TextStyle( + height: 0.1, + color: Colors.transparent, + ), + decoration: InputDecoration( + contentPadding: EdgeInsets.all(0), + focusedErrorBorder: transparentBorder, + errorBorder: transparentBorder, + disabledBorder: transparentBorder, + enabledBorder: transparentBorder, + focusedBorder: transparentBorder, + counterText: null, + counterStyle: null, + helperStyle: TextStyle( + height: 0.0, + color: Colors.transparent, + ), + labelStyle: TextStyle(height: 0.1), + fillColor: Colors.transparent, + border: InputBorder.none, + ), + cursorColor: Colors.transparent, + showCursor: false, + maxLength: widget.maxLength, + onChanged: _onTextChanged, + ), + ); + } + + void _onTextChanged(text) { + var onTextChanged = widget.onTextChanged; + if (onTextChanged != null) { + onTextChanged(text); + } + setState(() { + this.text = text; + if (text.length >= currentIndex) { + for (int i = currentIndex; i < text.length; i++) { + strList[i] = text[i]; + } + } + currentIndex = text.length; + }); + if (text.length == widget.maxLength) { + FocusScope.of(context).requestFocus(FocusNode()); + var onDone = widget.onDone; + if (onDone != null) { + onDone(text); + } + } + } + + Widget _pinBoxRow(BuildContext context) { + _calculateStrList(); + List pinCodes = List.generate(widget.maxLength, (int i) { + return _buildPinCode(i, context); + }); + return Row(children: pinCodes, mainAxisSize: MainAxisSize.min); + } + + Widget _buildPinCode(int i, BuildContext context) { + Color borderColor; + Color pinBoxColor = widget.pinBoxColor; + + if (widget.hasError) { + borderColor = widget.errorBorderColor; + } else if (i < text.length) { + borderColor = widget.textBorderColor; + } else { + borderColor = widget.defaultBorderColor; + pinBoxColor = widget.pinBoxColor; + } + + EdgeInsets insets; + if (i == 0) { + insets = EdgeInsets.only( + left: 0, + top: widget.pinBoxOuterPadding.top, + right: widget.pinBoxOuterPadding.right, + bottom: widget.pinBoxOuterPadding.bottom, + ); + } else if (i == strList.length - 1) { + insets = EdgeInsets.only( + left: widget.pinBoxOuterPadding.left, + top: widget.pinBoxOuterPadding.top, + right: 0, + bottom: widget.pinBoxOuterPadding.bottom, + ); + } else { + insets = widget.pinBoxOuterPadding; + } + return Container( + key: ValueKey("container$i"), + alignment: Alignment.center, + padding: EdgeInsets.symmetric(vertical: 4.0, horizontal: 1.0), + margin: insets, + child: _animatedTextBox(strList[i], i), + decoration: BoxDecoration( + border: Border.all( + color: borderColor, + width: widget.pinBoxBorderWidth, + ), + color: pinBoxColor, + borderRadius: BorderRadius.circular(widget.pinBoxRadius), + ), + width: widget.pinBoxWidth, + height: widget.pinBoxHeight, + ); + } + + Widget _animatedTextBox(String text, int i) { + if (widget.pinTextAnimatedSwitcherTransition != null) { + return AnimatedSwitcher( + duration: widget.pinTextAnimatedSwitcherDuration, + transitionBuilder: widget.pinTextAnimatedSwitcherTransition ?? + (Widget child, Animation animation) { + return child; + }, + child: Text( + text, + key: ValueKey("$text$i"), + style: widget.pinTextStyle, + ), + ); + } else { + return Text( + text, + key: ValueKey("${strList[i]}$i"), + style: widget.pinTextStyle, + ); + } + } +} diff --git a/lib/widgets/show_card_buttton.dart b/lib/widgets/show_card_buttton.dart deleted file mode 100644 index 7b9ac38..0000000 --- a/lib/widgets/show_card_buttton.dart +++ /dev/null @@ -1,32 +0,0 @@ -import 'package:mohem_flutter_app/theme/colors.dart'; -import 'package:mohem_flutter_app/widgets/show_fill_button.dart'; -import 'package:flutter/material.dart'; - -class ShowCardButton extends StatelessWidget { - String title; - VoidCallback onPressed; - Color txtColor; - - ShowCardButton({ - required this.title, - required this.onPressed, - this.txtColor = Colors.white, - }); - - @override - Widget build(BuildContext context) { - return Card( - margin: EdgeInsets.zero, - elevation: 20, - child: Container( - width: double.infinity, - padding: EdgeInsets.all(12), - child: ShowFillButton( - title: title, - onPressed: onPressed, - txtColor: txtColor, - ), - ), - ); - } -} diff --git a/lib/widgets/show_fill_button.dart b/lib/widgets/show_fill_button.dart deleted file mode 100644 index 168521e..0000000 --- a/lib/widgets/show_fill_button.dart +++ /dev/null @@ -1,41 +0,0 @@ -import 'package:mohem_flutter_app/theme/colors.dart'; -import 'package:mohem_flutter_app/widgets/txt.dart'; -import 'package:flutter/material.dart'; - -class ShowFillButton extends StatelessWidget { - String title; - VoidCallback onPressed; - Color txtColor; - double elevation, radius,width; - - ShowFillButton({ - required this.title, - required this.onPressed, - this.txtColor = Colors.white, - this.elevation = 4, - this.radius = 6, - this.width=88, - }); - - @override - Widget build(BuildContext context) { - return ElevatedButton( - style: ElevatedButton.styleFrom( - onPrimary: Colors.black87, - primary: accentColor, - minimumSize: Size(width, 45), - padding: EdgeInsets.symmetric(horizontal: 16), - elevation: elevation, - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.all(Radius.circular(radius)), - ), - ), - onPressed: onPressed, - child: Txt( - title.toUpperCase(), - color: txtColor, - txtType: TxtType.heading1, - ), - ); - } -} diff --git a/lib/widgets/txt.dart b/lib/widgets/txt.dart deleted file mode 100644 index 8591277..0000000 --- a/lib/widgets/txt.dart +++ /dev/null @@ -1,170 +0,0 @@ -// import 'package:auto_size_text/auto_size_text.dart'; -import 'package:mohem_flutter_app/theme/colors.dart'; -import 'package:mohem_flutter_app/utils/utils.dart'; -import 'package:flutter/material.dart'; -import 'package:sizer/sizer.dart'; - -enum TxtType { - small, - normal, - heading1, - heading2, - heading3, - appBar, -} - -class Txt extends StatelessWidget { - String text; - int? maxLines; - double? fontSize; - Color? color; - bool? bold; - bool? isUnderline; - bool? isFlatButton; - double? pedding; - TextAlign? textAlign; - FontWeight? fontWeight; - Function? onTap; - TxtType txtType; - - Txt(this.text, {this.maxLines, this.color, this.bold, this.fontSize, this.isUnderline, this.isFlatButton, this.pedding, this.textAlign, this.fontWeight, this.onTap, this.txtType = TxtType.normal}); - - @override - Widget build(BuildContext context) { - if (isFlatButton != null) - return Padding( - padding: EdgeInsets.only(right: pedding ?? 0, left: pedding ?? 0), - child: InkWell( - onTap: () { - onTap!(); - }, - customBorder: inkWellCorner(r: 4), - child: Padding( - padding: const EdgeInsets.only( - left: 14, - right: 14, - top: 6, - bottom: 6, - ), - child: getText(), - ), - ), - ); - else - return getText(); - } - - Widget getText() { - return Material( - type: MaterialType.transparency, - child: Text( - text, - maxLines: maxLines, - textAlign: textAlign, - overflow: maxLines != null ? TextOverflow.ellipsis : null, - style: TextStyle( - fontSize: fontSize ?? - (txtType == TxtType.small - ? 8.sp - : txtType == TxtType.normal - ? 10.sp - : txtType == TxtType.heading1 - ? 11.sp - : txtType == TxtType.heading2 - ? 12.sp - : txtType == TxtType.heading3 - ? 13.sp - : txtType == TxtType.appBar - ? 14.sp - : 8.sp), - color: color ?? - (txtType == TxtType.appBar - ? Colors.black - : txtType == TxtType.heading1 - ? headingColor - : txtType == TxtType.heading2 - ? headingColor - : txtType == TxtType.heading3 - ? headingColor - : null), - fontWeight: (fontWeight != null) - ? fontWeight - : ((bold != null) - ? FontWeight.bold - : (txtType == TxtType.appBar - ? FontWeight.bold - : txtType == TxtType.heading1 - ? FontWeight.bold - : txtType == TxtType.heading2 - ? FontWeight.bold - : txtType == TxtType.heading3 - ? FontWeight.bold - : null)), - decoration: (isUnderline != null) ? TextDecoration.underline : null, - ), - ), - ); - } -} - -// class TxtAuto extends StatelessWidget { -// String text; -// int? maxLines; -// double? fontSize; -// Color? color; -// bool? bold; -// bool? isUnderline; -// bool? isFlatButton; -// double? pedding; -// TextAlign? textAlign; -// -// TxtAuto( -// this.text, { -// this.maxLines, -// this.color, -// this.bold, -// this.fontSize, -// this.isUnderline, -// this.isFlatButton, -// this.pedding, -// this.textAlign, -// }); -// -// @override -// Widget build(BuildContext context) { -// if (isFlatButton != null) -// return Padding( -// padding: EdgeInsets.only(right: pedding ?? 0, left: pedding ?? 0), -// child: InkWell( -// onTap: () {}, -// customBorder: inkWellCorner(r: 4), -// child: Padding( -// padding: const EdgeInsets.only( -// left: 14, -// right: 14, -// top: 6, -// bottom: 6, -// ), -// child: getText(), -// ), -// ), -// ); -// else -// return getText(); -// } -// -// Widget getText() { -// return AutoSizeText( -// text, -// maxLines: maxLines, -// textAlign: textAlign, -// overflow: maxLines != null ? TextOverflow.ellipsis : null, -// style: TextStyle( -// fontSize: fontSize, -// color: color, -// fontWeight: (bold != null) ? FontWeight.bold : null, -// decoration: (isUnderline != null) ? TextDecoration.underline : null, -// ), -// ); -// } -// } diff --git a/lib/widgets/txt_field.dart b/lib/widgets/txt_field.dart deleted file mode 100644 index c081229..0000000 --- a/lib/widgets/txt_field.dart +++ /dev/null @@ -1,155 +0,0 @@ -import 'package:mohem_flutter_app/theme/colors.dart'; -import 'package:mohem_flutter_app/utils/utils.dart'; -import 'package:mohem_flutter_app/widgets/txt.dart'; -import 'package:flutter/material.dart'; -import 'package:sizer/sizer.dart'; - -class TxtField extends StatelessWidget { - TextEditingController controller = new TextEditingController(); - String? title; - String? hint; - String? lable; - IconData? prefixData; - IconData? postfixData; - bool isNeedFilterButton; - bool isNeedClickAll; - bool isButtonEnable; - double? elevation; - Function? onTap; - String? buttonTitle; - int? maxLines; - bool isSidePaddingZero; - bool isNeedBorder; - - TxtField({ - this.title, - this.lable, - this.hint, - this.prefixData, - this.postfixData, - this.isNeedClickAll = false, - this.isNeedFilterButton = false, - this.elevation, - this.onTap, - this.isButtonEnable = false, - this.buttonTitle, - this.maxLines, - this.isSidePaddingZero = false, - this.isNeedBorder = true, - }); - - @override - Widget build(BuildContext context) { - controller.text = title ?? ""; - return InkWell( - onTap: isNeedClickAll == false - ? null - : () { - onTap!(); - }, - customBorder: inkWellCorner(), - child: Row( - children: [ - Expanded( - child: Card( - elevation: elevation, - margin: isSidePaddingZero ? EdgeInsets.zero : null, - child: TextField( - autofocus: false, - controller: controller, - enabled: isNeedClickAll == true ? false : true, - maxLines: maxLines, - onTap: () {}, - decoration: InputDecoration( - labelText: lable, - alignLabelWithHint: true, - fillColor: Colors.white, - focusedBorder: OutlineInputBorder( - borderSide: BorderSide( - color: accentColor, width: isNeedBorder ? 1.0 : 0), - borderRadius: BorderRadius.circular(4.0), - ), - enabledBorder: OutlineInputBorder( - borderSide: BorderSide( - color: borderColor, width: isNeedBorder ? 1.0 : 0), - borderRadius: BorderRadius.circular(4.0), - ), - disabledBorder: OutlineInputBorder( - borderSide: BorderSide( - color: borderColor, width: isNeedBorder ? 1.0 : 0), - borderRadius: BorderRadius.circular(4.0), - ), - prefixIcon: prefixData != null - ? Icon( - Icons.search, - color: borderColor, - ) - : null, - labelStyle: TextStyle(color: borderColor, fontSize: 13.sp), - hintStyle: TextStyle(color: borderColor, fontSize: 9.sp), - hintText: hint ?? "", - contentPadding: prefixData == null - ? EdgeInsets.only( - left: 12, - right: 12, - top: maxLines != null ? 12 : 0, - bottom: maxLines != null ? 12 : 0, - ) - : EdgeInsets.zero, - ), - ), - ), - ), - if (isNeedFilterButton) mWidth(8), - if (isNeedFilterButton) - InkWell( - onTap: isNeedClickAll - ? null - : () { - controller.clear(); - }, - child: Container( - width: 55, - height: 55, - child: Card( - color: accentColor, - // margin: EdgeInsets.all(4), - // shape: cardRadius(0), - child: Icon( - postfixData ?? Icons.filter_alt, - color: Colors.white, - ), - ), - ), - ), - if (isButtonEnable) - Material( - child: InkWell( - onTap: () {}, - customBorder: inkWellCorner(), - child: Container( - height: 55, - child: Card( - color: accentColor, - // margin: EdgeInsets.all(4), - // shape: cardRadius(0), - child: Center( - child: Padding( - padding: const EdgeInsets.only(left: 12, right: 12), - child: Txt( - buttonTitle ?? "Search", - color: Colors.white, - fontSize: 18, - bold: true, - ), - ), - ), - ), - ), - ), - ), - ], - ), - ); - } -} diff --git a/lib/widgets/user_image.dart b/lib/widgets/user_image.dart deleted file mode 100644 index 9ff8102..0000000 --- a/lib/widgets/user_image.dart +++ /dev/null @@ -1,26 +0,0 @@ -import 'package:mohem_flutter_app/config/constants.dart'; -import 'package:mohem_flutter_app/utils/utils.dart'; -import 'package:flutter/material.dart'; - -class UserImage extends StatelessWidget { - double? size; - String? url; - - UserImage({this.size, this.url}); - - @override - Widget build(BuildContext context) { - return Container( - height: size ?? 60, - width: size ?? 60, - decoration: containerRadius(Colors.transparent, 1000), - clipBehavior: Clip.antiAlias, - child: Image.asset( - url ?? icons + "Blue Masked.jpg", - width: double.infinity, - height: double.infinity, - fit: BoxFit.cover, - ), - ); - } -} diff --git a/pubspec.lock b/pubspec.lock index b656e4d..302ac7a 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -116,6 +116,13 @@ packages: description: flutter source: sdk version: "0.0.0" + flutter_plugin_android_lifecycle: + dependency: transitive + description: + name: flutter_plugin_android_lifecycle + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.5" flutter_svg: dependency: "direct main" description: @@ -133,6 +140,13 @@ packages: description: flutter source: sdk version: "0.0.0" + fluttertoast: + dependency: "direct main" + description: + name: fluttertoast + url: "https://pub.dartlang.org" + source: hosted + version: "8.0.8" http: dependency: "direct main" description: @@ -175,6 +189,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.0.1" + local_auth: + dependency: "direct main" + description: + name: local_auth + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.9" matcher: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 50eef52..04a1968 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -42,6 +42,8 @@ dependencies: permission_handler: ^8.3.0 flutter_svg: ^1.0.0 sizer: ^2.0.15 + local_auth: ^1.1.9 + fluttertoast: ^8.0.8 dev_dependencies: From b620c682a587e203441b2d151dc45d6d589db872 Mon Sep 17 00:00:00 2001 From: Sikander Saleem Date: Tue, 21 Dec 2021 17:38:15 +0300 Subject: [PATCH 2/7] icons added & dashboard ui --- android/app/src/main/AndroidManifest.xml | 1 + assets/images/add.svg | 3 + assets/images/announcements.svg | 6 + assets/images/arrow_next.svg | 3 + assets/images/clear_field.svg | 3 + assets/images/clock.svg | 3 + assets/images/close.svg | 3 + assets/images/delegate.svg | 3 + assets/images/dot_circle.svg | 3 + assets/images/fav.svg | 3 + assets/images/jpg.svg | 12 + assets/images/{ => login}/verify_face.svg | 0 assets/images/{ => login}/verify_sms.svg | 0 assets/images/{ => login}/verify_thumb.svg | 0 assets/images/{ => login}/verify_whatsapp.svg | 0 assets/images/logos/mohemm_logo.svg | 62 +++++ assets/images/miss_swipe.svg | 13 + assets/images/monthly_attendance.svg | 15 ++ assets/images/more_dotted.svg | 19 ++ assets/images/nfc.svg | 7 + assets/images/pdf.svg | 12 + assets/images/png.svg | 12 + assets/images/request_info.svg | 7 + assets/images/side_nav.svg | 6 + assets/images/skip.svg | 14 + assets/images/stop.svg | 14 + assets/images/ticket_request.svg | 6 + assets/images/un_fav.svg | 3 + assets/images/work_from_home.svg | 11 + assets/images/wufu.svg | 11 + assets/images/xls.svg | 12 + assets/langs/ar-SA.json | 23 +- assets/langs/en-US.json | 23 +- lib/classes/colors.dart | 9 +- lib/dialogs/otp_dialog.dart | 2 +- lib/extensions/string_extensions.dart | 34 ++- lib/generated/codegen_loader.g.dart | 46 +++- lib/ui/dashboard.dart | 252 +++++++++++++++++- lib/ui/login/verify_login_screen.dart | 18 +- lib/widgets/app_logo.dart | 19 ++ lib/widgets/button/default_button.dart | 7 +- lib/widgets/circular_avatar.dart | 25 ++ pubspec.yaml | 2 + 43 files changed, 698 insertions(+), 29 deletions(-) create mode 100644 assets/images/add.svg create mode 100644 assets/images/announcements.svg create mode 100644 assets/images/arrow_next.svg create mode 100644 assets/images/clear_field.svg create mode 100644 assets/images/clock.svg create mode 100644 assets/images/close.svg create mode 100644 assets/images/delegate.svg create mode 100644 assets/images/dot_circle.svg create mode 100644 assets/images/fav.svg create mode 100644 assets/images/jpg.svg rename assets/images/{ => login}/verify_face.svg (100%) rename assets/images/{ => login}/verify_sms.svg (100%) rename assets/images/{ => login}/verify_thumb.svg (100%) rename assets/images/{ => login}/verify_whatsapp.svg (100%) create mode 100644 assets/images/logos/mohemm_logo.svg create mode 100644 assets/images/miss_swipe.svg create mode 100644 assets/images/monthly_attendance.svg create mode 100644 assets/images/more_dotted.svg create mode 100644 assets/images/nfc.svg create mode 100644 assets/images/pdf.svg create mode 100644 assets/images/png.svg create mode 100644 assets/images/request_info.svg create mode 100644 assets/images/side_nav.svg create mode 100644 assets/images/skip.svg create mode 100644 assets/images/stop.svg create mode 100644 assets/images/ticket_request.svg create mode 100644 assets/images/un_fav.svg create mode 100644 assets/images/work_from_home.svg create mode 100644 assets/images/wufu.svg create mode 100644 assets/images/xls.svg create mode 100644 lib/widgets/app_logo.dart create mode 100644 lib/widgets/circular_avatar.dart diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index 857f1d1..472e794 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -1,5 +1,6 @@ + diff --git a/assets/images/add.svg b/assets/images/add.svg new file mode 100644 index 0000000..0230942 --- /dev/null +++ b/assets/images/add.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/announcements.svg b/assets/images/announcements.svg new file mode 100644 index 0000000..d204e60 --- /dev/null +++ b/assets/images/announcements.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/assets/images/arrow_next.svg b/assets/images/arrow_next.svg new file mode 100644 index 0000000..76de3b9 --- /dev/null +++ b/assets/images/arrow_next.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/clear_field.svg b/assets/images/clear_field.svg new file mode 100644 index 0000000..618ed79 --- /dev/null +++ b/assets/images/clear_field.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/clock.svg b/assets/images/clock.svg new file mode 100644 index 0000000..bc9faed --- /dev/null +++ b/assets/images/clock.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/close.svg b/assets/images/close.svg new file mode 100644 index 0000000..7ef696b --- /dev/null +++ b/assets/images/close.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/delegate.svg b/assets/images/delegate.svg new file mode 100644 index 0000000..aa2bd7a --- /dev/null +++ b/assets/images/delegate.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/dot_circle.svg b/assets/images/dot_circle.svg new file mode 100644 index 0000000..b3ac566 --- /dev/null +++ b/assets/images/dot_circle.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/fav.svg b/assets/images/fav.svg new file mode 100644 index 0000000..ebbaf1c --- /dev/null +++ b/assets/images/fav.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/jpg.svg b/assets/images/jpg.svg new file mode 100644 index 0000000..cfda5a7 --- /dev/null +++ b/assets/images/jpg.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/assets/images/verify_face.svg b/assets/images/login/verify_face.svg similarity index 100% rename from assets/images/verify_face.svg rename to assets/images/login/verify_face.svg diff --git a/assets/images/verify_sms.svg b/assets/images/login/verify_sms.svg similarity index 100% rename from assets/images/verify_sms.svg rename to assets/images/login/verify_sms.svg diff --git a/assets/images/verify_thumb.svg b/assets/images/login/verify_thumb.svg similarity index 100% rename from assets/images/verify_thumb.svg rename to assets/images/login/verify_thumb.svg diff --git a/assets/images/verify_whatsapp.svg b/assets/images/login/verify_whatsapp.svg similarity index 100% rename from assets/images/verify_whatsapp.svg rename to assets/images/login/verify_whatsapp.svg diff --git a/assets/images/logos/mohemm_logo.svg b/assets/images/logos/mohemm_logo.svg new file mode 100644 index 0000000..1cb9a0b --- /dev/null +++ b/assets/images/logos/mohemm_logo.svg @@ -0,0 +1,62 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/images/miss_swipe.svg b/assets/images/miss_swipe.svg new file mode 100644 index 0000000..05d32f2 --- /dev/null +++ b/assets/images/miss_swipe.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/assets/images/monthly_attendance.svg b/assets/images/monthly_attendance.svg new file mode 100644 index 0000000..c84a9a1 --- /dev/null +++ b/assets/images/monthly_attendance.svg @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/assets/images/more_dotted.svg b/assets/images/more_dotted.svg new file mode 100644 index 0000000..add7848 --- /dev/null +++ b/assets/images/more_dotted.svg @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + diff --git a/assets/images/nfc.svg b/assets/images/nfc.svg new file mode 100644 index 0000000..aff027e --- /dev/null +++ b/assets/images/nfc.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/assets/images/pdf.svg b/assets/images/pdf.svg new file mode 100644 index 0000000..fc59aea --- /dev/null +++ b/assets/images/pdf.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/assets/images/png.svg b/assets/images/png.svg new file mode 100644 index 0000000..2a0091d --- /dev/null +++ b/assets/images/png.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/assets/images/request_info.svg b/assets/images/request_info.svg new file mode 100644 index 0000000..43ac9c1 --- /dev/null +++ b/assets/images/request_info.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/assets/images/side_nav.svg b/assets/images/side_nav.svg new file mode 100644 index 0000000..a53378f --- /dev/null +++ b/assets/images/side_nav.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/assets/images/skip.svg b/assets/images/skip.svg new file mode 100644 index 0000000..01831e0 --- /dev/null +++ b/assets/images/skip.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/assets/images/stop.svg b/assets/images/stop.svg new file mode 100644 index 0000000..5f658a8 --- /dev/null +++ b/assets/images/stop.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/assets/images/ticket_request.svg b/assets/images/ticket_request.svg new file mode 100644 index 0000000..f489a8e --- /dev/null +++ b/assets/images/ticket_request.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/assets/images/un_fav.svg b/assets/images/un_fav.svg new file mode 100644 index 0000000..de1b852 --- /dev/null +++ b/assets/images/un_fav.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/work_from_home.svg b/assets/images/work_from_home.svg new file mode 100644 index 0000000..cf9a8d7 --- /dev/null +++ b/assets/images/work_from_home.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/assets/images/wufu.svg b/assets/images/wufu.svg new file mode 100644 index 0000000..dd3ebab --- /dev/null +++ b/assets/images/wufu.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/assets/images/xls.svg b/assets/images/xls.svg new file mode 100644 index 0000000..658ba92 --- /dev/null +++ b/assets/images/xls.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/assets/langs/ar-SA.json b/assets/langs/ar-SA.json index bfa680d..5419919 100644 --- a/assets/langs/ar-SA.json +++ b/assets/langs/ar-SA.json @@ -18,8 +18,29 @@ "useAnotherAccount": "Use Another Account", "pleaseEnterTheVerificationCodeSentTo": "Please enter the verification code sent to ", "theVerificationCodeWillExpireIn": "The verification code will expire in ", - "title": "Hello", + "goodMorning": "Good Morning", + "markAttendance": "Mark Attendance", + "timeLeftToday": "Time Left Today", + "checkIn": "Check In", + "workList": "Work List", + "leaveBalance": "Leave Balance", + "missingSwipes": "Missing Swipes", + "ticketBalance": "Ticket Balance", + "other": "Other", + "services": "Services", + "viewAllServices": "View All Services", + "monthlyAttendance": "Monthly Attendance", + "workFromHome": "Work From Home", + "ticketRequest": "Ticket Request", + "viewAllOffers": "View All Offers", + "offers": "Offers & ", + "discounts": "Discounts", + "title": "Title", + "home": "Home", + "mySalary": "My Salary", + "createRequest": "Create Request", "forgotPassword": "Forgot Password", + "itemsForSale": "Items for Sale", "msg": "Hello {} in the {} world ", "msg_named": "{} are written in the {lang} language", "clickMe": "Click me", diff --git a/assets/langs/en-US.json b/assets/langs/en-US.json index bfa680d..5419919 100644 --- a/assets/langs/en-US.json +++ b/assets/langs/en-US.json @@ -18,8 +18,29 @@ "useAnotherAccount": "Use Another Account", "pleaseEnterTheVerificationCodeSentTo": "Please enter the verification code sent to ", "theVerificationCodeWillExpireIn": "The verification code will expire in ", - "title": "Hello", + "goodMorning": "Good Morning", + "markAttendance": "Mark Attendance", + "timeLeftToday": "Time Left Today", + "checkIn": "Check In", + "workList": "Work List", + "leaveBalance": "Leave Balance", + "missingSwipes": "Missing Swipes", + "ticketBalance": "Ticket Balance", + "other": "Other", + "services": "Services", + "viewAllServices": "View All Services", + "monthlyAttendance": "Monthly Attendance", + "workFromHome": "Work From Home", + "ticketRequest": "Ticket Request", + "viewAllOffers": "View All Offers", + "offers": "Offers & ", + "discounts": "Discounts", + "title": "Title", + "home": "Home", + "mySalary": "My Salary", + "createRequest": "Create Request", "forgotPassword": "Forgot Password", + "itemsForSale": "Items for Sale", "msg": "Hello {} in the {} world ", "msg_named": "{} are written in the {lang} language", "clickMe": "Click me", diff --git a/lib/classes/colors.dart b/lib/classes/colors.dart index d19edc6..79b0d31 100644 --- a/lib/classes/colors.dart +++ b/lib/classes/colors.dart @@ -3,11 +3,14 @@ import 'package:flutter/cupertino.dart'; class MyColors { static const Color darkIconColor = Color(0xff28323A); static const Color darkTextColor = Color(0xff2B353E); - static const Color gradiantStartColor = Color(0xff32D892); - static const Color gradiantEndColor = Color(0xff259CB8); + static const Color gradiantStartColor = Color(0xff33c0a5); + static const Color gradiantEndColor = Color(0xff259db7 ); static const Color textMixColor = Color(0xff2BB8A6); static const Color backgroundColor = Color(0xffF8F8F8); - static const Color greyColor = Color(0xff575757); + static const Color grey57Color = Color(0xff575757); + static const Color grey77Color = Color(0xff777777); + static const Color grey98Color = Color(0xff989898); static const Color lightGreyColor = Color(0xffEFEFEF); static const Color darkWhiteColor = Color(0xffE0E0E0); + static const Color redColor = Color(0xffD02127); } diff --git a/lib/dialogs/otp_dialog.dart b/lib/dialogs/otp_dialog.dart index 3d625bf..6a14d63 100644 --- a/lib/dialogs/otp_dialog.dart +++ b/lib/dialogs/otp_dialog.dart @@ -102,7 +102,7 @@ class OtpDialog { ], ), 22.height, - (LocaleKeys.pleaseEnterTheVerificationCodeSentTo.tr() + ' xxxxxxxx' + mobileNo.toString().substring(mobileNo.toString().length - 3)).toText16, + (LocaleKeys.pleaseEnterTheVerificationCodeSentTo.tr() + ' xxxxxxxx' + mobileNo.toString().substring(mobileNo.toString().length - 3)).toText16(), 18.height, Directionality( textDirection: TextDirection.ltr, diff --git a/lib/extensions/string_extensions.dart b/lib/extensions/string_extensions.dart index bd52c85..9ba31c8 100644 --- a/lib/extensions/string_extensions.dart +++ b/lib/extensions/string_extensions.dart @@ -10,24 +10,44 @@ extension EmailValidator on String { style: TextStyle(fontSize: 10, fontWeight: FontWeight.w600, color: color ?? MyColors.darkTextColor, letterSpacing: -0.4), ); - Widget toText12({Color? color, bool isUnderLine = false}) => Text( + Widget toText11({Color? color, bool isUnderLine = false, bool isBold = false}) => Text( this, - style: TextStyle(fontSize: 12, fontWeight: FontWeight.w600, color: color ?? MyColors.darkTextColor, letterSpacing: -0.72, decoration: isUnderLine ? TextDecoration.underline : null), + style: TextStyle( + fontSize: 11, + fontWeight: isBold ? FontWeight.bold : FontWeight.w600, + color: color ?? MyColors.darkTextColor, + letterSpacing: -0.33, + decoration: isUnderLine ? TextDecoration.underline : null), ); - Widget get toText14 => Text( + Widget toText12({Color? color, bool isUnderLine = false, bool isBold = false}) => Text( + this, + style: TextStyle( + fontSize: 12, + fontWeight: isBold ? FontWeight.bold : FontWeight.w600, + color: color ?? MyColors.darkTextColor, + letterSpacing: -0.72, + decoration: isUnderLine ? TextDecoration.underline : null), + ); + + Widget toText13({Color? color, bool isUnderLine = false}) => Text( + this, + style: TextStyle(fontSize: 13, fontWeight: FontWeight.w600, color: color ?? MyColors.darkTextColor, letterSpacing: -0.52, decoration: isUnderLine ? TextDecoration.underline : null), + ); + + Widget toText14({Color? color,bool isBold = false}) => Text( this, - style: const TextStyle(color: MyColors.darkTextColor, fontSize: 14, letterSpacing: -0.48, fontWeight: FontWeight.w600), + style: TextStyle(color: color ?? MyColors.darkTextColor, fontSize: 14, letterSpacing: -0.48, fontWeight: isBold ? FontWeight.bold :FontWeight.w600), ); - Widget get toText16 => Text( + Widget toText16({Color? color, bool isBold = false}) => Text( this, - style: const TextStyle(color: MyColors.darkTextColor, fontSize: 16, letterSpacing: -0.64, fontWeight: FontWeight.w600), + style: TextStyle(color: color ?? MyColors.darkTextColor, fontSize: 16, letterSpacing: -0.64, fontWeight: isBold ? FontWeight.bold : FontWeight.w600), ); Widget toText24({bool isBold = false}) => Text( this, - style: TextStyle(color: MyColors.darkTextColor, fontSize: 24, letterSpacing: -1.44, fontWeight: isBold ? FontWeight.bold : FontWeight.w600), + style: TextStyle(height: 23 / 24, color: MyColors.darkTextColor, fontSize: 24, letterSpacing: -1.44, fontWeight: isBold ? FontWeight.bold : FontWeight.w600), ); bool isValidEmail() { diff --git a/lib/generated/codegen_loader.g.dart b/lib/generated/codegen_loader.g.dart index c0810e9..0991c28 100644 --- a/lib/generated/codegen_loader.g.dart +++ b/lib/generated/codegen_loader.g.dart @@ -34,8 +34,29 @@ class CodegenLoader extends AssetLoader{ "useAnotherAccount": "Use Another Account", "pleaseEnterTheVerificationCodeSentTo": "Please enter the verification code sent to ", "theVerificationCodeWillExpireIn": "The verification code will expire in ", - "title": "Hello", + "goodMorning": "Good Morning", + "markAttendance": "Mark Attendance", + "timeLeftToday": "Time Left Today", + "checkIn": "Check In", + "workList": "Work List", + "leaveBalance": "Leave Balance", + "missingSwipes": "Missing Swipes", + "ticketBalance": "Ticket Balance", + "other": "Other", + "services": "Services", + "viewAllServices": "View All Services", + "monthlyAttendance": "Monthly Attendance", + "workFromHome": "Work From Home", + "ticketRequest": "Ticket Request", + "viewAllOffers": "View All Offers", + "offers": "Offers & ", + "discounts": "Discounts", + "title": "Title", + "home": "Home", + "mySalary": "My Salary", + "createRequest": "Create Request", "forgotPassword": "Forgot Password", + "itemsForSale": "Items for Sale", "msg": "Hello {} in the {} world ", "msg_named": "{} are written in the {lang} language", "clickMe": "Click me", @@ -92,8 +113,29 @@ static const Map en_US = { "useAnotherAccount": "Use Another Account", "pleaseEnterTheVerificationCodeSentTo": "Please enter the verification code sent to ", "theVerificationCodeWillExpireIn": "The verification code will expire in ", - "title": "Hello", + "goodMorning": "Good Morning", + "markAttendance": "Mark Attendance", + "timeLeftToday": "Time Left Today", + "checkIn": "Check In", + "workList": "Work List", + "leaveBalance": "Leave Balance", + "missingSwipes": "Missing Swipes", + "ticketBalance": "Ticket Balance", + "other": "Other", + "services": "Services", + "viewAllServices": "View All Services", + "monthlyAttendance": "Monthly Attendance", + "workFromHome": "Work From Home", + "ticketRequest": "Ticket Request", + "viewAllOffers": "View All Offers", + "offers": "Offers & ", + "discounts": "Discounts", + "title": "Title", + "home": "Home", + "mySalary": "My Salary", + "createRequest": "Create Request", "forgotPassword": "Forgot Password", + "itemsForSale": "Items for Sale", "msg": "Hello {} in the {} world ", "msg_named": "{} are written in the {lang} language", "clickMe": "Click me", diff --git a/lib/ui/dashboard.dart b/lib/ui/dashboard.dart index f6699ae..65d4cfd 100644 --- a/lib/ui/dashboard.dart +++ b/lib/ui/dashboard.dart @@ -1,4 +1,13 @@ +import 'package:easy_localization/src/public_ext.dart'; +import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_svg/flutter_svg.dart'; +import 'package:mohem_flutter_app/classes/colors.dart'; +import 'package:mohem_flutter_app/extensions/int_extensions.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/widgets/circular_avatar.dart'; class Dashboard extends StatefulWidget { Dashboard({Key? key}) : super(key: key); @@ -22,6 +31,245 @@ class _DashboardState extends State { @override Widget build(BuildContext context) { - return Scaffold(); + List names = [LocaleKeys.workList.tr(), LocaleKeys.missingSwipes.tr(), LocaleKeys.leaveBalance.tr(), LocaleKeys.ticketBalance.tr()]; + List namesInt = [118, 02, 18.5, 03]; + List namesColor = [0xff125765, 0xff239D8F, 0xff2BB8A8, 0xff1D92AA]; + + List namesT = [LocaleKeys.monthlyAttendance.tr(), LocaleKeys.workFromHome.tr(), LocaleKeys.ticketRequest.tr(), LocaleKeys.monthlyAttendance.tr()]; + List iconT = ["assets/images/monthly_attendance.svg", "assets/images/work_from_home.svg", "assets/images/ticket_request.svg", "assets/images/work_from_home.svg"]; + + return Scaffold( + body: Column( + children: [ + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + children: [ + Row( + mainAxisSize: MainAxisSize.min, + children: [ + CircularAvatar( + width: 34, + height: 34, + url: "https://cdn4.iconfinder.com/data/icons/professions-2-2/151/89-512.png", + ), + 8.width, + SvgPicture.asset("assets/images/side_nav.svg"), + ], + ).onPress(() {}), + Expanded( + child: Row( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.center, + mainAxisSize: MainAxisSize.min, + children: [ + //AppLogo(), + 8.width, + LocaleKeys.mohemm.tr().toText14() + ], + ), + ), + SizedBox( + width: 36, + height: 36, + child: Stack( + alignment: Alignment.centerLeft, + children: [ + SvgPicture.asset("assets/images/announcements.svg"), + Positioned( + right: 0, + top: 0, + child: Container( + padding: const EdgeInsets.only(left: 5, right: 5), + decoration: BoxDecoration(color: MyColors.redColor, borderRadius: BorderRadius.circular(17)), + child: "3".toText12(color: Colors.white), + ), + ) + ], + ), + ) + ], + ), + 14.height, + LocaleKeys.goodMorning.tr().toText14(color: MyColors.grey77Color), + "Mahmoud Shrouf".toText24(isBold: true), + 16.height, + Row( + children: [ + Expanded( + child: AspectRatio( + aspectRatio: 159 / 159, + child: Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(15), + gradient: const LinearGradient(transform: GradientRotation(.46), begin: Alignment.topRight, end: Alignment.bottomRight, colors: [ + MyColors.gradiantEndColor, + MyColors.gradiantStartColor, + ]), + ), + child: Stack( + alignment: Alignment.center, + children: [ + SvgPicture.asset("assets/images/"), + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Expanded( + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + LocaleKeys.markAttendance.tr().toText14(color: Colors.white, isBold: true), + 9.height, + "07:55:12".toText14(color: Colors.white, isBold: true), + LocaleKeys.timeLeftToday.tr().toText12(color: Colors.white), + 9.height, + ClipRRect( + borderRadius: const BorderRadius.all( + Radius.circular(20), + ), + child: LinearProgressIndicator( + value: 0.7, + minHeight: 8, + valueColor: const AlwaysStoppedAnimation(Colors.white), + backgroundColor: const Color(0xff196D73), + ), + ), + ], + ).paddingOnly(top: 12, right: 15, left: 12), + ), + Row( + children: [ + Expanded( + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [LocaleKeys.checkIn.tr().toText12(color: Colors.white), "09:00".toText14(color: Colors.white, isBold: true), 4.height], + ).paddingOnly(left: 12), + ), + Container( + width: 45, + height: 45, + padding: const EdgeInsets.only(left: 14, right: 14), + decoration: const BoxDecoration( + color: Color(0xff259EA4), + borderRadius: BorderRadius.only( + bottomRight: Radius.circular(15), + ), + ), + child: SvgPicture.asset("assets/images/stop.svg"), + ), + ], + ), + ], + ), + ], + ), + ), + ), + ), + 9.width, + Expanded( + child: GridView.builder( + shrinkWrap: true, + primary: false, + physics: const NeverScrollableScrollPhysics(), + gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2, childAspectRatio: 2 / 2, crossAxisSpacing: 9, mainAxisSpacing: 9), + padding: EdgeInsets.zero, + itemCount: 4, + itemBuilder: (BuildContext context, int index) { + return Container( + decoration: BoxDecoration( + color: Color(namesColor[index]), + borderRadius: BorderRadius.circular(10), + ), + child: Column( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + names[index].toText12(color: Colors.white), + Row( + children: [ + Expanded( + child: namesInt[index].toStringAsFixed(1).toText16(color: Colors.white, isBold: true), + ), + SvgPicture.asset("assets/images/arrow_next.svg", color: Colors.white) + ], + ) + ], + ).paddingOnly(left: 10, right: 10, bottom: 6, top: 6), + ); + }, + ), + ), + ], + ), + 20.height, + Row( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + LocaleKeys.other.tr().toText12(), + LocaleKeys.services.tr().toText24(isBold: true), + ], + ), + ), + LocaleKeys.viewAllServices.tr().toText12(isUnderLine: true), + ], + ), + ], + ).paddingOnly(left: 21, right: 21, top: 48), + SizedBox( + height: 105 + 26, + child: ListView.separated( + shrinkWrap: true, + physics: const BouncingScrollPhysics(), + padding: const EdgeInsets.only(left: 21, right: 21, top: 13, bottom: 13), + scrollDirection: Axis.horizontal, + itemBuilder: (cxt, index) { + return AspectRatio( + aspectRatio: 105 / 105, + child: Container( + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(15), + boxShadow: [ + BoxShadow( + color: const Color(0xff000000).withOpacity(.05), + blurRadius: 26, + offset: const Offset(0, -3), + ), + ], + ), + child: Column( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + SvgPicture.asset(iconT[index]), + Row( + crossAxisAlignment: CrossAxisAlignment.end, + children: [ + Expanded( + child: namesT[index].toText11(isBold: true), + ), + SvgPicture.asset("assets/images/arrow_next.svg").paddingOnly(bottom: 4) + ], + ) + ], + ).paddingOnly(left: 10, right: 10, bottom: 10, top: 12), + ), + ); + }, + separatorBuilder: (cxt, index) => 9.width, + itemCount: 4), + ) + ], + ), + ); } -} \ No newline at end of file +} diff --git a/lib/ui/login/verify_login_screen.dart b/lib/ui/login/verify_login_screen.dart index e661456..249fa52 100644 --- a/lib/ui/login/verify_login_screen.dart +++ b/lib/ui/login/verify_login_screen.dart @@ -59,7 +59,7 @@ class _VerifyLoginScreenState extends State { LocaleKeys.welcomeBack.tr().toText12(), "Mohammad Hussain".toText24(isBold: true), 10.height, - LocaleKeys.wouldYouLikeToLoginWithCurrentUsername.tr().toText16, + LocaleKeys.wouldYouLikeToLoginWithCurrentUsername.tr().toText16(), Container( height: 72, margin: const EdgeInsets.only(top: 23, bottom: 23), @@ -80,7 +80,7 @@ class _VerifyLoginScreenState extends State { mainAxisAlignment: MainAxisAlignment.spaceBetween, crossAxisAlignment: CrossAxisAlignment.center, children: [ - LocaleKeys.lastLoginDetails.tr().toText16, + LocaleKeys.lastLoginDetails.tr().toText16(), // Text( // user.editedOn != null // ? DateUtil.getDayMonthYearDateFormatted(DateUtil.convertStringToDate(user.editedOn)) @@ -95,7 +95,7 @@ class _VerifyLoginScreenState extends State { mainAxisAlignment: MainAxisAlignment.spaceBetween, crossAxisAlignment: CrossAxisAlignment.center, children: [ - LocaleKeys.verificationType.tr().toText10(color: MyColors.greyColor), + LocaleKeys.verificationType.tr().toText10(color: MyColors.grey57Color), Text( "SMS", // " " + getType(user.logInType, context), @@ -119,7 +119,7 @@ class _VerifyLoginScreenState extends State { ], ), ), - LocaleKeys.pleaseVerify.tr().toText16, + LocaleKeys.pleaseVerify.tr().toText16(), GridView( gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2, crossAxisSpacing: 13, mainAxisSpacing: 9), physics: const NeverScrollableScrollPhysics(), @@ -653,7 +653,7 @@ class _VerifyLoginScreenState extends State { width: 38, color: isDisable ? MyColors.darkTextColor.withOpacity(0.7) : null, ), - _title.toText16 + _title.toText16() ], ), ), @@ -663,13 +663,13 @@ class _VerifyLoginScreenState extends State { Widget getButton(int flag) { switch (flag) { case 4: - return _loginOptionButton(LocaleKeys.verifyThroughWhatsapp.tr(), 'assets/images/verify_whatsapp.svg', flag, null); + return _loginOptionButton(LocaleKeys.verifyThroughWhatsapp.tr(), 'assets/images/login/verify_whatsapp.svg', flag, null); case 1: - return _loginOptionButton(LocaleKeys.verifyThroughSMS.tr(), 'assets/images/verify_sms.svg', flag, null); + return _loginOptionButton(LocaleKeys.verifyThroughSMS.tr(), 'assets/images/login/verify_sms.svg', flag, null); case 2: - return _loginOptionButton(LocaleKeys.verifyThroughFingerprint.tr(), 'assets/images/verify_thumb.svg', flag, BiometricType.fingerprint.index); + return _loginOptionButton(LocaleKeys.verifyThroughFingerprint.tr(), 'assets/images/login/verify_thumb.svg', flag, BiometricType.fingerprint.index); case 3: - return _loginOptionButton(LocaleKeys.verifyThroughFace.tr(), 'assets/images/verify_face.svg', flag, BiometricType.face.index); + return _loginOptionButton(LocaleKeys.verifyThroughFace.tr(), 'assets/images/login/verify_face.svg', flag, BiometricType.face.index); default: return const SizedBox(); } diff --git a/lib/widgets/app_logo.dart b/lib/widgets/app_logo.dart new file mode 100644 index 0000000..1c0bc37 --- /dev/null +++ b/lib/widgets/app_logo.dart @@ -0,0 +1,19 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_svg/svg.dart'; + +class AppLogo extends StatelessWidget { + AppLogo({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + // TODO: implement build + return Row(children: [ + SvgPicture.asset( + "assets/mohemm_logo.svg", + height: 100, + width: 100, + alignment: Alignment.centerRight, + ), + ],); + } +} diff --git a/lib/widgets/button/default_button.dart b/lib/widgets/button/default_button.dart index b8ad88e..9e0fd23 100644 --- a/lib/widgets/button/default_button.dart +++ b/lib/widgets/button/default_button.dart @@ -1,5 +1,6 @@ import 'package:flutter/material.dart'; import 'package:flutter_svg/svg.dart'; +import 'package:mohem_flutter_app/classes/colors.dart'; extension WithContainer on Widget { Widget get insideContainer => Container(color: Colors.white, padding: const EdgeInsets.only(top: 16, bottom: 16, right: 21, left: 21), child: this); @@ -29,9 +30,9 @@ class DefaultButton extends StatelessWidget { borderRadius: BorderRadius.circular(6.0), gradient: onPress == null ? const LinearGradient(colors: [Color(0xffEAEAEA), Color(0xffEAEAEA)]) - : const LinearGradient(transform: GradientRotation(.83), begin: Alignment.topLeft, end: Alignment.bottomRight, colors: [ - Color(0xff32D892), - Color(0xff259CB8), + : const LinearGradient(transform: GradientRotation(.83), begin: Alignment.topRight, end: Alignment.bottomLeft, colors: [ + MyColors.gradiantEndColor, + MyColors.gradiantStartColor, ]), ), child: Row( diff --git a/lib/widgets/circular_avatar.dart b/lib/widgets/circular_avatar.dart new file mode 100644 index 0000000..cd60e06 --- /dev/null +++ b/lib/widgets/circular_avatar.dart @@ -0,0 +1,25 @@ +import 'package:flutter/material.dart'; + +class CircularAvatar extends StatelessWidget { + final String? url; + final double radius; + final double width; + final double height; + + CircularAvatar({Key? key, this.radius = 70.0, this.width = 70, this.height = 60, this.url}) : super(key: key); + + @override + Widget build(BuildContext context) { + return Container( + width: width, + height: height, + decoration: BoxDecoration( + shape: BoxShape.circle, + image: DecorationImage( + fit: BoxFit.cover, + image: NetworkImage(url ?? "https://cdn4.iconfinder.com/data/icons/professions-2-2/151/89-512.png"), + ), + ), + ); + } +} diff --git a/pubspec.yaml b/pubspec.yaml index 04a1968..dfbb0eb 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -77,6 +77,8 @@ flutter: - assets/langs/ - assets/icons/ - assets/images/ + - assets/images/login/ + - assets/images/logos/ # An image asset can refer to one or more resolution-specific "variants", see # https://flutter.dev/assets-and-images/#resolution-aware. From 3047f3534197b5d9c2ccb8e9cf2dc6c70dcf5405 Mon Sep 17 00:00:00 2001 From: Sikander Saleem Date: Wed, 22 Dec 2021 15:56:18 +0300 Subject: [PATCH 3/7] dashboard ui added. --- assets/langs/ar-SA.json | 1 + assets/langs/en-US.json | 1 + lib/classes/colors.dart | 4 +- lib/dialogs/otp_dialog.dart | 4 +- lib/extensions/string_extensions.dart | 28 +- lib/ui/dashboard.dart | 490 +++++++++++++++----------- lib/ui/login/verify_login_screen.dart | 2 +- 7 files changed, 314 insertions(+), 216 deletions(-) diff --git a/assets/langs/ar-SA.json b/assets/langs/ar-SA.json index 5419919..ba920a8 100644 --- a/assets/langs/ar-SA.json +++ b/assets/langs/ar-SA.json @@ -35,6 +35,7 @@ "viewAllOffers": "View All Offers", "offers": "Offers & ", "discounts": "Discounts", + "newString": "New", "title": "Title", "home": "Home", "mySalary": "My Salary", diff --git a/assets/langs/en-US.json b/assets/langs/en-US.json index 5419919..ba920a8 100644 --- a/assets/langs/en-US.json +++ b/assets/langs/en-US.json @@ -35,6 +35,7 @@ "viewAllOffers": "View All Offers", "offers": "Offers & ", "discounts": "Discounts", + "newString": "New", "title": "Title", "home": "Home", "mySalary": "My Salary", diff --git a/lib/classes/colors.dart b/lib/classes/colors.dart index 79b0d31..e8b8b2a 100644 --- a/lib/classes/colors.dart +++ b/lib/classes/colors.dart @@ -10,7 +10,9 @@ class MyColors { static const Color grey57Color = Color(0xff575757); static const Color grey77Color = Color(0xff777777); static const Color grey98Color = Color(0xff989898); - static const Color lightGreyColor = Color(0xffEFEFEF); + static const Color lightGreyEFColor = Color(0xffEFEFEF); + static const Color lightGreyEDColor = Color(0xffEDEDED); static const Color darkWhiteColor = Color(0xffE0E0E0); static const Color redColor = Color(0xffD02127); + static const Color yellowColor = Color(0xffF4E31C); } diff --git a/lib/dialogs/otp_dialog.dart b/lib/dialogs/otp_dialog.dart index 6a14d63..f589211 100644 --- a/lib/dialogs/otp_dialog.dart +++ b/lib/dialogs/otp_dialog.dart @@ -3,10 +3,10 @@ import 'dart:async'; import 'package:easy_localization/src/public_ext.dart'; import 'package:flutter/material.dart'; import 'package:flutter_svg/svg.dart'; -import 'package:mohem_flutter_app/generated/locale_keys.g.dart'; import 'package:mohem_flutter_app/classes/colors.dart'; import 'package:mohem_flutter_app/extensions/int_extensions.dart'; import 'package:mohem_flutter_app/extensions/string_extensions.dart'; +import 'package:mohem_flutter_app/generated/locale_keys.g.dart'; import 'package:mohem_flutter_app/widgets/otp_widget.dart'; class OtpDialog { @@ -86,7 +86,7 @@ class OtpDialog { mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ SvgPicture.asset( - type == 1 ? "assets/images/verify_sms.svg" : "assets/images/verify_whatsapp.svg", + type == 1 ? "assets/images/login/verify_sms.svg" : "assets/images/login/verify_whatsapp.svg", height: 50, width: 50, ), diff --git a/lib/extensions/string_extensions.dart b/lib/extensions/string_extensions.dart index 9ba31c8..d77bbff 100644 --- a/lib/extensions/string_extensions.dart +++ b/lib/extensions/string_extensions.dart @@ -5,9 +5,9 @@ import 'package:mohem_flutter_app/classes/colors.dart'; extension EmailValidator on String { Widget get toWidget => Text(this); - Widget toText10({Color? color}) => Text( + Widget toText10({Color? color, bool isBold = false}) => Text( this, - style: TextStyle(fontSize: 10, fontWeight: FontWeight.w600, color: color ?? MyColors.darkTextColor, letterSpacing: -0.4), + style: TextStyle(fontSize: 10, fontWeight: isBold ? FontWeight.bold : FontWeight.w600, color: color ?? MyColors.darkTextColor, letterSpacing: -0.4), ); Widget toText11({Color? color, bool isUnderLine = false, bool isBold = false}) => Text( @@ -20,24 +20,26 @@ extension EmailValidator on String { decoration: isUnderLine ? TextDecoration.underline : null), ); - Widget toText12({Color? color, bool isUnderLine = false, bool isBold = false}) => Text( - this, - style: TextStyle( - fontSize: 12, - fontWeight: isBold ? FontWeight.bold : FontWeight.w600, - color: color ?? MyColors.darkTextColor, - letterSpacing: -0.72, - decoration: isUnderLine ? TextDecoration.underline : null), - ); + Widget toText12({Color? color, bool isUnderLine = false, bool isBold = false, bool isCenter = false, int maxLine = 0}) => Text( + this, + textAlign: isCenter ? TextAlign.center : null, + maxLines: (maxLine > 0) ? maxLine : null, + style: TextStyle( + fontSize: 12, + fontWeight: isBold ? FontWeight.bold : FontWeight.w600, + color: color ?? MyColors.darkTextColor, + letterSpacing: -0.72, + decoration: isUnderLine ? TextDecoration.underline : null), + ); Widget toText13({Color? color, bool isUnderLine = false}) => Text( this, style: TextStyle(fontSize: 13, fontWeight: FontWeight.w600, color: color ?? MyColors.darkTextColor, letterSpacing: -0.52, decoration: isUnderLine ? TextDecoration.underline : null), ); - Widget toText14({Color? color,bool isBold = false}) => Text( + Widget toText14({Color? color, bool isBold = false}) => Text( this, - style: TextStyle(color: color ?? MyColors.darkTextColor, fontSize: 14, letterSpacing: -0.48, fontWeight: isBold ? FontWeight.bold :FontWeight.w600), + style: TextStyle(color: color ?? MyColors.darkTextColor, fontSize: 14, letterSpacing: -0.48, fontWeight: isBold ? FontWeight.bold : FontWeight.w600), ); Widget toText16({Color? color, bool isBold = false}) => Text( diff --git a/lib/ui/dashboard.dart b/lib/ui/dashboard.dart index 65d4cfd..2c9cf50 100644 --- a/lib/ui/dashboard.dart +++ b/lib/ui/dashboard.dart @@ -38,235 +38,327 @@ class _DashboardState extends State { List namesT = [LocaleKeys.monthlyAttendance.tr(), LocaleKeys.workFromHome.tr(), LocaleKeys.ticketRequest.tr(), LocaleKeys.monthlyAttendance.tr()]; List iconT = ["assets/images/monthly_attendance.svg", "assets/images/work_from_home.svg", "assets/images/ticket_request.svg", "assets/images/work_from_home.svg"]; + List namesD = ["Nostalgia Perfume Perfume", "Al Nafoura", "AlJadi", "Nostalgia Perfume"]; + return Scaffold( body: Column( children: [ - Column( - crossAxisAlignment: CrossAxisAlignment.start, + Row( children: [ Row( + mainAxisSize: MainAxisSize.min, children: [ - Row( - mainAxisSize: MainAxisSize.min, - children: [ - CircularAvatar( - width: 34, - height: 34, - url: "https://cdn4.iconfinder.com/data/icons/professions-2-2/151/89-512.png", - ), - 8.width, - SvgPicture.asset("assets/images/side_nav.svg"), - ], - ).onPress(() {}), - Expanded( - child: Row( - crossAxisAlignment: CrossAxisAlignment.center, - mainAxisAlignment: MainAxisAlignment.center, - mainAxisSize: MainAxisSize.min, - children: [ - //AppLogo(), - 8.width, - LocaleKeys.mohemm.tr().toText14() - ], - ), + CircularAvatar( + width: 34, + height: 34, + url: "https://cdn4.iconfinder.com/data/icons/professions-2-2/151/89-512.png", ), - SizedBox( - width: 36, - height: 36, - child: Stack( - alignment: Alignment.centerLeft, - children: [ - SvgPicture.asset("assets/images/announcements.svg"), - Positioned( - right: 0, - top: 0, - child: Container( - padding: const EdgeInsets.only(left: 5, right: 5), - decoration: BoxDecoration(color: MyColors.redColor, borderRadius: BorderRadius.circular(17)), - child: "3".toText12(color: Colors.white), - ), - ) - ], - ), - ) + 8.width, + SvgPicture.asset("assets/images/side_nav.svg"), ], + ).onPress(() {}), + Expanded( + child: Row( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.center, + mainAxisSize: MainAxisSize.min, + children: [ + //AppLogo(), + 8.width, + LocaleKeys.mohemm.tr().toText14() + ], + ), ), - 14.height, - LocaleKeys.goodMorning.tr().toText14(color: MyColors.grey77Color), - "Mahmoud Shrouf".toText24(isBold: true), - 16.height, - Row( - children: [ - Expanded( - child: AspectRatio( - aspectRatio: 159 / 159, + SizedBox( + width: 36, + height: 36, + child: Stack( + alignment: Alignment.centerLeft, + children: [ + SvgPicture.asset("assets/images/announcements.svg"), + Positioned( + right: 0, + top: 0, child: Container( - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(15), - gradient: const LinearGradient(transform: GradientRotation(.46), begin: Alignment.topRight, end: Alignment.bottomRight, colors: [ - MyColors.gradiantEndColor, - MyColors.gradiantStartColor, - ]), - ), - child: Stack( - alignment: Alignment.center, - children: [ - SvgPicture.asset("assets/images/"), - Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Expanded( - child: Column( - mainAxisSize: MainAxisSize.min, + padding: const EdgeInsets.only(left: 5, right: 5), + decoration: BoxDecoration(color: MyColors.redColor, borderRadius: BorderRadius.circular(17)), + child: "3".toText12(color: Colors.white), + ), + ) + ], + ), + ) + ], + ).paddingOnly(left: 21, right: 21, top: 48, bottom: 7), + Expanded( + child: ListView( + padding: EdgeInsets.zero, + children: [ + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + LocaleKeys.goodMorning.tr().toText14(color: MyColors.grey77Color), + "Mahmoud Shrouf".toText24(isBold: true), + 16.height, + Row( + children: [ + Expanded( + child: AspectRatio( + aspectRatio: 159 / 159, + child: Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(15), + gradient: const LinearGradient(transform: GradientRotation(.46), begin: Alignment.topRight, end: Alignment.bottomRight, colors: [ + MyColors.gradiantEndColor, + MyColors.gradiantStartColor, + ]), + ), + child: Stack( + alignment: Alignment.center, + children: [ + SvgPicture.asset("assets/images/"), + Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - LocaleKeys.markAttendance.tr().toText14(color: Colors.white, isBold: true), - 9.height, - "07:55:12".toText14(color: Colors.white, isBold: true), - LocaleKeys.timeLeftToday.tr().toText12(color: Colors.white), - 9.height, - ClipRRect( - borderRadius: const BorderRadius.all( - Radius.circular(20), - ), - child: LinearProgressIndicator( - value: 0.7, - minHeight: 8, - valueColor: const AlwaysStoppedAnimation(Colors.white), - backgroundColor: const Color(0xff196D73), - ), + Expanded( + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + LocaleKeys.markAttendance.tr().toText14(color: Colors.white, isBold: true), + 9.height, + "07:55:12".toText14(color: Colors.white, isBold: true), + LocaleKeys.timeLeftToday.tr().toText12(color: Colors.white), + 9.height, + const ClipRRect( + borderRadius: BorderRadius.all( + Radius.circular(20), + ), + child: LinearProgressIndicator( + value: 0.7, + minHeight: 8, + valueColor: const AlwaysStoppedAnimation(Colors.white), + backgroundColor: const Color(0xff196D73), + ), + ), + ], + ).paddingOnly(top: 12, right: 15, left: 12), + ), + Row( + children: [ + Expanded( + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [LocaleKeys.checkIn.tr().toText12(color: Colors.white), "09:00".toText14(color: Colors.white, isBold: true), 4.height], + ).paddingOnly(left: 12), + ), + Container( + width: 45, + height: 45, + padding: const EdgeInsets.only(left: 14, right: 14), + decoration: const BoxDecoration( + color: Color(0xff259EA4), + borderRadius: BorderRadius.only( + bottomRight: Radius.circular(15), + ), + ), + child: SvgPicture.asset("assets/images/stop.svg"), + ), + ], ), ], - ).paddingOnly(top: 12, right: 15, left: 12), + ), + ], + ), + ), + ), + ), + 9.width, + Expanded( + child: GridView.builder( + shrinkWrap: true, + primary: false, + physics: const NeverScrollableScrollPhysics(), + gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2, childAspectRatio: 2 / 2, crossAxisSpacing: 9, mainAxisSpacing: 9), + padding: EdgeInsets.zero, + itemCount: 4, + itemBuilder: (BuildContext context, int index) { + return Container( + decoration: BoxDecoration( + color: Color(namesColor[index]), + borderRadius: BorderRadius.circular(10), ), - Row( + child: Column( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.start, children: [ - Expanded( - child: Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, - children: [LocaleKeys.checkIn.tr().toText12(color: Colors.white), "09:00".toText14(color: Colors.white, isBold: true), 4.height], - ).paddingOnly(left: 12), - ), - Container( - width: 45, - height: 45, - padding: const EdgeInsets.only(left: 14, right: 14), - decoration: const BoxDecoration( - color: Color(0xff259EA4), - borderRadius: BorderRadius.only( - bottomRight: Radius.circular(15), + names[index].toText12(color: Colors.white), + Row( + children: [ + Expanded( + child: namesInt[index].toStringAsFixed(1).toText16(color: Colors.white, isBold: true), ), - ), - child: SvgPicture.asset("assets/images/stop.svg"), - ), + SvgPicture.asset("assets/images/arrow_next.svg", color: Colors.white) + ], + ) ], - ), - ], - ), - ], + ).paddingOnly(left: 10, right: 10, bottom: 6, top: 6), + ); + }, + ), ), - ), + ], ), - ), - 9.width, - Expanded( - child: GridView.builder( - shrinkWrap: true, - primary: false, - physics: const NeverScrollableScrollPhysics(), - gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2, childAspectRatio: 2 / 2, crossAxisSpacing: 9, mainAxisSpacing: 9), - padding: EdgeInsets.zero, - itemCount: 4, - itemBuilder: (BuildContext context, int index) { - return Container( - decoration: BoxDecoration( - color: Color(namesColor[index]), - borderRadius: BorderRadius.circular(10), - ), + 20.height, + Row( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Expanded( child: Column( - mainAxisAlignment: MainAxisAlignment.spaceBetween, crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, children: [ - names[index].toText12(color: Colors.white), - Row( - children: [ - Expanded( - child: namesInt[index].toStringAsFixed(1).toText16(color: Colors.white, isBold: true), - ), - SvgPicture.asset("assets/images/arrow_next.svg", color: Colors.white) - ], - ) + LocaleKeys.other.tr().toText12(), + LocaleKeys.services.tr().toText24(isBold: true), ], - ).paddingOnly(left: 10, right: 10, bottom: 6, top: 6), - ); - }, - ), - ), - ], - ), - 20.height, - Row( - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisSize: MainAxisSize.min, - children: [ - LocaleKeys.other.tr().toText12(), - LocaleKeys.services.tr().toText24(isBold: true), + ), + ), + LocaleKeys.viewAllServices.tr().toText12(isUnderLine: true), ], ), + ], + ).paddingOnly(left: 21, right: 21, top: 7), + SizedBox( + height: 105 + 26, + child: ListView.separated( + shrinkWrap: true, + physics: const BouncingScrollPhysics(), + padding: const EdgeInsets.only(left: 21, right: 21, top: 13, bottom: 13), + scrollDirection: Axis.horizontal, + itemBuilder: (cxt, index) { + return AspectRatio( + aspectRatio: 105 / 105, + child: Container( + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(15), + boxShadow: [ + BoxShadow( + color: const Color(0xff000000).withOpacity(.05), + blurRadius: 26, + offset: const Offset(0, -3), + ), + ], + ), + child: Column( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + SvgPicture.asset(iconT[index]), + Row( + crossAxisAlignment: CrossAxisAlignment.end, + children: [ + Expanded( + child: namesT[index].toText11(isBold: true), + ), + SvgPicture.asset("assets/images/arrow_next.svg").paddingOnly(bottom: 4) + ], + ) + ], + ).paddingOnly(left: 10, right: 10, bottom: 10, top: 12), + ), + ); + }, + separatorBuilder: (cxt, index) => 9.width, + itemCount: 4), + ), + 8.height, + Container( + width: double.infinity, + padding: EdgeInsets.only(top: 31), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.only(topRight: Radius.circular(50), topLeft: Radius.circular(50)), + border: Border.all(color: MyColors.lightGreyEDColor, width: 1), ), - LocaleKeys.viewAllServices.tr().toText12(isUnderLine: true), - ], - ), - ], - ).paddingOnly(left: 21, right: 21, top: 48), - SizedBox( - height: 105 + 26, - child: ListView.separated( - shrinkWrap: true, - physics: const BouncingScrollPhysics(), - padding: const EdgeInsets.only(left: 21, right: 21, top: 13, bottom: 13), - scrollDirection: Axis.horizontal, - itemBuilder: (cxt, index) { - return AspectRatio( - aspectRatio: 105 / 105, - child: Container( - decoration: BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.circular(15), - boxShadow: [ - BoxShadow( - color: const Color(0xff000000).withOpacity(.05), - blurRadius: 26, - offset: const Offset(0, -3), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Row( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + LocaleKeys.offers.tr().toText12(), + Row( + children: [ + LocaleKeys.discounts.tr().toText24(isBold: true), + 6.width, + Container( + padding: const EdgeInsets.only(left: 8, right: 8), + decoration: BoxDecoration( + color: MyColors.yellowColor, + borderRadius: BorderRadius.circular(10), + ), + child: LocaleKeys.newString.tr().toText10(isBold: true)), + ], + ), + ], + ), ), + LocaleKeys.viewAllOffers.tr().toText12(isUnderLine: true), ], + ).paddingOnly(left: 21, right: 21), + SizedBox( + height: 103 + 33, + child: ListView.separated( + shrinkWrap: true, + physics: const BouncingScrollPhysics(), + padding: const EdgeInsets.only(left: 21, right: 21, top: 13), + scrollDirection: Axis.horizontal, + itemBuilder: (cxt, index) { + return SizedBox( + width: 73, + child: Column( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Container( + width: 73, + height: 73, + decoration: BoxDecoration( + borderRadius: const BorderRadius.all( + Radius.circular(100), + ), + border: Border.all(color: MyColors.lightGreyEDColor, width: 1), + ), + child: ClipRRect( + borderRadius: const BorderRadius.all( + Radius.circular(50), + ), + child: Image.network( + "https://play-lh.googleusercontent.com/NPo88ojmhah4HDiposucJmfQIop4z4xc8kqJK9ITO9o-yCab2zxIp7PPB_XPj2iUojo", + fit: BoxFit.cover, + ), + ), + ), + 4.height, + Expanded(child: namesD[6 % (index + 1)].toText12(isCenter: true,maxLine: 2)), + ], + ), + ); + }, + separatorBuilder: (cxt, index) => 8.width, + itemCount: 6), ), - child: Column( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - SvgPicture.asset(iconT[index]), - Row( - crossAxisAlignment: CrossAxisAlignment.end, - children: [ - Expanded( - child: namesT[index].toText11(isBold: true), - ), - SvgPicture.asset("assets/images/arrow_next.svg").paddingOnly(bottom: 4) - ], - ) - ], - ).paddingOnly(left: 10, right: 10, bottom: 10, top: 12), - ), - ); - }, - separatorBuilder: (cxt, index) => 9.width, - itemCount: 4), + ], + ), + ) + ], + ), ) ], ), diff --git a/lib/ui/login/verify_login_screen.dart b/lib/ui/login/verify_login_screen.dart index 249fa52..54be916 100644 --- a/lib/ui/login/verify_login_screen.dart +++ b/lib/ui/login/verify_login_screen.dart @@ -641,7 +641,7 @@ class _VerifyLoginScreenState extends State { decoration: BoxDecoration( borderRadius: BorderRadius.circular(15), color: isDisable ? Colors.grey.withOpacity(0.3) : Colors.white, - border: Border.all(color: MyColors.lightGreyColor, width: 1), + border: Border.all(color: MyColors.lightGreyEFColor, width: 1), ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, From ad1dd5370bc5799f1ee4b5cb07590d5b0372a8be Mon Sep 17 00:00:00 2001 From: tall3at <91608104+tall3at@users.noreply.github.com> Date: Wed, 22 Dec 2021 21:44:13 +0500 Subject: [PATCH 4/7] Work List screen --- assets/langs/ar-SA.json | 2 + assets/langs/en-US.json | 2 + ios/Runner.xcodeproj/project.pbxproj | 68 ++++++ .../contents.xcworkspacedata | 3 + lib/classes/colors.dart | 3 + lib/config/routes.dart | 7 + lib/extensions/string_extensions.dart | 50 ++++- lib/generated/codegen_loader.g.dart | 2 + lib/ui/app_bar.dart | 25 +++ lib/ui/dashboard.dart | 191 +++++++++++++---- lib/ui/work_list/work_list_screen.dart | 200 ++++++++++++++++++ pubspec.lock | 10 +- 12 files changed, 502 insertions(+), 61 deletions(-) create mode 100644 lib/ui/app_bar.dart create mode 100644 lib/ui/work_list/work_list_screen.dart diff --git a/assets/langs/ar-SA.json b/assets/langs/ar-SA.json index ba920a8..a0625e6 100644 --- a/assets/langs/ar-SA.json +++ b/assets/langs/ar-SA.json @@ -45,6 +45,8 @@ "msg": "Hello {} in the {} world ", "msg_named": "{} are written in the {lang} language", "clickMe": "Click me", + "human": "Human", + "resources": "Resources", "profile": { "reset_password": { "label": "Reset Password", diff --git a/assets/langs/en-US.json b/assets/langs/en-US.json index ba920a8..a0625e6 100644 --- a/assets/langs/en-US.json +++ b/assets/langs/en-US.json @@ -45,6 +45,8 @@ "msg": "Hello {} in the {} world ", "msg_named": "{} are written in the {lang} language", "clickMe": "Click me", + "human": "Human", + "resources": "Resources", "profile": { "reset_password": { "label": "Reset Password", diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index 6a06610..7ca764b 100644 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -9,6 +9,7 @@ /* Begin PBXBuildFile section */ 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; + 6BB994F47479089301AC9232 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6CBD2B2B1A504A0E0BA52E83 /* Pods_Runner.framework */; }; 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; }; 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; @@ -31,7 +32,11 @@ /* Begin PBXFileReference section */ 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; + 3085328F552329DC897B71DD /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; }; + 3A5ABA8306DCFDB9E71D453A /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = ""; }; 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; + 3B4D9CAD3B112CCF7FEE1F91 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; }; + 6CBD2B2B1A504A0E0BA52E83 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = ""; }; 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; @@ -49,12 +54,32 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 6BB994F47479089301AC9232 /* Pods_Runner.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ + 6BD33033650F08D3E79761E4 /* Frameworks */ = { + isa = PBXGroup; + children = ( + 6CBD2B2B1A504A0E0BA52E83 /* Pods_Runner.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; + 969F82F1FCE09135D9CB4C64 /* Pods */ = { + isa = PBXGroup; + children = ( + 3085328F552329DC897B71DD /* Pods-Runner.debug.xcconfig */, + 3B4D9CAD3B112CCF7FEE1F91 /* Pods-Runner.release.xcconfig */, + 3A5ABA8306DCFDB9E71D453A /* Pods-Runner.profile.xcconfig */, + ); + name = Pods; + path = Pods; + sourceTree = ""; + }; 9740EEB11CF90186004384FC /* Flutter */ = { isa = PBXGroup; children = ( @@ -72,6 +97,8 @@ 9740EEB11CF90186004384FC /* Flutter */, 97C146F01CF9000F007C117D /* Runner */, 97C146EF1CF9000F007C117D /* Products */, + 969F82F1FCE09135D9CB4C64 /* Pods */, + 6BD33033650F08D3E79761E4 /* Frameworks */, ); sourceTree = ""; }; @@ -105,12 +132,14 @@ isa = PBXNativeTarget; buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; buildPhases = ( + 7D19CFF3DFB977EA83F4C733 /* [CP] Check Pods Manifest.lock */, 9740EEB61CF901F6004384FC /* Run Script */, 97C146EA1CF9000F007C117D /* Sources */, 97C146EB1CF9000F007C117D /* Frameworks */, 97C146EC1CF9000F007C117D /* Resources */, 9705A1C41CF9048500538489 /* Embed Frameworks */, 3B06AD1E1E4923F5004D2608 /* Thin Binary */, + AAF25E5FC427CABFCDCC628C /* [CP] Embed Pods Frameworks */, ); buildRules = ( ); @@ -183,6 +212,28 @@ shellPath = /bin/sh; shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin"; }; + 7D19CFF3DFB977EA83F4C733 /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; 9740EEB61CF901F6004384FC /* Run Script */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; @@ -197,6 +248,23 @@ shellPath = /bin/sh; shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; }; + AAF25E5FC427CABFCDCC628C /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist", + ); + name = "[CP] Embed Pods Frameworks"; + outputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; /* End PBXShellScriptBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ diff --git a/ios/Runner.xcworkspace/contents.xcworkspacedata b/ios/Runner.xcworkspace/contents.xcworkspacedata index 1d526a1..21a3cc1 100644 --- a/ios/Runner.xcworkspace/contents.xcworkspacedata +++ b/ios/Runner.xcworkspace/contents.xcworkspacedata @@ -4,4 +4,7 @@ + + diff --git a/lib/classes/colors.dart b/lib/classes/colors.dart index e8b8b2a..7bca72b 100644 --- a/lib/classes/colors.dart +++ b/lib/classes/colors.dart @@ -3,6 +3,7 @@ import 'package:flutter/cupertino.dart'; class MyColors { static const Color darkIconColor = Color(0xff28323A); static const Color darkTextColor = Color(0xff2B353E); + static const Color lightTextColor = Color(0xffBFBFBF); static const Color gradiantStartColor = Color(0xff33c0a5); static const Color gradiantEndColor = Color(0xff259db7 ); static const Color textMixColor = Color(0xff2BB8A6); @@ -15,4 +16,6 @@ class MyColors { static const Color darkWhiteColor = Color(0xffE0E0E0); static const Color redColor = Color(0xffD02127); static const Color yellowColor = Color(0xffF4E31C); + static const Color black = Color(0xff000000); + static const Color white = Color(0xffffffff); } diff --git a/lib/config/routes.dart b/lib/config/routes.dart index d60f2b8..c204655 100644 --- a/lib/config/routes.dart +++ b/lib/config/routes.dart @@ -2,6 +2,7 @@ import 'package:flutter/material.dart'; import 'package:mohem_flutter_app/ui/dashboard.dart'; import 'package:mohem_flutter_app/ui/login/login_screen.dart'; import 'package:mohem_flutter_app/ui/login/verify_login_screen.dart'; +import 'package:mohem_flutter_app/ui/work_list/work_list_screen.dart'; class AppRoutes { static const String splash = "/splash"; @@ -14,9 +15,15 @@ class AppRoutes { static const String dashboard = "/dashboard"; static const String initialRoute = login; + //Work List + static const String workList = "/workList"; + static final Map routes = { login: (context) => LoginScreen(), verifyLogin: (context) => VerifyLoginScreen(), dashboard: (context) => Dashboard(), + + //Work List + workList: (context) => WorkListScreen(), }; } diff --git a/lib/extensions/string_extensions.dart b/lib/extensions/string_extensions.dart index d77bbff..21e370a 100644 --- a/lib/extensions/string_extensions.dart +++ b/lib/extensions/string_extensions.dart @@ -7,10 +7,16 @@ extension EmailValidator on String { Widget toText10({Color? color, bool isBold = false}) => Text( this, - style: TextStyle(fontSize: 10, fontWeight: isBold ? FontWeight.bold : FontWeight.w600, color: color ?? MyColors.darkTextColor, letterSpacing: -0.4), + style: TextStyle( + fontSize: 10, + fontWeight: isBold ? FontWeight.bold : FontWeight.w600, + color: color ?? MyColors.darkTextColor, + letterSpacing: -0.4), ); - Widget toText11({Color? color, bool isUnderLine = false, bool isBold = false}) => Text( + Widget toText11( + {Color? color, bool isUnderLine = false, bool isBold = false}) => + Text( this, style: TextStyle( fontSize: 11, @@ -20,7 +26,13 @@ extension EmailValidator on String { decoration: isUnderLine ? TextDecoration.underline : null), ); - Widget toText12({Color? color, bool isUnderLine = false, bool isBold = false, bool isCenter = false, int maxLine = 0}) => Text( + Widget toText12( + {Color? color, + bool isUnderLine = false, + bool isBold = false, + bool isCenter = false, + int maxLine = 0}) => + Text( this, textAlign: isCenter ? TextAlign.center : null, maxLines: (maxLine > 0) ? maxLine : null, @@ -34,26 +46,46 @@ extension EmailValidator on String { Widget toText13({Color? color, bool isUnderLine = false}) => Text( this, - style: TextStyle(fontSize: 13, fontWeight: FontWeight.w600, color: color ?? MyColors.darkTextColor, letterSpacing: -0.52, decoration: isUnderLine ? TextDecoration.underline : null), + style: TextStyle( + fontSize: 13, + fontWeight: FontWeight.w600, + color: color ?? MyColors.darkTextColor, + letterSpacing: -0.52, + decoration: isUnderLine ? TextDecoration.underline : null), ); Widget toText14({Color? color, bool isBold = false}) => Text( this, - style: TextStyle(color: color ?? MyColors.darkTextColor, fontSize: 14, letterSpacing: -0.48, fontWeight: isBold ? FontWeight.bold : FontWeight.w600), + style: TextStyle( + color: color ?? MyColors.darkTextColor, + fontSize: 14, + letterSpacing: -0.48, + fontWeight: isBold ? FontWeight.bold : FontWeight.w600), ); Widget toText16({Color? color, bool isBold = false}) => Text( this, - style: TextStyle(color: color ?? MyColors.darkTextColor, fontSize: 16, letterSpacing: -0.64, fontWeight: isBold ? FontWeight.bold : FontWeight.w600), + style: TextStyle( + color: color ?? MyColors.darkTextColor, + fontSize: 16, + letterSpacing: -0.64, + fontWeight: isBold ? FontWeight.bold : FontWeight.w600), ); - Widget toText24({bool isBold = false}) => Text( + Widget toText24({bool isBold = false, Color? textColor}) => Text( this, - style: TextStyle(height: 23 / 24, color: MyColors.darkTextColor, fontSize: 24, letterSpacing: -1.44, fontWeight: isBold ? FontWeight.bold : FontWeight.w600), + style: TextStyle( + height: 23 / 24, + color: textColor ?? MyColors.darkTextColor, + fontSize: 24, + letterSpacing: -1.44, + fontWeight: isBold ? FontWeight.bold : FontWeight.w600), ); bool isValidEmail() { - return RegExp(r'^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$').hasMatch(this); + return RegExp( + r'^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$') + .hasMatch(this); } String toFormattedDate() { diff --git a/lib/generated/codegen_loader.g.dart b/lib/generated/codegen_loader.g.dart index 0991c28..a471169 100644 --- a/lib/generated/codegen_loader.g.dart +++ b/lib/generated/codegen_loader.g.dart @@ -51,6 +51,7 @@ class CodegenLoader extends AssetLoader{ "viewAllOffers": "View All Offers", "offers": "Offers & ", "discounts": "Discounts", + "newString": "New", "title": "Title", "home": "Home", "mySalary": "My Salary", @@ -130,6 +131,7 @@ static const Map en_US = { "viewAllOffers": "View All Offers", "offers": "Offers & ", "discounts": "Discounts", + "newString": "New", "title": "Title", "home": "Home", "mySalary": "My Salary", diff --git a/lib/ui/app_bar.dart b/lib/ui/app_bar.dart new file mode 100644 index 0000000..0823a5a --- /dev/null +++ b/lib/ui/app_bar.dart @@ -0,0 +1,25 @@ +import 'package:easy_localization/src/public_ext.dart'; +import 'package:flutter/material.dart'; +import 'package:mohem_flutter_app/classes/colors.dart'; +import 'package:mohem_flutter_app/generated/locale_keys.g.dart'; +import 'package:mohem_flutter_app/extensions/string_extensions.dart'; + +AppBar appBar(BuildContext context, {required String title}) { + return AppBar( + title: title.toText24(textColor: MyColors.darkTextColor), + centerTitle: false, + automaticallyImplyLeading: false, + backgroundColor: Colors.white, + actions: [ + IconButton( + onPressed: () { + Navigator.pop(context); + }, + icon: Icon( + Icons.close, + color: MyColors.darkIconColor, + ), + ), + ], + ); +} diff --git a/lib/ui/dashboard.dart b/lib/ui/dashboard.dart index 2c9cf50..91a6e4f 100644 --- a/lib/ui/dashboard.dart +++ b/lib/ui/dashboard.dart @@ -3,6 +3,7 @@ import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:mohem_flutter_app/classes/colors.dart'; +import 'package:mohem_flutter_app/config/routes.dart'; import 'package:mohem_flutter_app/extensions/int_extensions.dart'; import 'package:mohem_flutter_app/extensions/string_extensions.dart'; import 'package:mohem_flutter_app/extensions/widget_extensions.dart'; @@ -31,14 +32,34 @@ class _DashboardState extends State { @override Widget build(BuildContext context) { - List names = [LocaleKeys.workList.tr(), LocaleKeys.missingSwipes.tr(), LocaleKeys.leaveBalance.tr(), LocaleKeys.ticketBalance.tr()]; + List names = [ + LocaleKeys.workList.tr(), + LocaleKeys.missingSwipes.tr(), + LocaleKeys.leaveBalance.tr(), + LocaleKeys.ticketBalance.tr() + ]; List namesInt = [118, 02, 18.5, 03]; List namesColor = [0xff125765, 0xff239D8F, 0xff2BB8A8, 0xff1D92AA]; - List namesT = [LocaleKeys.monthlyAttendance.tr(), LocaleKeys.workFromHome.tr(), LocaleKeys.ticketRequest.tr(), LocaleKeys.monthlyAttendance.tr()]; - List iconT = ["assets/images/monthly_attendance.svg", "assets/images/work_from_home.svg", "assets/images/ticket_request.svg", "assets/images/work_from_home.svg"]; + List namesT = [ + LocaleKeys.monthlyAttendance.tr(), + LocaleKeys.workFromHome.tr(), + LocaleKeys.ticketRequest.tr(), + LocaleKeys.monthlyAttendance.tr() + ]; + List iconT = [ + "assets/images/monthly_attendance.svg", + "assets/images/work_from_home.svg", + "assets/images/ticket_request.svg", + "assets/images/work_from_home.svg" + ]; - List namesD = ["Nostalgia Perfume Perfume", "Al Nafoura", "AlJadi", "Nostalgia Perfume"]; + List namesD = [ + "Nostalgia Perfume Perfume", + "Al Nafoura", + "AlJadi", + "Nostalgia Perfume" + ]; return Scaffold( body: Column( @@ -51,7 +72,8 @@ class _DashboardState extends State { CircularAvatar( width: 34, height: 34, - url: "https://cdn4.iconfinder.com/data/icons/professions-2-2/151/89-512.png", + url: + "https://cdn4.iconfinder.com/data/icons/professions-2-2/151/89-512.png", ), 8.width, SvgPicture.asset("assets/images/side_nav.svg"), @@ -81,7 +103,9 @@ class _DashboardState extends State { top: 0, child: Container( padding: const EdgeInsets.only(left: 5, right: 5), - decoration: BoxDecoration(color: MyColors.redColor, borderRadius: BorderRadius.circular(17)), + decoration: BoxDecoration( + color: MyColors.redColor, + borderRadius: BorderRadius.circular(17)), child: "3".toText12(color: Colors.white), ), ) @@ -97,7 +121,9 @@ class _DashboardState extends State { Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - LocaleKeys.goodMorning.tr().toText14(color: MyColors.grey77Color), + LocaleKeys.goodMorning + .tr() + .toText14(color: MyColors.grey77Color), "Mahmoud Shrouf".toText24(isBold: true), 16.height, Row( @@ -108,27 +134,41 @@ class _DashboardState extends State { child: Container( decoration: BoxDecoration( borderRadius: BorderRadius.circular(15), - gradient: const LinearGradient(transform: GradientRotation(.46), begin: Alignment.topRight, end: Alignment.bottomRight, colors: [ - MyColors.gradiantEndColor, - MyColors.gradiantStartColor, - ]), + gradient: const LinearGradient( + transform: GradientRotation(.46), + begin: Alignment.topRight, + end: Alignment.bottomRight, + colors: [ + MyColors.gradiantEndColor, + MyColors.gradiantStartColor, + ]), ), child: Stack( alignment: Alignment.center, children: [ SvgPicture.asset("assets/images/"), Column( - crossAxisAlignment: CrossAxisAlignment.start, + crossAxisAlignment: + CrossAxisAlignment.start, children: [ Expanded( child: Column( mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, + crossAxisAlignment: + CrossAxisAlignment.start, children: [ - LocaleKeys.markAttendance.tr().toText14(color: Colors.white, isBold: true), + LocaleKeys.markAttendance + .tr() + .toText14( + color: Colors.white, + isBold: true), 9.height, - "07:55:12".toText14(color: Colors.white, isBold: true), - LocaleKeys.timeLeftToday.tr().toText12(color: Colors.white), + "07:55:12".toText14( + color: Colors.white, + isBold: true), + LocaleKeys.timeLeftToday + .tr() + .toText12(color: Colors.white), 9.height, const ClipRRect( borderRadius: BorderRadius.all( @@ -137,33 +177,50 @@ class _DashboardState extends State { child: LinearProgressIndicator( value: 0.7, minHeight: 8, - valueColor: const AlwaysStoppedAnimation(Colors.white), - backgroundColor: const Color(0xff196D73), + valueColor: + const AlwaysStoppedAnimation< + Color>(Colors.white), + backgroundColor: + const Color(0xff196D73), ), ), ], - ).paddingOnly(top: 12, right: 15, left: 12), + ).paddingOnly( + top: 12, right: 15, left: 12), ), Row( children: [ Expanded( child: Column( mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, - children: [LocaleKeys.checkIn.tr().toText12(color: Colors.white), "09:00".toText14(color: Colors.white, isBold: true), 4.height], + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ + LocaleKeys.checkIn + .tr() + .toText12( + color: Colors.white), + "09:00".toText14( + color: Colors.white, + isBold: true), + 4.height + ], ).paddingOnly(left: 12), ), Container( width: 45, height: 45, - padding: const EdgeInsets.only(left: 14, right: 14), + padding: const EdgeInsets.only( + left: 14, right: 14), decoration: const BoxDecoration( color: Color(0xff259EA4), borderRadius: BorderRadius.only( - bottomRight: Radius.circular(15), + bottomRight: + Radius.circular(15), ), ), - child: SvgPicture.asset("assets/images/stop.svg"), + child: SvgPicture.asset( + "assets/images/stop.svg"), ), ], ), @@ -180,7 +237,12 @@ class _DashboardState extends State { shrinkWrap: true, primary: false, physics: const NeverScrollableScrollPhysics(), - gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2, childAspectRatio: 2 / 2, crossAxisSpacing: 9, mainAxisSpacing: 9), + gridDelegate: + const SliverGridDelegateWithFixedCrossAxisCount( + crossAxisCount: 2, + childAspectRatio: 2 / 2, + crossAxisSpacing: 9, + mainAxisSpacing: 9), padding: EdgeInsets.zero, itemCount: 4, itemBuilder: (BuildContext context, int index) { @@ -190,21 +252,32 @@ class _DashboardState extends State { borderRadius: BorderRadius.circular(10), ), child: Column( - mainAxisAlignment: MainAxisAlignment.spaceBetween, + mainAxisAlignment: + MainAxisAlignment.spaceBetween, crossAxisAlignment: CrossAxisAlignment.start, children: [ names[index].toText12(color: Colors.white), Row( children: [ Expanded( - child: namesInt[index].toStringAsFixed(1).toText16(color: Colors.white, isBold: true), + child: namesInt[index] + .toStringAsFixed(1) + .toText16( + color: Colors.white, + isBold: true), ), - SvgPicture.asset("assets/images/arrow_next.svg", color: Colors.white) + SvgPicture.asset( + "assets/images/arrow_next.svg", + color: Colors.white) ], ) ], - ).paddingOnly(left: 10, right: 10, bottom: 6, top: 6), - ); + ).paddingOnly( + left: 10, right: 10, bottom: 6, top: 6), + ).onPress(() { + Navigator.pushNamed( + context, AppRoutes.workList); + }); }, ), ), @@ -219,12 +292,14 @@ class _DashboardState extends State { crossAxisAlignment: CrossAxisAlignment.start, mainAxisSize: MainAxisSize.min, children: [ - LocaleKeys.other.tr().toText12(), + "Other".toText12(), LocaleKeys.services.tr().toText24(isBold: true), ], ), ), - LocaleKeys.viewAllServices.tr().toText12(isUnderLine: true), + LocaleKeys.viewAllServices + .tr() + .toText12(isUnderLine: true), ], ), ], @@ -234,7 +309,8 @@ class _DashboardState extends State { child: ListView.separated( shrinkWrap: true, physics: const BouncingScrollPhysics(), - padding: const EdgeInsets.only(left: 21, right: 21, top: 13, bottom: 13), + padding: const EdgeInsets.only( + left: 21, right: 21, top: 13, bottom: 13), scrollDirection: Axis.horizontal, itemBuilder: (cxt, index) { return AspectRatio( @@ -245,7 +321,8 @@ class _DashboardState extends State { borderRadius: BorderRadius.circular(15), boxShadow: [ BoxShadow( - color: const Color(0xff000000).withOpacity(.05), + color: + const Color(0xff000000).withOpacity(.05), blurRadius: 26, offset: const Offset(0, -3), ), @@ -260,13 +337,17 @@ class _DashboardState extends State { crossAxisAlignment: CrossAxisAlignment.end, children: [ Expanded( - child: namesT[index].toText11(isBold: true), + child: + namesT[index].toText11(isBold: true), ), - SvgPicture.asset("assets/images/arrow_next.svg").paddingOnly(bottom: 4) + SvgPicture.asset( + "assets/images/arrow_next.svg") + .paddingOnly(bottom: 4) ], ) ], - ).paddingOnly(left: 10, right: 10, bottom: 10, top: 12), + ).paddingOnly( + left: 10, right: 10, bottom: 10, top: 12), ), ); }, @@ -279,8 +360,11 @@ class _DashboardState extends State { padding: EdgeInsets.only(top: 31), decoration: BoxDecoration( color: Colors.white, - borderRadius: BorderRadius.only(topRight: Radius.circular(50), topLeft: Radius.circular(50)), - border: Border.all(color: MyColors.lightGreyEDColor, width: 1), + borderRadius: BorderRadius.only( + topRight: Radius.circular(50), + topLeft: Radius.circular(50)), + border: + Border.all(color: MyColors.lightGreyEDColor, width: 1), ), child: Column( mainAxisSize: MainAxisSize.min, @@ -296,21 +380,29 @@ class _DashboardState extends State { LocaleKeys.offers.tr().toText12(), Row( children: [ - LocaleKeys.discounts.tr().toText24(isBold: true), + LocaleKeys.discounts + .tr() + .toText24(isBold: true), 6.width, Container( - padding: const EdgeInsets.only(left: 8, right: 8), + padding: const EdgeInsets.only( + left: 8, right: 8), decoration: BoxDecoration( color: MyColors.yellowColor, - borderRadius: BorderRadius.circular(10), + borderRadius: + BorderRadius.circular(10), ), - child: LocaleKeys.newString.tr().toText10(isBold: true)), + child: LocaleKeys.newString + .tr() + .toText10(isBold: true)), ], ), ], ), ), - LocaleKeys.viewAllOffers.tr().toText12(isUnderLine: true), + LocaleKeys.viewAllOffers + .tr() + .toText12(isUnderLine: true), ], ).paddingOnly(left: 21, right: 21), SizedBox( @@ -318,7 +410,8 @@ class _DashboardState extends State { child: ListView.separated( shrinkWrap: true, physics: const BouncingScrollPhysics(), - padding: const EdgeInsets.only(left: 21, right: 21, top: 13), + padding: const EdgeInsets.only( + left: 21, right: 21, top: 13), scrollDirection: Axis.horizontal, itemBuilder: (cxt, index) { return SizedBox( @@ -333,7 +426,9 @@ class _DashboardState extends State { borderRadius: const BorderRadius.all( Radius.circular(100), ), - border: Border.all(color: MyColors.lightGreyEDColor, width: 1), + border: Border.all( + color: MyColors.lightGreyEDColor, + width: 1), ), child: ClipRRect( borderRadius: const BorderRadius.all( @@ -346,7 +441,9 @@ class _DashboardState extends State { ), ), 4.height, - Expanded(child: namesD[6 % (index + 1)].toText12(isCenter: true,maxLine: 2)), + Expanded( + child: namesD[6 % (index + 1)].toText12( + isCenter: true, maxLine: 2)), ], ), ); diff --git a/lib/ui/work_list/work_list_screen.dart b/lib/ui/work_list/work_list_screen.dart new file mode 100644 index 0000000..9b9aee9 --- /dev/null +++ b/lib/ui/work_list/work_list_screen.dart @@ -0,0 +1,200 @@ +import 'package:easy_localization/src/public_ext.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_svg/svg.dart'; +import 'package:mohem_flutter_app/classes/colors.dart'; +import 'package:mohem_flutter_app/generated/locale_keys.g.dart'; +import 'package:mohem_flutter_app/ui/app_bar.dart'; +import 'package:mohem_flutter_app/extensions/string_extensions.dart'; +import 'package:mohem_flutter_app/extensions/int_extensions.dart'; +import 'package:mohem_flutter_app/extensions/widget_extensions.dart'; + +class WorkListScreen extends StatefulWidget { + @override + State createState() => _WorkListScreenState(); +} + +class _WorkListScreenState extends State { + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: Colors.white, + appBar: appBar( + context, + title: LocaleKeys.workList.tr(), + ), + body: Container( + width: double.infinity, + height: double.infinity, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Container( + width: double.infinity, + height: 2, + color: MyColors.darkWhiteColor, + ), + Container( + width: double.infinity, + height: 40, + margin: EdgeInsets.only( + top: 21, + ), + child: ListView.separated( + itemBuilder: (context, index) { + return Container( + padding: EdgeInsets.only( + left: 30, + right: 30, + ), + alignment: Alignment.center, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(6), + color: tabList[index].isSelected + ? MyColors.darkIconColor + : MyColors.darkWhiteColor, + ), + child: tabList[index].title.toText12( + color: tabList[index].isSelected + ? MyColors.white + : MyColors.black, + ), + ); + }, + separatorBuilder: (context, index) { + return 8.width; + }, + shrinkWrap: true, + itemCount: tabList.length, + scrollDirection: Axis.horizontal, + padding: const EdgeInsets.only( + left: 21, + right: 21, + ), + ), + ), + Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + LocaleKeys.human.toText12(), + LocaleKeys.resources.tr().toText24(isBold: true), + ], + ).paddingOnly(top: 24, left: 21, right: 21), + 24.height, + Expanded( + child: ListView.separated( + itemBuilder: (context, index) { + return rowItem(typesList[index]); + }, + separatorBuilder: (context, index) { + return 12.height; + }, + itemCount: typesList.length, + padding: EdgeInsets.only(left: 21, right: 21), + ), + ), + ], + ), + ), + ); + } + + Widget rowItem(Types types) { + return Container( + width: double.infinity, + padding: EdgeInsets.all(12), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(10), + boxShadow: [ + BoxShadow( + color: const Color(0xff000000).withOpacity(.05), + blurRadius: 26, + offset: const Offset(0, -3), + ), + ], + ), + child: Row( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(4), + gradient: LinearGradient( + transform: GradientRotation(.46), + begin: Alignment.topRight, + end: Alignment.bottomRight, + colors: types.colors), + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + SvgPicture.asset( + "assets/images/miss_swipe.svg", + color: Colors.white, + ), + 2.height, + types.title.toText10(color: Colors.white) + ], + ).paddingAll(6), + ), + 12.width, + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.start, + children: [ + "Missing Swipe Request".toText16(), + "Missing Swipe Request for Hussain, Mohammad has been approved" + .toText10(), + 12.height, + Row( + children: [ + Expanded( + child: "07 Jan 2021" + .toText10(color: MyColors.lightTextColor)), + SvgPicture.asset( + "assets/images/arrow_next.svg", + color: MyColors.darkIconColor, + ) + ], + ), + ], + ), + ), + ], + ), + ); + } +} + +class Tabs { + String title; + bool isSelected; + + Tabs(this.title, this.isSelected); +} + +List tabList = [ + Tabs("All", true), + Tabs("HR", false), + Tabs("MO", false), + Tabs("PR", false), + Tabs("PO", false), +]; + +class Types { + String title; + List colors; + + Types(this.title, this.colors); +} + +List typesList = [ + Types("HR", [Color(0xff32D892), Color(0xff1AB170)]), + Types("ITG", [Color(0xffEB8C90), Color(0xffDE6C70)]), + Types("PO", [Color(0xff5099E3), Color(0xff3670AA)]), + Types("PR", [Color(0xff48EACF), Color(0xff3DCAB3)]), + Types("MO", [Color(0xff58DCFA), Color(0xff3CB9D5)]), +]; diff --git a/pubspec.lock b/pubspec.lock index 302ac7a..56d2f3f 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -14,7 +14,7 @@ packages: name: async url: "https://pub.dartlang.org" source: hosted - version: "2.8.2" + version: "2.8.1" boolean_selector: dependency: transitive description: @@ -28,7 +28,7 @@ packages: name: characters url: "https://pub.dartlang.org" source: hosted - version: "1.2.0" + version: "1.1.0" charcode: dependency: transitive description: @@ -202,7 +202,7 @@ packages: name: matcher url: "https://pub.dartlang.org" source: hosted - version: "0.12.11" + version: "0.12.10" meta: dependency: transitive description: @@ -445,7 +445,7 @@ packages: name: test_api url: "https://pub.dartlang.org" source: hosted - version: "0.4.3" + version: "0.4.2" typed_data: dependency: transitive description: @@ -466,7 +466,7 @@ packages: name: vector_math url: "https://pub.dartlang.org" source: hosted - version: "2.1.1" + version: "2.1.0" win32: dependency: transitive description: From 88b86c66d5c57f1a8d5222ab237eb1a7ea24e266 Mon Sep 17 00:00:00 2001 From: tall3at <91608104+tall3at@users.noreply.github.com> Date: Sun, 26 Dec 2021 17:03:59 +0500 Subject: [PATCH 5/7] internal Work List screen --- lib/classes/colors.dart | 2 + lib/config/routes.dart | 3 + .../fragments/actions_fragment.dart | 126 +++++++++++++++++ .../fragments/attachments_fragment.dart | 11 ++ .../fragments/info_fragments.dart | 11 ++ .../fragments/request_fragment.dart | 87 ++++++++++++ .../missing_swipe/missing_swipe_screen.dart | 105 ++++++++++++++ lib/ui/work_list/work_list_screen.dart | 130 +++++++++--------- lib/widgets/button/app_button.dart | 96 +++++++++++++ lib/widgets/button/default_button.dart | 61 ++++++-- 10 files changed, 557 insertions(+), 75 deletions(-) create mode 100644 lib/ui/work_list/missing_swipe/fragments/actions_fragment.dart create mode 100644 lib/ui/work_list/missing_swipe/fragments/attachments_fragment.dart create mode 100644 lib/ui/work_list/missing_swipe/fragments/info_fragments.dart create mode 100644 lib/ui/work_list/missing_swipe/fragments/request_fragment.dart create mode 100644 lib/ui/work_list/missing_swipe/missing_swipe_screen.dart create mode 100644 lib/widgets/button/app_button.dart diff --git a/lib/classes/colors.dart b/lib/classes/colors.dart index 7bca72b..d9c5656 100644 --- a/lib/classes/colors.dart +++ b/lib/classes/colors.dart @@ -3,6 +3,7 @@ import 'package:flutter/cupertino.dart'; class MyColors { static const Color darkIconColor = Color(0xff28323A); static const Color darkTextColor = Color(0xff2B353E); + static const Color normalTextColor = Color(0xff5A5A5A); static const Color lightTextColor = Color(0xffBFBFBF); static const Color gradiantStartColor = Color(0xff33c0a5); static const Color gradiantEndColor = Color(0xff259db7 ); @@ -18,4 +19,5 @@ class MyColors { static const Color yellowColor = Color(0xffF4E31C); static const Color black = Color(0xff000000); static const Color white = Color(0xffffffff); + static const Color green = Color(0xffffffff); } diff --git a/lib/config/routes.dart b/lib/config/routes.dart index c204655..7d171b7 100644 --- a/lib/config/routes.dart +++ b/lib/config/routes.dart @@ -2,6 +2,7 @@ import 'package:flutter/material.dart'; import 'package:mohem_flutter_app/ui/dashboard.dart'; import 'package:mohem_flutter_app/ui/login/login_screen.dart'; import 'package:mohem_flutter_app/ui/login/verify_login_screen.dart'; +import 'package:mohem_flutter_app/ui/work_list/missing_swipe/missing_swipe_screen.dart'; import 'package:mohem_flutter_app/ui/work_list/work_list_screen.dart'; class AppRoutes { @@ -17,6 +18,7 @@ class AppRoutes { //Work List static const String workList = "/workList"; + static const String missingSwipe = "/missingSwipe"; static final Map routes = { login: (context) => LoginScreen(), @@ -25,5 +27,6 @@ class AppRoutes { //Work List workList: (context) => WorkListScreen(), + missingSwipe: (context) => MissingSwipeScreen(), }; } diff --git a/lib/ui/work_list/missing_swipe/fragments/actions_fragment.dart b/lib/ui/work_list/missing_swipe/fragments/actions_fragment.dart new file mode 100644 index 0000000..05cf9ce --- /dev/null +++ b/lib/ui/work_list/missing_swipe/fragments/actions_fragment.dart @@ -0,0 +1,126 @@ +import 'package:flutter/material.dart'; +import 'package:mohem_flutter_app/classes/colors.dart'; +import 'package:mohem_flutter_app/widgets/circular_avatar.dart'; +import 'package:mohem_flutter_app/extensions/string_extensions.dart'; +import 'package:mohem_flutter_app/extensions/int_extensions.dart'; +import 'package:mohem_flutter_app/extensions/widget_extensions.dart'; +import 'dart:math' as math; + +class ActionsFragment extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Container( + width: double.infinity, + height: double.infinity, + child: Column( + children: [ + showItem(), + ], + ), + ); + } + + Widget showItem() { + return Container( + width: double.infinity, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(15), + boxShadow: [ + BoxShadow( + color: const Color(0xff000000).withOpacity(.05), + blurRadius: 26, + offset: const Offset(0, -3), + ), + ], + ), + clipBehavior: Clip.antiAlias, + margin: EdgeInsets.all(21), + child: Stack( + clipBehavior: Clip.antiAlias, + children: [ + Positioned( + left: -21, + child: Transform.rotate( + angle: 125, + child: Container( + width: 60, + height: 20, + color: Colors.black, + ), + ), + ), + Column( + children: [ + Padding( + padding: const EdgeInsets.only(left: 12, right: 12, top: 12), + child: Column( + children: [ + Row( + children: [ + CircularAvatar(), + 12.width, + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + "Mahmoud Shrouf".toText16(), + 6.height, + "Missing Swipe Request for Hussain, Mohammad has been approved" + .toText12(), + 3.height, + Row( + children: [ + "Submitted".toText10(), + 12.width, + "On 07 Jan 2021" + .toText12(color: MyColors.lightTextColor) + ], + ) + ], + ), + ) + ], + ), + ], + ), + ), + 12.height, + Container( + width: double.infinity, + height: 1, + color: MyColors.lightTextColor, + ), + Row( + children: [ + Expanded( + child: Center( + child: "Request Info" + .toText12(isBold: true) + .paddingOnly(left: 21, right: 21, top: 16, bottom: 8), + ), + ), + Center( + child: Container( + width: 1, + height: 45, + color: MyColors.lightTextColor, + ), + ), + Expanded( + child: Center( + child: "Delegate" + .toText12( + color: MyColors.gradiantEndColor, isBold: true) + .paddingOnly(left: 21, right: 21, top: 16, bottom: 8), + ), + ), + ], + ), + ], + ), + ], + ), + ); + } +} diff --git a/lib/ui/work_list/missing_swipe/fragments/attachments_fragment.dart b/lib/ui/work_list/missing_swipe/fragments/attachments_fragment.dart new file mode 100644 index 0000000..01eb52f --- /dev/null +++ b/lib/ui/work_list/missing_swipe/fragments/attachments_fragment.dart @@ -0,0 +1,11 @@ +import 'package:flutter/material.dart'; + +class AttachmentsFragment extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Container( + width: double.infinity, + height: double.infinity, + ); + } +} diff --git a/lib/ui/work_list/missing_swipe/fragments/info_fragments.dart b/lib/ui/work_list/missing_swipe/fragments/info_fragments.dart new file mode 100644 index 0000000..8a6a2fa --- /dev/null +++ b/lib/ui/work_list/missing_swipe/fragments/info_fragments.dart @@ -0,0 +1,11 @@ +import 'package:flutter/material.dart'; + +class InfoFragment extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Container( + width: double.infinity, + height: double.infinity, + ); + } +} diff --git a/lib/ui/work_list/missing_swipe/fragments/request_fragment.dart b/lib/ui/work_list/missing_swipe/fragments/request_fragment.dart new file mode 100644 index 0000000..0fb5170 --- /dev/null +++ b/lib/ui/work_list/missing_swipe/fragments/request_fragment.dart @@ -0,0 +1,87 @@ +import 'package:flutter/material.dart'; +import 'package:mohem_flutter_app/classes/colors.dart'; +import 'package:mohem_flutter_app/extensions/string_extensions.dart'; +import 'package:mohem_flutter_app/extensions/int_extensions.dart'; + +class RequestFragment extends StatefulWidget { + @override + State createState() => _RequestFragmentState(); +} + +class _RequestFragmentState extends State { + bool isOpened = false; + + @override + Widget build(BuildContext context) { + return Container( + width: double.infinity, + height: double.infinity, + child: Column( + children: [ + Container( + width: double.infinity, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(15), + boxShadow: [ + BoxShadow( + color: const Color(0xff000000).withOpacity(.05), + blurRadius: 26, + offset: const Offset(0, -3), + ), + ], + ), + margin: EdgeInsets.all(21), + padding: EdgeInsets.only(top: 21, bottom: 21, right: 16, left: 16), + child: Column( + children: [ + Row( + children: [ + Expanded( + child: "Hardware Mobility 161 Messenger".toText16(), + ), + Icon(Icons.keyboard_arrow_down_rounded), + ], + ), + Column( + children: [ + 12.height, + showItem("Code:", "3188000067"), + showItem("Quantity:", "1"), + showItem("Line Status:", "Pending Approval"), + showItem("Transection Type:", "Move Order Issue:"), + showItem("Organization Code:", "SWD"), + showItem("From Subinventory:", "SWD_MSPS"), + showItem("To Subinventory:", "SWD_MSPS"), + showItem("Ship To Location :", + "SWD 11206-E.R. (Emergency Room)"), + showItem("Unit:", "Each"), + showItem("Date Required:", "12/23/2019 4:54:04 PM"), + showItem("Status Date:", "12/23/2019 4:54:04 PM"), + showItem("Operation Unit:", "Sehat Al Sewedi"), + showItem("Organization:", "Sehat Al Sewedi"), + showItem("From Locator:", "-"), + showItem("To Locator :", "-"), + ], + ), + ], + ), + ), + ], + ), + ); + } + + Widget showItem(String title, String value) { + return Padding( + padding: const EdgeInsets.only(top: 4, bottom: 4), + child: Row( + children: [ + title.toText12(isBold: true), + 6.width, + title.toText12(isBold: false, color: MyColors.normalTextColor), + ], + ), + ); + } +} diff --git a/lib/ui/work_list/missing_swipe/missing_swipe_screen.dart b/lib/ui/work_list/missing_swipe/missing_swipe_screen.dart new file mode 100644 index 0000000..ca3f5e1 --- /dev/null +++ b/lib/ui/work_list/missing_swipe/missing_swipe_screen.dart @@ -0,0 +1,105 @@ +import 'package:flutter/material.dart'; +import 'package:mohem_flutter_app/classes/colors.dart'; +import 'package:mohem_flutter_app/ui/app_bar.dart'; +import 'package:mohem_flutter_app/extensions/string_extensions.dart'; +import 'package:mohem_flutter_app/ui/work_list/missing_swipe/fragments/actions_fragment.dart'; +import 'package:mohem_flutter_app/ui/work_list/missing_swipe/fragments/attachments_fragment.dart'; +import 'package:mohem_flutter_app/ui/work_list/missing_swipe/fragments/info_fragments.dart'; +import 'package:mohem_flutter_app/ui/work_list/missing_swipe/fragments/request_fragment.dart'; +import 'package:mohem_flutter_app/widgets/button/app_button.dart'; +import 'package:mohem_flutter_app/widgets/button/default_button.dart'; +import 'package:mohem_flutter_app/extensions/int_extensions.dart'; + +class MissingSwipeScreen extends StatelessWidget { + @override + Widget build(BuildContext context) { + return DefaultTabController( + length: 4, + child: Scaffold( + appBar: appBar(context, title: "Missing Swipe Request"), + body: Container( + width: double.infinity, + height: double.infinity, + child: Column( + children: [ + Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.only( + bottomLeft: Radius.circular(20), + bottomRight: Radius.circular(20)), + gradient: LinearGradient( + transform: GradientRotation(.46), + begin: Alignment.topRight, + end: Alignment.bottomRight, + colors: [ + MyColors.gradiantEndColor, + MyColors.gradiantStartColor, + ]), + ), + clipBehavior: Clip.antiAlias, + child: TabBar( + indicatorColor: Colors.white, + labelColor: Colors.white, + tabs: [ + Tab( + text: "Request", + ), + Tab( + text: "Actions", + ), + Tab( + text: "Attachments", + ), + Tab( + text: "Info.", + ), + ], + ), + ), + Expanded( + child: TabBarView( + children: [ + RequestFragment(), + ActionsFragment(), + AttachmentsFragment(), + InfoFragment(), + ], + ), + ), + Container( + width: double.infinity, + height: 60, + padding: EdgeInsets.only(left: 21, right: 21), + child: Row( + children: [ + Expanded( + child: DefaultButton( + "Reject", + () {}, + colors: [ + Color(0xffEB8C90), + Color(0xffDE6C70), + ], + ), + ), + 12.width, + Expanded( + child: DefaultButton( + "Approve", + () {}, + colors: [ + Color(0xff32D892), + Color(0xff1AB170), + ], + ), + ), + ], + ), + ) + ], + ), + ), + ), + ); + } +} diff --git a/lib/ui/work_list/work_list_screen.dart b/lib/ui/work_list/work_list_screen.dart index 9b9aee9..c3de75f 100644 --- a/lib/ui/work_list/work_list_screen.dart +++ b/lib/ui/work_list/work_list_screen.dart @@ -2,6 +2,7 @@ import 'package:easy_localization/src/public_ext.dart'; import 'package:flutter/material.dart'; import 'package:flutter_svg/svg.dart'; import 'package:mohem_flutter_app/classes/colors.dart'; +import 'package:mohem_flutter_app/config/routes.dart'; import 'package:mohem_flutter_app/generated/locale_keys.g.dart'; import 'package:mohem_flutter_app/ui/app_bar.dart'; import 'package:mohem_flutter_app/extensions/string_extensions.dart'; @@ -100,70 +101,75 @@ class _WorkListScreenState extends State { } Widget rowItem(Types types) { - return Container( - width: double.infinity, - padding: EdgeInsets.all(12), - decoration: BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.circular(10), - boxShadow: [ - BoxShadow( - color: const Color(0xff000000).withOpacity(.05), - blurRadius: 26, - offset: const Offset(0, -3), - ), - ], - ), - child: Row( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisAlignment: MainAxisAlignment.start, - children: [ - Container( - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(4), - gradient: LinearGradient( - transform: GradientRotation(.46), - begin: Alignment.topRight, - end: Alignment.bottomRight, - colors: types.colors), + return InkWell( + onTap: (){ + Navigator.pushNamed(context, AppRoutes.missingSwipe); + }, + child: Container( + width: double.infinity, + padding: EdgeInsets.all(12), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(10), + boxShadow: [ + BoxShadow( + color: const Color(0xff000000).withOpacity(.05), + blurRadius: 26, + offset: const Offset(0, -3), ), - child: Column( - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - SvgPicture.asset( - "assets/images/miss_swipe.svg", - color: Colors.white, - ), - 2.height, - types.title.toText10(color: Colors.white) - ], - ).paddingAll(6), - ), - 12.width, - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisAlignment: MainAxisAlignment.start, - children: [ - "Missing Swipe Request".toText16(), - "Missing Swipe Request for Hussain, Mohammad has been approved" - .toText10(), - 12.height, - Row( - children: [ - Expanded( - child: "07 Jan 2021" - .toText10(color: MyColors.lightTextColor)), - SvgPicture.asset( - "assets/images/arrow_next.svg", - color: MyColors.darkIconColor, - ) - ], - ), - ], + ], + ), + child: Row( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(4), + gradient: LinearGradient( + transform: GradientRotation(.46), + begin: Alignment.topRight, + end: Alignment.bottomRight, + colors: types.colors), + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + SvgPicture.asset( + "assets/images/miss_swipe.svg", + color: Colors.white, + ), + 2.height, + types.title.toText10(color: Colors.white) + ], + ).paddingAll(6), ), - ), - ], + 12.width, + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.start, + children: [ + "Missing Swipe Request".toText16(), + "Missing Swipe Request for Hussain, Mohammad has been approved" + .toText10(), + 12.height, + Row( + children: [ + Expanded( + child: "07 Jan 2021" + .toText10(color: MyColors.lightTextColor)), + SvgPicture.asset( + "assets/images/arrow_next.svg", + color: MyColors.darkIconColor, + ) + ], + ), + ], + ), + ), + ], + ), ), ); } diff --git a/lib/widgets/button/app_button.dart b/lib/widgets/button/app_button.dart new file mode 100644 index 0000000..ba9fe64 --- /dev/null +++ b/lib/widgets/button/app_button.dart @@ -0,0 +1,96 @@ +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:mohem_flutter_app/theme/colors.dart'; + +class AppButton extends StatefulWidget { + late AppButtonState _state; + + final String? text; + final double cornerRadius; + final EdgeInsets? margin; + final double? height; + final double? minWidth; + final VoidCallback? onClick; + final Color? color; + final Color? textColor; + final double fontSize; + final double elevation; + final bool bold; + + AppButton( + {this.text, + this.onClick, + this.cornerRadius = 10, + this.margin, + this.height, + this.color, + this.textColor, + this.minWidth, + this.fontSize = 15, + this.bold = true, + this.elevation = 5}); + + @override + State createState() => _state = AppButtonState(); + + enable() { + _state.setState(() { + _state.enable = true; + }); + } + + disable() { + _state.setState(() { + _state.enable = false; + }); + } + + Color borderColor = Colors.transparent; + double borderWidth = 0; + BorderStyle borderStyle = BorderStyle.solid; + + AppButton border(Color color, double width, {BorderStyle? style}) { + borderColor = color; + borderStyle = style ?? BorderStyle.solid; + borderWidth = width; + return this; + } +} + +class AppButtonState extends State { + bool enable = true; + + @override + Widget build(BuildContext context) { + var disableColor = + widget.color == null ? accentColor : widget.color!.withOpacity(0.2); + + // if(widget.bold) text.bold(); + // if(widget.fontSize != null) text.customSize(widget.fontSize); + + return Container( + height: widget.height ?? 60, + margin: widget.margin, + child: MaterialButton( + minWidth: widget.minWidth ?? 10, + elevation: widget.elevation, + onPressed: widget.onClick, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(widget.cornerRadius), + side: BorderSide( + style: widget.borderStyle, + color: widget.borderColor, + width: widget.borderWidth)), + disabledColor: disableColor, + color: widget.color ?? accentColor, + child: Text( + widget.text ?? "", + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.bold, + ), + ), + ), + ); + } +} diff --git a/lib/widgets/button/default_button.dart b/lib/widgets/button/default_button.dart index 9e0fd23..77d1c61 100644 --- a/lib/widgets/button/default_button.dart +++ b/lib/widgets/button/default_button.dart @@ -3,7 +3,10 @@ import 'package:flutter_svg/svg.dart'; import 'package:mohem_flutter_app/classes/colors.dart'; extension WithContainer on Widget { - Widget get insideContainer => Container(color: Colors.white, padding: const EdgeInsets.only(top: 16, bottom: 16, right: 21, left: 21), child: this); + Widget get insideContainer => Container( + color: Colors.white, + padding: const EdgeInsets.only(top: 16, bottom: 16, right: 21, left: 21), + child: this); } class DefaultButton extends StatelessWidget { @@ -17,8 +20,18 @@ class DefaultButton extends StatelessWidget { final double? fontSize; final bool isTextExpanded; final int count; + final List? colors; - DefaultButton(this.text, this.onPress, {this.color, this.isTextExpanded = true, this.svgIcon, this.disabledColor, this.count = 0, this.textColor = Colors.white, this.iconData, this.fontSize}); + DefaultButton(this.text, this.onPress, + {this.color, + this.isTextExpanded = true, + this.svgIcon, + this.disabledColor, + this.count = 0, + this.textColor = Colors.white, + this.iconData, + this.fontSize, + this.colors}); @override Widget build(BuildContext context) { @@ -29,24 +42,36 @@ class DefaultButton extends StatelessWidget { decoration: BoxDecoration( borderRadius: BorderRadius.circular(6.0), gradient: onPress == null - ? const LinearGradient(colors: [Color(0xffEAEAEA), Color(0xffEAEAEA)]) - : const LinearGradient(transform: GradientRotation(.83), begin: Alignment.topRight, end: Alignment.bottomLeft, colors: [ - MyColors.gradiantEndColor, - MyColors.gradiantStartColor, - ]), + ? const LinearGradient( + colors: [Color(0xffEAEAEA), Color(0xffEAEAEA)]) + : LinearGradient( + transform: GradientRotation(.83), + begin: Alignment.topRight, + end: Alignment.bottomLeft, + colors: colors ?? + [ + MyColors.gradiantEndColor, + MyColors.gradiantStartColor, + ]), ), child: Row( mainAxisAlignment: MainAxisAlignment.center, children: [ if (iconData != null) Icon(iconData, color: textColor), - if (svgIcon != null) SvgPicture.asset(svgIcon ?? "", color: textColor), + if (svgIcon != null) + SvgPicture.asset(svgIcon ?? "", color: textColor), if (!isTextExpanded) Padding( - padding: EdgeInsets.only(left: (iconData ?? svgIcon) != null ? 6 : 0), + padding: EdgeInsets.only( + left: (iconData ?? svgIcon) != null ? 6 : 0), child: Text( text, textAlign: TextAlign.center, - style: TextStyle(fontSize: fontSize ?? 16, fontWeight: FontWeight.w600, color: textColor, letterSpacing: -0.48), + style: TextStyle( + fontSize: fontSize ?? 16, + fontWeight: FontWeight.w600, + color: textColor, + letterSpacing: -0.48), ), ), if (isTextExpanded) @@ -54,7 +79,11 @@ class DefaultButton extends StatelessWidget { child: Text( text, textAlign: TextAlign.center, - style: TextStyle(fontSize: fontSize ?? 16, fontWeight: FontWeight.w600, color: textColor, letterSpacing: -0.48), + style: TextStyle( + fontSize: fontSize ?? 16, + fontWeight: FontWeight.w600, + color: textColor, + letterSpacing: -0.48), ), ), if (count > 0) @@ -65,11 +94,17 @@ class DefaultButton extends StatelessWidget { padding: const EdgeInsets.only(left: 5, right: 5), alignment: Alignment.center, height: 16, - decoration: BoxDecoration(borderRadius: BorderRadius.circular(10.0), color: Colors.white), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(10.0), + color: Colors.white), child: Text( "$count", textAlign: TextAlign.center, - style: const TextStyle(fontSize: 12, fontWeight: FontWeight.w700, color: Color(0xffD02127), letterSpacing: -0.6), + style: const TextStyle( + fontSize: 12, + fontWeight: FontWeight.w700, + color: Color(0xffD02127), + letterSpacing: -0.6), ), ), ) From dcabb4081150d3df34fcc60bdc7d1a4535119313 Mon Sep 17 00:00:00 2001 From: tall3at <91608104+tall3at@users.noreply.github.com> Date: Sun, 26 Dec 2021 17:08:59 +0500 Subject: [PATCH 6/7] internal Work List screen 1.0 --- .../missing_swipe/missing_swipe_screen.dart | 1 - lib/widgets/button/app_button.dart | 96 ------------------- 2 files changed, 97 deletions(-) delete mode 100644 lib/widgets/button/app_button.dart diff --git a/lib/ui/work_list/missing_swipe/missing_swipe_screen.dart b/lib/ui/work_list/missing_swipe/missing_swipe_screen.dart index ca3f5e1..850f565 100644 --- a/lib/ui/work_list/missing_swipe/missing_swipe_screen.dart +++ b/lib/ui/work_list/missing_swipe/missing_swipe_screen.dart @@ -6,7 +6,6 @@ import 'package:mohem_flutter_app/ui/work_list/missing_swipe/fragments/actions_f import 'package:mohem_flutter_app/ui/work_list/missing_swipe/fragments/attachments_fragment.dart'; import 'package:mohem_flutter_app/ui/work_list/missing_swipe/fragments/info_fragments.dart'; import 'package:mohem_flutter_app/ui/work_list/missing_swipe/fragments/request_fragment.dart'; -import 'package:mohem_flutter_app/widgets/button/app_button.dart'; import 'package:mohem_flutter_app/widgets/button/default_button.dart'; import 'package:mohem_flutter_app/extensions/int_extensions.dart'; diff --git a/lib/widgets/button/app_button.dart b/lib/widgets/button/app_button.dart deleted file mode 100644 index ba9fe64..0000000 --- a/lib/widgets/button/app_button.dart +++ /dev/null @@ -1,96 +0,0 @@ -import 'package:flutter/cupertino.dart'; -import 'package:flutter/material.dart'; -import 'package:mohem_flutter_app/theme/colors.dart'; - -class AppButton extends StatefulWidget { - late AppButtonState _state; - - final String? text; - final double cornerRadius; - final EdgeInsets? margin; - final double? height; - final double? minWidth; - final VoidCallback? onClick; - final Color? color; - final Color? textColor; - final double fontSize; - final double elevation; - final bool bold; - - AppButton( - {this.text, - this.onClick, - this.cornerRadius = 10, - this.margin, - this.height, - this.color, - this.textColor, - this.minWidth, - this.fontSize = 15, - this.bold = true, - this.elevation = 5}); - - @override - State createState() => _state = AppButtonState(); - - enable() { - _state.setState(() { - _state.enable = true; - }); - } - - disable() { - _state.setState(() { - _state.enable = false; - }); - } - - Color borderColor = Colors.transparent; - double borderWidth = 0; - BorderStyle borderStyle = BorderStyle.solid; - - AppButton border(Color color, double width, {BorderStyle? style}) { - borderColor = color; - borderStyle = style ?? BorderStyle.solid; - borderWidth = width; - return this; - } -} - -class AppButtonState extends State { - bool enable = true; - - @override - Widget build(BuildContext context) { - var disableColor = - widget.color == null ? accentColor : widget.color!.withOpacity(0.2); - - // if(widget.bold) text.bold(); - // if(widget.fontSize != null) text.customSize(widget.fontSize); - - return Container( - height: widget.height ?? 60, - margin: widget.margin, - child: MaterialButton( - minWidth: widget.minWidth ?? 10, - elevation: widget.elevation, - onPressed: widget.onClick, - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(widget.cornerRadius), - side: BorderSide( - style: widget.borderStyle, - color: widget.borderColor, - width: widget.borderWidth)), - disabledColor: disableColor, - color: widget.color ?? accentColor, - child: Text( - widget.text ?? "", - style: TextStyle( - fontSize: 16, - fontWeight: FontWeight.bold, - ), - ), - ), - ); - } -} From af674407930619af59d564803fa5943de14f1152 Mon Sep 17 00:00:00 2001 From: tall3at <91608104+tall3at@users.noreply.github.com> Date: Sun, 26 Dec 2021 17:23:26 +0500 Subject: [PATCH 7/7] internal Work List screen 1.2 --- .../fragments/attachments_fragment.dart | 50 ++++++++++++++++ .../fragments/info_fragments.dart | 58 +++++++++++++++++++ .../fragments/request_fragment.dart | 2 +- 3 files changed, 109 insertions(+), 1 deletion(-) diff --git a/lib/ui/work_list/missing_swipe/fragments/attachments_fragment.dart b/lib/ui/work_list/missing_swipe/fragments/attachments_fragment.dart index 01eb52f..652eba8 100644 --- a/lib/ui/work_list/missing_swipe/fragments/attachments_fragment.dart +++ b/lib/ui/work_list/missing_swipe/fragments/attachments_fragment.dart @@ -1,4 +1,7 @@ import 'package:flutter/material.dart'; +import 'package:flutter_svg/flutter_svg.dart'; +import 'package:mohem_flutter_app/extensions/string_extensions.dart'; +import 'package:mohem_flutter_app/extensions/int_extensions.dart'; class AttachmentsFragment extends StatelessWidget { @override @@ -6,6 +9,53 @@ class AttachmentsFragment extends StatelessWidget { return Container( width: double.infinity, height: double.infinity, + child: ListView.separated( + itemCount: 2, + padding: EdgeInsets.all(21), + itemBuilder: (context, index) { + return showItem(attachmentsList[index]); + }, + separatorBuilder: (BuildContext context, int index) { + return 21.height; + }, + ), + ); + } + + Widget showItem(Attachments attachments) { + return Container( + width: double.infinity, + padding: EdgeInsets.all(21), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(15), + boxShadow: [ + BoxShadow( + color: const Color(0xff000000).withOpacity(.05), + blurRadius: 26, + offset: const Offset(0, -3), + ), + ], + ), + child: Row( + children: [ + SvgPicture.asset(attachments.icon), + 12.width, + attachments.title.toText16() + ], + ), ); } } + +class Attachments { + String title; + String icon; + + Attachments(this.title, this.icon); +} + +List attachmentsList = [ + Attachments("Attachment File Name.png", "assets/images/png.svg"), + Attachments("Attachment File Name.pdf", "assets/images/pdf.svg"), +]; diff --git a/lib/ui/work_list/missing_swipe/fragments/info_fragments.dart b/lib/ui/work_list/missing_swipe/fragments/info_fragments.dart index 8a6a2fa..b115df9 100644 --- a/lib/ui/work_list/missing_swipe/fragments/info_fragments.dart +++ b/lib/ui/work_list/missing_swipe/fragments/info_fragments.dart @@ -1,4 +1,7 @@ import 'package:flutter/material.dart'; +import 'package:mohem_flutter_app/classes/colors.dart'; +import 'package:mohem_flutter_app/extensions/int_extensions.dart'; +import 'package:mohem_flutter_app/extensions/string_extensions.dart'; class InfoFragment extends StatelessWidget { @override @@ -6,6 +9,61 @@ class InfoFragment extends StatelessWidget { return Container( width: double.infinity, height: double.infinity, + child: Column( + children: [ + Container( + width: double.infinity, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(15), + boxShadow: [ + BoxShadow( + color: const Color(0xff000000).withOpacity(.05), + blurRadius: 26, + offset: const Offset(0, -3), + ), + ], + ), + margin: EdgeInsets.all(21), + padding: EdgeInsets.only(top: 21, bottom: 21, right: 16, left: 16), + child: Column( + children: [ + Row( + children: [ + Expanded( + child: "Info Details".toText16(), + ), + // Icon(Icons.keyboard_arrow_down_rounded), + ], + ), + Column( + children: [ + 12.height, + showItem("From:", "Alma Linde Mendoza"), + showItem("To:", "Al Yabis, Norah"), + showItem("Sent:", "1/26/2020 10:41:07 AM"), + showItem("ID:", "30581045"), + showItem("Closed:", "-"), + ], + ), + ], + ), + ), + ], + ), + ); + } + + Widget showItem(String title, String value) { + return Padding( + padding: const EdgeInsets.only(top: 2, bottom: 2), + child: Row( + children: [ + title.toText12(isBold: true), + 6.width, + title.toText12(isBold: false, color: MyColors.normalTextColor), + ], + ), ); } } diff --git a/lib/ui/work_list/missing_swipe/fragments/request_fragment.dart b/lib/ui/work_list/missing_swipe/fragments/request_fragment.dart index 0fb5170..f87995a 100644 --- a/lib/ui/work_list/missing_swipe/fragments/request_fragment.dart +++ b/lib/ui/work_list/missing_swipe/fragments/request_fragment.dart @@ -74,7 +74,7 @@ class _RequestFragmentState extends State { Widget showItem(String title, String value) { return Padding( - padding: const EdgeInsets.only(top: 4, bottom: 4), + padding: const EdgeInsets.only(top: 2, bottom: 2), child: Row( children: [ title.toText12(isBold: true),