D1APP-13 Authentication (otp)

This commit is contained in:
MohammadTaha Basiri 2021-12-09 19:01:33 +03:30
parent 5ec97ecb3b
commit 6299949461
11 changed files with 285 additions and 154 deletions

View File

@ -44,7 +44,7 @@ android {
defaultConfig {
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
applicationId "com.didvan.didvanapp"
minSdkVersion 16
minSdkVersion 18
targetSdkVersion 30
versionCode flutterVersionCode.toInteger()
versionName flutterVersionName

View File

@ -17,8 +17,10 @@ class DesignConfig {
fontFamily: 'dana-fa',
textTheme: const TextTheme(
bodyText1: body1Text,
bodyText2: body1Text,
caption: captionText,
subtitle2: subtitle2Text,
subtitle1: subtitle1Text,
),
);
@ -40,6 +42,10 @@ class DesignConfig {
static const currentColorScheme = lightColorScheme;
static const TextStyle subtitle1Text = TextStyle(
fontSize: 17,
fontWeight: FontWeight.w700,
);
static const TextStyle subtitle2Text = TextStyle(
fontSize: 15,
fontWeight: FontWeight.w700,

View File

@ -1,11 +1,8 @@
import 'package:didvan/config/design_config.dart';
import 'package:didvan/pages/authentication/authentication_state.dart';
import 'package:didvan/pages/authentication/widgets/authentication_app_bar.dart';
import 'package:didvan/widgets/didvan/button.dart';
import 'package:didvan/widgets/didvan/text.dart';
import 'package:didvan/widgets/didvan/text_field.dart';
import 'package:didvan/widgets/logos/didvan_horizontal_logo.dart';
import 'package:flutter/gestures.dart';
import 'package:didvan/pages/authentication/screens/password.dart';
import 'package:didvan/pages/authentication/screens/phone_number.dart';
import 'package:didvan/pages/authentication/screens/verification.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
@ -20,6 +17,7 @@ class _AuthenticationState extends State<Authentication> {
final List<Widget> _pages = const [
PhoneNumberInput(),
PasswordInput(),
Verification(),
];
@override
@ -34,149 +32,3 @@ class _AuthenticationState extends State<Authentication> {
);
}
}
class PhoneNumberInput extends StatelessWidget {
const PhoneNumberInput({
Key? key,
}) : super(key: key);
@override
Widget build(BuildContext context) {
final AuthenticationState state = context.read<AuthenticationState>();
return SingleChildScrollView(
physics: const NeverScrollableScrollPhysics(),
padding: const EdgeInsets.all(20),
child: SizedBox(
height: MediaQuery.of(context).size.height,
child: Column(
children: [
const Padding(
padding: EdgeInsets.only(
top: 80,
left: 100,
right: 100,
bottom: 40,
),
child: DidvanVerticalLogo(),
),
DidvanTextField(
title: 'شماره موبایل',
textInputType: TextInputType.phone,
hintText: 'شماره موبایل',
onChanged: (value) {
state.phoneNumber = value;
},
),
const SizedBox(
height: 20,
),
DidvanButton(
title: 'ورود',
onPressed: () {
state.currentPageIndex = 1;
},
),
const Spacer(),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 60),
child: RichText(
textAlign: TextAlign.center,
text: TextSpan(
style: Theme.of(context).textTheme.caption,
children: [
const TextSpan(text: 'با ثبت نام و ورود به دیدوان،'),
TextSpan(
text: ' شرایط ',
style: Theme.of(context)
.textTheme
.caption!
.copyWith(color: Theme.of(context).primaryColor),
recognizer: TapGestureRecognizer()
..onTap = () {
//TODO: Needs implementaion
},
),
const TextSpan(text: 'و\n'),
TextSpan(
text: ' قوانین حریم خصوصی ',
style: Theme.of(context)
.textTheme
.caption!
.copyWith(color: Theme.of(context).primaryColor),
recognizer: TapGestureRecognizer()
..onTap = () {
//TODO: Needs implementaion
},
),
const TextSpan(text: 'را می‌پذیرم'),
],
),
),
),
const SizedBox(
height: 48,
),
],
),
),
);
}
}
class PasswordInput extends StatelessWidget {
const PasswordInput({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
final AuthenticationState state = context.read<AuthenticationState>();
return SingleChildScrollView(
padding: const EdgeInsets.symmetric(horizontal: 20),
child: SizedBox(
height: MediaQuery.of(context).size.height,
child: Column(
children: [
AuthenticationAppBar(
title: 'ورود با شماره موبایل ' + state.phoneNumber,
),
const Padding(
padding: EdgeInsets.only(
bottom: 44,
top: 34,
left: 100,
right: 100,
),
child: DidvanVerticalLogo(),
),
DidvanTextField(
onChanged: (value) => state.password = value,
title: 'کلمه عبور',
hintText: 'کلمه عبور',
obsecureText: true,
),
const SizedBox(
height: 32,
),
GestureDetector(
onTap: () {
//TODO: Needs implementaion
},
child: DidvanText(
'فراموشی رمز عبور',
style: Theme.of(context).textTheme.subtitle2,
color: Theme.of(context).primaryColor,
),
),
const Spacer(),
DidvanButton(
onPressed: () {},
title: 'ورود ',
),
const SizedBox(
height: 48,
),
],
),
),
);
}
}

View File

@ -4,6 +4,7 @@ class AuthenticationState extends CoreProvier {
int _currentPageIndex = 0;
String phoneNumber = '';
String password = '';
String verificationCode = '';
set currentPageIndex(int value) {
_currentPageIndex = value;

View File

@ -0,0 +1,65 @@
import 'package:didvan/pages/authentication/authentication_state.dart';
import 'package:didvan/pages/authentication/widgets/authentication_app_bar.dart';
import 'package:didvan/widgets/didvan/button.dart';
import 'package:didvan/widgets/didvan/text.dart';
import 'package:didvan/widgets/didvan/text_field.dart';
import 'package:didvan/widgets/logos/didvan_horizontal_logo.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
class PasswordInput extends StatelessWidget {
const PasswordInput({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
final AuthenticationState state = context.read<AuthenticationState>();
return SingleChildScrollView(
padding: const EdgeInsets.symmetric(horizontal: 20),
child: SizedBox(
height: MediaQuery.of(context).size.height,
child: Column(
children: [
AuthenticationAppBar(
title: 'ورود با شماره موبایل ' + state.phoneNumber,
),
const Padding(
padding: EdgeInsets.only(
bottom: 44,
top: 34,
left: 100,
right: 100,
),
child: DidvanVerticalLogo(),
),
DidvanTextField(
onChanged: (value) => state.password = value,
autoFocus: true,
title: 'کلمه عبور',
hintText: 'کلمه عبور',
obsecureText: true,
),
const SizedBox(
height: 32,
),
GestureDetector(
onTap: () => state.currentPageIndex++,
child: DidvanText(
'فراموشی رمز عبور',
style: Theme.of(context).textTheme.subtitle2,
color: Theme.of(context).primaryColor,
),
),
const Spacer(),
DidvanButton(
onPressed: () {},
title: 'ورود',
),
const SizedBox(
height: 48,
),
],
),
),
);
}
}

View File

@ -0,0 +1,96 @@
import 'package:didvan/pages/authentication/authentication_state.dart';
import 'package:didvan/widgets/didvan/button.dart';
import 'package:didvan/widgets/didvan/text_field.dart';
import 'package:didvan/widgets/logos/didvan_horizontal_logo.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
class PhoneNumberInput extends StatelessWidget {
const PhoneNumberInput({
Key? key,
}) : super(key: key);
@override
Widget build(BuildContext context) {
final AuthenticationState state = context.read<AuthenticationState>();
return SingleChildScrollView(
physics: const NeverScrollableScrollPhysics(),
padding: const EdgeInsets.all(20),
child: SizedBox(
height: MediaQuery.of(context).size.height,
child: Column(
children: [
const Padding(
padding: EdgeInsets.only(
top: 80,
left: 100,
right: 100,
bottom: 40,
),
child: DidvanVerticalLogo(),
),
DidvanTextField(
title: 'شماره موبایل',
textInputType: TextInputType.phone,
hintText: 'شماره موبایل',
textAlign: TextAlign.center,
onChanged: (value) {
state.phoneNumber = value;
},
),
const SizedBox(
height: 20,
),
DidvanButton(
title: 'ورود',
onPressed: () {
state.currentPageIndex = 1;
},
),
const Spacer(),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 60),
child: RichText(
textAlign: TextAlign.center,
text: TextSpan(
style: Theme.of(context).textTheme.caption,
children: [
const TextSpan(text: 'با ثبت نام و ورود به دیدوان،'),
TextSpan(
text: ' شرایط ',
style: Theme.of(context)
.textTheme
.caption!
.copyWith(color: Theme.of(context).primaryColor),
recognizer: TapGestureRecognizer()
..onTap = () {
//TODO: Needs implementaion
},
),
const TextSpan(text: 'و\n'),
TextSpan(
text: ' قوانین حریم خصوصی ',
style: Theme.of(context)
.textTheme
.caption!
.copyWith(color: Theme.of(context).primaryColor),
recognizer: TapGestureRecognizer()
..onTap = () {
//TODO: Needs implementaion
},
),
const TextSpan(text: 'را می‌پذیرم'),
],
),
),
),
const SizedBox(
height: 48,
),
],
),
),
);
}
}

View File

@ -0,0 +1,92 @@
import 'package:didvan/config/design_config.dart';
import 'package:didvan/pages/authentication/authentication_state.dart';
import 'package:didvan/pages/authentication/widgets/authentication_app_bar.dart';
import 'package:didvan/widgets/didvan/button.dart';
import 'package:didvan/widgets/didvan/text.dart';
import 'package:didvan/widgets/logos/didvan_horizontal_logo.dart';
import 'package:flutter/material.dart';
import 'package:pin_code_fields/pin_code_fields.dart';
import 'package:provider/provider.dart';
class Verification extends StatelessWidget {
const Verification({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
final AuthenticationState state = context.read<AuthenticationState>();
return SingleChildScrollView(
physics: const NeverScrollableScrollPhysics(),
padding: const EdgeInsets.symmetric(horizontal: 20),
child: SizedBox(
height: MediaQuery.of(context).size.height,
child: Column(
children: [
const AuthenticationAppBar(
title: 'تغییر رمز عبور',
),
const Padding(
padding: EdgeInsets.only(
bottom: 24,
top: 34,
left: 100,
right: 100,
),
child: DidvanVerticalLogo(),
),
DidvanText(
'کد 6 رقممی ارسال شده به موبایل',
style: Theme.of(context).textTheme.subtitle2,
fontWeight: FontWeight.normal,
),
const SizedBox(
height: 8,
),
DidvanText(
state.phoneNumber,
style: Theme.of(context).textTheme.subtitle1,
),
const SizedBox(
height: 8,
),
DidvanText(
'را وارد کنید:',
style: Theme.of(context).textTheme.subtitle2,
fontWeight: FontWeight.normal,
),
const SizedBox(
height: 24,
),
Directionality(
textDirection: TextDirection.ltr,
child: PinCodeTextField(
keyboardType: TextInputType.number,
animationType: AnimationType.scale,
pinTheme: PinTheme(
fieldHeight: 48,
fieldWidth: 48,
inactiveColor: DesignConfig.greyColor4,
activeFillColor: Theme.of(context).primaryColorLight,
activeColor: Theme.of(context).primaryColor,
borderRadius: DesignConfig.lowBorderRadius,
borderWidth: 1,
shape: PinCodeFieldShape.box,
),
appContext: context,
length: 6,
onChanged: (value) => state.verificationCode = value,
),
),
const Spacer(),
DidvanButton(
onPressed: () {},
title: 'تایید',
),
const SizedBox(
height: 48,
),
],
),
),
);
}
}

View File

@ -1,3 +1,4 @@
import 'package:didvan/config/design_config.dart';
import 'package:didvan/pages/authentication/authentication_state.dart';
import 'package:didvan/widgets/didvan/text.dart';
import 'package:flutter/material.dart';
@ -17,12 +18,18 @@ class AuthenticationAppBar extends StatelessWidget {
onTap: () => context.read<AuthenticationState>().currentPageIndex--,
child: const Icon(
Icons.arrow_back,
color: DesignConfig.darkPrimaryColor2,
),
),
const SizedBox(
width: 20,
),
if (title != null) DidvanText(title!)
if (title != null)
DidvanText(
title!,
style: Theme.of(context).textTheme.subtitle2,
color: DesignConfig.darkPrimaryColor2,
)
],
),
);

View File

@ -5,6 +5,7 @@ import 'package:flutter/material.dart';
class DidvanTextField extends StatefulWidget {
final void Function(String value)? onChanged;
final bool enabled;
final bool autoFocus;
final TextAlign textAlign;
final String? title;
final String? hintText;
@ -23,6 +24,7 @@ class DidvanTextField extends StatefulWidget {
this.textInputType,
this.textAlign = TextAlign.right,
this.obsecureText = false,
this.autoFocus = false,
}) : super(key: key);
@override
@ -63,6 +65,7 @@ class _DidvanTextFieldState extends State<DidvanTextField> {
border: Border.all(color: _borderColor()),
),
child: TextFormField(
autofocus: widget.autoFocus,
obscureText: _hideContent,
textAlign: widget.textAlign,
keyboardType: widget.textInputType,
@ -71,6 +74,7 @@ class _DidvanTextFieldState extends State<DidvanTextField> {
onChanged: _onChanged,
validator: _validator,
obscuringCharacter: '*',
style: Theme.of(context).textTheme.bodyText1,
decoration: InputDecoration(
suffixIcon: _suffixBuilder(),
enabled: widget.enabled,

View File

@ -121,6 +121,13 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "1.8.0"
pin_code_fields:
dependency: "direct main"
description:
name: pin_code_fields
url: "https://pub.dartlang.org"
source: hosted
version: "7.3.0"
provider:
dependency: "direct main"
description:

View File

@ -37,6 +37,7 @@ dependencies:
# Use with the CupertinoIcons class for iOS style icons.
cupertino_icons: ^1.0.2
provider: ^6.0.1
pin_code_fields: ^7.3.0
dev_dependencies:
flutter_test: