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 { defaultConfig {
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
applicationId "com.didvan.didvanapp" applicationId "com.didvan.didvanapp"
minSdkVersion 16 minSdkVersion 18
targetSdkVersion 30 targetSdkVersion 30
versionCode flutterVersionCode.toInteger() versionCode flutterVersionCode.toInteger()
versionName flutterVersionName versionName flutterVersionName

View File

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

View File

@ -1,11 +1,8 @@
import 'package:didvan/config/design_config.dart'; import 'package:didvan/config/design_config.dart';
import 'package:didvan/pages/authentication/authentication_state.dart'; import 'package:didvan/pages/authentication/authentication_state.dart';
import 'package:didvan/pages/authentication/widgets/authentication_app_bar.dart'; import 'package:didvan/pages/authentication/screens/password.dart';
import 'package:didvan/widgets/didvan/button.dart'; import 'package:didvan/pages/authentication/screens/phone_number.dart';
import 'package:didvan/widgets/didvan/text.dart'; import 'package:didvan/pages/authentication/screens/verification.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:flutter/material.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
@ -20,6 +17,7 @@ class _AuthenticationState extends State<Authentication> {
final List<Widget> _pages = const [ final List<Widget> _pages = const [
PhoneNumberInput(), PhoneNumberInput(),
PasswordInput(), PasswordInput(),
Verification(),
]; ];
@override @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; int _currentPageIndex = 0;
String phoneNumber = ''; String phoneNumber = '';
String password = ''; String password = '';
String verificationCode = '';
set currentPageIndex(int value) { set currentPageIndex(int value) {
_currentPageIndex = 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/pages/authentication/authentication_state.dart';
import 'package:didvan/widgets/didvan/text.dart'; import 'package:didvan/widgets/didvan/text.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
@ -17,12 +18,18 @@ class AuthenticationAppBar extends StatelessWidget {
onTap: () => context.read<AuthenticationState>().currentPageIndex--, onTap: () => context.read<AuthenticationState>().currentPageIndex--,
child: const Icon( child: const Icon(
Icons.arrow_back, Icons.arrow_back,
color: DesignConfig.darkPrimaryColor2,
), ),
), ),
const SizedBox( const SizedBox(
width: 20, 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 { class DidvanTextField extends StatefulWidget {
final void Function(String value)? onChanged; final void Function(String value)? onChanged;
final bool enabled; final bool enabled;
final bool autoFocus;
final TextAlign textAlign; final TextAlign textAlign;
final String? title; final String? title;
final String? hintText; final String? hintText;
@ -23,6 +24,7 @@ class DidvanTextField extends StatefulWidget {
this.textInputType, this.textInputType,
this.textAlign = TextAlign.right, this.textAlign = TextAlign.right,
this.obsecureText = false, this.obsecureText = false,
this.autoFocus = false,
}) : super(key: key); }) : super(key: key);
@override @override
@ -63,6 +65,7 @@ class _DidvanTextFieldState extends State<DidvanTextField> {
border: Border.all(color: _borderColor()), border: Border.all(color: _borderColor()),
), ),
child: TextFormField( child: TextFormField(
autofocus: widget.autoFocus,
obscureText: _hideContent, obscureText: _hideContent,
textAlign: widget.textAlign, textAlign: widget.textAlign,
keyboardType: widget.textInputType, keyboardType: widget.textInputType,
@ -71,6 +74,7 @@ class _DidvanTextFieldState extends State<DidvanTextField> {
onChanged: _onChanged, onChanged: _onChanged,
validator: _validator, validator: _validator,
obscuringCharacter: '*', obscuringCharacter: '*',
style: Theme.of(context).textTheme.bodyText1,
decoration: InputDecoration( decoration: InputDecoration(
suffixIcon: _suffixBuilder(), suffixIcon: _suffixBuilder(),
enabled: widget.enabled, enabled: widget.enabled,

View File

@ -121,6 +121,13 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.8.0" 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: provider:
dependency: "direct main" dependency: "direct main"
description: description:

View File

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