Commit 5d73fef8 by Rizal Hermawan

feat (login): implementation of the login page of the json component using the…

feat (login): implementation of the login page of the json component using the widgetparser package, REST API, json schema validator, and state rebuilder package. Story #1

there are still bugs that need to be fixed. bugs related to the state rebuilder, one of which is the validator textfield.
parent f0064b8a
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
# #
# For more info see: https://dart.dev/go/dot-packages-deprecation # For more info see: https://dart.dev/go/dot-packages-deprecation
# #
# Generated by pub on 2021-06-23 14:29:28.997524. # Generated by pub on 2021-06-28 17:34:00.086929.
async:file:///D:/flutter/2.0.4-stable/.pub-cache/hosted/pub.dartlang.org/async-2.5.0/lib/ async:file:///D:/flutter/2.0.4-stable/.pub-cache/hosted/pub.dartlang.org/async-2.5.0/lib/
boolean_selector:file:///D:/flutter/2.0.4-stable/.pub-cache/hosted/pub.dartlang.org/boolean_selector-2.1.0/lib/ boolean_selector:file:///D:/flutter/2.0.4-stable/.pub-cache/hosted/pub.dartlang.org/boolean_selector-2.1.0/lib/
characters:file:///D:/flutter/2.0.4-stable/.pub-cache/hosted/pub.dartlang.org/characters-1.1.0/lib/ characters:file:///D:/flutter/2.0.4-stable/.pub-cache/hosted/pub.dartlang.org/characters-1.1.0/lib/
......
...@@ -4,8 +4,7 @@ ...@@ -4,8 +4,7 @@
"name": "Flutter", "name": "Flutter",
"program": "example/lib/main.dart", "program": "example/lib/main.dart",
"request": "launch", "request": "launch",
"type": "dart", "type": "dart"
"args": ["--no-sound-null-safety"]
} }
] ]
} }
\ No newline at end of file
## 0.0.8 - 2021-06-06
### feat (login): implementation of the login page of the json component using the widgetparser package, REST API, json schema validator, and state rebuilder package.
* there are still bugs that need to be fixed. bugs related to the state rebuilder, one of which is the validator textfield.
## 0.0.5 - 2021-06-06 ## 0.0.5 - 2021-06-06
### feat (ui component): add and implemet carousel, toggle and toast components. ### feat (ui component): add and implemet carousel, toggle and toast components.
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
# #
# For more info see: https://dart.dev/go/dot-packages-deprecation # For more info see: https://dart.dev/go/dot-packages-deprecation
# #
# Generated by pub on 2021-06-23 15:35:44.277132. # Generated by pub on 2021-06-28 19:37:02.142195.
args:file:///D:/flutter/2.0.4-stable/.pub-cache/hosted/pub.dartlang.org/args-2.1.1/lib/ args:file:///D:/flutter/2.0.4-stable/.pub-cache/hosted/pub.dartlang.org/args-2.1.1/lib/
async:file:///D:/flutter/2.0.4-stable/.pub-cache/hosted/pub.dartlang.org/async-2.5.0/lib/ async:file:///D:/flutter/2.0.4-stable/.pub-cache/hosted/pub.dartlang.org/async-2.5.0/lib/
bloc:file:///D:/flutter/2.0.4-stable/.pub-cache/hosted/pub.dartlang.org/bloc-7.0.0/lib/ bloc:file:///D:/flutter/2.0.4-stable/.pub-cache/hosted/pub.dartlang.org/bloc-7.0.0/lib/
...@@ -22,7 +22,6 @@ flutter:file:///D:/flutter/2.0.4-stable/packages/flutter/lib/ ...@@ -22,7 +22,6 @@ flutter:file:///D:/flutter/2.0.4-stable/packages/flutter/lib/
flutter_bloc:file:///D:/flutter/2.0.4-stable/.pub-cache/hosted/pub.dartlang.org/flutter_bloc-7.0.1/lib/ flutter_bloc:file:///D:/flutter/2.0.4-stable/.pub-cache/hosted/pub.dartlang.org/flutter_bloc-7.0.1/lib/
flutter_sequence_animation_null_safety:file:///D:/flutter/2.0.4-stable/.pub-cache/git/flutter_sequence_animation_null_safety-773d67311fed31fae22214b385265ae275854495/lib/ flutter_sequence_animation_null_safety:file:///D:/flutter/2.0.4-stable/.pub-cache/git/flutter_sequence_animation_null_safety-773d67311fed31fae22214b385265ae275854495/lib/
flutter_test:file:///D:/flutter/2.0.4-stable/packages/flutter_test/lib/ flutter_test:file:///D:/flutter/2.0.4-stable/packages/flutter_test/lib/
flutter_user_agent:file:///D:/flutter/2.0.4-stable/.pub-cache/hosted/pub.dartlang.org/flutter_user_agent-1.2.2/lib/
flutter_web_plugins:file:///D:/flutter/2.0.4-stable/packages/flutter_web_plugins/lib/ flutter_web_plugins:file:///D:/flutter/2.0.4-stable/packages/flutter_web_plugins/lib/
fluttertoast:file:///D:/flutter/2.0.4-stable/.pub-cache/hosted/pub.dartlang.org/fluttertoast-8.0.7/lib/ fluttertoast:file:///D:/flutter/2.0.4-stable/.pub-cache/hosted/pub.dartlang.org/fluttertoast-8.0.7/lib/
font_awesome_flutter:file:///D:/flutter/2.0.4-stable/.pub-cache/hosted/pub.dartlang.org/font_awesome_flutter-9.0.0/lib/ font_awesome_flutter:file:///D:/flutter/2.0.4-stable/.pub-cache/hosted/pub.dartlang.org/font_awesome_flutter-9.0.0/lib/
......
...@@ -2,7 +2,8 @@ ...@@ -2,7 +2,8 @@
package="com.demo_package_ui_semantic"> package="com.demo_package_ui_semantic">
<application <application
android:label="Demo Package UI Semantic" android:label="Demo Package UI Semantic"
android:icon="@mipmap/ic_launcher"> android:icon="@mipmap/ic_launcher"
android:usesCleartextTraffic="true">
<activity <activity
android:name=".MainActivity" android:name=".MainActivity"
android:launchMode="singleTop" android:launchMode="singleTop"
......
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:fluttertoast/fluttertoast.dart'; import 'package:fluttertoast/fluttertoast.dart';
// ignore: import_of_legacy_library_into_null_safe
import 'package:flutter_user_agent/flutter_user_agent.dart';
import 'package:llswidget/llswidget.dart'; import 'package:llswidget/llswidget.dart';
......
...@@ -100,13 +100,13 @@ showToastWidget( ...@@ -100,13 +100,13 @@ showToastWidget(
); );
} }
Future<String> initUserAgentState() async { // Future<String> initUserAgentState() async {
String userAgent; // String userAgent;
try { // try {
userAgent = await FlutterUserAgent.getPropertyAsync('userAgent'); // userAgent = await FlutterUserAgent.getPropertyAsync('userAgent');
await FlutterUserAgent.init(); // await FlutterUserAgent.init();
} on PlatformException { // } on PlatformException {
userAgent = '<error>'; // userAgent = '<error>';
} // }
return userAgent; // return userAgent;
} // }
\ No newline at end of file \ No newline at end of file
...@@ -2,7 +2,6 @@ import 'package:flutter/material.dart'; ...@@ -2,7 +2,6 @@ import 'package:flutter/material.dart';
import 'package:responsive_framework/responsive_framework.dart'; import 'package:responsive_framework/responsive_framework.dart';
import 'package:states_rebuilder/states_rebuilder.dart'; import 'package:states_rebuilder/states_rebuilder.dart';
import 'package:demo_package_ui_semantic/data_source/hive_storage.dart'; import 'package:demo_package_ui_semantic/data_source/hive_storage.dart';
import 'route_generator.dart';
import 'ui/pages/pages.dart'; import 'ui/pages/pages.dart';
void main() async { void main() async {
...@@ -12,6 +11,7 @@ void main() async { ...@@ -12,6 +11,7 @@ void main() async {
print("Error : ${details.exception}"); print("Error : ${details.exception}");
print("StackTrace : ${details.stack}"); print("StackTrace : ${details.stack}");
}; };
RM.navigate.transitionsBuilder = RM.transitions.bottomToUp();
runApp(MyApp()); runApp(MyApp());
} }
...@@ -58,7 +58,7 @@ class MyApp extends StatelessWidget { ...@@ -58,7 +58,7 @@ class MyApp extends StatelessWidget {
), ),
home: On.auth( home: On.auth(
onInitialWaiting: () => Center(child: CircularProgressIndicator()), onInitialWaiting: () => Center(child: CircularProgressIndicator()),
onUnsigned: () => LoginPage(), onUnsigned: () => LoginDynamicPage(),
onSigned: () => MainPage(), onSigned: () => MainPage(),
).listenTo( ).listenTo(
user, user,
...@@ -68,7 +68,7 @@ class MyApp extends StatelessWidget { ...@@ -68,7 +68,7 @@ class MyApp extends StatelessWidget {
onGenerateRoute: RM.navigate.onGenerateRoute( onGenerateRoute: RM.navigate.onGenerateRoute(
{ {
MainPage.routeName: (_) => MainPage(), MainPage.routeName: (_) => MainPage(),
LoginPage.routeName: (_) => LoginPage(), LoginDynamicPage.routeName: (_) => LoginDynamicPage(),
ButtonsPage.routeName: (_) => ButtonsPage(), ButtonsPage.routeName: (_) => ButtonsPage(),
StandardsButtonPage.routeName: (_) => StandardsButtonPage(), StandardsButtonPage.routeName: (_) => StandardsButtonPage(),
LabelPage.routeName: (_) => LabelPage(), LabelPage.routeName: (_) => LabelPage(),
......
...@@ -11,12 +11,10 @@ class AuthRepository implements IAuth<AuthModel?, LoginParam> { ...@@ -11,12 +11,10 @@ class AuthRepository implements IAuth<AuthModel?, LoginParam> {
Future<AuthModel?> signIn(LoginParam? param) async { Future<AuthModel?> signIn(LoginParam? param) async {
AuthModel auth; AuthModel auth;
String url = '${SharedValue.api}/login/store'; String url = '${SharedValue.api}/login/store';
String userAgent = await initUserAgentState(); // String userAgent = await initUserAgentState();
var response = await http.post(Uri.parse(url), body: { var response = await http.post(Uri.parse(url), body: {
"email": param!.email, "email": param!.email,
"password": param.password "password": param.password
}, headers: {
"User-Agent" : userAgent
}); });
if (response.statusCode == 200) { if (response.statusCode == 200) {
auth = AuthModel.fromJson(response.body); auth = AuthModel.fromJson(response.body);
...@@ -34,11 +32,9 @@ class AuthRepository implements IAuth<AuthModel?, LoginParam> { ...@@ -34,11 +32,9 @@ class AuthRepository implements IAuth<AuthModel?, LoginParam> {
@override @override
Future<String> signOut(LoginParam? param) async { Future<String> signOut(LoginParam? param) async {
String url = '${SharedValue.api}/logout?token=${param!.token}'; String url = '${SharedValue.api}/logout?token=${param!.token}';
String userAgent = await initUserAgentState(); // String userAgent = await initUserAgentState();
var response = await http.post(Uri.parse(url), body: { var response = await http.post(Uri.parse(url), body: {
"userId": param.userId.toString() "userId": param.userId.toString()
}, headers: {
"User-Agent" : userAgent
}); });
if (response.statusCode == 200) { if (response.statusCode == 200) {
return '200'; return '200';
......
import 'package:flutter/material.dart';
import 'package:llswidget/llswidget.dart';
import 'ui/pages/pages.dart';
class RouteGenerator {
static Route<dynamic> generateRoute(RouteSettings settings) {
//final args = settings.arguments;
switch (settings.name) {
case MainPage.routeName:
return MaterialPageRoute(builder: (_) => MainPage());
case ButtonsPage.routeName:
return MaterialPageRoute(builder: (_) => ButtonsPage());
case StandardsButtonPage.routeName:
return MaterialPageRoute(builder: (_) => StandardsButtonPage());
case LabelPage.routeName:
return MaterialPageRoute(builder: (_) => LabelPage());
case TilesPage.routeName:
return MaterialPageRoute(builder: (_) => TilesPage());
case RoundedButtonPage.routeName:
return MaterialPageRoute(builder: (_) => RoundedButtonPage());
case SquareButtonPage.routeName:
return MaterialPageRoute(builder: (_) => SquareButtonPage());
case ButtonsPageDynamic.routeName:
return MaterialPageRoute(builder: (_) => ButtonsPageDynamic());
case AccordionPage.routeName:
return MaterialPageRoute(builder: (_) => AccordionPage());
case AlertPage.routeName:
return MaterialPageRoute(builder: (_) => AlertPage());
case AppbarHomePage.routeName:
return MaterialPageRoute(builder: (_) => AppbarHomePage());
case AvatarPage.routeName:
return MaterialPageRoute(builder: (_) => AvatarPage());
case BadgesPage.routeName:
return MaterialPageRoute(builder: (_) => BadgesPage());
case IconsButtonsPage.routeName:
return MaterialPageRoute(builder: (_) => IconsButtonsPage());
case CardPage.routeName:
return MaterialPageRoute(builder: (_) => CardPage());
case TestStatePage.routeName:
return MaterialPageRoute(builder: (_) => TestStatePage());
case TabsPage.routeName:
return MaterialPageRoute(builder: (_) => TabsPage());
case SegmentedTabPage.routeName:
return MaterialPageRoute(builder: (_) => SegmentedTabPage());
case IconTabPage.routeName:
return MaterialPageRoute(builder: (_) => IconTabPage());
case LabeledTabPage.routeName:
return MaterialPageRoute(builder: (_) => LabeledTabPage());
case BottomIconTabPage.routeName:
return MaterialPageRoute(builder: (_) => BottomIconTabPage());
case BottomLabeledTabPage.routeName:
return MaterialPageRoute(builder: (_) => BottomLabeledTabPage());
case CarouselPage.routeName:
return MaterialPageRoute(builder: (_) => CarouselPage());
case ToastPage.routeName:
return MaterialPageRoute(builder: (_) => ToastPage());
case TogglePage.routeName:
return MaterialPageRoute(builder: (_) => TogglePage());
default:
// If there is no such named route in the switch statement
return MaterialPageRoute(builder: (context) {
return Scaffold(
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Text(
'In Progress. Sabar yah :)',
style: TextStyle(fontSize: 20),
),
const SizedBox(
height: 15
),
LLSButton(
onPressed: () {
Navigator.of(context).pop();
},
child: const Text(
'Back',
style: TextStyle(fontSize: 16),
),
type: LLSButtonType.outline,
color: LLSColors.SUCCESS,
),
]
),
)
);
});
}
}
}
part of '../pages.dart';
final user = RM.injectAuth<AuthModel?, LoginParam>(
() => AuthRepository(),
persist: () => PersistState<AuthModel?>(
key: '__AuthModel__',
toJson: (user) => user!.toJson(),
fromJson: (json) {
final user = AuthModel.fromJson(json);
return user.data!.token != null ? user : null;
},
debugPrintOperations: true,
),
autoSignOut: (user) {
if (user!.data == null) {
return Duration(seconds: 5);
}
return Duration(days: 3);
},
onSetState: On.error(
(error, refresh) {
String err = checkError(error.toString());
showToastWidget(
err,
duration: 'long'
);
},
),
);
final RegExp _passwordRegExp = RegExp(
r'^(?=.*[A-Za-z])(?=.*\d)[A-Za-z\d]{8,}$',
);
final RegExp _emailRegExp = RegExp(
r'^[a-zA-Z0-9.!#$%&’*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$',
);
final _email = RM.injectTextEditing(
validator: (email) {
if (!_emailRegExp.hasMatch(email!)) {
return "Enter a valid email";
}
},
);
final _password = RM.injectTextEditing(
validateOnTyping: true,
validator: (password) {
if (password!.length < 4) {
return "Enter a valid password";
}
},
);
final _form = RM.injectForm(
submit: () async {
await user.auth.signIn(
(_) => LoginParam(
email: _email.text,
password: _password.text,
),
onError: (error, refresh) {
showToastWidget(
error.message,
duration: 'long'
);
}
);
if (user.error != null) {
showToastWidget(
user.error.message,
duration: 'long'
);
}
},
);
class AuthException implements Exception {
final String message;
AuthException(this.message);
}
class LoginDynamicPage extends StatefulWidget {
const LoginDynamicPage({Key? key}) : super(key: key);
static const routeName = '/login_dynamic_page';
@override
_LoginDynamicPageState createState() => _LoginDynamicPageState();
}
class _LoginDynamicPageState extends State<LoginDynamicPage> {
Map<String, dynamic> variables = {
"listenToFormState": _form,
"emailFieldKey": Key('__EmailField__'),
"emailController": _email.controller,
"emailFocusNode": _email.focusNode,
"emailErrorText": _email.error,
"passwordFieldKey": Key('__PasswordField__'),
"passwordController": _password.controller,
"passwordFocusNode": _password.focusNode,
"passwordErrorText": _password.error,
"submitFocusNode": _form.submitFocusNode
};
final pageJson = '''
{
"widget": "Scaffold",
"body": {
"widget": "Padding",
"padding": "10.0,10.0,10.0,10.0",
"child": {
"widget": "Onform",
"child": {
"widget": "Column",
"mainAxisAlignment": "center",
"crossAxisAlignment": "stretch",
"children": [
{
"widget": "TextField",
"key": "emailFieldKey",
"controller": "emailController",
"focusNode": "emailFocusNode",
"decoration": {
"icon": {
"widget": "Icon",
"data": "email"
},
"labelText": "Email",
"errorText": "emailErrorText"
},
"keyboardType": "emailAddress",
"autocorrect": false,
"onSubmitted": {
"function": "emailOnSubmitted"
}
},
{
"widget": "TextField",
"key": "passwordFieldKey",
"controller": "passwordController",
"focusNode": "passwordFocusNode",
"decoration": {
"icon": {
"widget": "Icon",
"data": "lock"
},
"labelText": "Password",
"errorText": "passwordErrorText"
},
"obscureText": true,
"autocorrect": false,
"onSubmitted": {
"function": "passwordOnSubmitted"
}
},
{
"widget": "SizedBox",
"height": 10.0
},
{
"widget": "OnformSubmission",
"onSubmitting": {
"widget": "Center",
"child": {
"widget": "CircularProgressIndicator"
}
},
"child": {
"widget": "LLSButton",
"size": "small",
"text": "Sign In",
"textColor": "lls_white",
"onPressed": {
"function": "submitOnPressed"
}
},
"state": "listenToFormState"
},
{
"widget": "SizedBox",
"height": 10.0
}
]
},
"state": "listenToFormState"
}
}
}
''';
Widget _buildErrorPage(String error, BuildContext context) {
return Scaffold(
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
error,
style: TextStyle(fontSize: 14),
),
),
const SizedBox(
height: 15
),
LLSButton(
onPressed: () {
Navigator.of(context).pop();
},
child: const Text(
'Back',
style: TextStyle(fontSize: 16),
),
type: LLSButtonType.outline,
color: LLSColors.SUCCESS,
),
]
),
)
);
}
Future<Widget?> _buildWidget(BuildContext context) async {
try {
return WidgetParserBuilder.build(pageJson, context, LoginPageMethodListener(), variables);
} catch (e) {
String err = e.toString();
return _buildErrorPage(err, context);
}
}
@override
Widget build(BuildContext context) {
return FutureBuilder<Widget?>(
future: _buildWidget(context),
builder: (BuildContext context, AsyncSnapshot<Widget?> snapshot) {
if (snapshot.hasError) {
return _buildErrorPage(snapshot.error.toString(), context);
}
return snapshot.hasData ? snapshot.data! : Scaffold(
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
CircularProgressIndicator()
]
),
)
);
},
);
}
}
class LoginPageMethodListener extends MethodListener {
@override
run(BuildContext context, Map<String, dynamic>? event) {
if (isFunctionNameExist(event)) {
if (event!['function'] == 'emailOnSubmitted') {
_password.focusNode.requestFocus();
} else if (event['function'] == 'passwordOnSubmitted') {
_form.submitFocusNode.requestFocus();
} else if (event['function'] == 'submitOnPressed') {
_form.submit();
}
} else {
print("receiver event: ${event.toString()}");
}
}
}
\ No newline at end of file
part of '../pages.dart'; // part of '../pages.dart';
final user = RM.injectAuth<AuthModel?, LoginParam>( // final user = RM.injectAuth<AuthModel?, LoginParam>(
() => AuthRepository(), // () => AuthRepository(),
persist: () => PersistState<AuthModel?>( // persist: () => PersistState<AuthModel?>(
key: '__AuthModel__', // key: '__AuthModel__',
toJson: (user) => user!.toJson(), // toJson: (user) => user!.toJson(),
fromJson: (json) { // fromJson: (json) {
final user = AuthModel.fromJson(json); // final user = AuthModel.fromJson(json);
return user.data!.token != null ? user : null; // return user.data!.token != null ? user : null;
}, // },
debugPrintOperations: true, // debugPrintOperations: true,
), // ),
autoSignOut: (user) { // autoSignOut: (user) {
if (user!.data == null) { // if (user!.data == null) {
return Duration(seconds: 5); // return Duration(seconds: 5);
} // }
return Duration(days: 3); // return Duration(days: 3);
}, // },
onSetState: On.error( // onSetState: On.error(
(error, refresh) { // (error, refresh) {
String err = checkError(error.toString()); // String err = checkError(error.toString());
showToastWidget( // showToastWidget(
err, // err,
duration: 'long' // duration: 'long'
); // );
}, // },
), // ),
); // );
final RegExp _passwordRegExp = RegExp( // final RegExp _passwordRegExp = RegExp(
r'^(?=.*[A-Za-z])(?=.*\d)[A-Za-z\d]{8,}$', // r'^(?=.*[A-Za-z])(?=.*\d)[A-Za-z\d]{8,}$',
); // );
final RegExp _emailRegExp = RegExp( // final RegExp _emailRegExp = RegExp(
r'^[a-zA-Z0-9.!#$%&’*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$', // r'^[a-zA-Z0-9.!#$%&’*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$',
); // );
final _email = RM.injectTextEditing( // final _email = RM.injectTextEditing(
validator: (email) { // validator: (email) {
if (!_emailRegExp.hasMatch(email!)) { // if (!_emailRegExp.hasMatch(email!)) {
return "Enter a valid email"; // return "Enter a valid email";
} // }
}, // },
); // );
final _password = RM.injectTextEditing( // final _password = RM.injectTextEditing(
validateOnTyping: true, // validateOnTyping: true,
validator: (password) { // validator: (password) {
if (password!.length < 4) { // if (password!.length < 4) {
return "Enter a valid password"; // return "Enter a valid password";
} // }
}, // },
); // );
final _form = RM.injectForm( // final _form = RM.injectForm(
submit: () async { // submit: () async {
await user.auth.signIn( // await user.auth.signIn(
(_) => LoginParam( // (_) => LoginParam(
email: _email.text, // email: _email.text,
password: _password.text, // password: _password.text,
), // ),
onError: (error, refresh) { // onError: (error, refresh) {
showToastWidget( // showToastWidget(
error.message, // error.message,
duration: 'long' // duration: 'long'
); // );
} // }
); // );
if (user.error != null) { // if (user.error != null) {
showToastWidget( // showToastWidget(
user.error.message, // user.error.message,
duration: 'long' // duration: 'long'
); // );
} // }
}, // },
); // );
class AuthException implements Exception { // class AuthException implements Exception {
final String message; // final String message;
AuthException(this.message); // AuthException(this.message);
} // }
class LoginPage extends StatelessWidget { // class LoginPage extends StatelessWidget {
const LoginPage({Key? key}) : super(key: key); // const LoginPage({Key? key}) : super(key: key);
static const routeName = '/login_page'; // static const routeName = '/login_page';
@override // @override
Widget build(BuildContext context) { // Widget build(BuildContext context) {
return Scaffold( // return Scaffold(
body: Padding( // body: Padding(
padding: EdgeInsets.all(10), // padding: EdgeInsets.all(10),
child: On.form( // child: On.form(
() => Column( // () => Column(
mainAxisAlignment: MainAxisAlignment.center, // mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.stretch, // crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[ // children: <Widget>[
TextField( // TextField(
key: Key('__EmailField__'), // key: Key('__EmailField__'),
controller: _email.controller, // controller: _email.controller,
focusNode: _email.focusNode, // focusNode: _email.focusNode,
decoration: InputDecoration( // decoration: InputDecoration(
icon: Icon(Icons.email), // icon: Icon(Icons.email),
labelText: "Email", // labelText: "Email",
errorText: _email.error, // errorText: _email.error,
), // ),
keyboardType: TextInputType.emailAddress, // keyboardType: TextInputType.emailAddress,
autocorrect: false, // autocorrect: false,
onSubmitted: (_) { // onSubmitted: (_) {
_password.focusNode.requestFocus(); // _password.focusNode.requestFocus();
}, // },
), // ),
TextField( // TextField(
key: Key('__PasswordField__'), // key: Key('__PasswordField__'),
controller: _password.controller, // controller: _password.controller,
focusNode: _password.focusNode, // focusNode: _password.focusNode,
decoration: InputDecoration( // decoration: InputDecoration(
icon: Icon(Icons.lock), // icon: Icon(Icons.lock),
labelText: "Password", // labelText: "Password",
errorText: _password.error, // errorText: _password.error,
), // ),
obscureText: true, // obscureText: true,
autocorrect: false, // autocorrect: false,
onSubmitted: (_) { // onSubmitted: (_) {
_form.submitFocusNode.requestFocus(); // _form.submitFocusNode.requestFocus();
}, // },
), // ),
SizedBox(height: 10), // SizedBox(height: 10),
On.formSubmission( // On.formSubmission(
onSubmitting: () => const Center( // onSubmitting: () => const Center(
child: CircularProgressIndicator(), // child: CircularProgressIndicator(),
), // ),
child: ElevatedButton( // child: ElevatedButton(
focusNode: _form.submitFocusNode, // focusNode: _form.submitFocusNode,
child: Text("Sign in"), // child: Text("Sign in"),
onPressed: _form.submit, // onPressed: _form.submit,
), // ),
).listenTo(_form), // ).listenTo(_form),
SizedBox(height: 10), // SizedBox(height: 10),
SelectableText("email : ${SharedValue.email}"), // SelectableText("email : ${SharedValue.email}"),
SelectableText("password : ${SharedValue.password}"), // SelectableText("password : ${SharedValue.password}"),
], // ],
), // ),
).listenTo(_form) // ).listenTo(_form)
) // )
); // );
} // }
} // }
\ No newline at end of file \ No newline at end of file
...@@ -37,4 +37,5 @@ part 'tabs_page/bottom_labeled_tab_page.dart'; ...@@ -37,4 +37,5 @@ part 'tabs_page/bottom_labeled_tab_page.dart';
part 'carousel_page.dart'; part 'carousel_page.dart';
part 'toast_page.dart'; part 'toast_page.dart';
part 'toggle_page.dart'; part 'toggle_page.dart';
part 'auth/login_page.dart'; //part 'auth/login_page.dart';
\ No newline at end of file part 'auth/login_dynamic_page.dart';
\ No newline at end of file
...@@ -44,7 +44,7 @@ class _TilesPageState extends State<TilesPage> { ...@@ -44,7 +44,7 @@ class _TilesPageState extends State<TilesPage> {
LLSCard( LLSCard(
content: LLSListTile( content: LLSListTile(
titleText: 'Title', titleText: 'Title',
subTitleText: 'Open source UI library', subTitleText: 'PT Locator Logic Solutions',
icon: Icon(Icons.favorite), icon: Icon(Icons.favorite),
), ),
), ),
...@@ -73,7 +73,7 @@ class _TilesPageState extends State<TilesPage> { ...@@ -73,7 +73,7 @@ class _TilesPageState extends State<TilesPage> {
shape: LLSAvatarShape.circle, shape: LLSAvatarShape.circle,
), ),
titleText: 'Title', titleText: 'Title',
subTitleText: 'Open source UI library', subTitleText: 'PT Locator Logic Solutions',
), ),
), ),
const LLSCard( const LLSCard(
......
...@@ -125,13 +125,6 @@ packages: ...@@ -125,13 +125,6 @@ packages:
description: flutter description: flutter
source: sdk source: sdk
version: "0.0.0" version: "0.0.0"
flutter_user_agent:
dependency: "direct main"
description:
name: flutter_user_agent
url: "https://pub.dartlang.org"
source: hosted
version: "1.2.2"
flutter_web_plugins: flutter_web_plugins:
dependency: transitive dependency: transitive
description: flutter description: flutter
...@@ -213,7 +206,7 @@ packages: ...@@ -213,7 +206,7 @@ packages:
path: ".." path: ".."
relative: true relative: true
source: path source: path
version: "0.0.5" version: "0.0.8"
logging: logging:
dependency: transitive dependency: transitive
description: description:
...@@ -360,7 +353,7 @@ packages: ...@@ -360,7 +353,7 @@ packages:
source: hosted source: hosted
version: "1.10.0" version: "1.10.0"
states_rebuilder: states_rebuilder:
dependency: "direct main" dependency: transitive
description: description:
name: states_rebuilder name: states_rebuilder
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
...@@ -428,7 +421,7 @@ packages: ...@@ -428,7 +421,7 @@ packages:
path: "../../widgetparser" path: "../../widgetparser"
relative: true relative: true
source: path source: path
version: "0.0.1" version: "0.0.6"
win32: win32:
dependency: transitive dependency: transitive
description: description:
......
...@@ -31,9 +31,7 @@ dependencies: ...@@ -31,9 +31,7 @@ dependencies:
flutter_bloc: 7.0.1 flutter_bloc: 7.0.1
equatable: 1.1.1 equatable: 1.1.1
http: 0.13.0 http: 0.13.0
states_rebuilder: 4.3.0
fluttertoast: 8.0.7 fluttertoast: 8.0.7
flutter_user_agent: 1.2.2
hive: 2.0.4 hive: 2.0.4
hive_flutter: 1.1.0 hive_flutter: 1.1.0
......
name: llswidget name: llswidget
description: A Flutter UI Components package. description: A Flutter UI Components package.
version: 0.0.5 version: 0.0.8
author: Rizal Hermawan author: Rizal Hermawan
homepage: https://locatorlogic.com homepage: https://locatorlogic.com
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment