Change Login page UI, add icon, add feature remember me, forgot pass, sign up
This commit is contained in:
parent
c296201017
commit
05ab4c4811
4 changed files with 289 additions and 36 deletions
|
@ -1,8 +1,11 @@
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter/services.dart';
|
||||||
|
import 'package:flutter_launcher_icons_maker/xml_templates.dart';
|
||||||
import 'package:lottie/lottie.dart';
|
import 'package:lottie/lottie.dart';
|
||||||
import 'package:flutter_form_builder/flutter_form_builder.dart';
|
import 'package:flutter_form_builder/flutter_form_builder.dart';
|
||||||
import 'package:nekoya_flutter/api/api.dart';
|
import 'package:nekoya_flutter/api/api.dart';
|
||||||
import 'package:nekoya_flutter/components/login_error.dart';
|
import 'package:nekoya_flutter/components/login_error.dart';
|
||||||
|
import 'package:nekoya_flutter/utils/utils.dart';
|
||||||
|
|
||||||
class LoginForm extends StatefulWidget {
|
class LoginForm extends StatefulWidget {
|
||||||
const LoginForm({Key? key}) : super(key: key);
|
const LoginForm({Key? key}) : super(key: key);
|
||||||
|
@ -14,47 +17,241 @@ class LoginForm extends StatefulWidget {
|
||||||
final _formKey = GlobalKey<FormBuilderState>();
|
final _formKey = GlobalKey<FormBuilderState>();
|
||||||
|
|
||||||
class LoginFormState extends State<LoginForm> {
|
class LoginFormState extends State<LoginForm> {
|
||||||
|
bool _rememberMe = false;
|
||||||
|
|
||||||
|
Widget _buildEmailTF() {
|
||||||
|
return Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: <Widget>[
|
||||||
|
Text(
|
||||||
|
'Email',
|
||||||
|
style: kLabelStyle,
|
||||||
|
),
|
||||||
|
SizedBox(height: 10.0),
|
||||||
|
Container(
|
||||||
|
alignment: Alignment.centerLeft,
|
||||||
|
decoration: kBoxDecorationStyle,
|
||||||
|
height: 60.0,
|
||||||
|
child: TextField(
|
||||||
|
keyboardType: TextInputType.emailAddress,
|
||||||
|
style: TextStyle(
|
||||||
|
color: Colors.white,
|
||||||
|
fontFamily: 'OpenSans',
|
||||||
|
),
|
||||||
|
decoration: InputDecoration(
|
||||||
|
border: InputBorder.none,
|
||||||
|
contentPadding: EdgeInsets.only(top: 14.0),
|
||||||
|
prefixIcon: Icon(
|
||||||
|
Icons.email,
|
||||||
|
color: Colors.white,
|
||||||
|
),
|
||||||
|
hintText: 'Enter yout Email',
|
||||||
|
hintStyle: kHintTextStyle,
|
||||||
|
),
|
||||||
|
))
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildPasswordTF() {
|
||||||
|
return Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: <Widget>[
|
||||||
|
Text(
|
||||||
|
'Password',
|
||||||
|
style: kLabelStyle,
|
||||||
|
),
|
||||||
|
SizedBox(height: 10.0),
|
||||||
|
Container(
|
||||||
|
alignment: Alignment.centerLeft,
|
||||||
|
decoration: kBoxDecorationStyle,
|
||||||
|
height: 60.0,
|
||||||
|
child: TextField(
|
||||||
|
obscureText: true,
|
||||||
|
style: TextStyle(
|
||||||
|
color: Colors.white,
|
||||||
|
fontFamily: 'OpenSans',
|
||||||
|
),
|
||||||
|
decoration: InputDecoration(
|
||||||
|
border: InputBorder.none,
|
||||||
|
contentPadding: EdgeInsets.only(top: 14.0),
|
||||||
|
prefixIcon: Icon(
|
||||||
|
Icons.lock,
|
||||||
|
color: Colors.white,
|
||||||
|
),
|
||||||
|
hintText: 'Enter yout Password',
|
||||||
|
hintStyle: kHintTextStyle,
|
||||||
|
),
|
||||||
|
))
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildForgotPasswordBtn() {
|
||||||
|
return Container(
|
||||||
|
alignment: Alignment.centerRight,
|
||||||
|
child: FlatButton(
|
||||||
|
onPressed: () => print('Forgot Password Button Pressed'),
|
||||||
|
padding: EdgeInsets.only(right: 0.0),
|
||||||
|
child: Text(
|
||||||
|
'Forgot Password?',
|
||||||
|
style: kLabelStyle,
|
||||||
|
),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildRememberMeCheckBox() {
|
||||||
|
return Container(
|
||||||
|
height: 13.0,
|
||||||
|
child: Row(
|
||||||
|
children: <Widget>[
|
||||||
|
Theme(
|
||||||
|
data: ThemeData(unselectedWidgetColor: Colors.white),
|
||||||
|
child: Checkbox(
|
||||||
|
value: _rememberMe,
|
||||||
|
checkColor: Colors.green,
|
||||||
|
activeColor: Colors.white,
|
||||||
|
onChanged: (value) {
|
||||||
|
setState(() {
|
||||||
|
_rememberMe = value!;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
'Remember me',
|
||||||
|
style: kLabelStyle,
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildLoginBtn() {
|
||||||
|
return Container(
|
||||||
|
padding: EdgeInsets.symmetric(vertical: 25.0),
|
||||||
|
width: double.infinity,
|
||||||
|
child: RaisedButton(
|
||||||
|
elevation: 5.0,
|
||||||
|
onPressed: () => print('Login Button Pressed'),
|
||||||
|
padding: EdgeInsets.all(15.0),
|
||||||
|
shape: RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.circular(30.0),
|
||||||
|
),
|
||||||
|
color: const Color(0xff8B0000),
|
||||||
|
child: Text(
|
||||||
|
'LOGIN',
|
||||||
|
style: TextStyle(
|
||||||
|
color: Colors.white,
|
||||||
|
letterSpacing: 1.5,
|
||||||
|
fontSize: 18.0,
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
fontFamily: 'OpenSans',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildSignupBtn() {
|
||||||
|
return GestureDetector(
|
||||||
|
onTap: () => print('Sign Up Button Pressed'),
|
||||||
|
child: RichText(
|
||||||
|
text: TextSpan(
|
||||||
|
children: [
|
||||||
|
TextSpan(
|
||||||
|
text: 'Don\'t have an Account? ',
|
||||||
|
style: TextStyle(
|
||||||
|
color: Colors.white,
|
||||||
|
fontSize: 18.0,
|
||||||
|
fontWeight: FontWeight.w400,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
TextSpan(
|
||||||
|
text: 'Sign Up',
|
||||||
|
style: TextStyle(
|
||||||
|
color: Colors.white,
|
||||||
|
fontSize: 18.0,
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return SafeArea(
|
return SafeArea(
|
||||||
child: Container(
|
child: Container(
|
||||||
margin: const EdgeInsets.fromLTRB(10, 15, 10, 5),
|
margin: const EdgeInsets.fromLTRB(10, 10, 10, 5),
|
||||||
child: Card(
|
child: Card(
|
||||||
color: const Color(0xff212226),
|
color: const Color(0xff212226),
|
||||||
shape: RoundedRectangleBorder(
|
shape: RoundedRectangleBorder(
|
||||||
borderRadius: BorderRadius.circular(15),
|
borderRadius: BorderRadius.circular(15),
|
||||||
),
|
),
|
||||||
child: SingleChildScrollView(
|
child: SingleChildScrollView(
|
||||||
child: Container(
|
child: Container(
|
||||||
transform: Matrix4.translationValues(0, -35, 0),
|
transform: Matrix4.translationValues(0, -35, 0),
|
||||||
padding: const EdgeInsets.fromLTRB(10, 20, 10, 0),
|
padding: const EdgeInsets.fromLTRB(10, 0, 10, 0),
|
||||||
height: MediaQuery.of(context).size.height,
|
height: MediaQuery.of(context).size.height,
|
||||||
width: double.infinity,
|
width: double.infinity,
|
||||||
child: Column(
|
child: Column(
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
Column(
|
Lottie.asset(
|
||||||
children: [
|
"assets/lottieanims/login_form.json",
|
||||||
Column(
|
frameRate: FrameRate.max,
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
alignment: Alignment.center,
|
||||||
children: [
|
fit: BoxFit.fitHeight,
|
||||||
Lottie.asset(
|
height: 250,
|
||||||
"assets/lottieanims/login_form.json",
|
),
|
||||||
frameRate: FrameRate.max,
|
SizedBox(height: 10.0),
|
||||||
alignment: Alignment.center,
|
_buildEmailTF(),
|
||||||
fit: BoxFit.fitHeight,
|
SizedBox(
|
||||||
height: 250,
|
height: 30.0,
|
||||||
),
|
),
|
||||||
],
|
_buildPasswordTF(),
|
||||||
),
|
_buildForgotPasswordBtn(),
|
||||||
Padding(
|
_buildRememberMeCheckBox(),
|
||||||
|
_buildLoginBtn(),
|
||||||
|
_buildSignupBtn(),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Padding(
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 25),
|
padding: const EdgeInsets.symmetric(horizontal: 25),
|
||||||
child: FormBuilder(
|
child: FormBuilder(
|
||||||
key: _formKey,
|
key: _formKey,
|
||||||
child: Column(
|
child: Column(
|
||||||
children: [
|
children: [
|
||||||
makeInput(label: "Email"),
|
TextField(
|
||||||
makeInput(label: "Password", obscureText: true)
|
style: TextStyle(
|
||||||
|
fontSize: 20,
|
||||||
|
fontStyle: FontStyle.italic,
|
||||||
|
color: Colors.white,
|
||||||
|
),
|
||||||
|
decoration: new InputDecoration(
|
||||||
|
hintText: "Enter your email",
|
||||||
|
labelText: "Email",
|
||||||
|
prefixIcon: Icon(Icons.email),
|
||||||
|
labelStyle: new TextStyle(
|
||||||
|
color: const Color(0xFFFFFFFF)),
|
||||||
|
border: new UnderlineInputBorder(
|
||||||
|
borderSide:
|
||||||
|
new BorderSide(color: Colors.red))),
|
||||||
|
),
|
||||||
|
makeInput(
|
||||||
|
label: "Password",
|
||||||
|
obscureText: true,
|
||||||
|
)
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -131,9 +328,9 @@ class LoginFormState extends State<LoginForm> {
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
*/
|
||||||
|
|
||||||
Widget makeInput({label, obscureText = false}) {
|
/* Widget makeInput({label, obscureText = false}) {
|
||||||
return Column(
|
return Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
|
@ -204,3 +401,4 @@ showAlertDialog(BuildContext context) {
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
*/
|
|
@ -1,9 +1,11 @@
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:nekoya_flutter/screens/login.dart';
|
||||||
import 'dart:math' as math;
|
import 'dart:math' as math;
|
||||||
|
|
||||||
import 'package:nekoya_flutter/screens/products.dart';
|
import 'package:nekoya_flutter/screens/products.dart';
|
||||||
import 'package:nekoya_flutter/screens/payment.dart';
|
import 'package:nekoya_flutter/screens/payment.dart';
|
||||||
import 'package:nekoya_flutter/screens/cart.dart';
|
import 'package:nekoya_flutter/screens/cart.dart';
|
||||||
|
import 'package:nekoya_flutter/screens/register.dart';
|
||||||
import 'package:nekoya_flutter/screens/sessions.dart';
|
import 'package:nekoya_flutter/screens/sessions.dart';
|
||||||
import 'package:nekoya_flutter/screens/transactions.dart';
|
import 'package:nekoya_flutter/screens/transactions.dart';
|
||||||
|
|
||||||
|
@ -59,7 +61,7 @@ class _MenuState extends State<Menu> {
|
||||||
setState(() {
|
setState(() {
|
||||||
_selectedIndex = index;
|
_selectedIndex = index;
|
||||||
if (index == 0) {
|
if (index == 0) {
|
||||||
_selectedWidget = const Sessions();
|
_selectedWidget = const Login();
|
||||||
} else if (index == 1) {
|
} else if (index == 1) {
|
||||||
_selectedWidget = const Payment();
|
_selectedWidget = const Payment();
|
||||||
} else if (index == 2) {
|
} else if (index == 2) {
|
||||||
|
@ -67,7 +69,7 @@ class _MenuState extends State<Menu> {
|
||||||
} else if (index == 3) {
|
} else if (index == 3) {
|
||||||
_selectedWidget = const Cart();
|
_selectedWidget = const Cart();
|
||||||
} else if (index == 4) {
|
} else if (index == 4) {
|
||||||
_selectedWidget = const Transactions();
|
_selectedWidget = const Register();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,4 +6,27 @@ class HideScrollGlow extends ScrollBehavior {
|
||||||
BuildContext context, Widget child, ScrollableDetails details) {
|
BuildContext context, Widget child, ScrollableDetails details) {
|
||||||
return child;
|
return child;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final kHintTextStyle = TextStyle(
|
||||||
|
color: Colors.white54,
|
||||||
|
fontFamily: 'OpenSans',
|
||||||
|
);
|
||||||
|
|
||||||
|
final kLabelStyle = TextStyle(
|
||||||
|
color: Colors.white,
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
fontFamily: 'OpenSans',
|
||||||
|
);
|
||||||
|
|
||||||
|
final kBoxDecorationStyle = BoxDecoration(
|
||||||
|
color: Color(0xFF6CA8F1),
|
||||||
|
borderRadius: BorderRadius.circular(10.0),
|
||||||
|
boxShadow: [
|
||||||
|
BoxShadow(
|
||||||
|
color: Colors.black12,
|
||||||
|
blurRadius: 6.0,
|
||||||
|
offset: Offset(0, 2),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
|
30
test/widget_test.dart
Normal file
30
test/widget_test.dart
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
// This is a basic Flutter widget test.
|
||||||
|
//
|
||||||
|
// To perform an interaction with a widget in your test, use the WidgetTester
|
||||||
|
// utility that Flutter provides. For example, you can send tap and scroll
|
||||||
|
// gestures. You can also use WidgetTester to find child widgets in the widget
|
||||||
|
// tree, read text, and verify that the values of widget properties are correct.
|
||||||
|
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
|
|
||||||
|
import 'package:app/main.dart';
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
testWidgets('Counter increments smoke test', (WidgetTester tester) async {
|
||||||
|
// Build our app and trigger a frame.
|
||||||
|
await tester.pumpWidget(const MyApp());
|
||||||
|
|
||||||
|
// Verify that our counter starts at 0.
|
||||||
|
expect(find.text('0'), findsOneWidget);
|
||||||
|
expect(find.text('1'), findsNothing);
|
||||||
|
|
||||||
|
// Tap the '+' icon and trigger a frame.
|
||||||
|
await tester.tap(find.byIcon(Icons.add));
|
||||||
|
await tester.pump();
|
||||||
|
|
||||||
|
// Verify that our counter has incremented.
|
||||||
|
expect(find.text('0'), findsNothing);
|
||||||
|
expect(find.text('1'), findsOneWidget);
|
||||||
|
});
|
||||||
|
}
|
Loading…
Reference in a new issue