diff --git a/android/app/build.gradle b/android/app/build.gradle index 054a98c..52a5999 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -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 diff --git a/lib/config/design_config.dart b/lib/config/design_config.dart index 933c788..a3efd0d 100644 --- a/lib/config/design_config.dart +++ b/lib/config/design_config.dart @@ -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, diff --git a/lib/pages/authentication/authentication.dart b/lib/pages/authentication/authentication.dart index ff1b069..c18eeb0 100644 --- a/lib/pages/authentication/authentication.dart +++ b/lib/pages/authentication/authentication.dart @@ -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 { final List _pages = const [ PhoneNumberInput(), PasswordInput(), + Verification(), ]; @override @@ -34,149 +32,3 @@ class _AuthenticationState extends State { ); } } - -class PhoneNumberInput extends StatelessWidget { - const PhoneNumberInput({ - Key? key, - }) : super(key: key); - - @override - Widget build(BuildContext context) { - final AuthenticationState state = context.read(); - 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(); - 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, - ), - ], - ), - ), - ); - } -} diff --git a/lib/pages/authentication/authentication_state.dart b/lib/pages/authentication/authentication_state.dart index d3975e7..395288c 100644 --- a/lib/pages/authentication/authentication_state.dart +++ b/lib/pages/authentication/authentication_state.dart @@ -4,6 +4,7 @@ class AuthenticationState extends CoreProvier { int _currentPageIndex = 0; String phoneNumber = ''; String password = ''; + String verificationCode = ''; set currentPageIndex(int value) { _currentPageIndex = value; diff --git a/lib/pages/authentication/screens/password.dart b/lib/pages/authentication/screens/password.dart new file mode 100644 index 0000000..9a6d1c0 --- /dev/null +++ b/lib/pages/authentication/screens/password.dart @@ -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(); + 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, + ), + ], + ), + ), + ); + } +} diff --git a/lib/pages/authentication/screens/phone_number.dart b/lib/pages/authentication/screens/phone_number.dart new file mode 100644 index 0000000..5e848c9 --- /dev/null +++ b/lib/pages/authentication/screens/phone_number.dart @@ -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(); + 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, + ), + ], + ), + ), + ); + } +} diff --git a/lib/pages/authentication/screens/verification.dart b/lib/pages/authentication/screens/verification.dart new file mode 100644 index 0000000..a60c7f5 --- /dev/null +++ b/lib/pages/authentication/screens/verification.dart @@ -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(); + 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, + ), + ], + ), + ), + ); + } +} diff --git a/lib/pages/authentication/widgets/authentication_app_bar.dart b/lib/pages/authentication/widgets/authentication_app_bar.dart index 844a8ea..3361f0f 100644 --- a/lib/pages/authentication/widgets/authentication_app_bar.dart +++ b/lib/pages/authentication/widgets/authentication_app_bar.dart @@ -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().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, + ) ], ), ); diff --git a/lib/widgets/didvan/text_field.dart b/lib/widgets/didvan/text_field.dart index 732e3c4..02e141e 100644 --- a/lib/widgets/didvan/text_field.dart +++ b/lib/widgets/didvan/text_field.dart @@ -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 { 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 { onChanged: _onChanged, validator: _validator, obscuringCharacter: '*', + style: Theme.of(context).textTheme.bodyText1, decoration: InputDecoration( suffixIcon: _suffixBuilder(), enabled: widget.enabled, diff --git a/pubspec.lock b/pubspec.lock index 4b8b781..b3e8f86 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -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: diff --git a/pubspec.yaml b/pubspec.yaml index d429595..ecd8d13 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -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: