Merge issue 1.0

development_mirza
mirza.shafique 3 years ago
commit 45b5482b87

Binary file not shown.

@ -0,0 +1,93 @@
Copyright (c) 2014-2015 Wei Huang (wweeiihhuuaanngg@gmail.com)
This Font Software is licensed under the SIL Open Font License, Version 1.1.
This license is copied below, and is also available with a FAQ at:
http://scripts.sil.org/OFL
-----------------------------------------------------------
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
-----------------------------------------------------------
PREAMBLE
The goals of the Open Font License (OFL) are to stimulate worldwide
development of collaborative font projects, to support the font creation
efforts of academic and linguistic communities, and to provide a free and
open framework in which fonts may be shared and improved in partnership
with others.
The OFL allows the licensed fonts to be used, studied, modified and
redistributed freely as long as they are not sold by themselves. The
fonts, including any derivative works, can be bundled, embedded,
redistributed and/or sold with any software provided that any reserved
names are not used by derivative works. The fonts and derivatives,
however, cannot be released under any other type of license. The
requirement for fonts to remain under this license does not apply
to any document created using the fonts or their derivatives.
DEFINITIONS
"Font Software" refers to the set of files released by the Copyright
Holder(s) under this license and clearly marked as such. This may
include source files, build scripts and documentation.
"Reserved Font Name" refers to any names specified as such after the
copyright statement(s).
"Original Version" refers to the collection of Font Software components as
distributed by the Copyright Holder(s).
"Modified Version" refers to any derivative made by adding to, deleting,
or substituting -- in part or in whole -- any of the components of the
Original Version, by changing formats or by porting the Font Software to a
new environment.
"Author" refers to any designer, engineer, programmer, technical
writer or other person who contributed to the Font Software.
PERMISSION & CONDITIONS
Permission is hereby granted, free of charge, to any person obtaining
a copy of the Font Software, to use, study, copy, merge, embed, modify,
redistribute, and sell modified and unmodified copies of the Font
Software, subject to the following conditions:
1) Neither the Font Software nor any of its individual components,
in Original or Modified Versions, may be sold by itself.
2) Original or Modified Versions of the Font Software may be bundled,
redistributed and/or sold with any software, provided that each copy
contains the above copyright notice and this license. These can be
included either as stand-alone text files, human-readable headers or
in the appropriate machine-readable metadata fields within text or
binary files as long as those fields can be easily viewed by the user.
3) No Modified Version of the Font Software may use the Reserved Font
Name(s) unless explicit written permission is granted by the corresponding
Copyright Holder. This restriction only applies to the primary font name as
presented to the users.
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
Software shall not be used to promote, endorse or advertise any
Modified Version, except to acknowledge the contribution(s) of the
Copyright Holder(s) and the Author(s) or with their explicit written
permission.
5) The Font Software, modified or unmodified, in part or in whole,
must be distributed entirely under this license, and must not be
distributed under any other license. The requirement for fonts to
remain under this license does not apply to any document created
using the Font Software.
TERMINATION
This license becomes null and void if any of the above conditions are
not met.
DISCLAIMER
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
OTHER DEALINGS IN THE FONT SOFTWARE.

Binary file not shown.

After

Width:  |  Height:  |  Size: 488 B

@ -0,0 +1,9 @@
<svg xmlns="http://www.w3.org/2000/svg" width="38.595" height="38.024" viewBox="0 0 38.595 38.024">
<g id="fingerprint1-scan" transform="translate(0.342 0.655)">
<path id="Path_4539" data-name="Path 4539" d="M38.892,0H33.378A1.379,1.379,0,0,0,32,1.378v8.27a1.378,1.378,0,0,0,2.757,0V2.757h4.135a1.378,1.378,0,1,0,0-2.757Z" transform="translate(-32.342 -0.655)" fill="#28323a"/>
<path id="Path_4540" data-name="Path 4540" d="M38.892,200.27H34.757v-6.892a1.378,1.378,0,1,0-2.757,0v8.27a1.379,1.379,0,0,0,1.378,1.378h5.514a1.378,1.378,0,1,0,0-2.757Z" transform="translate(-32.342 -165.658)" fill="#28323a"/>
<path id="Path_4541" data-name="Path 4541" d="M390.892,0h-5.514a1.378,1.378,0,0,0,0,2.757h4.135V9.649a1.378,1.378,0,0,0,2.757,0V1.378A1.379,1.379,0,0,0,390.892,0Z" transform="translate(-354.018 -0.655)" fill="#28323a"/>
<path id="Path_4542" data-name="Path 4542" d="M390.892,192a1.379,1.379,0,0,0-1.378,1.378v6.892h-4.135a1.378,1.378,0,0,0,0,2.757h5.514a1.379,1.379,0,0,0,1.378-1.378v-8.27A1.379,1.379,0,0,0,390.892,192Z" transform="translate(-354.018 -165.658)" fill="#28323a"/>
<path id="Path_4648" data-name="Path 4648" d="M13.343,0A13.343,13.343,0,1,0,26.686,13.343,13.343,13.343,0,0,0,13.343,0Zm4.924,8.9a1.911,1.911,0,1,1-1.911,1.911A1.912,1.912,0,0,1,18.267,8.9Zm-9.849,0a1.911,1.911,0,1,1-1.911,1.911A1.912,1.912,0,0,1,8.418,8.9Zm12.124,9.083a8.733,8.733,0,0,1-14.4,0A1.169,1.169,0,1,1,8.07,16.657a6.4,6.4,0,0,0,10.55,0,1.168,1.168,0,1,1,1.923,1.325Z" transform="translate(5.611 4.855)" fill="#28323a"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

@ -0,0 +1,11 @@
<svg xmlns="http://www.w3.org/2000/svg" width="38.595" height="38.024" viewBox="0 0 38.595 38.024">
<g id="sms-speech-bubble" transform="translate(-1 1.645)">
<g id="textsms">
<path id="Path_4529" data-name="Path 4529" d="M21.992,0H2.444A2.451,2.451,0,0,0,0,2.444V24.436l4.887-4.887h17.1A2.451,2.451,0,0,0,24.436,17.1V2.444A2.451,2.451,0,0,0,21.992,0ZM8.552,11H6.109V8.552H8.552Zm4.887,0H11V8.552H13.44Zm4.887,0H15.883V8.552h2.444Z" transform="translate(8.144 5.013)" fill="#28323a"/>
<path id="Path_4543" data-name="Path 4543" d="M38.892,0H33.378A1.379,1.379,0,0,0,32,1.378v8.27a1.378,1.378,0,0,0,2.757,0V2.757h4.135a1.378,1.378,0,1,0,0-2.757Z" transform="translate(-31 -1.645)" fill="#28323a"/>
<path id="Path_4544" data-name="Path 4544" d="M38.892,200.27H34.757v-6.892a1.378,1.378,0,1,0-2.757,0v8.27a1.379,1.379,0,0,0,1.378,1.378h5.514a1.378,1.378,0,1,0,0-2.757Z" transform="translate(-31 -166.648)" fill="#28323a"/>
<path id="Path_4545" data-name="Path 4545" d="M390.892,0h-5.514a1.378,1.378,0,0,0,0,2.757h4.135V9.649a1.378,1.378,0,0,0,2.757,0V1.378A1.379,1.379,0,0,0,390.892,0Z" transform="translate(-352.676 -1.645)" fill="#28323a"/>
<path id="Path_4546" data-name="Path 4546" d="M390.892,192a1.379,1.379,0,0,0-1.378,1.378v6.892h-4.135a1.378,1.378,0,0,0,0,2.757h5.514a1.379,1.379,0,0,0,1.378-1.378v-8.27A1.379,1.379,0,0,0,390.892,192Z" transform="translate(-352.676 -166.648)" fill="#28323a"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

@ -0,0 +1,9 @@
<svg xmlns="http://www.w3.org/2000/svg" width="38.595" height="38.024" viewBox="0 0 38.595 38.024">
<g id="fingerprint-scan" transform="translate(0.342 0.655)">
<path id="Path_4535" data-name="Path 4535" d="M24,0H2.909A2.913,2.913,0,0,0,0,2.909V24a2.913,2.913,0,0,0,2.909,2.909H24A2.913,2.913,0,0,0,26.913,24V2.909A2.913,2.913,0,0,0,24,0ZM5,5.182c5.592-4.061,11.49-4.018,17,.072a.789.789,0,0,1-.47,1.422c-.894,0-6.986-6.478-15.607-.218A.788.788,0,0,1,5,5.182Zm7.349,20.277a.788.788,0,0,1-1.1-.2c-1.111-1.606-3.634-3.4-3.634-6.757a6.063,6.063,0,0,1,5.835-6.255A6.063,6.063,0,0,1,19.291,18.5v.841a.788.788,0,0,1-1.577,0V18.5a4.488,4.488,0,0,0-4.258-4.678A4.488,4.488,0,0,0,9.2,18.5C9.2,22.3,14.037,24.294,12.353,25.459Zm9.8-4.08a4.132,4.132,0,0,1-7.8-2.035c0-3.4-2.327-2.255-1.811-.191a.788.788,0,0,1-1.53.383c-1.074-4.295,4.917-6.037,4.917-.191A2.544,2.544,0,0,0,17.9,21.971c3.65.861,4.733-5.161,1.093-9.037-5.033-5.363-13.16-1.227-13.16,5.148A6.378,6.378,0,0,0,6.95,22.25a.788.788,0,0,1-1.284.916,8.033,8.033,0,0,1-1.408-5.084,9.351,9.351,0,0,1,9.2-9.2c6.8,0,11.128,7.628,8.7,12.5Zm.527-9.761a.788.788,0,0,1-1.075-.293C20.033,8.578,16.234,7.1,13.457,7.1a11.282,11.282,0,0,0-8.175,4.275A.788.788,0,0,1,3.97,10.5a12.781,12.781,0,0,1,9.487-4.977c5.841,0,11.056,5.05,9.222,6.1Z" transform="translate(5.793 4.943)" fill="#28323a"/>
<path id="Path_4539" data-name="Path 4539" d="M38.892,0H33.378A1.379,1.379,0,0,0,32,1.378v8.27a1.378,1.378,0,0,0,2.757,0V2.757h4.135a1.378,1.378,0,1,0,0-2.757Z" transform="translate(-32.342 -0.655)" fill="#28323a"/>
<path id="Path_4540" data-name="Path 4540" d="M38.892,200.27H34.757v-6.892a1.378,1.378,0,1,0-2.757,0v8.27a1.379,1.379,0,0,0,1.378,1.378h5.514a1.378,1.378,0,1,0,0-2.757Z" transform="translate(-32.342 -165.658)" fill="#28323a"/>
<path id="Path_4541" data-name="Path 4541" d="M390.892,0h-5.514a1.378,1.378,0,0,0,0,2.757h4.135V9.649a1.378,1.378,0,0,0,2.757,0V1.378A1.379,1.379,0,0,0,390.892,0Z" transform="translate(-354.018 -0.655)" fill="#28323a"/>
<path id="Path_4542" data-name="Path 4542" d="M390.892,192a1.379,1.379,0,0,0-1.378,1.378v6.892h-4.135a1.378,1.378,0,0,0,0,2.757h5.514a1.379,1.379,0,0,0,1.378-1.378v-8.27A1.379,1.379,0,0,0,390.892,192Z" transform="translate(-354.018 -165.658)" fill="#28323a"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.2 KiB

@ -0,0 +1,12 @@
<svg xmlns="http://www.w3.org/2000/svg" width="38.595" height="38.024" viewBox="0 0 38.595 38.024">
<g id="whatsapp_1_" data-name="whatsapp (1)" transform="translate(0.233 -4.309)">
<g id="Group_7424" data-name="Group 7424" transform="translate(4.808 8.729)">
<path id="Path_4537" data-name="Path 4537" d="M0,28.186l2.424-7.271a13.848,13.848,0,1,1,5.468,5.195Z" fill="#2cb742"/>
<path id="Path_4538" data-name="Path 4538" d="M29.341,23.6c-.64-1.209-3-2.591-3-2.591-.534-.3-1.177-.338-1.482.2a12.215,12.215,0,0,1-.961,1.051,1.791,1.791,0,0,1-2.547-.253l-1.935-1.935-1.935-1.935A1.791,1.791,0,0,1,17.23,15.6a12.216,12.216,0,0,1,1.051-.961c.542-.3.508-.948.2-1.482,0,0-1.382-2.358-2.591-3a1.325,1.325,0,0,0-1.557.234l-.854.854c-2.71,2.71-1.376,5.77,1.334,8.48L17.3,22.2l2.477,2.477c2.71,2.71,5.77,4.045,8.48,1.334l.854-.854A1.326,1.326,0,0,0,29.341,23.6Z" transform="translate(-6.169 -5.141)" fill="#fff"/>
</g>
<path id="Path_4547" data-name="Path 4547" d="M38.892,0H33.378A1.379,1.379,0,0,0,32,1.378v8.27a1.378,1.378,0,0,0,2.757,0V2.757h4.135a1.378,1.378,0,1,0,0-2.757Z" transform="translate(-32.233 4.309)" fill="#28323a"/>
<path id="Path_4548" data-name="Path 4548" d="M38.892,200.27H34.757v-6.892a1.378,1.378,0,1,0-2.757,0v8.27a1.379,1.379,0,0,0,1.378,1.378h5.514a1.378,1.378,0,1,0,0-2.757Z" transform="translate(-32.233 -160.693)" fill="#28323a"/>
<path id="Path_4549" data-name="Path 4549" d="M390.892,0h-5.514a1.378,1.378,0,0,0,0,2.757h4.135V9.649a1.378,1.378,0,0,0,2.757,0V1.378A1.379,1.379,0,0,0,390.892,0Z" transform="translate(-353.909 4.309)" fill="#28323a"/>
<path id="Path_4550" data-name="Path 4550" d="M390.892,192a1.379,1.379,0,0,0-1.378,1.378v6.892h-4.135a1.378,1.378,0,0,0,0,2.757h5.514a1.379,1.379,0,0,0,1.378-1.378v-8.27A1.379,1.379,0,0,0,390.892,192Z" transform="translate(-353.909 -160.693)" fill="#28323a"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 549 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 453 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 453 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 988 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 652 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 733 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 940 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 417 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 995 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 854 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 399 B

@ -2,6 +2,51 @@
"mohemm": "Mohemm",
"english": "English",
"arabic": "عربي",
"login": "تسجيل الدخول"
"login": "تسجيل الدخول",
"drSulaiman": "سليمان الحبيب",
"welcomeTo": "مرحبا بك في",
"userID" : "معرف المستخدم",
"password" : "كلمة المرور",
"branch" : "فرع",
"pleaseEnterLoginDetails": "الرجاء إدخال التفاصيل أدناه لتسجيل الدخول",
"username": "اسم المستخدم",
"welcomeBack": "مرحبا بعودتك",
"wouldYouLikeToLoginWithCurrentUsername": "هل ترغب في تسجيل الدخول باسم المستخدم الحالي؟",
"lastLoginDetails": "تفاصيل تسجيل الدخول الأخير:",
"verificationType": "نوع التحقق:",
"pleaseVerify": "ارجوك تحقق",
"pleaseVerifyForBio": "الرجاء التحقق من تسجيل الدخول باستخدام أحد هذه الخيارات",
"verifyThroughFace": "تحقق من خلال الوجه",
"verifyThroughFingerprint": "تحقق من خلال بصمة الإصبع",
"verifyThroughSMS": "تحقق من خلال الرسائل القصيرة",
"verifyThroughWhatsapp": "تحقق من خلال Whatsapp",
"useAnotherAccount": "استخدم حسابا آخر",
"pleaseEnterTheVerificationCodeSentTo": "الرجاء إدخال رمز التحقق المرسل إلى ",
"theVerificationCodeWillExpireIn": "ستنتهي صلاحية رمز التحقق في ",
"goodMorning": "صباح الخير",
"markAttendance": "علامة الحضور",
"timeLeftToday": "الوقت المتبقي اليوم",
"checkIn": "تحقق في",
"workList": "قائمة العمل",
"doNotUseRecentPassword": "لا تستخدم كلمة مرور حديثة",
"atLeastOneLowercase": "حرف صغير واحد على الأقل",
"atLeastOneUppercase": "حرف كبير واحد على الأقل",
"atLeastOneNumeric": "رقم واحد على الأقل",
"minimum8Characters": "8 أحرف على الأقل",
"doNotAddRepeatingLetters": "لا تقم بإضافة أحرف متكررة",
"itShouldContainSpecialCharacter": "يجب أن يحتوي على طابع خاص",
"confirmPasswordMustMatch": "يجب أن يتطابق تأكيد كلمة المرور",
"sms": "رسالة قصيرة",
"fingerPrint": "بصمة",
"face": "التعرف على الوجه",
"whatsapp": "واتس اب",
"reject": "يرفض",
"approve": "يوافق",
"cancel": "إلغاء",
"otp": "OTP",
"verification": "تَحَقّق",
"resend": "إعادة إرسال",
"codeExpire": "انتهت صلاحية رمز التحقق",
"moreVerificationOpts" :"المزيد من خيارات التحقق"
}

@ -2,6 +2,50 @@
"mohemm": "Mohemm",
"english": "English",
"arabic": "عربي",
"login": "Login"
"login": "Login",
"drSulaiman" : "Dr Sulaiman Al Habib",
"welcomeTo": "Welcome to",
"userID" : "User ID",
"password" : "Password",
"branch" : "Branch",
"pleaseEnterLoginDetails": "Please enter the detail below to login",
"username": "Username",
"welcomeBack": "Welcome back",
"wouldYouLikeToLoginWithCurrentUsername": "Would you like to login with current Username?",
"lastLoginDetails": "Last Login Details:",
"verificationType": "Verification Type:",
"pleaseVerify": "Please Verify",
"pleaseVerifyForBio": "Please verify login with one of the following options",
"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 ",
"goodMorning": "Good Morning",
"markAttendance": "Mark Attendance",
"timeLeftToday": "Time Left Today",
"checkIn": "Check In",
"workList": "Work List",
"doNotUseRecentPassword": "Do not use recent password",
"atLeastOneLowercase": "At least one lowercase",
"atLeastOneUppercase": "At least one uppercase",
"atLeastOneNumeric": "At least one numeric",
"minimum8Characters": "Minimum 8 characters",
"doNotAddRepeatingLetters": "Do not add repeating letters",
"itShouldContainSpecialCharacter": "It should contain special character",
"confirmPasswordMustMatch": "Confirm password must match",
"sms": "SMS",
"fingerPrint": "Fingerprint",
"face": "Face",
"whatsapp": "Whatsapp",
"reject": "Reject",
"approve": "Approve",
"cancel": "Cancel",
"otp": "OTP",
"verification": "Verification",
"resend": "Resend",
"codeExpire": "The verification code has been expired",
"moreVerificationOpts" :"More verification options"
}

@ -1 +1,2 @@
#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
#include "Generated.xcconfig"

@ -1 +1,2 @@
#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
#include "Generated.xcconfig"

@ -3,7 +3,7 @@
archiveVersion = 1;
classes = {
};
objectVersion = 50;
objectVersion = 51;
objects = {
/* Begin PBXBuildFile section */
@ -13,6 +13,7 @@
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; };
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; };
97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; };
9D12EA470E69A39F3F4EEEAC /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CBDA1EC0585A028F26394B8F /* Pods_Runner.framework */; };
/* End PBXBuildFile section */
/* Begin PBXCopyFilesBuildPhase section */
@ -31,6 +32,7 @@
/* Begin PBXFileReference section */
1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = "<group>"; };
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = "<group>"; };
27FAD59055A271CDB6345D20 /* 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 = "<group>"; };
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = "<group>"; };
74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = "<group>"; };
74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
@ -42,6 +44,9 @@
97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
CBDA1EC0585A028F26394B8F /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; };
E8F2C56CA7A126F5FC598365 /* 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 = "<group>"; };
FF2E7CCDDEE1BDF1A3E7D477 /* 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 = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@ -49,12 +54,21 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
9D12EA470E69A39F3F4EEEAC /* Pods_Runner.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
5070F4CF6F638C91B59F4B67 /* Frameworks */ = {
isa = PBXGroup;
children = (
CBDA1EC0585A028F26394B8F /* Pods_Runner.framework */,
);
name = Frameworks;
sourceTree = "<group>";
};
9740EEB11CF90186004384FC /* Flutter */ = {
isa = PBXGroup;
children = (
@ -72,6 +86,8 @@
9740EEB11CF90186004384FC /* Flutter */,
97C146F01CF9000F007C117D /* Runner */,
97C146EF1CF9000F007C117D /* Products */,
CACFC9B4D329C2F774D03EE9 /* Pods */,
5070F4CF6F638C91B59F4B67 /* Frameworks */,
);
sourceTree = "<group>";
};
@ -98,6 +114,16 @@
path = Runner;
sourceTree = "<group>";
};
CACFC9B4D329C2F774D03EE9 /* Pods */ = {
isa = PBXGroup;
children = (
FF2E7CCDDEE1BDF1A3E7D477 /* Pods-Runner.debug.xcconfig */,
27FAD59055A271CDB6345D20 /* Pods-Runner.release.xcconfig */,
E8F2C56CA7A126F5FC598365 /* Pods-Runner.profile.xcconfig */,
);
path = Pods;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
@ -105,12 +131,14 @@
isa = PBXNativeTarget;
buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */;
buildPhases = (
CDED494F0D32669A035C1EA5 /* [CP] Check Pods Manifest.lock */,
9740EEB61CF901F6004384FC /* Run Script */,
97C146EA1CF9000F007C117D /* Sources */,
97C146EB1CF9000F007C117D /* Frameworks */,
97C146EC1CF9000F007C117D /* Resources */,
9705A1C41CF9048500538489 /* Embed Frameworks */,
3B06AD1E1E4923F5004D2608 /* Thin Binary */,
2CEBFA1962BF46DCB0A31085 /* [CP] Embed Pods Frameworks */,
);
buildRules = (
);
@ -169,6 +197,23 @@
/* End PBXResourcesBuildPhase section */
/* Begin PBXShellScriptBuildPhase section */
2CEBFA1962BF46DCB0A31085 /* [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;
};
3B06AD1E1E4923F5004D2608 /* Thin Binary */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
@ -197,6 +242,28 @@
shellPath = /bin/sh;
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build";
};
CDED494F0D32669A035C1EA5 /* [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;
};
/* End PBXShellScriptBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
@ -288,6 +355,7 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
DEVELOPMENT_TEAM = KT58FV5WJU;
ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
@ -416,6 +484,7 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
DEVELOPMENT_TEAM = KT58FV5WJU;
ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
@ -438,6 +507,7 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
DEVELOPMENT_TEAM = KT58FV5WJU;
ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (

@ -4,4 +4,7 @@
<FileRef
location = "group:Runner.xcodeproj">
</FileRef>
<FileRef
location = "group:Pods/Pods.xcodeproj">
</FileRef>
</Workspace>

@ -28,6 +28,7 @@ class LoginApiRepo implements ILoginApiRepo {
Map<String, dynamic> postParams = {};
postParams.addAll(appState.postParamsJson);
postParams["stamp"] = DateTime.now().toIso8601String();
postParams["IMEI"] = token;
GenericResponseModel response;
try {

@ -0,0 +1,22 @@
import 'package:flutter/material.dart';
import 'package:hmg_nurses/classes/enums.dart';
class BaseViewModel extends ChangeNotifier {
ViewState _state = ViewState.idle;
bool isInternetConnection = true;
ViewState get state => _state;
String error = "";
//TODO add the user login model when we need it
void setState(ViewState viewState) {
_state = viewState;
notifyListeners();
}
}

@ -1,4 +1,8 @@
class ApiConsts {
static const MAX_SMALL_SCREEN = 660;
//static String baseUrl = "http://10.200.204.20:2801/"; // Local server
//static String baseUrl = 'https://hmgwebservices.com/';
static String baseUrl = 'https://uat.hmgwebservices.com/';

@ -0,0 +1,3 @@
enum APPSTATUS { loading, unAuthenticated, authenticated, unverified }
enum AuthMethodTypes { sms, whatsApp, fingerPrint, faceID, moreOptions }
enum ViewState { idle, busy, error, busyLocal, errorLocal }

@ -0,0 +1,103 @@
import 'package:flutter/cupertino.dart';
import 'package:hmg_nurses/classes/consts.dart';
class SizeConfig {
static double _blockWidth = 0;
static double _blockHeight = 0;
static double? realScreenWidth;
static double? realScreenHeight;
static double? screenWidth;
static double? screenHeight;
static double? textMultiplier;
static double? imageSizeMultiplier;
static double? heightMultiplier;
static bool isPortrait = true;
static double? widthMultiplier;
static bool isMobilePortrait = false;
static bool isMobile = false;
static bool isHeightShort = false;
static bool isHeightVeryShort = false;
static bool isHeightMiddle = false;
static bool isHeightLarge = false;
static bool isWidthLarge = false;
void init(BoxConstraints constraints, Orientation orientation) {
realScreenHeight = constraints.maxHeight;
realScreenWidth = constraints.maxWidth;
if (constraints.maxWidth <= ApiConsts.MAX_SMALL_SCREEN) {
isMobile = true;
}
if (constraints.maxHeight < 600) {
isHeightVeryShort = true;
} else if (constraints.maxHeight < 800) {
isHeightShort = true;
} else if (constraints.maxHeight < 1000) {
isHeightMiddle = true;
} else {
isHeightLarge = true;
}
if (constraints.maxWidth > 600) {
isWidthLarge = true;
}
if (orientation == Orientation.portrait) {
isPortrait = true;
if (realScreenWidth! < 450) {
isMobilePortrait = true;
}
// textMultiplier = _blockHeight;
// imageSizeMultiplier = _blockWidth;
screenHeight = realScreenHeight;
screenWidth = realScreenWidth;
} else {
isPortrait = false;
isMobilePortrait = false;
// textMultiplier = _blockWidth;
// imageSizeMultiplier = _blockHeight;
screenHeight = realScreenWidth;
screenWidth = realScreenHeight;
}
_blockWidth = screenWidth! / 100;
_blockHeight = screenHeight! / 100;
textMultiplier = _blockHeight;
imageSizeMultiplier = _blockWidth;
heightMultiplier = _blockHeight;
widthMultiplier = _blockWidth;
print('realScreenWidth $realScreenWidth');
print('realScreenHeight $realScreenHeight');
print('textMultiplier $textMultiplier');
print('imageSizeMultiplier $imageSizeMultiplier');
print('heightMultiplier$heightMultiplier');
print('widthMultiplier $widthMultiplier');
print('isPortrait $isPortrait');
print('isMobilePortrait $isMobilePortrait');
}
static getTextMultiplierBasedOnWidth({double? width}) {
// TODO handel LandScape case
if (width != null) {
return width / 100;
}
return widthMultiplier;
}
static getWidthMultiplier({double? width}) {
// TODO handel LandScape case
if (width != null) {
return width / 100;
}
return widthMultiplier;
}
static getHeightMultiplier({double? height}) {
// TODO handel LandScape case
if (height != null) {
return height / 100;
}
return heightMultiplier;
}
}

@ -14,6 +14,7 @@ import 'package:hmg_nurses/exceptions/api_exception.dart';
import 'package:hmg_nurses/extensions/int_extensions.dart';
import 'package:hmg_nurses/extensions/string_extensions.dart';
import 'package:hmg_nurses/extensions/widget_extensions.dart';
import 'package:hmg_nurses/main.dart';
import 'package:hmg_nurses/widgets/dialogs/confirm_dialog.dart';
import 'package:hmg_nurses/widgets/loading_dialog.dart';
import 'package:shared_preferences/shared_preferences.dart';
@ -55,11 +56,11 @@ class Utils {
return await Future.delayed(Duration(milliseconds: millis));
}
static void showLoading(BuildContext context) {
static void showLoading() {
WidgetsBinding.instance.addPostFrameCallback((_) {
_isLoadingVisible = true;
showDialog(
context: context,
context: navigatorKey.currentState!.overlay!.context,
barrierColor: Colors.black.withOpacity(0.5),
builder: (BuildContext context) => LoadingDialog(),
).then((value) {

@ -1,19 +0,0 @@
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
class AppProvider extends StatelessWidget {
final Widget child;
AppProvider({required this.child});
@override
Widget build(BuildContext context) {
return child;
return MultiProvider(
providers: [
// ChangeNotifierProvider(create: (_) => Counter()),
],
child: child,
);
}
}

@ -0,0 +1,18 @@
import 'package:get_it/get_it.dart';
import 'package:hmg_nurses/ui/login/login_vm.dart';
GetIt getIt = GetIt.instance;
void initDependencies () {
// TODO; WE WILL REGISTER ALL THE SERVICES HERE AS LAZY SINGLETON
//TODO: WE WILL REGISTER ALL THE VIEW MODELS AS FACTORY HERE
/// View Model
getIt.registerFactory(() => LoginViewModel());
}

@ -0,0 +1,33 @@
import 'package:hmg_nurses/classes/enums.dart';
extension SelectedAuthMethodTypesService on AuthMethodTypes {
int getTypeIdService() {
switch (this) {
case AuthMethodTypes.sms:
return 1;
case AuthMethodTypes.whatsApp:
return 2;
case AuthMethodTypes.fingerPrint:
return 3;
case AuthMethodTypes.faceID:
return 4;
case AuthMethodTypes.moreOptions:
return 5;
}
}
static getMethodsTypeService(int typeId) {
switch (typeId) {
case 1:
return AuthMethodTypes.sms;
case 2:
return AuthMethodTypes.whatsApp;
case 3:
return AuthMethodTypes.fingerPrint;
case 4:
return AuthMethodTypes.faceID;
case 5:
return AuthMethodTypes.moreOptions;
}
}
}

@ -6,15 +6,115 @@ import 'dart:ui';
import 'package:easy_localization/easy_localization.dart' show AssetLoader;
class CodegenLoader extends AssetLoader {
class CodegenLoader extends AssetLoader{
const CodegenLoader();
@override
Future<Map<String, dynamic>> load(String fullPath, Locale locale) {
Future<Map<String, dynamic>> load(String fullPath, Locale locale ) {
return Future.value(mapLocales[locale.toString()]);
}
static const Map<String, dynamic> ar_SA = {"mohemm": "Mohemm", "english": "English", "arabic": "عربي", "login": "تسجيل الدخول"};
static const Map<String, dynamic> en_US = {"mohemm": "Mohemm", "english": "English", "arabic": "عربي", "login": "Login"};
static const Map<String, Map<String, dynamic>> mapLocales = {"ar_SA": ar_SA, "en_US": en_US};
static const Map<String,dynamic> ar_SA = {
"mohemm": "Mohemm",
"english": "English",
"arabic": "عربي",
"login": "تسجيل الدخول",
"drSulaiman": "سليمان الحبيب",
"welcomeTo": "مرحبا بك في",
"userID": "معرف المستخدم",
"password": "كلمة المرور",
"branch": "فرع",
"pleaseEnterLoginDetails": "الرجاء إدخال التفاصيل أدناه لتسجيل الدخول",
"username": "اسم المستخدم",
"welcomeBack": "مرحبا بعودتك",
"wouldYouLikeToLoginWithCurrentUsername": "هل ترغب في تسجيل الدخول باسم المستخدم الحالي؟",
"lastLoginDetails": "تفاصيل تسجيل الدخول الأخير:",
"verificationType": "نوع التحقق:",
"pleaseVerify": "ارجوك تحقق",
"pleaseVerifyForBio": "الرجاء التحقق من تسجيل الدخول باستخدام أحد هذه الخيارات",
"verifyThroughFace": "تحقق من خلال الوجه",
"verifyThroughFingerprint": "تحقق من خلال بصمة الإصبع",
"verifyThroughSMS": "تحقق من خلال الرسائل القصيرة",
"verifyThroughWhatsapp": "تحقق من خلال Whatsapp",
"useAnotherAccount": "استخدم حسابا آخر",
"pleaseEnterTheVerificationCodeSentTo": "الرجاء إدخال رمز التحقق المرسل إلى ",
"theVerificationCodeWillExpireIn": "ستنتهي صلاحية رمز التحقق في ",
"goodMorning": "صباح الخير",
"markAttendance": "علامة الحضور",
"timeLeftToday": "الوقت المتبقي اليوم",
"checkIn": "تحقق في",
"workList": "قائمة العمل",
"doNotUseRecentPassword": "لا تستخدم كلمة مرور حديثة",
"atLeastOneLowercase": "حرف صغير واحد على الأقل",
"atLeastOneUppercase": "حرف كبير واحد على الأقل",
"atLeastOneNumeric": "رقم واحد على الأقل",
"minimum8Characters": "8 أحرف على الأقل",
"doNotAddRepeatingLetters": "لا تقم بإضافة أحرف متكررة",
"itShouldContainSpecialCharacter": "يجب أن يحتوي على طابع خاص",
"confirmPasswordMustMatch": "يجب أن يتطابق تأكيد كلمة المرور",
"sms": "رسالة قصيرة",
"fingerPrint": "بصمة",
"face": "التعرف على الوجه",
"whatsapp": "واتس اب",
"reject": "يرفض",
"approve": "يوافق",
"cancel": "إلغاء",
"otp": "OTP",
"verification": "تَحَقّق",
"resend": "إعادة إرسال",
"codeExpire": "انتهت صلاحية رمز التحقق",
"moreVerificationOpts": "المزيد من خيارات التحقق"
};
static const Map<String,dynamic> en_US = {
"mohemm": "Mohemm",
"english": "English",
"arabic": "عربي",
"login": "Login",
"drSulaiman": "Dr Sulaiman Al Habib",
"welcomeTo": "Welcome to",
"userID": "User ID",
"password": "Password",
"branch": "Branch",
"pleaseEnterLoginDetails": "Please enter the detail below to login",
"username": "Username",
"welcomeBack": "Welcome back",
"wouldYouLikeToLoginWithCurrentUsername": "Would you like to login with current Username?",
"lastLoginDetails": "Last Login Details:",
"verificationType": "Verification Type:",
"pleaseVerify": "Please Verify",
"pleaseVerifyForBio": "Please verify login with one of the following options",
"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 ",
"goodMorning": "Good Morning",
"markAttendance": "Mark Attendance",
"timeLeftToday": "Time Left Today",
"checkIn": "Check In",
"workList": "Work List",
"doNotUseRecentPassword": "Do not use recent password",
"atLeastOneLowercase": "At least one lowercase",
"atLeastOneUppercase": "At least one uppercase",
"atLeastOneNumeric": "At least one numeric",
"minimum8Characters": "Minimum 8 characters",
"doNotAddRepeatingLetters": "Do not add repeating letters",
"itShouldContainSpecialCharacter": "It should contain special character",
"confirmPasswordMustMatch": "Confirm password must match",
"sms": "SMS",
"fingerPrint": "Fingerprint",
"face": "Face",
"whatsapp": "Whatsapp",
"reject": "Reject",
"approve": "Approve",
"cancel": "Cancel",
"otp": "OTP",
"verification": "Verification",
"resend": "Resend",
"codeExpire": "The verification code has been expired",
"moreVerificationOpts": "More verification options"
};
static const Map<String, Map<String,dynamic>> mapLocales = {"ar_SA": ar_SA, "en_US": en_US};
}

@ -0,0 +1,64 @@
class GetMobileLoginInfoListModel {
int? iD;
int? employeeID;
int? channelID;
int? companyID;
String? deviceType;
String? deviceToken;
int? language;
int? gender;
int? loginType;
String? createdOn;
String? editedOn;
String? employeeName;
bool? businessCardPrivilege;
GetMobileLoginInfoListModel(
{this.iD,
this.employeeID,
this.channelID,
this.companyID,
this.deviceType,
this.deviceToken,
this.language,
this.gender,
this.loginType,
this.createdOn,
this.editedOn,
this.employeeName,
this.businessCardPrivilege});
GetMobileLoginInfoListModel.fromJson(Map<String, dynamic> json) {
iD = json['ID'];
employeeID = json['EmployeeID'];
channelID = json['ChannelID'];
companyID = json['CompanyID'];
deviceType = json['DeviceType'];
deviceToken = json['DeviceToken'];
language = json['Language'];
gender = json['Gender'];
loginType = json['LoginType'];
createdOn = json['CreatedOn'];
editedOn = json['EditedOn'];
employeeName = json['EmployeeName'];
businessCardPrivilege = json['BusinessCardPrivilege'];
}
Map<String, dynamic> toJson() {
Map<String, dynamic> data = Map<String, dynamic>();
data['ID'] = iD;
data['EmployeeID'] = employeeID;
data['ChannelID'] = channelID;
data['CompanyID'] = companyID;
data['DeviceType'] = deviceType;
data['DeviceToken'] = deviceToken;
data['Language'] = language;
data['Gender'] = gender;
data['LoginType'] = loginType;
data['CreatedOn'] = createdOn;
data['EditedOn'] = editedOn;
data['EmployeeName'] = employeeName;
data['BusinessCardPrivilege'] = businessCardPrivilege;
return data;
}
}

@ -0,0 +1,310 @@
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:hexcolor/hexcolor.dart';
import 'package:hmg_nurses/classes/colors.dart';
import 'package:hmg_nurses/classes/enums.dart';
import 'package:hmg_nurses/classes/size_config.dart';
import 'package:hmg_nurses/extensions/string_extensions.dart';
import 'package:hmg_nurses/extensions/util_extensions.dart';
import 'package:hmg_nurses/extensions/widget_extensions.dart';
import 'package:hmg_nurses/generated/locale_keys.g.dart';
import 'package:hmg_nurses/ui/login/login_vm.dart';
import 'package:hmg_nurses/ui/login/widgets/verification_method_card.dart';
import 'package:hmg_nurses/widgets/button/default_button.dart';
import 'package:provider/provider.dart';
import 'package:sizer/sizer.dart';
// WhatsApp 2
// SMS 1
// Face ID 3
// Finger Print 4
class LoginMethodsPage extends StatefulWidget {
const LoginMethodsPage({Key? key}) : super(key: key);
@override
LoginMethodsPageState createState() => LoginMethodsPageState();
}
class LoginMethodsPageState extends State<LoginMethodsPage> {
bool isMoreOption = false;
bool onlySMSBox = false;
late AuthMethodTypes fingerPrintBefore;
late AuthMethodTypes selectedOption;
late LoginViewModel loginViewModel;
@override
Widget build(BuildContext context) {
loginViewModel = context.read<LoginViewModel>();
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: SingleChildScrollView(
child: Center(
child: FractionallySizedBox(
widthFactor: 0.9,
child: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
SizedBox(height: 1.h),
if (loginViewModel.isFromLogin)
InkWell(
onTap: () {
loginViewModel.setUnverified(false, isFromLogin: false);
loginViewModel.setAppStatus(APPSTATUS.unAuthenticated);
},
child: const Icon(Icons.arrow_back_ios, color: MyColors.darkTextColor)),
Column(
children: <Widget>[
SizedBox(height: 1.h),
isMoreOption != null && isMoreOption == false
? Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
LocaleKeys.welcomeBack.tr().toText12(),
SizedBox(height: 1.h),
"Faiz Hashmi".toText24(isBold: true),
SizedBox(height: 3.h),
LocaleKeys.wouldYouLikeToLoginWithCurrentUsername.tr().toText18(),
SizedBox(height: 3.h),
Container(
padding: const EdgeInsets.all(12),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: const BorderRadius.all(Radius.circular(10)),
border: Border.all(color: HexColor('#707070'), width: 0.1),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
LocaleKeys.lastLoginDetails.tr(),
overflow: TextOverflow.ellipsis,
style: TextStyle(
fontFamily: 'Poppins',
fontSize: SizeConfig.getTextMultiplierBasedOnWidth() * 4.8,
color: Color(0xFF2E303A),
fontWeight: FontWeight.w600,
letterSpacing: -0.4),
),
Container(
width: MediaQuery.of(context).size.width * 0.55,
child: RichText(
text: TextSpan(
text: "${LocaleKeys.verificationType.tr()} ",
style: TextStyle(
color: const Color(0xFF575757),
fontSize: SizeConfig.getTextMultiplierBasedOnWidth() * 3.5,
fontFamily: 'Poppins',
fontWeight: FontWeight.w600,
letterSpacing: -0.4),
children: <TextSpan>[
TextSpan(
text: loginViewModel.getType(1),
style: TextStyle(
color: MyColors.darkTextColor,
fontSize: SizeConfig.getTextMultiplierBasedOnWidth() * 3.5,
fontFamily: 'Poppins',
fontWeight: FontWeight.w600,
letterSpacing: -0.48),
)
]),
),
),
],
),
Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.end,
children: [
Text(
"12 NOV, 2022",
overflow: TextOverflow.ellipsis,
style: TextStyle(
fontFamily: 'Poppins',
fontSize: SizeConfig.getTextMultiplierBasedOnWidth() * 4.2,
color: Color(0xFF2E303A),
fontWeight: FontWeight.bold,
letterSpacing: -0.4),
),
Text(
"09:56 AM",
overflow: TextOverflow.ellipsis,
style: TextStyle(
fontFamily: 'Poppins',
fontSize: SizeConfig.getTextMultiplierBasedOnWidth() * 3.5,
color: Color(0xFF2E303A),
fontWeight: FontWeight.w600,
letterSpacing: -0.4),
),
// AppText(
// loginViewModel.user.editedOn != null
// ? AppDateUtils.getDayMonthYearDateFormatted(AppDateUtils.convertStringToDate(loginViewModel.user.editedOn), isMonthShort: true)
// : loginViewModel.user.createdOn != null
// ? AppDateUtils.getDayMonthYearDateFormatted(AppDateUtils.convertStringToDate(loginViewModel.user.createdOn), isMonthShort: true)
// : '--',
// textAlign: TextAlign.right,
// fontSize: SizeConfig.getTextMultiplierBasedOnWidth() * 4.5,
// color: Color(0xFF2E303A),
// fontWeight: FontWeight.w700,
// letterSpacing: -0.48,
// ),
// AppText(
// loginViewModel.user.editedOn != null
// ? AppDateUtils.getHour(AppDateUtils.convertStringToDate(loginViewModel.user.editedOn))
// : loginViewModel.user.createdOn != null
// ? AppDateUtils.getHour(AppDateUtils.convertStringToDate(loginViewModel.user.createdOn))
// : '--',
// textAlign: TextAlign.right,
// fontSize: SizeConfig.getTextMultiplierBasedOnWidth() * 3.5,
// fontWeight: FontWeight.w600,
// letterSpacing: -0.48,
// color: Color(0xFF575757),
// )
],
)
],
),
),
SizedBox(height: SizeConfig.heightMultiplier! * 3),
Row(
children: [
//todo add translation
LocaleKeys.pleaseVerify.tr().toText18().paddingOnly(left: 8),
],
),
SizedBox(
height: SizeConfig.heightMultiplier! * 2,
),
],
)
: Column(mainAxisAlignment: MainAxisAlignment.spaceEvenly, crossAxisAlignment: CrossAxisAlignment.start, children: <Widget>[
onlySMSBox == true
? Container(
margin: const EdgeInsets.only(bottom: 20, top: 30),
child: LocaleKeys.pleaseVerify.tr().toText16(),
)
: LocaleKeys.pleaseVerify.tr().toText16(),
]),
isMoreOption != null && isMoreOption == false
? Column(mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start, children: <Widget>[
Row(mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[
Expanded(
child: VerificationMethodsList(
loginViewModel: loginViewModel,
authMethodType: SelectedAuthMethodTypesService.getMethodsTypeService(1),
authenticateUser: (AuthMethodTypes authMethodType, isActive) {
loginViewModel.startSMSService(authMethodType, context: context);
},
),
),
Expanded(
child: VerificationMethodsList(
loginViewModel: loginViewModel,
authMethodType: AuthMethodTypes.moreOptions,
onShowMore: () {
setState(() {
isMoreOption = true;
});
},
))
]),
])
: Column(mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start, children: <Widget>[
onlySMSBox == false
? Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Expanded(
child: VerificationMethodsList(
loginViewModel: loginViewModel,
authMethodType: AuthMethodTypes.fingerPrint,
authenticateUser: (AuthMethodTypes authMethodType, isActive) {
loginViewModel.startSMSService(authMethodType, context: context);
},
)),
Expanded(
child: VerificationMethodsList(
loginViewModel: loginViewModel,
authMethodType: AuthMethodTypes.faceID,
authenticateUser: (AuthMethodTypes authMethodType, isActive) {
loginViewModel.startSMSService(authMethodType, context: context);
},
))
],
)
: const SizedBox(),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Expanded(
child: VerificationMethodsList(
loginViewModel: loginViewModel,
authMethodType: AuthMethodTypes.sms,
authenticateUser: (AuthMethodTypes authMethodType, isActive) {
loginViewModel.startSMSService(authMethodType, context: context);
},
)),
Expanded(
child: VerificationMethodsList(
loginViewModel: loginViewModel,
authMethodType: AuthMethodTypes.whatsApp,
authenticateUser: (AuthMethodTypes authMethodType, isActive) {
loginViewModel.startSMSService(authMethodType, context: context);
},
))
],
),
]),
// )
],
),
],
),
),
),
),
),
bottomSheet: !isMoreOption
? null
: Container(
height: 10.h,
color: MyColors.backgroundColor,
width: double.infinity,
child: Center(
child: FractionallySizedBox(
widthFactor: 0.9,
child: Column(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
Padding(
padding: EdgeInsets.symmetric(horizontal: 4.w),
child: DefaultButton(LocaleKeys.useAnotherAccount.tr(), () {}, colors: const [MyColors.redColor, MyColors.redColor]),
),
SizedBox(height: 3.h)
],
),
),
),
),
);
}
}

@ -0,0 +1,103 @@
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:hmg_nurses/classes/colors.dart';
import 'package:hmg_nurses/config/routes.dart';
import 'package:hmg_nurses/generated/locale_keys.g.dart';
import 'package:hmg_nurses/widgets/button/default_button.dart';
import 'package:hmg_nurses/widgets/cupertino_picker.dart';
import 'package:hmg_nurses/widgets/input_widget.dart';
import 'package:sizer/sizer.dart';
class LoginPage extends StatefulWidget {
const LoginPage({Key? key}) : super(key: key);
@override
State<LoginPage> createState() => _LoginPageState();
}
class _LoginPageState extends State<LoginPage> {
final loginFormKey = GlobalKey<FormState>();
var projectIdController = TextEditingController();
var userIdController = TextEditingController();
var passwordController = TextEditingController();
SizedBox buildSpacer20h() => SizedBox(height: 3.h);
@override
Widget build(BuildContext context) {
return Scaffold(
body: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SizedBox(height: 10.h),
Padding(
padding: EdgeInsets.only(left: 8.w),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
LocaleKeys.welcomeTo.tr(),
style: TextStyle(fontSize: 16.sp, fontWeight: FontWeight.w600, fontFamily: 'Poppins'),
),
Text(
LocaleKeys.drSulaiman.tr(),
style: TextStyle(color: MyColors.blackColor, fontWeight: FontWeight.bold, fontSize: 24.sp, fontFamily: 'Poppins'),
),
Text(
"Nurses App",
style: TextStyle(fontSize: 16.sp, fontWeight: FontWeight.w600, color: MyColors.redColor),
),
],
),
),
SizedBox(height: 4.h),
Form(
key: loginFormKey,
child: Padding(
padding: EdgeInsets.symmetric(horizontal: 8.w),
child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
buildSpacer20h(),
CustomTextField(LocaleKeys.userID.tr(), userIdController, isEnableBorder: true, ),
buildSpacer20h(),
CustomTextField(LocaleKeys.password.tr(), passwordController, isTextIsPassword: true),
buildSpacer20h(),
CustomTextField(
LocaleKeys.branch.tr(),
projectIdController,
hasSelection: true,
isEnable: false,
onClick: () => CustomCupertinoPicker.showCupertinoPicker(context, [], () {}),
),
buildSpacer20h()
]),
),
)
],
),
),
bottomSheet: Container(
height: 12.h,
color: MyColors.backgroundColor,
width: double.infinity,
child: Center(
child: FractionallySizedBox(
widthFactor: 0.9,
child: Column(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
Padding(
padding: EdgeInsets.symmetric(horizontal: 4.w),
child: DefaultButton(LocaleKeys.login.tr(), () {
Navigator.pushNamed(context, AppRoutes.loginMethodsPage);
}, colors: const [MyColors.redColor, MyColors.redColor]),
),
SizedBox(height: 3.h)
],
),
),
),
),
);
}
}

@ -0,0 +1,141 @@
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:hmg_nurses/base/base_vm.dart';
import 'package:hmg_nurses/classes/enums.dart';
import 'package:hmg_nurses/classes/utils.dart';
import 'package:hmg_nurses/dialogs/otp_dialog.dart';
import 'package:hmg_nurses/generated/locale_keys.g.dart';
import 'package:local_auth/local_auth.dart';
class LoginViewModel extends BaseViewModel {
bool isLogin = false;
bool unverified = false;
bool isFromLogin = false;
APPSTATUS appStatus = APPSTATUS.loading;
String localToken = "";
String nurseProfile = "";
final LocalAuthentication auth = LocalAuthentication();
late List<BiometricType> _availableBiometrics;
LoginViewModel();
/// get type name based on id.
getType(type) {
switch (type) {
case 1:
return LocaleKeys.sms.tr();
case 3:
return LocaleKeys.fingerPrint.tr();
case 4:
return LocaleKeys.face.tr();
case 2:
return LocaleKeys.whatsapp.tr();
default:
return LocaleKeys.sms.tr();
}
}
/// ask user to add his biometric
showIOSAuthMessages() async {
try {
await auth.authenticate(
localizedReason: 'Scan your fingerprint to authenticate',
);
} on PlatformException catch (e) {
if (kDebugMode) {
print(e);
}
}
}
/// check specific biometric if it available or not
Future<bool> checkIfBiometricAvailable(BiometricType biometricType) async {
bool isAvailable = false;
await _getAvailableBiometrics();
if (_availableBiometrics != null) {
for (var i = 0; i < _availableBiometrics.length; i++) {
if (biometricType == _availableBiometrics[i]) isAvailable = true;
}
}
return isAvailable;
}
/// get all available biometric on the device for local Auth service
Future<void> _getAvailableBiometrics() async {
try {
_availableBiometrics = await auth.getAvailableBiometrics();
} on PlatformException catch (e) {
if (kDebugMode) {
print(e);
}
}
}
/// determine the status of the app
APPSTATUS get status {
if (state == ViewState.busy) {
appStatus = APPSTATUS.loading;
} else {
if (nurseProfile != null) {
appStatus = APPSTATUS.authenticated;
} else if (unverified) {
appStatus = APPSTATUS.unverified;
} else if (isLogin) {
appStatus = APPSTATUS.authenticated;
} else {
appStatus = APPSTATUS.unAuthenticated;
}
}
return appStatus;
}
setAppStatus(APPSTATUS status) {
appStatus = status;
notifyListeners();
}
setUnverified(bool unverified, {bool isFromLogin = false}) {
this.unverified = unverified;
this.isFromLogin = isFromLogin;
notifyListeners();
}
/// logout function
logout({bool isFromLogin = false}) async {
// localToken = "";
// String lang = await sharedPref.getString(APP_Language);
// await Utils.clearSharedPref();
// doctorProfile = null;
// sharedPref.setString(APP_Language, lang);
// deleteUser();
// await getDeviceInfoFromFirebase();
// this.isFromLogin = isFromLogin;
// appStatus = APPSTATUS.unAuthenticated;
// setState(ViewState.Idle);
}
deleteUser() {
// user = null;
// unverified = false;
// isLogin = false;
}
startSMSService(AuthMethodTypes type, {isSilentLogin = false, required BuildContext context}) {
OtpDialog(
type: 1,
mobileNo: 0504278212,
onSuccess: (String otpCode, TextEditingController pinPut) {
Utils.showLoading();
//TODO: API CALL
// performDirectApiCall(_title, _icon, _flag, value);
},
onFailure: () => Navigator.pop(context),
onResendCode: () {})
.displayDialog(context);
}
}

@ -0,0 +1,135 @@
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/svg.dart';
import 'package:hexcolor/hexcolor.dart';
import 'package:hmg_nurses/classes/colors.dart';
import 'package:hmg_nurses/classes/enums.dart';
import 'package:hmg_nurses/classes/size_config.dart';
import 'package:hmg_nurses/generated/locale_keys.g.dart';
import 'package:hmg_nurses/ui/login/login_vm.dart';
import 'package:local_auth/local_auth.dart';
class VerificationMethodsList extends StatefulWidget {
final AuthMethodTypes authMethodType;
final Function(AuthMethodTypes type, bool isActive)? authenticateUser;
final Function? onShowMore;
final LoginViewModel loginViewModel;
const VerificationMethodsList({Key? key, required this.authMethodType, this.authenticateUser, this.onShowMore, required this.loginViewModel}) : super(key: key);
@override
VerificationMethodsListState createState() => VerificationMethodsListState();
}
class VerificationMethodsListState extends State<VerificationMethodsList> {
final LocalAuthentication auth = LocalAuthentication();
@override
Widget build(BuildContext context) {
switch (widget.authMethodType) {
case AuthMethodTypes.whatsApp:
return MethodTypeCard(
assetPath: 'assets/images/login/verify_whatsapp.svg',
onTap: () => {widget.authenticateUser!(AuthMethodTypes.whatsApp, true)},
label: LocaleKeys.verifyThroughWhatsapp.tr(),
);
case AuthMethodTypes.sms:
return MethodTypeCard(
assetPath: "assets/images/login/verify_sms.svg",
onTap: () => {widget.authenticateUser!(AuthMethodTypes.sms, true)},
label: LocaleKeys.verifyThroughSMS.tr(),
);
case AuthMethodTypes.fingerPrint:
return MethodTypeCard(
assetPath: 'assets/images/login/verify_thumb.svg',
onTap: () => {widget.authenticateUser!(AuthMethodTypes.fingerPrint, true)},
label: LocaleKeys.verifyThroughFingerprint.tr(),
);
case AuthMethodTypes.faceID:
return MethodTypeCard(
assetPath: 'assets/images/login/verify_face.svg',
onTap: () => {widget.authenticateUser!(AuthMethodTypes.faceID, true)},
label: LocaleKeys.verifyThroughFace.tr(),
);
default:
return MethodTypeCard(
assetPath: 'assets/images/login/more_icon.png',
onTap: () {
widget.onShowMore!();
},
isSvg: false,
label: LocaleKeys.moreVerificationOpts.tr(),
height: 0,
);
}
}
}
class MethodTypeCard extends StatelessWidget {
const MethodTypeCard({
Key? key,
required this.assetPath,
required this.onTap,
required this.label,
this.height = 20,
this.isSvg = true,
}) : super(key: key);
final String assetPath;
final GestureTapCallback onTap;
final String label;
final double height;
final bool isSvg;
@override
Widget build(BuildContext context) {
double cardHeight = SizeConfig.heightMultiplier! *
(SizeConfig.isHeightVeryShort
? 22
: SizeConfig.isHeightLarge
? 25
: 20);
return InkWell(
onTap: onTap,
child: Container(
margin: const EdgeInsets.all(10),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: const BorderRadius.all(Radius.circular(10)),
border: Border.all(color: HexColor('#707070'), width: 0.1),
),
height: cardHeight,
child: Padding(
padding: const EdgeInsets.all(12.0),
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
isSvg
? SvgPicture.asset(assetPath, width: SizeConfig.widthMultiplier! * (14), height: cardHeight * 0.20)
: Image.asset(
assetPath,
width: SizeConfig.widthMultiplier! * (12),
height: cardHeight * 0.35,
// height: ,
),
SizedBox(
height: height,
),
Text(
label,
style: TextStyle(
fontSize: SizeConfig.getTextMultiplierBasedOnWidth() * (SizeConfig.isHeightVeryShort ? 3 : 3.7),
color: MyColors.darkTextColor,
fontWeight: FontWeight.w600,
letterSpacing: -0.48,
),
)
],
),
),
)),
);
}
}

@ -0,0 +1,71 @@
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:hmg_nurses/generated/locale_keys.g.dart';
import 'package:sizer/sizer.dart';
class CustomCupertinoPicker {
static TextStyle textStyle(context) => TextStyle(color: Theme.of(context).primaryColor);
static int cupertinoPickerIndex = 0;
static buildPickerItems(context, List items, onSelectFun) {
return CupertinoPicker(
magnification: 1.5,
scrollController: FixedExtentScrollController(initialItem: cupertinoPickerIndex),
itemExtent: 25,
looping: false,
onSelectedItemChanged: (int index) {
cupertinoPickerIndex = index;
},
children: items.map((item) {
return Text(
'${item.facilityName}',
style: TextStyle(fontSize: 12.sp),
);
}).toList(),
);
}
static showCupertinoPicker(context, List items, onSelectFun) {
showModalBottomSheet(
isDismissible: false,
context: context,
builder: (BuildContext builder) {
return Container(
height: 40.h,
color: const Color(0xfff7f7f7),
child: Column(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
Container(
color: const Color(0xfff7f7f7),
child: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
CupertinoButton(
child: Text(LocaleKeys.userID.tr(), style: textStyle(context)),
onPressed: () {
Navigator.pop(context);
},
),
CupertinoButton(
child: Text(
LocaleKeys.userID.tr(),
style: textStyle(context),
),
onPressed: () {
Navigator.pop(context);
onSelectFun(cupertinoPickerIndex);
},
)
],
),
),
Container(height: 3.h, color: const Color(0xfff7f7f7), child: buildPickerItems(context, items, onSelectFun))
],
),
);
});
}
}

@ -2,10 +2,11 @@ import 'package:flutter/material.dart';
import 'package:hmg_nurses/classes/colors.dart';
import 'package:hmg_nurses/extensions/int_extensions.dart';
import 'package:hmg_nurses/extensions/widget_extensions.dart';
import 'package:sizer/sizer.dart';
class InputWidget extends StatefulWidget {
class CustomTextField extends StatefulWidget {
final String labelText;
final String hintText;
final String? hintText;
final TextEditingController controller;
final VoidCallback? suffixTap;
final bool isEnable;
@ -18,19 +19,21 @@ class InputWidget extends StatefulWidget {
final double verticalPadding;
final double horizontalPadding;
final Function(String)? onChange;
final Function? onClick;
InputWidget(
const CustomTextField(
this.labelText,
this.hintText,
this.controller, {
Key? key,
this.isTextIsPassword = false,
this.suffixTap,
this.hintText,
this.isEnable = true,
this.hasSelection = false,
this.isEnableBorder = true,
this.lines = 1,
this.onChange,
this.onClick,
this.isInputTypeNum = false,
this.isBackgroundEnable = false,
this.verticalPadding = 15,
@ -38,12 +41,10 @@ class InputWidget extends StatefulWidget {
}) : super(key: key);
@override
_InputWidgetState createState() {
return _InputWidgetState();
}
CustomTextFieldState createState() => CustomTextFieldState();
}
class _InputWidgetState extends State<InputWidget> {
class CustomTextFieldState extends State<CustomTextField> {
late bool isObscureText;
@override
@ -64,31 +65,34 @@ class _InputWidgetState extends State<InputWidget> {
alignment: Alignment.center,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(15),
color: widget.isBackgroundEnable ? Color(0xffF7F7F7) : Colors.white,
border: Border.all(
color: widget.isEnableBorder ? Color(0xffefefef) : Colors.transparent,
width: 1,
),
color: widget.isBackgroundEnable ? const Color(0xffF7F7F7) : Colors.white,
border: Border.all(color: widget.isEnableBorder ? Colors.grey.shade300 : Colors.transparent, width: 1),
),
child: InkWell(
onTap: widget.hasSelection ? () {} : null,
onTap: widget.hasSelection
? () {
widget.onClick!();
}
: null,
child: Row(
children: [
Expanded(
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
Text(
widget.labelText,
style: const TextStyle(
fontSize: 11,
style: TextStyle(
fontSize: 9.sp,
fontWeight: FontWeight.w600,
color: Color(0xff2B353E),
color: const Color(0xff2B353E),
letterSpacing: -0.44,
),
),
TextField(
autofocus: false,
enabled: widget.isEnable,
scrollPadding: EdgeInsets.zero,
keyboardType: widget.isInputTypeNum ? TextInputType.number : TextInputType.text,
@ -133,7 +137,7 @@ class _InputWidgetState extends State<InputWidget> {
});
})
],
if (widget.hasSelection) Icon(Icons.keyboard_arrow_down_outlined),
if (widget.hasSelection) const Icon(Icons.keyboard_arrow_down_outlined),
],
),
),

@ -49,6 +49,10 @@ dependencies:
auto_size_text: ^3.0.0
shimmer: ^2.0.0
sizer: ^2.0.15
local_auth: ^2.1.2
get_it: ^7.2.0
hexcolor: ^2.0.4
# Firebase
@ -80,4 +84,25 @@ flutter:
assets:
- assets/
- assets/langs/
- assets/langs/
- assets/images/login/
- assets/images/patient/
fonts:
- family: Poppins
fonts:
- asset: assets/fonts/Poppins/Poppins-Regular.ttf
weight: 400
- asset: assets/fonts/Poppins/Poppins-Medium.ttf
weight: 500
- asset: assets/fonts/Poppins/Poppins-SemiBold.ttf
weight: 600
- asset: assets/fonts/Poppins/Poppins-Bold.ttf
weight: 700
- asset: assets/fonts/Poppins/Poppins-Bold.ttf
weight: 800
- asset: assets/fonts/Poppins/Poppins-Bold.ttf
weight: 900

Loading…
Cancel
Save