Aitrainer_app 1.1.0
Login and Registraion
This commit is contained in:
+117
-9
@@ -1,23 +1,32 @@
|
||||
import 'package:aitrainer_app/model/auth.dart';
|
||||
import 'package:aitrainer_app/service/api.dart';
|
||||
import 'package:aitrainer_app/service/customer_service.dart';
|
||||
import 'package:aitrainer_app/view/customer_modify_page.dart';
|
||||
import 'package:aitrainer_app/view/customer_new_page.dart';
|
||||
import 'package:aitrainer_app/view/login.dart';
|
||||
import 'package:aitrainer_app/view/exercise_new_page.dart';
|
||||
import 'package:aitrainer_app/view/exercise_type_modify_page.dart';
|
||||
import 'package:aitrainer_app/view/exercise_type_new_page.dart';
|
||||
import 'package:aitrainer_app/view/registration.dart';
|
||||
import 'package:aitrainer_app/viewmodel/exercise_changing_view_model.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:aitrainer_app/view/customer_list_page.dart';
|
||||
import 'package:aitrainer_app/view/exercise_type_list_page.dart';
|
||||
import 'package:aitrainer_app/widgets/nav_drawer.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:flutter_localizations/flutter_localizations.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
|
||||
void main() {
|
||||
runApp(
|
||||
ChangeNotifierProvider(
|
||||
MultiProvider(
|
||||
// Initialize the model in the builder. That way, Provider
|
||||
// can own Models's lifecycle, making sure to call `dispose`
|
||||
// when not needed anymore.
|
||||
create: (context) => ExerciseChangingViewModel(null),
|
||||
providers: [
|
||||
ChangeNotifierProvider(create: (context) => ExerciseChangingViewModel(null)),
|
||||
],
|
||||
child: AitrainerApp(),
|
||||
),
|
||||
);
|
||||
@@ -48,6 +57,8 @@ class AitrainerApp extends StatelessWidget {
|
||||
'exerciseTypeNewPage': (context) => ExerciseTypeNewPage(),
|
||||
'exerciseTypeModifyPage': (context) => ExerciseTypeModifyPage(),
|
||||
'exerciseNewPage': (context) => ExerciseNewPage(),
|
||||
'login': (context) => LoginPage(),
|
||||
'registration': (context) => RegistrationPage(),
|
||||
},
|
||||
initialRoute: 'home',
|
||||
title: 'Aitrainer Demo',
|
||||
@@ -59,20 +70,117 @@ class AitrainerApp extends StatelessWidget {
|
||||
}
|
||||
}
|
||||
|
||||
class AitrainerHome extends StatelessWidget {
|
||||
final _biggerFont = const TextStyle(fontSize: 24.0, color: Color.fromRGBO(94, 123, 122, 0.9));
|
||||
class AitrainerHome extends StatefulWidget {
|
||||
static final String routeName = 'home';
|
||||
|
||||
|
||||
@override
|
||||
State<StatefulWidget> createState() {
|
||||
return new _HomePageState();
|
||||
}
|
||||
}
|
||||
|
||||
class _HomePageState extends State<AitrainerHome> {
|
||||
GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
|
||||
Future<SharedPreferences> _prefs = SharedPreferences.getInstance();
|
||||
Auth _auth = Auth();
|
||||
SharedPreferences _sharedPreferences;
|
||||
var _authToken;
|
||||
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_fetchSessionAndNavigate();
|
||||
}
|
||||
|
||||
_fetchSessionAndNavigate() async {
|
||||
_sharedPreferences = await _prefs;
|
||||
String authToken = Auth.getToken(_sharedPreferences);
|
||||
var customerId = _sharedPreferences.getInt(Auth.customerIdKey);
|
||||
|
||||
if ( _auth.firstLoad ) {
|
||||
_fetchToken(_sharedPreferences);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
Auth flow of the user, see auth.dart
|
||||
*/
|
||||
_fetchToken(SharedPreferences prefs) async {
|
||||
var responseJson = await APIClient.authenticateUser(
|
||||
Auth.username,
|
||||
Auth.password
|
||||
);
|
||||
|
||||
if(responseJson['error'] != null) {
|
||||
showSnackBar(_scaffoldKey, responseJson['error']);
|
||||
print("************** Here big error - no authentication");
|
||||
} else if (responseJson['token'] != null) {
|
||||
prefs.setString(Auth.authTokenKey, responseJson['token']);
|
||||
Auth auth = Auth();
|
||||
auth.authToken = responseJson['token'];
|
||||
if ( prefs.get(Auth.customerIdKey) == null ) {
|
||||
print("************** Registration");
|
||||
// registration
|
||||
Navigator.of(context).pushNamed('registration');
|
||||
prefs.setBool(Auth.isRegisteredKey, true);
|
||||
} else {
|
||||
DateTime now = DateTime.now();
|
||||
DateTime lastStoreDate = DateTime.parse( prefs.get(Auth.lastStoreDateKey) );
|
||||
DateTime minStoreDate = now.add(Duration(days: -10));
|
||||
|
||||
if ( lastStoreDate == null ||
|
||||
lastStoreDate.difference(minStoreDate) > Duration(days: 10) ||
|
||||
prefs.get(Auth.isLoggedInKey) == null ||
|
||||
prefs.get(Auth.isLoggedInKey) == false ) {
|
||||
print("************* Login");
|
||||
Navigator.of(context).pushNamed('login');
|
||||
|
||||
} else {
|
||||
print("************** Store SharedPreferences");
|
||||
// get API customer
|
||||
await CustomerApi().getCustomer( prefs.getInt(Auth.customerIdKey));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
setState(() {
|
||||
_auth.firstLoad = false;
|
||||
_authToken = auth.authToken;
|
||||
_sharedPreferences.setString(Auth.authTokenKey, _authToken);
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static showSnackBar(GlobalKey<ScaffoldState> scaffoldKey, String message) {
|
||||
scaffoldKey.currentState.showSnackBar(
|
||||
new SnackBar(
|
||||
content: new Text(message ?? 'You are offline'),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
key: _scaffoldKey,
|
||||
drawer: NavDrawer(),
|
||||
appBar: AppBar(
|
||||
title: Text('Menu'),
|
||||
title: Text('Home'),
|
||||
backgroundColor: Colors.transparent
|
||||
),
|
||||
body: Center(
|
||||
child: Text(
|
||||
'Welcome to the AITRAINER',
|
||||
style: _biggerFont),
|
||||
body: Image.asset('asset/WT01_loading_layers.png',
|
||||
fit: BoxFit.fill,
|
||||
height: double.infinity,
|
||||
width: double.infinity,
|
||||
alignment: Alignment.center,
|
||||
),
|
||||
|
||||
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,105 @@
|
||||
import 'package:aitrainer_app/model/customer.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
|
||||
enum SharePrefsChange {
|
||||
login,
|
||||
registration,
|
||||
logout,
|
||||
}
|
||||
/*
|
||||
Auth flow of the app
|
||||
1. During the login screen the authentication will be executed
|
||||
- if not successful: message: Network error, try again later
|
||||
- if successful
|
||||
- get the stored shared preferences and customer id
|
||||
- if customer_id not present -> registration page
|
||||
- if present, check if the expiration_date > 10 days -> login page
|
||||
- else get the API customer by the stored customer_id
|
||||
- After registration / login store the preferences:
|
||||
- AuthToken
|
||||
- customer_id
|
||||
- last_store_date
|
||||
- is_registered
|
||||
- is_logged_in
|
||||
*/
|
||||
|
||||
class Auth {
|
||||
static final Auth _singleton = Auth._internal();
|
||||
|
||||
// Keys to store and fetch data from SharedPreferences
|
||||
static final String authTokenKey = 'auth_token';
|
||||
static final String customerIdKey = 'customer_id';
|
||||
static final String lastStoreDateKey = 'last_date';
|
||||
static final String isRegisteredKey = 'is_registered';
|
||||
static final String isLoggedInKey = 'is_logged_in';
|
||||
|
||||
static final String _baseUrl = 'http://andio.eu:8888/api/';
|
||||
static final String username = 'bosi';
|
||||
static final String password = 'andio2009';
|
||||
|
||||
String authToken = "";
|
||||
Customer userLoggedIn;
|
||||
bool firstLoad = true;
|
||||
|
||||
factory Auth() {
|
||||
return _singleton;
|
||||
}
|
||||
|
||||
Auth._internal();
|
||||
|
||||
String getAuthToken() {
|
||||
return this.authToken;
|
||||
}
|
||||
|
||||
static String getToken(SharedPreferences prefs) {
|
||||
return prefs.getString(authTokenKey);
|
||||
}
|
||||
|
||||
static String getBaseUrl() {
|
||||
return _baseUrl;
|
||||
}
|
||||
|
||||
afterRegistration(Customer customer) {
|
||||
Future<SharedPreferences> prefs = SharedPreferences.getInstance();
|
||||
|
||||
userLoggedIn = customer;
|
||||
setPreferences(prefs, SharePrefsChange.registration, customer.customerId);
|
||||
}
|
||||
|
||||
afterLogin(Customer customer) {
|
||||
Future<SharedPreferences> prefs = SharedPreferences.getInstance();
|
||||
|
||||
userLoggedIn = customer;
|
||||
setPreferences(prefs, SharePrefsChange.login, customer.customerId);
|
||||
}
|
||||
|
||||
logout(){
|
||||
userLoggedIn = null;
|
||||
authToken = "";
|
||||
//firstLoad = true;
|
||||
Future<SharedPreferences> prefs = SharedPreferences.getInstance();
|
||||
setPreferences(prefs, SharePrefsChange.logout, 0);
|
||||
}
|
||||
|
||||
setPreferences(Future<SharedPreferences> prefs,
|
||||
SharePrefsChange type,
|
||||
int customerId) async {
|
||||
SharedPreferences sharedPreferences;
|
||||
sharedPreferences = await prefs;
|
||||
|
||||
DateTime now = DateTime.now();
|
||||
sharedPreferences.setString(Auth.lastStoreDateKey, now.toString());
|
||||
if ( type == SharePrefsChange.registration ) {
|
||||
sharedPreferences.setInt(Auth.customerIdKey, customerId);
|
||||
sharedPreferences.setBool(Auth.isRegisteredKey, true);
|
||||
sharedPreferences.setBool(Auth.isLoggedInKey, true);
|
||||
} else if ( type == SharePrefsChange.login ) {
|
||||
|
||||
sharedPreferences.setInt(Auth.customerIdKey, customerId);
|
||||
sharedPreferences.setBool(Auth.isLoggedInKey, true);
|
||||
} else if ( type == SharePrefsChange.login ) {
|
||||
sharedPreferences.setBool(Auth.isLoggedInKey, false);
|
||||
sharedPreferences.setInt(Auth.customerIdKey, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,9 +6,10 @@ class Customer {
|
||||
int age;
|
||||
String active;
|
||||
int customerId;
|
||||
String password;
|
||||
|
||||
|
||||
Customer({this.customerId, this.name, this.firstName, this.email, this.sex, this.age, this.active});
|
||||
Customer({this.customerId, this.name, this.firstName, this.email, this.sex, this.age, this.active, this.password});
|
||||
|
||||
Customer.fromJson(Map json) {
|
||||
this.customerId = json['customer_id'];
|
||||
@@ -27,6 +28,7 @@ class Customer {
|
||||
"email": email,
|
||||
"age": age,
|
||||
"sex": sex,
|
||||
"active": 'Y'
|
||||
"active": 'Y',
|
||||
"password": password,
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
class User {
|
||||
String email;
|
||||
String password;
|
||||
int customerId;
|
||||
|
||||
|
||||
User({this.customerId, this.email, this.password});
|
||||
|
||||
|
||||
Map<String, dynamic> toJson() =>
|
||||
{
|
||||
"username": email,
|
||||
"password": password,
|
||||
};
|
||||
}
|
||||
+69
-7
@@ -1,12 +1,19 @@
|
||||
import 'dart:convert';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'package:aitrainer_app/model/auth.dart';
|
||||
|
||||
class APIClient {
|
||||
final String _baseUrl = 'http://andio.eu:8888/api/';
|
||||
class APIClient extends ChangeNotifier {
|
||||
|
||||
Future<String> get(String endPoint, String param) async {
|
||||
final url = _baseUrl + endPoint + param;
|
||||
final response = await http.get(url, headers: {'Content-Type': 'application/json'});
|
||||
final url = Auth.getBaseUrl() + endPoint + param;
|
||||
Auth auth = Auth();
|
||||
final response = await http.get(url,
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'Authorization' : "Bearer " + auth.getAuthToken() }
|
||||
);
|
||||
notifyListeners();
|
||||
if(response.statusCode == 200) {
|
||||
return utf8.decode(response.bodyBytes);
|
||||
} else {
|
||||
@@ -15,14 +22,69 @@ class APIClient {
|
||||
}
|
||||
|
||||
Future<String> post(String endPoint, String body) async {
|
||||
final url = _baseUrl + endPoint;
|
||||
print(" ------------ http/post endpoint $endPoint body $body");
|
||||
final url = Auth.getBaseUrl() + endPoint;
|
||||
print(" ------------ http/post endpoint $endPoint body $body - url: $url ");
|
||||
Auth auth = Auth();
|
||||
final response = await http.post(url,
|
||||
headers: {'Content-Type': 'application/json'},
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'Authorization' : "Bearer " + auth.getAuthToken()
|
||||
},
|
||||
body: body
|
||||
);
|
||||
print(" ------------ response: " + response.body.toString());
|
||||
notifyListeners();
|
||||
return response.body;
|
||||
}
|
||||
|
||||
static dynamic authenticateUser(String email, String password) async {
|
||||
var uri = Auth.getBaseUrl() + "authenticate";
|
||||
|
||||
try {
|
||||
final body = '{"username":"$email", "password":"$password"}';
|
||||
final response = await http.post(
|
||||
uri,
|
||||
headers: {
|
||||
'Authorization': '1',
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: body
|
||||
);
|
||||
final responseCode = response.statusCode;
|
||||
if ( responseCode != 200) {
|
||||
return { "error" : "Authentication error, total failure", };
|
||||
}
|
||||
|
||||
final responseJson = json.decode(response.body);
|
||||
return responseJson;
|
||||
|
||||
} catch (exception) {
|
||||
return { "error" : "Network error, try again later"};
|
||||
}
|
||||
}
|
||||
|
||||
static fetch(var authToken, var endPoint) async {
|
||||
var uri = Auth.getBaseUrl() + endPoint;
|
||||
|
||||
try {
|
||||
final response = await http.get(
|
||||
uri,
|
||||
headers: {
|
||||
'Authorization': authToken
|
||||
},
|
||||
);
|
||||
|
||||
final responseJson = json.decode(response.body);
|
||||
return responseJson;
|
||||
|
||||
} catch (exception) {
|
||||
print(exception);
|
||||
if(exception.toString().contains('SocketException')) {
|
||||
return 'NetworkError';
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,7 +1,8 @@
|
||||
import 'dart:convert';
|
||||
import 'package:aitrainer_app/model/customer.dart';
|
||||
import 'package:aitrainer_app/model/user.dart';
|
||||
import 'package:aitrainer_app/service/api.dart';
|
||||
|
||||
import 'package:aitrainer_app/model/auth.dart';
|
||||
|
||||
class CustomerApi {
|
||||
final APIClient _client=new APIClient();
|
||||
@@ -29,4 +30,38 @@ class CustomerApi {
|
||||
"customers",
|
||||
body);
|
||||
}
|
||||
|
||||
Future<void> addUser(User user) async {
|
||||
String body = JsonEncoder().convert(user.toJson());
|
||||
print(" ===== register new user: " + body );
|
||||
final String responseBody = await _client.post(
|
||||
"registration",
|
||||
body);
|
||||
Auth auth = Auth();
|
||||
Customer customer = Customer.fromJson(jsonDecode(responseBody));
|
||||
auth.afterRegistration(customer);
|
||||
|
||||
}
|
||||
|
||||
Future<void> getUser(User user) async {
|
||||
String body = JsonEncoder().convert(user.toJson());
|
||||
print(" ===== login the user: " + body );
|
||||
final String responseBody = await _client.post(
|
||||
"login",
|
||||
body);
|
||||
Auth auth = Auth();
|
||||
Customer customer = Customer.fromJson(jsonDecode(responseBody));
|
||||
auth.afterRegistration(customer);
|
||||
}
|
||||
|
||||
Future<void> getCustomer(int customerId) async {
|
||||
String body = "";
|
||||
print(" ===== get the customer by id: " + customerId.toString() );
|
||||
final String responseBody = await _client.get(
|
||||
"customers/"+customerId.toString(),
|
||||
body);
|
||||
Auth auth = Auth();
|
||||
Customer customer = Customer.fromJson(jsonDecode(responseBody));
|
||||
auth.afterRegistration(customer);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
|
||||
import 'dart:collection';
|
||||
|
||||
class Common {
|
||||
|
||||
|
||||
static String toJson( Map<String, String> map ) {
|
||||
String rc = "{";
|
||||
map.forEach((key, value) {
|
||||
rc += "'$key':'$value'";
|
||||
});
|
||||
rc += "}";
|
||||
return rc;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
|
||||
import 'package:aitrainer_app/viewmodel/user_changing_view_model.dart';
|
||||
import 'package:aitrainer_app/viewmodel/user_view_model.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:aitrainer_app/widgets/nav_drawer.dart';
|
||||
|
||||
class LoginPage extends StatefulWidget{
|
||||
_LoginPageState createState() => _LoginPageState();
|
||||
}
|
||||
|
||||
class _LoginPageState extends State {
|
||||
final UserViewModel user = UserViewModel();
|
||||
bool _obscureText = true;
|
||||
|
||||
final _formKey = GlobalKey<FormState>();
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
UserChangingViewModel model = UserChangingViewModel(user);
|
||||
user.createNew();
|
||||
return Scaffold(
|
||||
drawer: NavDrawer(),
|
||||
appBar: AppBar(
|
||||
title: Text('Login'),
|
||||
),
|
||||
body: Center(
|
||||
child: Form(
|
||||
key: _formKey,
|
||||
child: Column(
|
||||
children: <Widget>[
|
||||
TextFormField(
|
||||
decoration: InputDecoration(
|
||||
border: OutlineInputBorder(),
|
||||
labelText: 'Email',
|
||||
icon: const Padding(
|
||||
padding:const EdgeInsets.only(left: 20.0, top: 50.0),
|
||||
child: const Icon(Icons.people)
|
||||
)
|
||||
),
|
||||
validator: (String input) {
|
||||
RegExp exp = new RegExp(r"[\w._]+\@[\w._]+.[a-z]+",
|
||||
caseSensitive: false,
|
||||
multiLine: false,);
|
||||
String ret = exp.hasMatch(input) == true ?
|
||||
null:
|
||||
"Please type an email address";
|
||||
return ret;
|
||||
},
|
||||
onChanged: (input) => user.setEmail(input),
|
||||
),
|
||||
new TextFormField(
|
||||
decoration: const InputDecoration(
|
||||
labelText: 'Password',
|
||||
icon: const Padding(
|
||||
padding: const EdgeInsets.only(left: 20.0, top: 15.0),
|
||||
child: const Icon(Icons.lock))),
|
||||
validator: (val) => val.length < 6 ? 'Password too short.' : null,
|
||||
obscureText: _obscureText,
|
||||
onChanged: (input) => user.setPassword(input),
|
||||
),
|
||||
new InkWell(
|
||||
child: new Text('SignUp'),
|
||||
onTap: () => Navigator.of(context).pushNamed('registration'),
|
||||
),
|
||||
new FloatingActionButton(
|
||||
child: Icon(Icons.cloud_done,),
|
||||
onPressed:() => {
|
||||
if (_formKey.currentState.validate()) {
|
||||
model = UserChangingViewModel(user),
|
||||
model.getUser(),
|
||||
Navigator.pop(context),
|
||||
}
|
||||
})
|
||||
])
|
||||
),
|
||||
),
|
||||
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
|
||||
import 'package:aitrainer_app/viewmodel/user_changing_view_model.dart';
|
||||
import 'package:aitrainer_app/viewmodel/user_view_model.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:aitrainer_app/widgets/nav_drawer.dart';
|
||||
|
||||
class RegistrationPage extends StatefulWidget{
|
||||
_RegistrationPageState createState() => _RegistrationPageState();
|
||||
}
|
||||
|
||||
class _RegistrationPageState extends State {
|
||||
final UserViewModel user = UserViewModel();
|
||||
bool _obscureText = true;
|
||||
|
||||
final _formKey = GlobalKey<FormState>();
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
UserChangingViewModel model = UserChangingViewModel(user);
|
||||
user.createNew();
|
||||
return Scaffold(
|
||||
drawer: NavDrawer(),
|
||||
appBar: AppBar(
|
||||
title: Text('Registration'),
|
||||
),
|
||||
body: Center(
|
||||
child: Form(
|
||||
key: _formKey,
|
||||
child: Column(
|
||||
children: <Widget>[
|
||||
TextFormField(
|
||||
decoration: InputDecoration(
|
||||
border: OutlineInputBorder(),
|
||||
labelText: 'Email',
|
||||
icon: const Padding(
|
||||
padding:const EdgeInsets.only(left: 20.0, top: 50.0),
|
||||
child: const Icon(Icons.people)
|
||||
)
|
||||
),
|
||||
/* validator: (String input) {
|
||||
RegExp exp = new RegExp(r"[\w._]+\@[\w._]+.[a-z]+",
|
||||
caseSensitive: false,
|
||||
multiLine: false,);
|
||||
String ret = exp.hasMatch(input) == true ?
|
||||
null:
|
||||
"Please type an email address";
|
||||
return ret;
|
||||
},*/
|
||||
onChanged: (input) => user.setEmail(input),
|
||||
),
|
||||
new TextFormField(
|
||||
decoration: const InputDecoration(
|
||||
labelText: 'Password',
|
||||
icon: const Padding(
|
||||
padding: const EdgeInsets.only(left: 20.0, top: 15.0),
|
||||
child: const Icon(Icons.lock))),
|
||||
/* validator: (String input) {
|
||||
String rc = input.length < 4 ? 'Password too short.' : null;
|
||||
return rc;
|
||||
}, */
|
||||
onChanged: (input) => user.setPassword(input),
|
||||
obscureText: _obscureText,
|
||||
),
|
||||
new InkWell(
|
||||
child: new Text('I have an account'),
|
||||
onTap: () => Navigator.of(context).pushNamed('login'),
|
||||
),
|
||||
new FloatingActionButton(
|
||||
child: Icon(Icons.cloud_done,),
|
||||
onPressed:() => {
|
||||
if (_formKey.currentState.validate()) {
|
||||
model = UserChangingViewModel(user),
|
||||
model.addUser(),
|
||||
Navigator.pop(context),
|
||||
}
|
||||
}
|
||||
)
|
||||
])
|
||||
),
|
||||
),
|
||||
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
import 'package:aitrainer_app/model/user.dart';
|
||||
import 'package:aitrainer_app/service/customer_service.dart';
|
||||
import 'package:aitrainer_app/viewmodel/user_view_model.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
|
||||
class UserChangingViewModel extends ChangeNotifier {
|
||||
UserViewModel userViewModel = UserViewModel();
|
||||
|
||||
UserChangingViewModel(userViewModel) {
|
||||
this.userViewModel = userViewModel;
|
||||
}
|
||||
|
||||
Future<void> addUser() async {
|
||||
final User modelUser = userViewModel.getUser();
|
||||
await CustomerApi().addUser(modelUser);
|
||||
}
|
||||
|
||||
Future<void> getUser() async {
|
||||
final User modelUser = userViewModel.getUser();
|
||||
await CustomerApi().getUser(modelUser);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
import 'package:aitrainer_app/model/user.dart';
|
||||
|
||||
class UserViewModel {
|
||||
User user;
|
||||
|
||||
UserViewModel({this.user});
|
||||
|
||||
setEmail(String email) {
|
||||
this.user.email = email;
|
||||
}
|
||||
|
||||
setPassword(String password) {
|
||||
this.user.password = password;
|
||||
}
|
||||
|
||||
User getUser() {
|
||||
return this.user;
|
||||
}
|
||||
|
||||
createNew() {
|
||||
this.user = User();
|
||||
}
|
||||
}
|
||||
@@ -57,7 +57,7 @@ class _CustomerListWidget extends State<CustomerListWidget> {
|
||||
),
|
||||
),
|
||||
onTap: () { setState( () {
|
||||
customer.visibleDetails = true;
|
||||
customer.visibleDetails = customer.visibleDetails ? false : true;
|
||||
});
|
||||
},
|
||||
);
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import 'package:aitrainer_app/model/auth.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class NavDrawer extends StatelessWidget {
|
||||
final Auth auth = Auth();
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Drawer(
|
||||
@@ -37,6 +39,19 @@ class NavDrawer extends StatelessWidget {
|
||||
title: Text("TRAINING!"),
|
||||
onTap: () => Navigator.of(context).pushNamed('exerciseNewPage'),
|
||||
),
|
||||
ListTile(
|
||||
leading: Icon(Icons.perm_identity),
|
||||
title: Text('Login'),
|
||||
onTap: () => Navigator.of(context).pushNamed('login'),
|
||||
),
|
||||
ListTile(
|
||||
leading: Icon(Icons.cancel),
|
||||
title: Text("Logout"),
|
||||
onTap: () => {
|
||||
auth.logout(),
|
||||
Navigator.of(context).pushNamed('home'),
|
||||
}
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user