From 03d5d3dc1afeb1b91a728b53b388b3a45cc9ae7f Mon Sep 17 00:00:00 2001 From: Rajshinde046 Date: Tue, 19 Mar 2024 12:19:01 +0530 Subject: [PATCH] secure access --- .vscode/settings.json | 3 + android/app/build.gradle | 2 +- assets/images/png/face-id.png | Bin 0 -> 1966 bytes assets/images/png/fingerprint.png | Bin 0 -> 4260 bytes assets/images/png/pin.png | Bin 0 -> 3409 bytes lib/Utils/Common/CommonAppbar.dart | 77 ++++++ lib/Utils/Common/CustomTextFormField.dart | 14 +- lib/Utils/Dialogs.dart | 33 +++ lib/Utils/{Common => }/text.dart | 22 ++ lib/resources/routes/route_name.dart | 11 + lib/resources/routes/routes.dart | 31 +++ lib/view/login/LoginScreen.dart | 39 ++- lib/view/login/VerifyOtp.dart | 128 +++++++++ lib/view/secureAccess.dart/Faceid.dart | 71 +++++ lib/view/secureAccess.dart/Fingerprint.dart | 71 +++++ lib/view/secureAccess.dart/Pin.dart | 122 +++++++++ lib/view/secureAccess.dart/SecureAccess.dart | 267 +++++++++++++++++++ pubspec.lock | 16 ++ pubspec.yaml | 2 + 19 files changed, 898 insertions(+), 11 deletions(-) create mode 100644 .vscode/settings.json create mode 100644 assets/images/png/face-id.png create mode 100644 assets/images/png/fingerprint.png create mode 100644 assets/images/png/pin.png create mode 100644 lib/Utils/Common/CommonAppbar.dart create mode 100644 lib/Utils/Dialogs.dart rename lib/Utils/{Common => }/text.dart (73%) create mode 100644 lib/view/login/VerifyOtp.dart create mode 100644 lib/view/secureAccess.dart/Faceid.dart create mode 100644 lib/view/secureAccess.dart/Fingerprint.dart create mode 100644 lib/view/secureAccess.dart/Pin.dart create mode 100644 lib/view/secureAccess.dart/SecureAccess.dart diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..c5f3f6b --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "java.configuration.updateBuildConfiguration": "interactive" +} \ No newline at end of file diff --git a/android/app/build.gradle b/android/app/build.gradle index 44c4caa..ae4a4ac 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -47,7 +47,7 @@ android { applicationId "com.example.traderscircuit" // You can update the following values to match your application needs. // For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-gradle-build-configuration. - minSdkVersion flutter.minSdkVersion + minSdkVersion 21 targetSdkVersion flutter.targetSdkVersion versionCode flutterVersionCode.toInteger() versionName flutterVersionName diff --git a/assets/images/png/face-id.png b/assets/images/png/face-id.png new file mode 100644 index 0000000000000000000000000000000000000000..cce8dbf422c581a412210450f7adab27d39c2bea GIT binary patch literal 1966 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 DNh}^; literal 0 HcmV?d00001 diff --git a/assets/images/png/pin.png b/assets/images/png/pin.png new file mode 100644 index 0000000000000000000000000000000000000000..6039cfcd2974755d12e909b71fced046808c9449 GIT binary patch literal 3409 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 Ao&W#< literal 0 HcmV?d00001 diff --git a/lib/Utils/Common/CommonAppbar.dart b/lib/Utils/Common/CommonAppbar.dart new file mode 100644 index 0000000..2203ac4 --- /dev/null +++ b/lib/Utils/Common/CommonAppbar.dart @@ -0,0 +1,77 @@ +// ignore_for_file: non_constant_identifier_names, file_names, prefer_const_constructors + +import 'package:flutter/material.dart'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; +import 'package:get/get.dart'; + +class CommonAppbar extends StatelessWidget implements PreferredSizeWidget { + @override + Size get preferredSize => Size.fromHeight(height); + const CommonAppbar( + {Key? key, + required this.titleTxt, + this.showLeading = true, + this.customBack, + this.backPageName = '', + this.height = 105}) + : super(key: key); + + final String titleTxt; + final bool? showLeading; + final bool? customBack; + final String? backPageName; + final double height; + @override + Widget build(BuildContext context) { + return PreferredSize( + preferredSize: Size.fromHeight(130), + child: AppBar( + scrolledUnderElevation: 0.0, + backgroundColor: Colors.black, + elevation: 0, + leadingWidth: 56.w, + leading: Padding( + padding: EdgeInsets.only(left: 16.w, top: 20.h), + child: GestureDetector( + onTap: () { + customBack ?? false ? Get.toNamed(backPageName!) : Get.back(); + }, + child: Padding( + padding: EdgeInsets.only(left: 8.w), + child: Icon( + Icons.arrow_back_ios, + color: Colors.white, + size: 25.r, + ), + ), + ), + ), + flexibleSpace: FlexibleSpaceBar( + centerTitle: false, + titlePadding: EdgeInsets.all(0), + title: Padding( + padding: EdgeInsets.only(left: 16.w), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.end, + children: [ + Text( + titleTxt, + style: TextStyle( + color: Colors.white, + fontSize: 24.sp, + fontWeight: FontWeight.w500, + fontFamily: 'manrope'), + maxLines: 2, + softWrap: true, + ), + // newTextfield( + // FontWeight.w400, 0) + ], + ), + ), + ), + ), + ); + } +} diff --git a/lib/Utils/Common/CustomTextFormField.dart b/lib/Utils/Common/CustomTextFormField.dart index d7156b2..0268f4d 100644 --- a/lib/Utils/Common/CustomTextFormField.dart +++ b/lib/Utils/Common/CustomTextFormField.dart @@ -123,13 +123,13 @@ class _CustomTextFormFieldState extends State { ), style: TextStyle(color: Colors.white), keyboardType: widget.texttype, - validator: widget.validator ?? - (value) { - if (value == null || value.isEmpty) { - return "Empty value"; - } - return null; - }, + // validator: widget.validator ?? + // (value) { + // if (value == null || value.isEmpty) { + // return "Empty value"; + // } + // return null; + // }, inputFormatters: widget.inputFormatters, onChanged: (value) { widget.onInput?.call(value); diff --git a/lib/Utils/Dialogs.dart b/lib/Utils/Dialogs.dart new file mode 100644 index 0000000..6cc75b5 --- /dev/null +++ b/lib/Utils/Dialogs.dart @@ -0,0 +1,33 @@ +import 'package:flutter/material.dart'; +import 'package:fluttertoast/fluttertoast.dart'; +import 'package:get/get.dart'; + +class utils { + static showToast(String? msg) { + if (msg != null && msg != "null" && msg.isNotEmpty) { + Fluttertoast.showToast(msg: msg); + } + } + + static loader() { + Get.dialog( + Dialog( + elevation: 0, + backgroundColor: Colors.transparent, + child: WillPopScope( + child: Container( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + CircularProgressIndicator( + color: Color(0xffc18948), + ), + ], + ), + ), + onWillPop: () async => false), + ), + barrierDismissible: false, + ); + } +} diff --git a/lib/Utils/Common/text.dart b/lib/Utils/text.dart similarity index 73% rename from lib/Utils/Common/text.dart rename to lib/Utils/text.dart index 631d1bc..904b2b6 100644 --- a/lib/Utils/Common/text.dart +++ b/lib/Utils/text.dart @@ -1,6 +1,17 @@ import 'package:flutter/material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; +Widget text20W400(String text) { + return Text( + text, + style: TextStyle( + fontSize: 20.sp, + color: Colors.white, + fontWeight: FontWeight.w400, + fontFamily: 'manrope'), + ); +} + Widget text18W800(String text) { return Text( text, @@ -23,6 +34,17 @@ Widget text18W600(String text) { ); } +Widget text18W400(String text) { + return Text( + text, + style: TextStyle( + fontSize: 18.sp, + color: Colors.white, + fontWeight: FontWeight.w400, + fontFamily: 'manrope'), + ); +} + Widget text16W400(String text) { return Text( text, diff --git a/lib/resources/routes/route_name.dart b/lib/resources/routes/route_name.dart index e1a33fa..bdb68ef 100644 --- a/lib/resources/routes/route_name.dart +++ b/lib/resources/routes/route_name.dart @@ -1,8 +1,19 @@ class RouteName { static const String splashScreen = '/'; static const String nointernet = '/nointernet'; + + //slidescreen static const String sliderscreen1 = '/sliderscreen1'; static const String sliderscreen2 = '/sliderscreen2'; static const String sliderscreen3 = '/sliderscreen3'; + + //login/signup static const String loginscreen = '/loginscreen'; + static const String verifyotp = '/verifyotp'; + + //secureaccess + static const String secureaccess = '/secureaccess'; + static const String faceid = '/faceid'; + static const String fingerprint = '/fingerprint'; + static const String pin = '/pin'; } diff --git a/lib/resources/routes/routes.dart b/lib/resources/routes/routes.dart index 4f45edd..591d019 100644 --- a/lib/resources/routes/routes.dart +++ b/lib/resources/routes/routes.dart @@ -2,10 +2,15 @@ import 'package:get/get.dart'; import 'package:traderscircuit/Utils/Common/noInternet.dart'; import 'package:traderscircuit/resources/routes/route_name.dart'; import 'package:traderscircuit/view/login/LoginScreen.dart'; +import 'package:traderscircuit/view/login/VerifyOtp.dart'; import 'package:traderscircuit/view/onBoarding/splashScreen.dart'; import 'package:traderscircuit/view/onBoarding/splashScreen1.dart'; import 'package:traderscircuit/view/onBoarding/splashScreen2.dart'; import 'package:traderscircuit/view/onBoarding/splashScreen3.dart'; +import 'package:traderscircuit/view/secureAccess.dart/Faceid.dart'; +import 'package:traderscircuit/view/secureAccess.dart/Fingerprint.dart'; +import 'package:traderscircuit/view/secureAccess.dart/Pin.dart'; +import 'package:traderscircuit/view/secureAccess.dart/SecureAccess.dart'; class AppRoutes { static appRoutes() => [ @@ -17,6 +22,8 @@ class AppRoutes { name: RouteName.nointernet, page: () => const NoInternet(), ), + + //slidescreen GetPage( name: RouteName.sliderscreen1, page: () => const Sliderscreen1(), @@ -29,9 +36,33 @@ class AppRoutes { name: RouteName.sliderscreen3, page: () => const Sliderscreen3(), ), + + //login/signup GetPage( name: RouteName.loginscreen, page: () => const LoginScreen(), ), + GetPage( + name: RouteName.verifyotp, + page: () => const VerifyOTP(), + ), + + //secureaccess + GetPage( + name: RouteName.secureaccess, + page: () => const SecureAccess(), + ), + GetPage( + name: RouteName.faceid, + page: () => const Faceid(), + ), + GetPage( + name: RouteName.fingerprint, + page: () => const Fingerprint(), + ), + GetPage( + name: RouteName.pin, + page: () => const Pin(), + ), ]; } diff --git a/lib/view/login/LoginScreen.dart b/lib/view/login/LoginScreen.dart index 026edda..abacfef 100644 --- a/lib/view/login/LoginScreen.dart +++ b/lib/view/login/LoginScreen.dart @@ -1,13 +1,16 @@ import 'dart:ui'; import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:flutter_svg/svg.dart'; +import 'package:get/get.dart'; import 'package:glassmorphism/glassmorphism.dart'; import 'package:traderscircuit/Utils/Common/CustomTextFormField.dart'; import 'package:traderscircuit/Utils/Common/commonBotton.dart'; -import 'package:traderscircuit/Utils/Common/text.dart'; +import 'package:traderscircuit/Utils/text.dart'; import 'package:traderscircuit/main.dart'; +import 'package:traderscircuit/resources/routes/route_name.dart'; import 'package:traderscircuit/view/onBoarding/splashScreen1.dart'; class LoginScreen extends StatefulWidget { @@ -18,6 +21,13 @@ class LoginScreen extends StatefulWidget { } class _LoginScreenState extends State { + TextEditingController phonecontroller = TextEditingController(); + bool isValidPhoneNumber(String phoneNumber) { + final RegExp phoneNumberExpression = RegExp(r"^0{10}$"); + + return !phoneNumberExpression.hasMatch(phoneNumber); + } + @override Widget build(BuildContext context) { return Scaffold( @@ -124,7 +134,26 @@ class _LoginScreenState extends State { ), Container( width: 285.w, - child: CustomTextFormField(), + child: CustomTextFormField( + texttype: TextInputType.phone, + textEditingController: phonecontroller, + // validator: (value) { + // if (value.isEmpty) { + // return 'Enter your phone number'; + // } else if (!RegExp(r'(^(?:[+0]9)?[0-9]{10}$)') + // .hasMatch(value)) { + // return 'Enter a valid phone number'; + // } else if (!isValidPhoneNumber(value)) { + // return 'Phone number cannot contain 10 zeros'; + // } + // return null; + // }, + inputFormatters: [ + LengthLimitingTextInputFormatter(10), + FilteringTextInputFormatter.allow( + RegExp('[0-9]')), + ], + ), ) ], ), @@ -136,7 +165,11 @@ class _LoginScreenState extends State { SizedBox( height: 65.h, ), - CommonBtn(text: "Login/Signup", onTap: () {}), + CommonBtn( + text: "Login/Signup", + onTap: () { + Get.toNamed(RouteName.verifyotp); + }), SizedBox( height: 10.h, ), diff --git a/lib/view/login/VerifyOtp.dart b/lib/view/login/VerifyOtp.dart new file mode 100644 index 0000000..3aea9ba --- /dev/null +++ b/lib/view/login/VerifyOtp.dart @@ -0,0 +1,128 @@ +import 'package:flutter/material.dart'; +import 'package:flutter/widgets.dart'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; +import 'package:get/get.dart'; +import 'package:pin_code_fields/pin_code_fields.dart'; +import 'package:traderscircuit/Utils/Common/CommonAppbar.dart'; +import 'package:traderscircuit/Utils/Common/commonBotton.dart'; +import 'package:traderscircuit/Utils/text.dart'; +import 'package:traderscircuit/resources/routes/route_name.dart'; +import 'package:traderscircuit/view/onBoarding/splashScreen1.dart'; +import 'package:traderscircuit/Utils/Dialogs.dart'; + +class VerifyOTP extends StatefulWidget { + const VerifyOTP({super.key}); + + @override + State createState() => _VerifyOTPState(); +} + +class _VerifyOTPState extends State { + final GlobalKey _otpform = GlobalKey(); + TextEditingController pincode = TextEditingController(); + Color primaryColor = Colors.transparent.withOpacity(0.2); + Color secondaryColor = Colors.grey.shade800; + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: CommonAppbar(titleTxt: "Verify OTP"), + backgroundColor: Colors.black, + extendBody: true, + body: Stack( + children: [ + CommonBlurLeft(), + CommonBlurRight(), + Stack( + children: [ + Padding( + padding: EdgeInsets.symmetric(horizontal: 16, vertical: 16), + child: Form( + key: _otpform, + child: ListView( + physics: BouncingScrollPhysics(), + // mainAxisAlignment: MainAxisAlignment.start, + // crossAxisAlignment: CrossAxisAlignment.start, + children: [ + text18W400("Enter four digit code send to"), + SizedBox( + height: 100.h, + ), + Container( + child: PinCodeTextField( + showCursor: true, + cursorColor: Colors.white, + textStyle: + TextStyle(fontSize: 18.sp, color: Colors.white), + errorTextSpace: 22, + validator: (value) { + if (value != null && value.isEmpty) { + return "Please Enter verification code"; + } else if (value != null && value.length < 4) { + return "OTP length should be atleast 4"; + } + return null; + }, + keyboardType: TextInputType.number, + mainAxisAlignment: MainAxisAlignment.spaceBetween, + length: 4, + obscureText: false, + animationType: AnimationType.fade, + pinTheme: PinTheme( + selectedFillColor: primaryColor, + inactiveFillColor: primaryColor, + activeFillColor: primaryColor, + inactiveColor: secondaryColor, + activeColor: secondaryColor, + selectedColor: secondaryColor, + shape: PinCodeFieldShape.box, + borderRadius: BorderRadius.circular(15), + fieldHeight: 60.h, + fieldWidth: 60.w, + ), + animationDuration: Duration(milliseconds: 300), + enableActiveFill: true, + controller: pincode, + onCompleted: (v) { + print("Completed"); + }, + onChanged: (value) { + print(value); + setState(() {}); + }, + beforeTextPaste: (text) { + print("Allowing to paste $text"); + + return true; + }, + appContext: context, + ), + ), + SizedBox( + height: 45.h, + ), + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + text16W700("Resend Code"), + ], + ), + SizedBox( + height: 200.h, + ), + CommonBtn( + text: "Verify OTP", + onTap: () { + Get.toNamed(RouteName.secureaccess); + }, + ) + ], + ), + ), + ), + ], + ), + ], + ), + ); + } +} diff --git a/lib/view/secureAccess.dart/Faceid.dart b/lib/view/secureAccess.dart/Faceid.dart new file mode 100644 index 0000000..ecd9b37 --- /dev/null +++ b/lib/view/secureAccess.dart/Faceid.dart @@ -0,0 +1,71 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; +import 'package:get/get.dart'; +import 'package:traderscircuit/Utils/Common/CommonAppbar.dart'; +import 'package:traderscircuit/Utils/Common/commonBotton.dart'; +import 'package:traderscircuit/Utils/text.dart'; +import 'package:traderscircuit/resources/routes/route_name.dart'; +import 'package:traderscircuit/view/onBoarding/splashScreen1.dart'; + +class Faceid extends StatefulWidget { + const Faceid({super.key}); + + @override + State createState() => _FaceidState(); +} + +class _FaceidState extends State { + Color primaryColor = Colors.transparent.withOpacity(0.2); + Color secondaryColor = Colors.grey.shade800; + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: CommonAppbar(titleTxt: "Secure your access"), + backgroundColor: Colors.black, + extendBody: true, + body: Stack( + children: [ + CommonBlurLeft(), + CommonBlurRight(), + Stack( + children: [ + Padding( + padding: EdgeInsets.symmetric(horizontal: 16, vertical: 16), + child: ListView( + physics: BouncingScrollPhysics(), + // mainAxisAlignment: MainAxisAlignment.start, + // crossAxisAlignment: CrossAxisAlignment.start, + + children: [ + SizedBox( + height: 10.h, + ), + text18W400("Quickly set up Face ID for secure access."), + SizedBox( + height: 180.h, + ), + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Image.asset("assets/images/png/face-id.png"), + ], + ), + SizedBox( + height: 180.h, + ), + CommonBtn( + text: "Setup", + onTap: () { + Get.toNamed(RouteName.loginscreen); + }, + ) + ], + ), + ), + ], + ), + ], + ), + ); + } +} diff --git a/lib/view/secureAccess.dart/Fingerprint.dart b/lib/view/secureAccess.dart/Fingerprint.dart new file mode 100644 index 0000000..e482638 --- /dev/null +++ b/lib/view/secureAccess.dart/Fingerprint.dart @@ -0,0 +1,71 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; +import 'package:get/get.dart'; +import 'package:traderscircuit/Utils/Common/CommonAppbar.dart'; +import 'package:traderscircuit/Utils/Common/commonBotton.dart'; +import 'package:traderscircuit/Utils/text.dart'; +import 'package:traderscircuit/resources/routes/route_name.dart'; +import 'package:traderscircuit/view/onBoarding/splashScreen1.dart'; + +class Fingerprint extends StatefulWidget { + const Fingerprint({super.key}); + + @override + State createState() => _FingerprintState(); +} + +class _FingerprintState extends State { + Color primaryColor = Colors.transparent.withOpacity(0.2); + Color secondaryColor = Colors.grey.shade800; + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: CommonAppbar(titleTxt: "Secure your access"), + backgroundColor: Colors.black, + extendBody: true, + body: Stack( + children: [ + CommonBlurLeft(), + CommonBlurRight(), + Stack( + children: [ + Padding( + padding: EdgeInsets.symmetric(horizontal: 16, vertical: 16), + child: ListView( + physics: BouncingScrollPhysics(), + // mainAxisAlignment: MainAxisAlignment.start, + // crossAxisAlignment: CrossAxisAlignment.start, + + children: [ + SizedBox( + height: 10.h, + ), + text18W400("Quickly set up Fingerprint for secure access."), + SizedBox( + height: 180.h, + ), + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Image.asset("assets/images/png/fingerprint.png"), + ], + ), + SizedBox( + height: 180.h, + ), + CommonBtn( + text: "Setup", + onTap: () { + Get.toNamed(RouteName.loginscreen); + }, + ) + ], + ), + ), + ], + ), + ], + ), + ); + } +} diff --git a/lib/view/secureAccess.dart/Pin.dart b/lib/view/secureAccess.dart/Pin.dart new file mode 100644 index 0000000..af2e77e --- /dev/null +++ b/lib/view/secureAccess.dart/Pin.dart @@ -0,0 +1,122 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; +import 'package:get/get.dart'; +import 'package:pin_code_fields/pin_code_fields.dart'; +import 'package:traderscircuit/Utils/Common/CommonAppbar.dart'; +import 'package:traderscircuit/Utils/Common/commonBotton.dart'; +import 'package:traderscircuit/Utils/text.dart'; +import 'package:traderscircuit/resources/routes/route_name.dart'; +import 'package:traderscircuit/view/onBoarding/splashScreen1.dart'; + +class Pin extends StatefulWidget { + const Pin({super.key}); + + @override + State createState() => _PinState(); +} + +class _PinState extends State { + TextEditingController pin = TextEditingController(); + Color primaryColor = Colors.transparent.withOpacity(0.2); + Color secondaryColor = Colors.grey.shade800; + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: CommonAppbar(titleTxt: "Verify your number"), + backgroundColor: Colors.black, + extendBody: true, + body: Stack( + children: [ + CommonBlurLeft(), + CommonBlurRight(), + Stack( + children: [ + Padding( + padding: EdgeInsets.symmetric(horizontal: 16, vertical: 16), + child: ListView( + physics: BouncingScrollPhysics(), + // mainAxisAlignment: MainAxisAlignment.start, + // crossAxisAlignment: CrossAxisAlignment.start, + + children: [ + SizedBox( + height: 10.h, + ), + text18W400("Quickly set up pin for secure access."), + SizedBox( + height: 180.h, + ), + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Container( + child: PinCodeTextField( + showCursor: true, + cursorColor: Colors.white, + textStyle: + TextStyle(fontSize: 18.sp, color: Colors.white), + errorTextSpace: 22, + validator: (value) { + if (value != null && value.isEmpty) { + return "Please Enter verification code"; + } else if (value != null && value.length < 4) { + return "OTP length should be atleast 4"; + } + return null; + }, + keyboardType: TextInputType.number, + mainAxisAlignment: MainAxisAlignment.spaceBetween, + length: 4, + obscureText: false, + animationType: AnimationType.fade, + pinTheme: PinTheme( + selectedFillColor: primaryColor, + inactiveFillColor: primaryColor, + activeFillColor: primaryColor, + inactiveColor: secondaryColor, + activeColor: secondaryColor, + selectedColor: secondaryColor, + shape: PinCodeFieldShape.box, + borderRadius: BorderRadius.circular(15), + fieldHeight: 60.h, + fieldWidth: 60.w, + ), + animationDuration: Duration(milliseconds: 300), + enableActiveFill: true, + controller: pin, + onCompleted: (v) { + print("Completed"); + }, + onChanged: (value) { + print(value); + setState(() {}); + }, + beforeTextPaste: (text) { + print("Allowing to paste $text"); + + return true; + }, + appContext: context, + ), + ), + ], + ), + SizedBox( + height: 180.h, + ), + CommonBtn( + text: "Setup", + onTap: () { + Get.toNamed(RouteName.loginscreen); + }, + ) + ], + ), + ), + ], + ), + ], + ), + ); + } +} diff --git a/lib/view/secureAccess.dart/SecureAccess.dart b/lib/view/secureAccess.dart/SecureAccess.dart new file mode 100644 index 0000000..dbaec0c --- /dev/null +++ b/lib/view/secureAccess.dart/SecureAccess.dart @@ -0,0 +1,267 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; +import 'package:get/get.dart'; +import 'package:glassmorphism/glassmorphism.dart'; +import 'package:traderscircuit/Utils/Common/CommonAppbar.dart'; +import 'package:traderscircuit/Utils/Common/commonBotton.dart'; +import 'package:traderscircuit/Utils/text.dart'; +import 'package:traderscircuit/resources/routes/route_name.dart'; +import 'package:traderscircuit/view/onBoarding/splashScreen1.dart'; + +class SecureAccess extends StatefulWidget { + const SecureAccess({super.key}); + + @override + State createState() => _SecureAccessState(); +} + +class _SecureAccessState extends State { + TextEditingController pincode = TextEditingController(); + Color primaryColor = Colors.transparent.withOpacity(0.2); + Color secondaryColor = Colors.grey.shade800; + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: CommonAppbar(titleTxt: "Secure ypur access"), + backgroundColor: Colors.black, + extendBody: true, + body: Stack( + children: [ + CommonBlurLeft(), + CommonBlurRight(), + Stack( + children: [ + Padding( + padding: EdgeInsets.symmetric(horizontal: 16, vertical: 16), + child: ListView( + physics: BouncingScrollPhysics(), + // mainAxisAlignment: MainAxisAlignment.start, + // crossAxisAlignment: CrossAxisAlignment.start, + + children: [ + SizedBox( + height: 30.h, + ), + InkWell( + onTap: () { + Get.toNamed(RouteName.faceid); + }, + child: GlassmorphicContainer( + width: double.infinity, + height: 80.h, + borderRadius: 8, + linearGradient: LinearGradient( + begin: Alignment.topLeft, + end: Alignment.bottomRight, + colors: [ + Colors.white.withOpacity(0.1), + Color(0xFFFFFFFF).withOpacity(0.05), + ], + stops: [ + 0.1, + 1, + ]), + border: 0, + blur: 10, + borderGradient: LinearGradient( + begin: Alignment.topLeft, + end: Alignment.bottomRight, + colors: [ + Color(0xff9A0000).withOpacity(0.5), + Color(0xFFffffff).withOpacity(0.5), + ], + ), + child: Center( + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Row( + children: [ + SizedBox( + width: 10.w, + ), + Image.asset( + "assets/images/png/face-id.png", + height: 40.h, + width: 40.w, + ), + SizedBox( + width: 20.w, + ), + text20W400( + "Face ID", + ), + ], + ), + Row( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + Icon( + Icons.arrow_forward_ios, + color: Colors.white, + ), + SizedBox( + width: 20.w, + ), + ], + ) + ], + ), + ), + ), + ), + SizedBox( + height: 20.h, + ), + InkWell( + onTap: () { + Get.toNamed(RouteName.fingerprint); + }, + child: GlassmorphicContainer( + width: double.infinity, + height: 80.h, + borderRadius: 8, + linearGradient: LinearGradient( + begin: Alignment.topLeft, + end: Alignment.bottomRight, + colors: [ + Colors.white.withOpacity(0.1), + Color(0xFFFFFFFF).withOpacity(0.05), + ], + stops: [ + 0.1, + 1, + ]), + border: 0, + blur: 10, + borderGradient: LinearGradient( + begin: Alignment.topLeft, + end: Alignment.bottomRight, + colors: [ + Color(0xff9A0000).withOpacity(0.5), + Color(0xFFffffff).withOpacity(0.5), + ], + ), + child: Center( + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Row( + children: [ + SizedBox( + width: 10.w, + ), + Image.asset( + "assets/images/png/fingerprint.png", + height: 40.h, + width: 40.w, + ), + SizedBox( + width: 20.w, + ), + text20W400("Fingerprint"), + ], + ), + Row( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + Icon( + Icons.arrow_forward_ios, + color: Colors.white, + ), + SizedBox( + width: 20.w, + ) + ], + ) + ], + ), + ), + ), + ), + SizedBox( + height: 20.h, + ), + InkWell( + onTap: () {}, + child: GlassmorphicContainer( + width: double.infinity, + height: 80.h, + borderRadius: 8, + linearGradient: LinearGradient( + begin: Alignment.topLeft, + end: Alignment.bottomRight, + colors: [ + Colors.white.withOpacity(0.1), + Color(0xFFFFFFFF).withOpacity(0.05), + ], + stops: [ + 0.1, + 1, + ]), + border: 0, + blur: 10, + borderGradient: LinearGradient( + begin: Alignment.topLeft, + end: Alignment.bottomRight, + colors: [ + Color(0xff9A0000).withOpacity(0.5), + Color(0xFFffffff).withOpacity(0.5), + ], + ), + child: Center( + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Row( + children: [ + SizedBox( + width: 10.w, + ), + Image.asset( + "assets/images/png/pin.png", + height: 40.h, + width: 40.w, + ), + SizedBox( + width: 20.w, + ), + text20W400("4 Digit Pin"), + ], + ), + Row( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + Icon( + Icons.arrow_forward_ios, + color: Colors.white, + ), + SizedBox( + width: 20.w, + ) + ], + ), + ], + ), + ), + ), + ), + SizedBox( + height: 250.h, + ), + CommonBtn( + text: "Verify OTP", + onTap: () { + Get.toNamed(RouteName.loginscreen); + }, + ) + ], + ), + ), + ], + ), + ], + ), + ); + } +} diff --git a/pubspec.lock b/pubspec.lock index 510fa38..2363400 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -144,6 +144,14 @@ packages: description: flutter source: sdk version: "0.0.0" + fluttertoast: + dependency: "direct main" + description: + name: fluttertoast + sha256: dfdde255317af381bfc1c486ed968d5a43a2ded9c931e87cbecd88767d6a71c1 + url: "https://pub.dev" + source: hosted + version: "8.2.4" get: dependency: "direct main" description: @@ -272,6 +280,14 @@ packages: url: "https://pub.dev" source: hosted version: "6.0.2" + pin_code_fields: + dependency: "direct main" + description: + name: pin_code_fields + sha256: "4c0db7fbc889e622e7c71ea54b9ee624bb70c7365b532abea0271b17ea75b729" + url: "https://pub.dev" + source: hosted + version: "8.0.1" platform: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 4dc407d..755ae70 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -41,6 +41,8 @@ dependencies: shared_preferences: ^2.0.15 connectivity_plus: ^5.0.2 glassmorphism: ^3.0.0 + pin_code_fields: ^8.0.1 + fluttertoast: ^8.0.9