Aitrainer_app 1.1.1

test menu, customer modification, exercise save images, localization
This commit is contained in:
Bossanyi Tibor
2020-07-07 16:53:03 +02:00
parent 79142b92f2
commit 2177db10ea
80 changed files with 2751 additions and 553 deletions
+248
View File
@@ -0,0 +1,248 @@
import 'package:aitrainer_app/localization/app_language.dart';
import 'package:aitrainer_app/localization/app_localization.dart';
import 'package:aitrainer_app/model/auth.dart';
import 'package:aitrainer_app/util/common.dart';
import 'package:aitrainer_app/viewmodel/exercise_changing_view_model.dart';
import 'package:aitrainer_app/viewmodel/exercise_view_model.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:aitrainer_app/viewmodel/user_view_model.dart';
import 'package:aitrainer_app/widgets/bottom_nav.dart';
import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
import 'package:provider/provider.dart';
class AccountPage extends StatefulWidget{
_AccountPagePageState _state;
_AccountPagePageState createState() {
_state = new _AccountPagePageState();
return _state;
}
}
class _AccountPagePageState extends State<AccountPage> {
final UserViewModel user = UserViewModel();
final AppLanguage appLanguage = AppLanguage();
final Future<SharedPreferences> _prefs = SharedPreferences.getInstance();
final BottomNavigator bottomNav = BottomNavigator();
bool _loggedIn = Auth().userLoggedIn != null && Auth().userLoggedIn.email.length > 0;
Future<List<ExerciseViewModel>> _exercises;
ExerciseChangingViewModel model;
@override
void initState() {
super.initState();
model = Provider.of<ExerciseChangingViewModel>(context, listen: false);
if ( Auth().userLoggedIn != null ) {
_exercises = model.getExercisesByCustomer(Auth().userLoggedIn.customerId);
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(AppLocalizations.of(context).translate('Account')),
backgroundColor: Colors.transparent,
),
body: Container(
foregroundDecoration: BoxDecoration(
image: DecorationImage(
image: AssetImage('asset/image/WT_long_logo.png'),
//fit: BoxFit.scaleDown,
scale: 1.2,
alignment: Alignment.topRight,
),
),
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage('asset/image/WT_light_background.png'),
fit: BoxFit.cover,
alignment: Alignment.center,
),
),
child:
ListView(
padding: EdgeInsets.only(top: 135),
children: <Widget>[
ListTile(
leading: Icon(Icons.perm_identity),
subtitle: Text(
AppLocalizations.of(context).translate("Profile")),
title: FlatButton(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(_loggedIn ? Auth().userLoggedIn.email + " " +
Auth().userLoggedIn.name + " " +
Auth().userLoggedIn.firstName : "",
style: TextStyle(color: Colors.blue)),
Icon(Icons.arrow_forward_ios),
]),
textColor: Colors.grey,
color: Colors.white,
onPressed: () {
if (_loggedIn) {
Navigator.of(context).pushNamed('customerModifyPage');
print("Profile");
}
},
),
),
ListTile(
leading: Icon(Icons.language),
title: Text(appLanguage.appLocal == Locale('en') ?
AppLocalizations.of(context).translate("English") :
AppLocalizations.of(context).translate("Hungarian")),
subtitle: Text(AppLocalizations.of(context).translate(
"Selected Language")),
),
loginOut(),
exercises( model ),
]
)
),
bottomNavigationBar: bottomNav.buildBottomNavigator(context, widget._state)
);
}
ListTile loginOut() {
ListTile element = ListTile();
String text = "Logout";
Color buttonColor = Colors.orange;
if ( ! _loggedIn ) {
text = "Login";
buttonColor = Colors.blue;
}
element = ListTile(
enabled: true,
leading: Icon(Icons.input),
title: FlatButton(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(AppLocalizations.of(context).translate(text),
style: TextStyle(
color: buttonColor
)),
Icon(Icons.arrow_forward_ios),
]),
textColor: buttonColor,
color: Colors.white,
onPressed: () {
setState(() {
if ( ! _loggedIn) {
print("Login");
Navigator.of(context).pushNamed("login");
} else {
print("Logout");
_loggedIn = false;
Auth().logout();
}
});
},
),
);
return element;
}
ListTile exercises( ExerciseChangingViewModel model ) {
ListTile element = ListTile();
if ( Auth().userLoggedIn == null ) {
return element;
}
element = ListTile(
title: Text(AppLocalizations.of(context).translate("Exercises")),
subtitle: Column(
children: [
FutureBuilder<List<ExerciseViewModel>>(
future: _exercises,
builder: (context, snapshot) {
if (snapshot.hasData) {
return getExercises( model );//CustomerListWidget(customers: _exerciseViewModel.exerciseList);
} else if (snapshot.hasError) {
return Text("${snapshot.error}");
}
// By default, show a loading spinner.
return CircularProgressIndicator();
}
),]
));
return element;
}
Widget getExercises( ExerciseChangingViewModel model ) {
List<ExerciseViewModel> exercises = model.exerciseList;
Column element = Column();
if (exercises.length > 0) {
List<Column> rows = List();
exercises.forEach((exercise) {
String exerciseName = AppLocalizations.of(context).translate(
Common.getExerciseType(exercise.getExercise().exerciseTypeId).name);
String quantity = exercise.getExercise().quantity.toString() + " " +
AppLocalizations.of(context).translate(exercise.getExercise().unit);
String unitQuantity = "";
String unitQuantityUnit = "";
String date = Common.getDateLocale(exercise.getExercise().dateAdd, false);
if (exercise.getExercise().unitQuantity != null) {
unitQuantity = exercise.getExercise().unitQuantity.toString();
unitQuantityUnit = AppLocalizations.of(context).translate(
Common.getExerciseType(exercise.getExercise().exerciseTypeId).unitQuantityUnit);
}
TableRow row = TableRow(
children: [
Text(date),
Text(exerciseName),
Text(quantity),
Text(unitQuantity + " " + unitQuantityUnit),
]
);
Table table = Table(
defaultColumnWidth: FractionColumnWidth(0.28),
children: [row],
);
Column col = Column(
children: [
table,
Row(
children: [
Text(" "),
]
)
],
);
rows.add(col);
});
element = Column(
children: rows,
);
}
return element;
}
}
+81
View File
@@ -0,0 +1,81 @@
import 'package:aitrainer_app/localization/app_localization.dart';
import 'package:aitrainer_app/viewmodel/customer_changing_view_model.dart';
import 'package:flutter/material.dart';
// ignore: must_be_immutable
class CustomerBodyTypePage extends StatefulWidget{
_CustomerBodyTypePageState _state;
_CustomerBodyTypePageState createState() {
_state = _CustomerBodyTypePageState();
return _state;
}
}
class GenderItem {
GenderItem(this.dbValue,this.name);
final String dbValue;
String name;
}
class _CustomerBodyTypePageState extends State<CustomerBodyTypePage> {
@override
Widget build(BuildContext context) {
final CustomerChangingViewModel changingViewModel = ModalRoute.of(context).settings.arguments;
return Scaffold(
appBar: AppBar(
title: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
Image.asset(
'asset/image/WT_long_logo.png',
fit: BoxFit.cover,
height: 65.0,
),
],
),
backgroundColor: Colors.transparent,
),
body: Container(
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage('asset/image/WT_light_background.png'),
fit: BoxFit.cover,
alignment: Alignment.center,
),
),
child: Center(
child: Column(
children: [
Divider(),
InkWell(
child: Text("Your Body Type",
style: TextStyle(color: Colors.orange,
fontSize: 50, fontFamily: 'Arial',
fontWeight: FontWeight.w900 ),),
highlightColor: Colors.white,
),
RaisedButton(
color: Colors.orange,
textColor: Colors.white,
child: InkWell(
child: Text(AppLocalizations.of(context).translate("Next"))),
onPressed: () => {
//changingViewModel.saveCustomer(),
Navigator.of(context).pop(),
Navigator.of(context).pushNamed("customerWelcomePage", arguments: changingViewModel)
},
)
],
),
)
),
);
}
}
+80
View File
@@ -0,0 +1,80 @@
import 'package:aitrainer_app/localization/app_localization.dart';
import 'package:aitrainer_app/viewmodel/customer_changing_view_model.dart';
import 'package:flutter/material.dart';
// ignore: must_be_immutable
class CustomerFitnessPage extends StatefulWidget{
_CustomerFitnessPageState _state;
_CustomerFitnessPageState createState() {
_state = _CustomerFitnessPageState();
return _state;
}
}
class GenderItem {
GenderItem(this.dbValue,this.name);
final String dbValue;
String name;
}
class _CustomerFitnessPageState extends State<CustomerFitnessPage> {
@override
Widget build(BuildContext context) {
final CustomerChangingViewModel changingViewModel = ModalRoute.of(context).settings.arguments;
return Scaffold(
appBar: AppBar(
title: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
Image.asset(
'asset/image/WT_long_logo.png',
fit: BoxFit.cover,
height: 65.0,
),
],
),
backgroundColor: Colors.transparent,
),
body: Container(
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage('asset/image/WT_light_background.png'),
fit: BoxFit.cover,
alignment: Alignment.center,
),
),
child: Center(
child: Column(
children: [
Divider(),
InkWell(
child: Text("Your Fitness State",
style: TextStyle(color: Colors.orange,
fontSize: 50, fontFamily: 'Arial',
fontWeight: FontWeight.w900 ),),
highlightColor: Colors.white,
),
RaisedButton(
color: Colors.orange,
textColor: Colors.white,
child: InkWell(
child: Text(AppLocalizations.of(context).translate("Next"))),
onPressed: () => {
//changingViewModel.saveCustomer(),
Navigator.of(context).pop(),
Navigator.of(context).pushNamed("customerBodyTypePage", arguments: changingViewModel)
},
)
],
),
)
),
);
}
}
+124
View File
@@ -0,0 +1,124 @@
import 'package:aitrainer_app/localization/app_localization.dart';
import 'package:aitrainer_app/viewmodel/customer_changing_view_model.dart';
import 'package:flutter/material.dart';
// ignore: must_be_immutable
class CustomerGoalPage extends StatefulWidget{
_CustomerGoalPageState _state;
_CustomerGoalPageState createState() {
_state = _CustomerGoalPageState();
return _state;
}
}
class GenderItem {
GenderItem(this.dbValue,this.name);
final String dbValue;
String name;
}
class _CustomerGoalPageState extends State<CustomerGoalPage> {
@override
Widget build(BuildContext context) {
final CustomerChangingViewModel changingViewModel = ModalRoute.of(context).settings.arguments;
return Scaffold(
appBar: AppBar(
title: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
Image.asset(
'asset/image/WT_long_logo.png',
fit: BoxFit.cover,
height: 65.0,
),
],
),
backgroundColor: Colors.transparent,
),
body: Container(
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage('asset/image/WT_light_background.png'),
fit: BoxFit.cover,
alignment: Alignment.center,
),
),
child: Center(
child: Column(
children: [
Divider(),
InkWell(
child: Text("Set Your Goals",
style: TextStyle(color: Colors.orange,
fontSize: 50, fontFamily: 'Arial',
fontWeight: FontWeight.w900 ),),
highlightColor: Colors.white,
),
Stack(
alignment: Alignment.bottomLeft,
overflow: Overflow.visible,
children: [
FlatButton(
child: Image.asset("asset/image/WT_gain_muscle.png", height: 250,),
padding: EdgeInsets.all(0.0),
onPressed:() =>
{
print("gain muscle"),
changingViewModel.customer.setGoal("gain_muscle"),
}
),
InkWell(
child: Text("Gain Muscle",
style: TextStyle(color: Colors.white,
fontSize: 36, fontFamily: 'Arial',
fontWeight: FontWeight.w900 ),),
highlightColor: Colors.white,
)
]
),
Stack(
alignment: Alignment.bottomLeft,
overflow: Overflow.visible,
children: [
FlatButton(
child: Image.asset("asset/image/WT_weight_loss.png", height: 220,),
padding: EdgeInsets.all(0.0),
onPressed:() =>
{
print("weight_loss"),
changingViewModel.customer.setGoal("weight_loss"),
}
),
InkWell(
child: Text("Loose Weight",
style: TextStyle(color: Colors.white,
fontSize: 36, fontFamily: 'Arial',
fontWeight: FontWeight.w900 ),),
highlightColor: Colors.white,
)
]
),
RaisedButton(
color: Colors.orange,
textColor: Colors.white,
child: InkWell(
child: Text(AppLocalizations.of(context).translate("Next"))),
onPressed: () => {
//changingViewModel.saveCustomer(),
Navigator.of(context).pop(),
Navigator.of(context).pushNamed("customerFitnessPage", arguments: changingViewModel)
},
)
],
),
)
),
);
}
}
+261 -13
View File
@@ -1,29 +1,277 @@
import 'package:aitrainer_app/localization/app_localization.dart';
import 'package:aitrainer_app/model/auth.dart';
import 'package:aitrainer_app/viewmodel/customer_changing_view_model.dart';
import 'package:aitrainer_app/viewmodel/customer_view_model.dart';
import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
import 'package:aitrainer_app/widgets/nav_drawer.dart';
import 'package:flutter/services.dart';
class CustomerModifyPage extends StatefulWidget{
_CustomerModifyPageState createState() => _CustomerModifyPageState();
_CustomerModifyPageState _state;
_CustomerModifyPageState createState() {
_state = _CustomerModifyPageState();
return _state;
}
}
class _CustomerModifyPageState extends State {
//final _formKey = GlobalKey<FormState>();
class GenderItem {
GenderItem(this.dbValue,this.name);
final String dbValue;
String name;
}
class _CustomerModifyPageState extends State<CustomerModifyPage> {
final _formKey = GlobalKey<FormState>();
GenderItem selectedGender;
List<GenderItem> genders;
@override
void initState() {
super.initState();
genders = [
GenderItem("m", "Man"),
GenderItem("w", "Woman"),
];
selectedGender = genders[0];
}
@override
Widget build(BuildContext context) {
final CustomerViewModel model = CustomerViewModel();
model.customer = Auth().userLoggedIn;
final CustomerChangingViewModel customerChangeModel =
CustomerChangingViewModel(model);
customerChangeModel.customer.customer.sex = selectedGender.dbValue;
// we cannot initialize the translations in the initState
genders.forEach((GenderItem element) {
if ( element.dbValue == "m") {
element.name = AppLocalizations.of(context).translate("Man");
}
if ( element.dbValue == "w") {
element.name = AppLocalizations.of(context).translate("Woman");
}
});
return Scaffold(
drawer: NavDrawer(),
resizeToAvoidBottomInset: true,
appBar: AppBar(
title: Text('Modify customer'),
title: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Text("Profil"),
Image.asset(
'asset/image/WT_long_logo.png',
fit: BoxFit.cover,
height: 65.0,
),
],
),
//title: Text(AppLocalizations.of(context).translate('Settings')),
backgroundColor: Colors.transparent,
),
body: Center(
child: Text('Modify customer'),
),
floatingActionButton: FloatingActionButton(
onPressed: () => {},
child: Icon(Icons.save,),
mini: true,
body: Container(
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage('asset/image/WT_light_background.png'),
fit: BoxFit.cover,
alignment: Alignment.center,
),
),
child: Form(
key: _formKey,
child: SingleChildScrollView(
scrollDirection: Axis.vertical,
padding: EdgeInsets.only(top: 40, left: 25, right: 45, bottom:100),
child: Container(
alignment: Alignment.center,
child: Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded(
child: TextFormField(
style: TextStyle(fontSize: 12),
decoration: InputDecoration(
fillColor: Colors.white24,
filled: true,
labelText: AppLocalizations.of(context).translate('Email'),
),
initialValue: customerChangeModel.customer.customer.email,
onFieldSubmitted: (input) => customerChangeModel.customer.setEmail(input)
)
)
],
),
Divider(),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded(
child: TextFormField(
style: TextStyle(fontSize: 12),
obscureText: true,
decoration: InputDecoration(
fillColor: Colors.white24,
filled: true,
labelText: AppLocalizations.of(context).translate('Password (Leave empty if you don\'t want to change)' ),
),
initialValue: customerChangeModel.customer.customer.password,
onFieldSubmitted: (input) => customerChangeModel.customer.setPassword(input)
)
)
],
),
Divider(),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded(
child: TextFormField(
style: TextStyle(fontSize: 12),
decoration: InputDecoration(
fillColor: Colors.white24,
filled: true,
labelText: AppLocalizations.of(context).translate('Name'),
),
initialValue: customerChangeModel.customer.customer.name,
onFieldSubmitted: (input) => customerChangeModel.customer.setName(input)
)
)
],
),
Divider(),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded(
child: TextFormField(
style: TextStyle(fontSize: 12),
decoration: InputDecoration(
fillColor: Colors.white24,
filled: true,
labelText: AppLocalizations.of(context).translate('First Name'),
),
keyboardType: TextInputType.emailAddress,
initialValue: customerChangeModel.customer.customer.firstName,
onFieldSubmitted: (input) => customerChangeModel.customer.setFirstName(input)
)
)
],
),
Divider(),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded(
child: TextFormField(
style: TextStyle(fontSize: 12),
decoration: InputDecoration(
fillColor: Colors.white24,
filled: true,
labelText: AppLocalizations.of(context).translate('Birth Year'),
),
keyboardType: TextInputType.number,
inputFormatters: <TextInputFormatter>[
WhitelistingTextInputFormatter.digitsOnly
],
initialValue: customerChangeModel.customer.customer.birthYear.toString(),
onFieldSubmitted: (input) => customerChangeModel.customer.setBirthYear(int.parse(input))
)
)
],
),
Divider(),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded(
child: TextFormField(
style: TextStyle(fontSize: 12),
decoration: InputDecoration(
fillColor: Colors.white24,
filled: true,
labelText: AppLocalizations.of(context).translate('Weight'),
),
inputFormatters: <TextInputFormatter>[
WhitelistingTextInputFormatter.digitsOnly
],
initialValue: customerChangeModel.customer.customer.weight.toString(),
keyboardType: TextInputType.number,
onFieldSubmitted: (input) => customerChangeModel.customer.setWeight(int.parse(input)),
)
)
],
),
Divider(),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded(
child: DropdownButtonHideUnderline(
child: DropdownButton<GenderItem>(
hint: Text(AppLocalizations.of(context).translate('Select a gender')),
style: TextStyle(fontSize: 12, color: Colors.black),
focusColor: Colors.white24,
value: selectedGender,
items: genders.map((GenderItem gender){
return DropdownMenuItem<GenderItem>(
value: gender,
child: Text(gender.name)
);
}).toList(),
onChanged:(GenderItem gender) => {
setState(() {
selectedGender = gender;
customerChangeModel.customer.setSex(gender.dbValue);
print ("Gender " + gender.name);
})
//model.customer.sex =
},
)
)
)
],
),
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
Expanded(
child: RaisedButton(
color: Colors.orange,
textColor: Colors.white,
child: InkWell(
child: Text(AppLocalizations.of(context).translate("Next"))),
onPressed: () => {
customerChangeModel.saveCustomer(),
Navigator.of(context).pushNamed("customerGoalPage", arguments: customerChangeModel)
},
)
)
],
),
],
),
),
),
)
)
);
}
}
+1 -1
View File
@@ -68,7 +68,7 @@ class _CustomerNewPageState extends State {
validator: (input) => (int.parse(input) < 99 && int.parse(input) > 0) ?
null :
"Please type the right age 0-99",
onChanged: (input) => customer.setAge(int.parse(input)),
onChanged: (input) => customer.setBirthYear(int.parse(input)),
),
RadioListTile(
title: const Text('Man'),
+75
View File
@@ -0,0 +1,75 @@
import 'package:aitrainer_app/localization/app_localization.dart';
import 'package:aitrainer_app/viewmodel/customer_changing_view_model.dart';
import 'package:flutter/material.dart';
// ignore: must_be_immutable
class CustomerWelcomePage extends StatefulWidget{
_CustomerWelcomePageState _state;
_CustomerWelcomePageState createState() {
_state = _CustomerWelcomePageState();
return _state;
}
}
class GenderItem {
GenderItem(this.dbValue,this.name);
final String dbValue;
String name;
}
class _CustomerWelcomePageState extends State<CustomerWelcomePage> {
@override
Widget build(BuildContext context) {
final CustomerChangingViewModel changingViewModel = ModalRoute.of(context).settings.arguments;
return Scaffold(
appBar: AppBar(
title: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
Image.asset(
'asset/image/WT_long_logo.png',
fit: BoxFit.cover,
height: 65.0,
),
],
),
backgroundColor: Colors.transparent,
),
body: Container(
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage('asset/image/WT_welcome.png'),
fit: BoxFit.cover,
alignment: Alignment.center,
),
),
child: Center(
child: Column(
children: [
Divider(),
RaisedButton(
color: Colors.orange,
textColor: Colors.white,
child: InkWell(
child: Text(AppLocalizations.of(context).translate("Next"))),
onPressed: () => {
Navigator.of(context).pop(),
Navigator.of(context).pushNamed("home", arguments: changingViewModel)
},
)
],
),
)
),
);
}
}
+207 -89
View File
@@ -1,108 +1,226 @@
import 'package:aitrainer_app/localization/app_language.dart';
import 'package:aitrainer_app/localization/app_localization.dart';
import 'package:aitrainer_app/viewmodel/exercise_changing_view_model.dart';
import 'package:aitrainer_app/widgets/nav_drawer.dart';
import 'package:intl/intl.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:datetime_picker_formfield/datetime_picker_formfield.dart';
//import 'package:datetime_picker_formfield/datetime_picker_formfield.dart';
class ExerciseNewPage extends StatefulWidget{
_ExerciseNewPageState createState() => _ExerciseNewPageState();
}
class _ExerciseNewPageState extends State {
final List excluded = [43,44];
final _formKey = GlobalKey<FormState>();
final format = DateFormat("yyyy-MM-dd HH:mm");
@override
Widget build(BuildContext context) {
ExerciseChangingViewModel model = Provider.of<ExerciseChangingViewModel>(context, listen: false);
model.createNewModel();
return Scaffold(
drawer: NavDrawer(),
appBar: AppBar(
title: Text('New exercise'),
),
body: Center(
child: Form(
key: _formKey,
child: Column(
children: <Widget>[
TextFormField(
decoration: InputDecoration(
border: OutlineInputBorder(),
labelText: 'Name',
),
readOnly: true,
initialValue: model != null && model.customer != null ? model.customer.name + " " + model.customer.firstName : "Please select a customer",
),
TextFormField(
decoration: InputDecoration(
border: OutlineInputBorder(),
labelText: 'Exercise',
),
readOnly: true,
initialValue: model != null && model.exerciseType != null ? model.exerciseType.name : "Please select an exercise",
),
TextFormField(
decoration: InputDecoration(
border: OutlineInputBorder(),
labelText: 'Quantity',
),
validator: (input) => (int.parse(input) < 1000 && int.parse(input) > 0) ?
null :
"Please type the right quantity 0-1000",
onChanged: (input) => model.exerciseViewModel.setQuantity(int.parse(input)),
),
Text('Exercise date and time'),
DateTimeField(
format: format,
initialValue: DateTime.now(),
onShowPicker: (context, currentValue) async {
final date = await showDatePicker(
context: context,
firstDate: DateTime(1900),
initialDate: DateTime.now(),
lastDate: DateTime(2100),
builder: (context, child) => Localizations.override(
context: context,
locale: Locale('hu'),
child: child,
),
);
if (date != null) {
final time = await showTimePicker(
context: context,
initialTime:
TimeOfDay.fromDateTime(currentValue ?? DateTime.now()),
builder: (context, child) => Localizations.override(
context: context,
locale: Locale('hu'),
child: child,
),
);
return DateTimeField.combine(date, time);
} else {
return currentValue;
}
},
onChanged: (input) => model.exerciseViewModel.setDatetimeExercise(input),
),
]),
)
),
floatingActionButton: FloatingActionButton(
onPressed: () => {
if (_formKey.currentState.validate()) {
//model = ExerciseChangingViewModel(model.exerciseViewModel),
model.addExercise(),
Navigator.pop(context),
return Consumer<ExerciseChangingViewModel>(
builder: (context, model, child ) {
String exerciseName = "";
String customerName = "";
if ( model != null ) {
if ( model.exerciseViewModel == null ) {
model.createNewModel();
}
},
child: Icon(Icons.save,),
mini: true,
)
);
model.exerciseViewModel.createNew();
customerName = model != null && model.customer != null
? model.customer.name + " " +
model.customer.firstName
: "Please select a customer";
exerciseName = model != null &&
model.exerciseType != null
? model.exerciseType.name
: "Please select an exercise";
}
AppLanguage appLanguage = AppLanguage();
var date = DateTime.now();
String dateName = DateFormat(DateFormat.YEAR_MONTH_DAY, appLanguage.appLocal.toString()).format(date.toUtc()) +
" " +DateFormat(DateFormat.HOUR_MINUTE, appLanguage.appLocal.toString()).format(date.toUtc());
return Form(
key: _formKey,
autovalidate: true,
child: Scaffold(
resizeToAvoidBottomInset: false,
appBar: AppBar(
leading: IconButton(
icon: Icon(Icons.arrow_back, color: Colors.deepOrange),
onPressed: () => {
Navigator.of(context).pop()
},
),
title: Text(AppLocalizations.of(context).translate(exerciseName) + " " +
AppLocalizations.of(context).translate('Save Exercise'),
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 18, color: Colors.deepOrange)),
backgroundColor: Colors.white70,
),
body: Container(
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage('asset/image/WT_login.png'),
fit: BoxFit.cover,
//height: double.infinity,
//width: double.infinity,
alignment: Alignment.center,
),
),
child: Container(
padding: const EdgeInsets.only (top: 65, left:25, right: 100),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
columnQuantityUnit(model),
columnQuantity(model),
Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
new InkWell(
child: new Text(dateName,
style: TextStyle( fontSize: 16,color: Colors.blue)),
),
ButtonTheme(
minWidth: 30.0,
height: 30.0,
child: FlatButton(
padding: EdgeInsets.only(bottom: 0),
color: Colors.transparent,
splashColor: Colors.black26,
child: Row(
children: [
Icon(Icons.arrow_forward_ios, color: Colors.orange,)
]),
onPressed:() { print("date change");},
)),
],
),
new InkWell(
child: new Text(AppLocalizations.of(context).translate('Exercise date and time'),
style: TextStyle( fontSize: 16)),
),
]),
RaisedButton(
textColor: Colors.white,
color: Colors.deepOrange,
focusColor: Colors.white,
onPressed: () =>
{
if (_formKey.currentState.validate()) {
//model = ExerciseChangingViewModel(model.exerciseViewModel),
if ( ! excluded.contains(model.exerciseType.exerciseTypeId) ) {
model.addExercise(),
},
Navigator.pop(context),
}
},
child: Text("Save", style: TextStyle(fontSize: 16),)
),
]),
)
),
),
);
});
}
Column columnQuantityUnit( ExerciseChangingViewModel model) {
Column column = Column();
if ( model.exerciseType != null && model.exerciseType.unitQuantity == "1") {
column = Column(
children: [
TextFormField(
autovalidate: true,
textAlign: TextAlign.center,
initialValue: "0",
style: TextStyle(fontSize: 30,
color: Colors.lightBlue,
fontWeight: FontWeight.bold),
validator: (input) {
return validateNumberInput(input);
},
onFieldSubmitted: (input) => {
print ("UnitQuantity value $input"),
model.exerciseViewModel.setUnitQuantity(
double.parse(input))
},
),
new InkWell(
child: new Text(AppLocalizations.of(context).translate(
model.exerciseType.unitQuantityUnit),
style: TextStyle(fontSize: 16)),
),
]);
};
return column;
}
Column columnQuantity( ExerciseChangingViewModel model) {
Column column = Column();
column = Column(
children: [
TextFormField(
autovalidate: true,
textAlign: TextAlign.center,
initialValue: "0",
style: TextStyle(fontSize: 60,
color: Colors.deepOrange,
fontWeight: FontWeight.bold),
validator: (input) {
return validateNumberInput(input);
},
onFieldSubmitted: (input) =>
{
print ("Quantity value $input"),
model.exerciseViewModel.setQuantity(
double.parse(input)),
model.exerciseViewModel.setUnit(model.exerciseType.unit)
}
),
new InkWell(
child: new Text(AppLocalizations.of(context).translate(model.exerciseType.unit),
style: TextStyle(fontSize: 16)),
),
]);
return column;
}
String validateNumberInput( input ) {
String error = AppLocalizations.of(context).translate("Please type the right quantity 0-10000");
dynamic rc = ( input != null && input.length > 0);
if ( ! rc ) {
return null;
}
rc = double.tryParse(input);
if ( rc == null ) {
return error;
}
if ( ! ( double.parse(input) < 10000 && double.parse(input) > 0) ) {
return error;
}
return null;
}
}
+39
View File
@@ -0,0 +1,39 @@
import 'package:aitrainer_app/localization/app_localization.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
class Gdpr extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
padding: const EdgeInsets.only (left:15, right: 15),
child: ListView(
children: <Widget>[
new InkWell(
child: new Text(
AppLocalizations.of(context).translate('gdpr_text'),
),
customBorder: Border.all(color:Colors.teal, width:1),
),
Spacer(flex:2),
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
FlatButton(
textColor: Colors.black,
onPressed: () { },
)
],
)
],
)
)
);
}
}
+118 -60
View File
@@ -1,9 +1,12 @@
import 'package:aitrainer_app/localization/app_localization.dart';
import 'package:aitrainer_app/model/auth.dart';
import 'package:aitrainer_app/viewmodel/exercise_changing_view_model.dart';
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';
import 'package:provider/provider.dart';
class LoginPage extends StatefulWidget{
_LoginPageState createState() => _LoginPageState();
@@ -11,71 +14,126 @@ class LoginPage extends StatefulWidget{
class _LoginPageState extends State {
final UserViewModel user = UserViewModel();
bool _obscureText = true;
final bool _obscureText = true;
final _formKey = GlobalKey<FormState>();
@override
Widget build(BuildContext context) {
UserChangingViewModel model = UserChangingViewModel(user);
ExerciseChangingViewModel exerciseModel = Provider.of<ExerciseChangingViewModel>(context, listen: false);
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),
}
})
])
),
),
return Scaffold(
body: Container(
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage('asset/image/WT_login.png'),
fit: BoxFit.cover,
//height: double.infinity,
//width: double.infinity,
alignment: Alignment.center,
),
),
child: Form(
key: _formKey,
child: Container(
padding: const EdgeInsets.only (left: 25, right: 100),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
Spacer(flex: 4),
Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
new InkWell(
child: new Text(
AppLocalizations.of(context).translate(
'Login'),
style: TextStyle(fontWeight: FontWeight.bold,
fontSize: 24)),
),
],
),
TextFormField(
decoration: InputDecoration(
fillColor: Colors.white,
filled: true,
labelText: 'Email',
),
validator: (String input) {
RegExp exp = new RegExp(r"[\w._]+\@[\w._]+.[a-z]+",
caseSensitive: false,
multiLine: false,);
String ret = exp.hasMatch(input) == true ?
null :
AppLocalizations.of(context).translate(
'Please type an email address');
return ret;
},
onChanged: (input) => user.setEmail(input),
),
Spacer(flex: 1),
new TextFormField(
decoration: const InputDecoration(
filled: true,
labelText: "Password",
fillColor: Colors.white,
focusColor: Colors.white,
),
validator: (val) => val.length < 6
? AppLocalizations.of(context).translate(
'Password too short')
: null,
obscureText: _obscureText,
onChanged: (input) => user.setPassword(input),
),
Spacer(flex: 1),
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[ new FlatButton(
child: Image.asset('asset/image/WT_OK.png',
width: 100,
height: 100
),
onPressed: () =>
{
if (_formKey.currentState.validate()) {
model = UserChangingViewModel(user),
model.getUser(),
exerciseModel.setCustomer(
Auth().userLoggedIn),
Navigator.pop(context),
}
}),
]),
Spacer(flex: 2),
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
new InkWell(
child: new Text(
AppLocalizations.of(context).translate(
'SignUp')),
onTap: () =>
Navigator.of(context).pushNamed(
'registration'),
),
Spacer(flex: 1),
new InkWell(
child: new Text(
AppLocalizations.of(context).translate(
'Privacy')),
onTap: () =>
Navigator.of(context).pushNamed('gdpr'),
),
Spacer(flex: 2),
]),
Spacer(flex: 2),
])
),
),
)
);
}
}
+154
View File
@@ -0,0 +1,154 @@
import 'package:aitrainer_app/model/auth.dart';
import 'package:aitrainer_app/model/exercise_type.dart';
import 'package:aitrainer_app/model/workout_tree.dart';
import 'package:aitrainer_app/util/common.dart';
import 'package:aitrainer_app/util/menu_tests.dart';
import 'package:aitrainer_app/viewmodel/exercise_changing_view_model.dart';
import 'package:aitrainer_app/widgets/bottom_nav.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'dart:collection';
import 'package:provider/provider.dart';
// ignore: must_be_immutable
class MenuPage extends StatefulWidget {
_MenuPageState _state;
static const routeName = '/menu_page';
int parent;
MenuPage({this.parent});
@override
_MenuPageState createState() {
_state = new _MenuPageState();
return _state;
}
}
class _MenuPageState extends State<MenuPage> {
final BottomNavigator bottomNav = BottomNavigator();
@override
Widget build(BuildContext context) {
final MenuTests menu = MenuTests(context);
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.transparent,
title: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
Image.asset(
'asset/image/WT_long_logo.png',
fit: BoxFit.cover,
height: 65.0,
),
],
),
leading: IconButton(
icon: Icon(Icons.arrow_back, color: Colors.black),
onPressed: () => {
this.setState(() {
widget.parent = 0;
},
)},
),
),
body: Container(
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage('asset/image/WT_menu_dark.png'),
fit: BoxFit.fill,
alignment: Alignment.center,
),
),
child: CustomScrollView(
scrollDirection: Axis.vertical,
slivers: <Widget>[
buildMenuColumn(widget.parent, context, menu)
]
)
),
);
}
SliverList buildMenuColumn(int parent, BuildContext context, MenuTests menu) {
LinkedHashMap tree = menu.getMenuItems();
List<Widget> _columnChildren = List();
ExerciseType exerciseType;
ExerciseChangingViewModel model = Provider.of<ExerciseChangingViewModel>(context, listen: false);
tree.forEach((treeName, value) {
WorkoutTree workoutTree = value as WorkoutTree;
if ( workoutTree.parent == parent ) {
_columnChildren.add(
Container(
padding: EdgeInsets.only(top: 16.0),
child: Center(
child: Stack(
alignment: Alignment.bottomLeft,
overflow: Overflow.visible,
children: [
FlatButton(
child: _getButtonImage(workoutTree),
padding: EdgeInsets.all(0.0),
onPressed:() =>
{
print("Hi!, Menu clicked " + workoutTree.id.toString()),
if ( workoutTree.child == false ) {
this.setState(() {
widget.parent = workoutTree.id;
},
),
} else {
exerciseType = Common.getExerciseType(workoutTree.exercise_type_id),
model.setExerciseType(exerciseType),
model.setCustomer(Auth().userLoggedIn),
if ( Auth().userLoggedIn == null ) {
Scaffold.of(context)
. showSnackBar(SnackBar(content: Text('Please log in')))
} else {
Navigator.of(context).pushNamed('exerciseNewPage'),
}
}
}
),
InkWell(
child: Text(workoutTree.name, style: TextStyle(color: workoutTree.color, fontSize: workoutTree.fontSize, fontFamily: 'Arial', fontWeight: FontWeight.w900 ),),
highlightColor: workoutTree.color,
)]))));
}
});
//_columnChildren.add(Spacer(flex: 3));
SliverList sliverList =
SliverList(
delegate: SliverChildListDelegate(
_columnChildren
)
);
return sliverList;
}
dynamic _getButtonImage(WorkoutTree workoutTree) {
dynamic image;
if ( workoutTree.imageName.startsWith("http") ) {
image = FadeInImage.assetNetwork(
image: workoutTree.imageName,
placeholder: 'asset/image/dots.gif',
//imageScale: 0.1,
height: 180,
placeholderScale: 0.1,
);
} else {
image = Image.asset(workoutTree.imageName, height: 180,);
}
return image;
}
}
+83 -46
View File
@@ -1,4 +1,5 @@
import 'package:aitrainer_app/localization/app_localization.dart';
import 'package:aitrainer_app/viewmodel/user_changing_view_model.dart';
import 'package:aitrainer_app/viewmodel/user_view_model.dart';
import 'package:flutter/material.dart';
@@ -19,66 +20,102 @@ class _RegistrationPageState extends State {
Widget build(BuildContext context) {
UserChangingViewModel model = UserChangingViewModel(user);
user.createNew();
return Scaffold(
drawer: NavDrawer(),
appBar: AppBar(
title: Text('Registration'),
body: Container(
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage('asset/image/WT_login.png'),
fit: BoxFit.cover,
//height: double.infinity,
//width: double.infinity,
alignment: Alignment.center,
),
),
body: Center(
child: Form(
key: _formKey,
child: Column(
child: Form(
key: _formKey,
child: Container(
padding: const EdgeInsets.only (left:25, right: 100),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
Spacer(flex:4),
Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
new InkWell(
child: new Text(AppLocalizations.of(context).translate('SignUp'),
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 24)),
),
],
),
TextFormField(
decoration: InputDecoration(
border: OutlineInputBorder(),
fillColor: Colors.white,
filled:true,
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;
},*/
validator: (String input) {
RegExp exp = new RegExp(r"[\w._]+\@[\w._]+.[a-z]+",
caseSensitive: false,
multiLine: false,);
String ret = exp.hasMatch(input) == true ?
null:
AppLocalizations.of(context).translate('Please type an email address');
return ret;
},
onChanged: (input) => user.setEmail(input),
),
Spacer(flex:1),
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),
filled:true,
labelText: "Password",
fillColor: Colors.white,
focusColor: Colors.white,
),
validator: (val) => val.length < 6 ? AppLocalizations.of(context).translate('Password too short') : null,
obscureText: _obscureText,
onChanged: (input) => user.setPassword(input),
),
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),
}
}
)
])
),
Spacer(flex:1),
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[ new FlatButton(
child: Image.asset('asset/image/WT_OK.png',
width: 100,
height:100
),
onPressed:() => {
if (_formKey.currentState.validate()) {
model = UserChangingViewModel(user),
model.addUser(),
Navigator.of(context).pushNamed("customerModifyPage",)
}
}),
]),
Spacer(flex:2),
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
new InkWell(
child: new Text(AppLocalizations.of(context).translate('Login')),
onTap: () => Navigator.of(context).pushNamed('login'),
),
Spacer(flex:1),
new InkWell(
child: new Text(AppLocalizations.of(context).translate('Privacy')),
onTap: () => Navigator.of(context).pushNamed('gdpr'),
),
Spacer(flex:2),
]),
Spacer(flex:2),
])
),
),
),
);
}
+103
View File
@@ -0,0 +1,103 @@
import 'package:aitrainer_app/localization/app_language.dart';
import 'package:aitrainer_app/localization/app_localization.dart';
import 'package:aitrainer_app/widgets/bottom_nav.dart';
import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
class SettingsPage extends StatefulWidget{
_SettingsPageState _state;
_SettingsPageState createState() {
_state = new _SettingsPageState();
return _state;
}
}
class _SettingsPageState extends State<SettingsPage> {
final AppLanguage appLanguage = AppLanguage();
Locale _locale;
final _formKey = GlobalKey<FormState>();
@override
Widget build(BuildContext context) {
BottomNavigator bottomNav = BottomNavigator();
_locale = appLanguage.appLocal;
return Scaffold(
appBar: AppBar(
title: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Text(AppLocalizations.of(context).translate('Settings')),
Image.asset(
'asset/image/WT_long_logo.png',
fit: BoxFit.cover,
height: 65.0,
),
],
),
//title: Text(AppLocalizations.of(context).translate('Settings')),
backgroundColor: Colors.transparent,
),
body: Container(
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage('asset/image/WT_light_background.png'),
fit: BoxFit.cover,
alignment: Alignment.center,
),
),
child: Form(
key: _formKey,
child:
ListView(
padding: EdgeInsets.only(top: 150),
children: <Widget>[
ListTile(
leading: Icon(Icons.language),
subtitle: Text(AppLocalizations.of(context).translate("Change App Language")),
title: DropdownButton(
value: _locale == Locale('en') ? AppLocalizations.of(context).translate("English") : AppLocalizations.of(context).translate("Hungarian"),
items: [AppLocalizations.of(context).translate("English"), AppLocalizations.of(context).translate("Hungarian")]
.map<DropdownMenuItem<String>>((String value) {
return DropdownMenuItem<String>(
value: value,
child: Text(value),
);
}).toList(),
onChanged:(String lang) => _changeLanguage(lang),
)
),
]
),
),
),
bottomNavigationBar: bottomNav.buildBottomNavigator(context, widget._state)
);
}
_changeLanguage( String lang ) {
setState(() {
switch ( lang ) {
case "English":
case "Angol":
_locale = Locale('en');
break;
case "Hungarian":
case "Magyar":
_locale = Locale('hu');
break;
}
appLanguage.changeLanguage(_locale);
AppLocalizations.of(context).setLocale(_locale);
AppLocalizations.of(context).load();
});
}
}