Added Login UI and methods
@ -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.
|
||||
|
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 |
|
After Width: | Height: | Size: 549 B |
|
After Width: | Height: | Size: 453 B |
|
After Width: | Height: | Size: 453 B |
|
After Width: | Height: | Size: 988 B |
|
After Width: | Height: | Size: 652 B |
|
After Width: | Height: | Size: 2.0 KiB |
|
After Width: | Height: | Size: 2.0 KiB |
|
After Width: | Height: | Size: 733 B |
|
After Width: | Height: | Size: 1.9 KiB |
|
After Width: | Height: | Size: 1.9 KiB |
|
After Width: | Height: | Size: 940 B |
|
After Width: | Height: | Size: 417 B |
|
After Width: | Height: | Size: 1.9 KiB |
|
After Width: | Height: | Size: 1.9 KiB |
|
After Width: | Height: | Size: 3.4 KiB |
|
After Width: | Height: | Size: 3.9 KiB |
|
After Width: | Height: | Size: 995 B |
|
After Width: | Height: | Size: 854 B |
|
After Width: | Height: | Size: 1.8 KiB |
|
After Width: | Height: | Size: 1.8 KiB |
|
After Width: | Height: | Size: 399 B |
@ -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"
|
||||
|
||||
@ -1,25 +1,17 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:hmg_nurses/ui/login/splash_page.dart';
|
||||
|
||||
|
||||
import 'package:hmg_nurses/ui/login/login_method_page.dart';
|
||||
import 'package:hmg_nurses/ui/login/login_page.dart';
|
||||
|
||||
class AppRoutes {
|
||||
|
||||
//Login
|
||||
static const String splash = "/splash";
|
||||
static const String registerSelection = "/registerSelection";
|
||||
static const String loginVerifyAccount = "/loginVerifyAccount";
|
||||
static const String loginMethodsPage = "/loginMethodsPage";
|
||||
static const String login = "/login";
|
||||
|
||||
|
||||
|
||||
static final Map<String, WidgetBuilder> routes = {
|
||||
|
||||
//Login
|
||||
splash: (BuildContext context) => SplashPage(),
|
||||
// login: (BuildContext context) => LoginScreen(),
|
||||
|
||||
|
||||
|
||||
login: (BuildContext context) => const LoginPage(),
|
||||
loginMethodsPage: (BuildContext context) => const LoginMethodsPage(),
|
||||
};
|
||||
}
|
||||
|
||||
@ -0,0 +1,187 @@
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_svg/svg.dart';
|
||||
import 'package:hmg_nurses/classes/colors.dart';
|
||||
import 'package:hmg_nurses/classes/utils.dart';
|
||||
import 'package:hmg_nurses/generated/locale_keys.g.dart';
|
||||
import 'package:local_auth/local_auth.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> {
|
||||
final LocalAuthentication localAuth = LocalAuthentication();
|
||||
List<BiometricType> _availableBioMetricType = [];
|
||||
|
||||
int selectedFlag = 0;
|
||||
bool isNeedVerifyWithFaceIDAndBiometrics = false;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
_getAvailableBiometrics();
|
||||
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: ListView(
|
||||
padding: const EdgeInsets.all(21),
|
||||
physics: const BouncingScrollPhysics(),
|
||||
children: [
|
||||
Text(
|
||||
LocaleKeys.pleaseVerifyForBio.tr(),
|
||||
style: TextStyle(fontSize: 14.sp, fontWeight: FontWeight.w600),
|
||||
),
|
||||
if (isNeedVerifyWithFaceIDAndBiometrics) Text(LocaleKeys.pleaseVerifyForBio.tr()),
|
||||
GridView(
|
||||
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2, crossAxisSpacing: 13, mainAxisSpacing: 9),
|
||||
physics: const NeverScrollableScrollPhysics(),
|
||||
padding: const EdgeInsets.only(top: 9),
|
||||
shrinkWrap: true,
|
||||
children: [
|
||||
if (!isNeedVerifyWithFaceIDAndBiometrics) getButton(3),
|
||||
if (!isNeedVerifyWithFaceIDAndBiometrics) getButton(4),
|
||||
getButton(2),
|
||||
getButton(1),
|
||||
],
|
||||
)
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> _getAvailableBiometrics() async {
|
||||
try {
|
||||
_availableBioMetricType = await localAuth.getAvailableBiometrics();
|
||||
} on PlatformException catch (e) {
|
||||
// AppToast.showErrorToast(message: e.message);
|
||||
if (kDebugMode) {
|
||||
print(e);
|
||||
}
|
||||
}
|
||||
if (mounted) setState(() {});
|
||||
}
|
||||
|
||||
Future<bool> loginWithFaceIDAndBiometrics() async {
|
||||
bool authenticated = false;
|
||||
try {
|
||||
authenticated = await localAuth.authenticate(
|
||||
localizedReason: 'Scan your fingerprint to authenticate',
|
||||
);
|
||||
} on PlatformException catch (e) {
|
||||
if (kDebugMode) {
|
||||
print(e);
|
||||
}
|
||||
Utils.hideLoading(context);
|
||||
Utils.showToast("Please enable your Touch or Face ID");
|
||||
}
|
||||
return authenticated;
|
||||
}
|
||||
|
||||
Widget _loginOptionButton(String title, String icon, int flag, int? loginIndex) {
|
||||
bool isDisable = ((flag == 3 && !checkBiometricIsAvailable(BiometricType.face)) || (flag == 4 && !checkBiometricIsAvailable(BiometricType.fingerprint)));
|
||||
return InkWell(
|
||||
onTap: isDisable
|
||||
? null
|
||||
: () async {
|
||||
if (flag == 0) {
|
||||
setState(() {
|
||||
// isMoreOption = true;
|
||||
});
|
||||
} else {
|
||||
if (flag == 3 || flag == 4) {
|
||||
bool authenticateWithFaceAndTouchID = await loginWithFaceIDAndBiometrics();
|
||||
if (!authenticateWithFaceAndTouchID) {
|
||||
return;
|
||||
} else {
|
||||
isNeedVerifyWithFaceIDAndBiometrics = true;
|
||||
selectedFlag = flag;
|
||||
setState(() {
|
||||
return;
|
||||
});
|
||||
}
|
||||
} else {
|
||||
if (isNeedVerifyWithFaceIDAndBiometrics) {
|
||||
// performApiCall(_title, _icon, selectedFlag, _flag);
|
||||
|
||||
} else {
|
||||
// performApiCall(_title, _icon, _flag, _flag);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
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.lightGreyEFColor, width: 1),
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: <Widget>[
|
||||
SvgPicture.asset(
|
||||
icon,
|
||||
height: 38,
|
||||
width: 38,
|
||||
color: isDisable ? MyColors.darkTextColor.withOpacity(0.7) : null,
|
||||
),
|
||||
Text(
|
||||
title,
|
||||
style: const TextStyle(fontWeight: FontWeight.w600),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget getButton(int flag) {
|
||||
switch (flag) {
|
||||
case 1:
|
||||
return _loginOptionButton(LocaleKeys.verifyThroughSMS.tr(), 'assets/images/login/verify_sms.svg', flag, null);
|
||||
case 2:
|
||||
return _loginOptionButton(LocaleKeys.verifyThroughWhatsapp.tr(), 'assets/images/login/verify_whatsapp.svg', flag, null);
|
||||
case 3:
|
||||
return _loginOptionButton(LocaleKeys.verifyThroughFace.tr(), 'assets/images/login/verify_face.svg', flag, BiometricType.face.index);
|
||||
case 4:
|
||||
return _loginOptionButton(LocaleKeys.verifyThroughFingerprint.tr(), 'assets/images/login/verify_thumb.svg', flag, BiometricType.fingerprint.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;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,113 @@
|
||||
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,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))
|
||||
],
|
||||
),
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||