wt1.1a flutter_bloc

This commit is contained in:
Bossanyi Tibor
2020-08-17 12:38:47 +02:00
parent 8363d7772f
commit ac1c6be8f3
90 changed files with 4281 additions and 2854 deletions
+104 -140
View File
@@ -1,142 +1,110 @@
import 'package:aitrainer_app/localization/app_language.dart';
import 'package:aitrainer_app/bloc/account/account_bloc.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/customer_changing_view_model.dart';
import 'package:aitrainer_app/viewmodel/customer_view_model.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:flutter_bloc/flutter_bloc.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;
}
State getState() {
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();
Future<List<ExerciseViewModel>> _exercises;
ExerciseChangingViewModel exerciseChangingViewModel;
@override
void initState() {
exerciseChangingViewModel = Provider.of<ExerciseChangingViewModel>(context, listen: false);
super.initState();
}
// ignore: must_be_immutable
class AccountPage extends StatelessWidget {
// ignore: close_sinks
AccountBloc accountBloc;
@override
Widget build(BuildContext context) {
return Consumer<CustomerChangingViewModel>(
builder: (context, model, child ) {
if ( model.customer == null ) {
CustomerViewModel customerViewModel = CustomerViewModel();
model.customer = customerViewModel;
if ( model.customer.getCustomer() == null ) {
model.customer.setCustomer(Auth().userLoggedIn);
accountBloc = BlocProvider.of<AccountBloc>(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'),
alignment: Alignment.topRight,
),
),
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage('asset/image/WT_light_background.png'),
fit: BoxFit.cover,
alignment: Alignment.center,
),
),
child: BlocConsumer<AccountBloc, AccountState>(
listener: (context, state) {
if (state is AccountError) {
Scaffold.of(context).showSnackBar(SnackBar(
backgroundColor: Colors.orange,
content:
Text(state.message, style: TextStyle(color: Colors.white))));
} else if (state is AccountLoading) {
}
},
builder: (context, state) {
if ( state is AccountInitial ) {
String customerName = accountBloc.customerRepository.firstName +
" " + accountBloc.customerRepository.name;
return accountWidget(context, customerName, accountBloc);
} else if ( state is AccountLoggedIn ) {
String customerName = accountBloc.customerRepository.firstName +
" " + accountBloc.customerRepository.name;
return accountWidget(context, customerName, accountBloc);
} else if ( state is AccountLoggedOut ) {
String customerName = "";
return accountWidget(context, customerName, accountBloc);
} else if ( state is AccountReady ) {
String customerName = accountBloc.customerRepository.firstName +
" " + accountBloc.customerRepository.name;
return accountWidget(context, customerName, accountBloc);
} else {
return accountWidget(context, "", accountBloc);
}
}
}
if ( Auth().userLoggedIn != null ) {
_exercises =
exerciseChangingViewModel.getExercisesByCustomer(
Auth().userLoggedIn.customerId);
}
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'),
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(Auth().userLoggedIn != null ?
Auth().userLoggedIn.name + " " +
Auth().userLoggedIn.firstname : "",
style: TextStyle(color: Colors.blue)),
Icon(Icons.arrow_forward_ios),
]),
textColor: Colors.grey,
color: Colors.white,
onPressed: () => {
if (model.customer.getCustomer() != null) {
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( model ),
exercises(exerciseChangingViewModel),
]
)
),
bottomNavigationBar: bottomNav.buildBottomNavigator(
context, widget._state)
);
});
),
bottomNavigationBar: BottomNavigator(bottomNavIndex: 2));
}
ListTile loginOut( CustomerChangingViewModel model ) {
ListView accountWidget(BuildContext context, String customerName, AccountBloc accountBloc) {
return 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(customerName,
style: TextStyle(color: Colors.blue)),
Icon(Icons.arrow_forward_ios),
]),
textColor: Colors.grey,
color: Colors.white,
onPressed: () => {
if (accountBloc.customerRepository.customer != null) {
Navigator.of(context).pushNamed('customerModifyPage'),
print("Profile"),
}
},
),
),
loginOut( context, accountBloc ),
//exercises(exerciseChangingViewModel),
]);
}
ListTile loginOut( BuildContext context, AccountBloc accountBloc ) {
ListTile element = ListTile();
String text = "Logout";
Color buttonColor = Colors.orange;
if ( model.customer.getCustomer() == null ) {
if ( accountBloc.customerRepository.customer == null || accountBloc.customerRepository.customer.email == null) {
text = "Login";
buttonColor = Colors.blue;
}
@@ -149,25 +117,20 @@ class _AccountPagePageState extends State<AccountPage> {
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(AppLocalizations.of(context).translate(text),
style: TextStyle(
color: buttonColor
)),
style: TextStyle(
color: buttonColor
)),
Icon(Icons.arrow_forward_ios),
]),
textColor: buttonColor,
color: Colors.white,
onPressed: () => {
setState(() {
if ( model.customer.getCustomer() == null ) {
print("Login");
Navigator.of(context).pushNamed("login", arguments: widget._state);
} else {
print("Logout");
Auth().logout();
model.customer.setCustomer(null);
}
})
if ( accountBloc.loggedIn ) {
accountBloc.add(AccountLogout())
} else {
accountBloc.add(AccountLogin()),
Navigator.of(context).pushNamed('login'),
}
},
),
);
@@ -175,7 +138,7 @@ class _AccountPagePageState extends State<AccountPage> {
return element;
}
ListTile exercises( ExerciseChangingViewModel model ) {
/* ListTile exercises( ExerciseChangingViewModel model ) {
ListTile element = ListTile();
if ( Auth().userLoggedIn == null ) {
return element;
@@ -202,7 +165,8 @@ class _AccountPagePageState extends State<AccountPage> {
return element;
}
*/
/*
Widget getExercises( ExerciseChangingViewModel model ) {
List<ExerciseViewModel> exercises = model.exerciseList;
@@ -262,5 +226,5 @@ class _AccountPagePageState extends State<AccountPage> {
return element;
}
}
} */
}
+346
View File
@@ -0,0 +1,346 @@
import 'package:aitrainer_app/bloc/custom_exercise_form_bloc.dart';
import 'package:aitrainer_app/localization/app_localization.dart';
import 'package:aitrainer_app/model/exercise_type.dart';
import 'package:aitrainer_app/repository/exercise_repository.dart';
import 'package:aitrainer_app/widgets/splash.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_form_bloc/flutter_form_bloc.dart';
class CustomExercisePage extends StatefulWidget {
_CustomExerciseNewPageState createState() => _CustomExerciseNewPageState();
}
class _CustomExerciseNewPageState extends State<CustomExercisePage> {
final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
@override
Widget build(BuildContext context) {
final ExerciseType exerciseType = ModalRoute.of(context).settings.arguments;
return BlocProvider(
create: (context) =>
CustomExerciseFormBloc(exerciseRepository: ExerciseRepository()),
child: Builder(builder: (context) {
// ignore: close_sinks
final exerciseBloc = BlocProvider.of<CustomExerciseFormBloc>(context);
exerciseBloc.exerciseRepository.setExerciseType(exerciseType);
return Scaffold(
key: _scaffoldKey,
resizeToAvoidBottomInset: true,
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.white),
onPressed: () => Navigator.of(context).pop(),
),
),
body: FormBlocListener<CustomExerciseFormBloc, String, String>(
onSubmitting: (context, state) {
LoadingDialog.show(context);
},
onSuccess: (context, state) {
LoadingDialog.hide(context);
},
onFailure: (context, state) {
LoadingDialog.hide(context);
Scaffold.of(context).showSnackBar(SnackBar(
backgroundColor: Colors.orange,
content: Text(state.failureResponse,
style: TextStyle(color: Colors.white))));
},
child: Container(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height,
decoration: BoxDecoration(
image: DecorationImage(
image:
AssetImage('asset/image/WT_light_background.png'),
fit: BoxFit.fill,
alignment: Alignment.center,
),
),
child: CustomScrollView(
scrollDirection: Axis.vertical,
slivers: [
SliverList(
delegate: SliverChildListDelegate(
[
Container(
padding: EdgeInsets.only(top:20,left:25, right:25),
alignment: Alignment.center,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text("Custom Exercise",
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 14,
color: Colors.deepOrange)),
columnQuantityUnit(exerciseBloc),
columnQuantity(exerciseBloc),
]
)
),
]
),
),
gridCalculation(exerciseBloc)
]
)
)
)
);
}));
}
Column columnQuantityUnit(CustomExerciseFormBloc bloc) {
Column column = Column();
if (bloc.exerciseRepository.exerciseType != null &&
bloc.exerciseRepository.exerciseType.unitQuantity == "1") {
column = Column(children: [
TextFieldBlocBuilder(
textFieldBloc: bloc.unitQuantityField,
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 16,
color: Colors.lightBlue,
fontWeight: FontWeight.bold),
inputFormatters: [
FilteringTextInputFormatter(RegExp(r"[\d.]"), allow: true)
],
onChanged: (input) => {
print("UnitQuantity value $input"),
bloc.exerciseRepository.setUnitQuantity(double.parse(input))
},
decoration: InputDecoration(
fillColor: Colors.white,
filled: false,
hintStyle: TextStyle(
fontSize: 12,
color: Colors.black54,
fontWeight: FontWeight.w100),
hintText: AppLocalizations.of(context)
.translate("The number of the exercise done with"),
labelStyle: TextStyle(fontSize: 12, color: Colors.lightBlue),
labelText: AppLocalizations.of(context).translate(
bloc.exerciseRepository.exerciseType.unitQuantityUnit),
),
),
new InkWell(
child: new Text(
AppLocalizations.of(context).translate(
bloc.exerciseRepository.exerciseType.unitQuantityUnit),
style: TextStyle(fontSize: 12)),
),
]);
}
;
return column;
}
Column columnQuantity(CustomExerciseFormBloc bloc) {
Column column = Column(children: [
TextFieldBlocBuilder(
textFieldBloc: bloc.quantityField,
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 20,
color: Colors.deepOrange,
fontWeight: FontWeight.bold),
inputFormatters: [
FilteringTextInputFormatter(RegExp(r"[\d.]"), allow: true)
],
onChanged: (input) => {
print("Quantity value $input"),
bloc.exerciseRepository.setQuantity(double.parse(input)),
bloc.exerciseRepository
.setUnit(bloc.exerciseRepository.exerciseType.unit)
},
decoration: InputDecoration(
fillColor: Colors.white,
filled: false,
hintStyle: TextStyle(
fontSize: 12, color: Colors.black54, fontWeight: FontWeight.w100),
hintText: AppLocalizations.of(context)
.translate("The number of the exercise"),
labelStyle: TextStyle(fontSize: 12, color: Colors.deepOrange),
labelText: AppLocalizations.of(context)
.translate(bloc.exerciseRepository.exerciseType.unit),
),
),
]);
return column;
}
SliverGrid gridCalculation(CustomExerciseFormBloc bloc) {
return SliverGrid(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
mainAxisSpacing: 10.0,
crossAxisSpacing: 10.0,
childAspectRatio: 4.0,
),
delegate: SliverChildListDelegate(
[
TextFieldBlocBuilder(
isEnabled: false,
textFieldBloc: bloc.rmWendlerField,
padding: EdgeInsets.only(left:30),
style: TextStyle(color: Colors.deepOrange, fontSize: 12),
decoration: InputDecoration(
border: InputBorder.none,
fillColor: Colors.white,
filled: false,
labelText: "1RM by Wendler: ",
)),
TextFieldBlocBuilder(
isEnabled: false,
padding: EdgeInsets.only(left:30),
textFieldBloc: bloc.rmMcGothlinField,
style: TextStyle(color: Colors.deepOrange, fontSize: 12),
decoration: InputDecoration(
border: InputBorder.none,
fillColor: Colors.white,
filled: false,
labelText: "1RM by McGlothin: ",
)),
TextFieldBlocBuilder(
isEnabled: false,
padding: EdgeInsets.only(left:30),
maxLines: 1,
textFieldBloc: bloc.rmLombardiField,
style: TextStyle(color: Colors.deepOrange, fontSize: 12),
decoration: InputDecoration(
border: InputBorder.none,
fillColor: Colors.white,
filled: false,
labelText: "1RM by Lambordini: ",
)),
TextFieldBlocBuilder(
isEnabled: false,
padding: EdgeInsets.only(left:30),
maxLines: 1,
textFieldBloc: bloc.rmWathenField,
style: TextStyle(color: Colors.deepOrange, fontSize: 12),
decoration: InputDecoration(
border: InputBorder.none,
fillColor: Colors.white,
filled: false,
labelText: "1RM by Wahten: ",
)),
TextFieldBlocBuilder(
isEnabled: false,
padding: EdgeInsets.only(left:30),
maxLines: 1,
textFieldBloc: bloc.rmOconnerField,
style: TextStyle(color: Colors.deepOrange, fontSize: 12),
decoration: InputDecoration(
border: InputBorder.none,
fillColor: Colors.white,
filled: false,
labelText: "1RM by O'Conner: ",
)),
TextFieldBlocBuilder(
isEnabled: false,
padding: EdgeInsets.only(left:30),
maxLines: 1,
textFieldBloc: bloc.rmMayhewField,
style: TextStyle(color: Colors.deepOrange, fontSize: 12),
decoration: InputDecoration(
border: InputBorder.none,
fillColor: Colors.white,
filled: false,
labelText: "1RM by Mayhew: ",
)),
TextFieldBlocBuilder(
isEnabled: false,
padding: EdgeInsets.only(left:30),
maxLines: 1,
textFieldBloc: bloc.rmAverageField,
style: TextStyle(color: Colors.blueAccent, fontSize: 12),
decoration: InputDecoration(
border: InputBorder.none,
fillColor: Colors.white,
filled: false,
labelText: "1RM Average: ",
)),
TextFieldBlocBuilder(
isEnabled: false,
padding: EdgeInsets.only(left:30),
maxLines: 1,
textFieldBloc: bloc.rm90Field,
style: TextStyle(color: Colors.deepOrange, fontSize: 12),
decoration: InputDecoration(
border: InputBorder.none,
fillColor: Colors.white,
filled: false,
labelText: "1RM 90%: ",
)),
TextFieldBlocBuilder(
isEnabled: false,
padding: EdgeInsets.only(left:30),
maxLines: 1,
textFieldBloc: bloc.rm80Field,
style: TextStyle(color: Colors.deepOrange, fontSize: 12),
decoration: InputDecoration(
border: InputBorder.none,
fillColor: Colors.white,
filled: false,
labelText: "1RM 80%: ",
)),
TextFieldBlocBuilder(
isEnabled: false,
padding: EdgeInsets.only(left:30),
maxLines: 1,
textFieldBloc: bloc.rm70Field,
style: TextStyle(color: Colors.deepOrange, fontSize: 12),
decoration: InputDecoration(
border: InputBorder.none,
fillColor: Colors.white,
filled: false,
labelText: "1RM 70%: ",
)),
TextFieldBlocBuilder(
isEnabled: false,
padding: EdgeInsets.only(left:30),
maxLines: 1,
textFieldBloc: bloc.rm60Field,
style: TextStyle(color: Colors.deepOrange, fontSize: 12),
decoration: InputDecoration(
border: InputBorder.none,
fillColor: Colors.white,
filled: false,
labelText: "1RM 60%: ",
)),
TextFieldBlocBuilder(
isEnabled: false,
padding: EdgeInsets.only(left:30),
maxLines: 1,
textFieldBloc: bloc.rm50Field,
style: TextStyle(color: Colors.deepOrange, fontSize: 12),
decoration: InputDecoration(
border: InputBorder.none,
fillColor: Colors.white,
filled: false,
labelText: "1RM 50%: ",
))
])
);
}
}
+152 -142
View File
@@ -1,9 +1,11 @@
import 'package:aitrainer_app/bloc/customer_change/customer_change_bloc.dart';
import 'package:aitrainer_app/localization/app_localization.dart';
import 'package:aitrainer_app/viewmodel/customer_changing_view_model.dart';
import 'package:aitrainer_app/repository/customer_repository.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
// ignore: must_be_immutable
class CustomerBodyTypePage extends StatefulWidget{
class CustomerBodyTypePage extends StatefulWidget {
_CustomerBodyTypePageState _state;
_CustomerBodyTypePageState createState() {
@@ -13,7 +15,6 @@ class CustomerBodyTypePage extends StatefulWidget{
}
class BodyTypeItem {
static String endomorph = "endomorph";
static String ectomorph = "ectomorph";
static String mesomorph = "mesomorph";
@@ -23,15 +24,15 @@ class _CustomerBodyTypePageState extends State<CustomerBodyTypePage> {
String selected;
@override
Widget build(BuildContext context) {
final CustomerChangingViewModel changingViewModel = ModalRoute.of(context).settings.arguments;
final double cWidth = MediaQuery.of(context).size.width*0.75;
final CustomerRepository customerRepository =
ModalRoute.of(context).settings.arguments;
final double cWidth = MediaQuery.of(context).size.width * 0.75;
return Scaffold(
appBar: AppBar(
title: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
Image.asset(
'asset/image/WT_long_logo.png',
fit: BoxFit.cover,
@@ -40,151 +41,160 @@ class _CustomerBodyTypePageState extends State<CustomerBodyTypePage> {
],
),
backgroundColor: Colors.transparent,
),
body: Container(
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage('asset/image/WT_light_background.png'),
fit: BoxFit.cover,
alignment: Alignment.center,
),
),
body: Container(
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage('asset/image/WT_light_background.png'),
fit: BoxFit.cover,
alignment: Alignment.center,
),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Divider(),
Wrap(
//runAlignment: WrapAlignment.center,
alignment: WrapAlignment.center,
),
child: BlocProvider(
create: (context) =>
CustomerChangeBloc(customerRepository: customerRepository),
child: Builder(builder: (context) {
// ignore: close_sinks
CustomerChangeBloc changeBloc =
BlocProvider.of<CustomerChangeBloc>(context);
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
AppLocalizations.of(context).translate("Your Body Type"),
textAlign: TextAlign.center,
style: TextStyle(color: Colors.orange,
fontSize: 42, fontFamily: 'Arial',
fontWeight: FontWeight.w900 ),)
]
),
Divider(),
FlatButton(
child: Container(
width: cWidth,
child: Column(
Divider(),
Wrap(
//runAlignment: WrapAlignment.center,
alignment: WrapAlignment.center,
children: [
Text(AppLocalizations.of(context).translate("Endomorph"),
textWidthBasis: TextWidthBasis.longestLine,
style: TextStyle(color: Colors.blue,
fontSize: 32, fontFamily: 'Arial',
fontWeight: FontWeight.w900 )),
],
)
),
padding: EdgeInsets.all(10.0),
shape: getShape(changingViewModel, BodyTypeItem.endomorph ),
onPressed:() =>
{
setState((){
selected = BodyTypeItem.endomorph;
changingViewModel.customer.setBodyType(selected);
print(selected);
}),
}
),
Divider(),
FlatButton(
child: Container(
width: cWidth,
child: Column(
children: [
InkWell(
child: Text(AppLocalizations.of(context).translate("Ectomorph"),
style: TextStyle(color: Colors.blue,
fontSize: 32, fontFamily: 'Arial',
fontWeight: FontWeight.w900 ),),
highlightColor: Colors.white,
Text(
AppLocalizations.of(context)
.translate("Your Body Type"),
textAlign: TextAlign.center,
style: TextStyle(
color: Colors.orange,
fontSize: 42,
fontFamily: 'Arial',
fontWeight: FontWeight.w900),
)
]),
Divider(),
FlatButton(
child: Container(
width: cWidth,
child: Column(
children: [
Text(
AppLocalizations.of(context)
.translate("Endomorph"),
textWidthBasis: TextWidthBasis.longestLine,
style: TextStyle(
color: Colors.blue,
fontSize: 32,
fontFamily: 'Arial',
fontWeight: FontWeight.w900)),
],
)),
padding: EdgeInsets.all(10.0),
shape: getShape(
customerRepository, BodyTypeItem.endomorph),
onPressed: () => {
setState(() {
selected = BodyTypeItem.endomorph;
changeBloc.add(CustomerBodyTypeChange(bodyType: selected));
print(selected);
}),
}),
Divider(),
FlatButton(
child: Container(
width: cWidth,
child: Column(
children: [
InkWell(
child: Text(
AppLocalizations.of(context)
.translate("Ectomorph"),
style: TextStyle(
color: Colors.blue,
fontSize: 32,
fontFamily: 'Arial',
fontWeight: FontWeight.w900),
),
highlightColor: Colors.white,
),
],
),
),
padding: EdgeInsets.all(10.0),
shape: getShape(customerRepository, BodyTypeItem.ectomorph ),
],
),
),
padding: EdgeInsets.all(10.0),
shape: getShape(changingViewModel, BodyTypeItem.ectomorph ),
onPressed:() =>
{
setState((){
selected = BodyTypeItem.ectomorph;
changingViewModel.customer.setBodyType(selected);
print(selected);
}),
}
),
Divider(),
FlatButton(
child: Container(
width: cWidth,
child: Column(
children: [
InkWell(
child: Text(AppLocalizations.of(context).translate("Mesomorph"),
style: TextStyle(color: Colors.blue,
fontSize: 32, fontFamily: 'Arial',
fontWeight: FontWeight.w900 ),),
highlightColor: Colors.white,
onPressed: () => {
setState(() {
selected = BodyTypeItem.ectomorph;
changeBloc.add(CustomerBodyTypeChange(bodyType: selected));
print(selected);
}),
}),
Divider(),
FlatButton(
child: Container(
width: cWidth,
child: Column(
children: [
InkWell(
child: Text(
AppLocalizations.of(context)
.translate("Mesomorph"),
style: TextStyle(
color: Colors.blue,
fontSize: 32,
fontFamily: 'Arial',
fontWeight: FontWeight.w900),
),
highlightColor: Colors.white,
),
],
),
),
padding: EdgeInsets.all(10.0),
shape: getShape(customerRepository, BodyTypeItem.mesomorph ),
onPressed: () => {
setState(() {
selected = BodyTypeItem.mesomorph;
changeBloc.add(CustomerBodyTypeChange(bodyType: selected));
],
),
),
padding: EdgeInsets.all(10.0),
shape: getShape(changingViewModel, BodyTypeItem.mesomorph ),
onPressed:() =>
{
setState((){
selected = BodyTypeItem.mesomorph;
changingViewModel.customer.setBodyType(selected);
print(selected);
}),
}
),
Divider(),
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)
},
)
],
),
),
);
print(selected);
}),
}),
Divider(),
RaisedButton(
color: Colors.orange,
textColor: Colors.white,
child: InkWell(
child: Text(
AppLocalizations.of(context).translate("Next"))),
onPressed: () => {
changeBloc.add(CustomerSave()),
Navigator.of(context).pop(),
Navigator.of(context).pushNamed("customerWelcomePage", arguments: customerRepository)
},
)
],
);
})),
));
}
dynamic getShape( CustomerChangingViewModel changingViewModel, String fitnessLevel ) {
String selected = changingViewModel.customer.bodyType;
dynamic returnCode = ( selected == fitnessLevel ) ?
RoundedRectangleBorder(
side: BorderSide(width: 4, color: Colors.orange),
)
:
RoundedRectangleBorder(
side: BorderSide(width: 1, color: Colors.blue),
);
dynamic getShape(CustomerRepository customerRepository, String fitnessLevel) {
String selected = customerRepository.bodyType;
dynamic returnCode = (selected == fitnessLevel)
? RoundedRectangleBorder(
side: BorderSide(width: 4, color: Colors.orange),
)
: RoundedRectangleBorder(
side: BorderSide(width: 1, color: Colors.blue),
);
//return
return returnCode;
}
}
}
+237 -198
View File
@@ -1,11 +1,13 @@
import 'package:aitrainer_app/bloc/customer_change/customer_change_bloc.dart';
import 'package:aitrainer_app/localization/app_localization.dart';
import 'package:aitrainer_app/viewmodel/customer_changing_view_model.dart';
import 'package:aitrainer_app/repository/customer_repository.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
// ignore: must_be_immutable
class CustomerFitnessPage extends StatefulWidget{
class CustomerFitnessPage extends StatefulWidget {
_CustomerFitnessPageState _state;
_CustomerFitnessPageState createState() {
@@ -29,15 +31,15 @@ class _CustomerFitnessPageState extends State<CustomerFitnessPage> {
@override
Widget build(BuildContext context) {
final double cWidth = MediaQuery.of(context).size.width*0.75;
final CustomerChangingViewModel changingViewModel = ModalRoute.of(context).settings.arguments;
selected = changingViewModel.customer.fitnessLevel;
final double cWidth = MediaQuery.of(context).size.width * 0.75;
final CustomerRepository customerRepository =
ModalRoute.of(context).settings.arguments;
selected = customerRepository.customer.fitnessLevel;
return Scaffold(
appBar: AppBar(
title: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
Image.asset(
'asset/image/WT_long_logo.png',
fit: BoxFit.cover,
@@ -46,206 +48,243 @@ class _CustomerFitnessPageState extends State<CustomerFitnessPage> {
],
),
backgroundColor: Colors.transparent,
),
body: SingleChildScrollView(
scrollDirection: Axis.vertical,
child: Container(
),
body: BlocProvider(
create: (context) =>
CustomerChangeBloc(customerRepository: customerRepository),
child: Builder(builder: (context) {
// ignore: close_sinks
CustomerChangeBloc changeBloc =
BlocProvider.of<CustomerChangeBloc>(context);
padding: EdgeInsets.only(bottom: 200),
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage('asset/image/WT_light_background.png'),
fit: BoxFit.cover,
alignment: Alignment.center,
),
),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Divider(),
Wrap(
//runAlignment: WrapAlignment.center,
alignment: WrapAlignment.center,
children: [
Text(
AppLocalizations.of(context).translate("Your Fitness State"),
textAlign: TextAlign.center,
style: TextStyle(color: Colors.orange,
fontSize: 42, fontFamily: 'Arial',
fontWeight: FontWeight.w900 ),)
]
return SingleChildScrollView(
scrollDirection: Axis.vertical,
child: Container(
padding: EdgeInsets.only(bottom: 200),
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage('asset/image/WT_light_background.png'),
fit: BoxFit.cover,
alignment: Alignment.center,
),
),
Divider(),
FlatButton(
child: Container(
width: cWidth,
child: Column(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Divider(),
Wrap(
//runAlignment: WrapAlignment.center,
alignment: WrapAlignment.center,
children: [
Text(AppLocalizations.of(context).translate("Beginner"),
textWidthBasis: TextWidthBasis.longestLine,
style: TextStyle(color: Colors.blue,
fontSize: 32, fontFamily: 'Arial',
fontWeight: FontWeight.w900 )),
Text(AppLocalizations.of(context).translate("I am beginner"),
style: TextStyle(color: Colors.black,
fontSize: 20, fontFamily: 'Arial',
fontWeight: FontWeight.w100 ),),
],
)
),
padding: EdgeInsets.all(10.0),
shape: getShape(changingViewModel, FitnessItem.beginner ),
onPressed:() =>
{
setState((){
selected = FitnessItem.beginner;
changingViewModel.customer.setFitnessLevel(selected);
print(selected);
}),
}
),
Divider(),
FlatButton(
child: Container(
width: cWidth,
child: Column(
children: [
InkWell(
child: Text(AppLocalizations.of(context).translate("Intermediate"),
style: TextStyle(color: Colors.blue,
fontSize: 32, fontFamily: 'Arial',
fontWeight: FontWeight.w900 ),),
highlightColor: Colors.white,
Text(
AppLocalizations.of(context)
.translate("Your Fitness State"),
textAlign: TextAlign.center,
style: TextStyle(
color: Colors.orange,
fontSize: 42,
fontFamily: 'Arial',
fontWeight: FontWeight.w900),
)
]),
Divider(),
FlatButton(
child: Container(
width: cWidth,
child: Column(
children: [
Text(
AppLocalizations.of(context)
.translate("Beginner"),
textWidthBasis:
TextWidthBasis.longestLine,
style: TextStyle(
color: Colors.blue,
fontSize: 32,
fontFamily: 'Arial',
fontWeight: FontWeight.w900)),
Text(
AppLocalizations.of(context)
.translate("I am beginner"),
style: TextStyle(
color: Colors.black,
fontSize: 20,
fontFamily: 'Arial',
fontWeight: FontWeight.w100),
),
],
)),
padding: EdgeInsets.all(10.0),
shape: getShape(
customerRepository, FitnessItem.beginner),
onPressed: () => {
setState(() {
selected = FitnessItem.beginner;
changeBloc.add(CustomerFitnessChange(fitness: selected));
print(selected);
}),
}),
Divider(),
FlatButton(
child: Container(
width: cWidth,
child: Column(
children: [
InkWell(
child: Text(
AppLocalizations.of(context)
.translate("Intermediate"),
style: TextStyle(
color: Colors.blue,
fontSize: 32,
fontFamily: 'Arial',
fontWeight: FontWeight.w900),
),
highlightColor: Colors.white,
),
InkWell(
child: Text(
AppLocalizations.of(context)
.translate("I am intermediate"),
style: TextStyle(
color: Colors.black,
fontSize: 20,
fontFamily: 'Arial',
fontWeight: FontWeight.w100),
),
highlightColor: Colors.white,
),
],
),
InkWell(
child: Text(AppLocalizations.of(context).translate("I am intermediate"),
style: TextStyle(color: Colors.black,
fontSize: 20, fontFamily: 'Arial',
fontWeight: FontWeight.w100 ),),
highlightColor: Colors.white,
),
padding: EdgeInsets.all(10.0),
shape: getShape(
customerRepository, FitnessItem.intermediate),
onPressed: () => {
setState(() {
selected = FitnessItem.intermediate;
changeBloc.add(CustomerFitnessChange(fitness: selected));
print(selected);
}),
}),
Divider(),
FlatButton(
child: Container(
width: cWidth,
child: Column(
children: [
InkWell(
child: Text(
AppLocalizations.of(context)
.translate("Advanced"),
style: TextStyle(
color: Colors.blue,
fontSize: 32,
fontFamily: 'Arial',
fontWeight: FontWeight.w900),
),
highlightColor: Colors.white,
),
InkWell(
child: Text(
AppLocalizations.of(context)
.translate("I am advanced"),
style: TextStyle(
color: Colors.black,
fontSize: 20,
fontFamily: 'Arial',
fontWeight: FontWeight.w100),
),
highlightColor: Colors.white,
),
],
),
],
),
),
padding: EdgeInsets.all(10.0),
shape: getShape(changingViewModel, FitnessItem.intermediate ),
onPressed:() =>
{
setState((){
selected = FitnessItem.intermediate;
changingViewModel.customer.setFitnessLevel(selected);
print(selected);
}),
}
),
Divider(),
FlatButton(
child: Container(
width: cWidth,
child: Column(
children: [
InkWell(
child: Text(AppLocalizations.of(context).translate("Advanced"),
style: TextStyle(color: Colors.blue,
fontSize: 32, fontFamily: 'Arial',
fontWeight: FontWeight.w900 ),),
highlightColor: Colors.white,
),
padding: EdgeInsets.all(10.0),
shape: getShape(
customerRepository, FitnessItem.advanced),
onPressed: () => {
setState(() {
selected = FitnessItem.advanced;
changeBloc.add(CustomerFitnessChange(fitness: selected));
print(selected);
}),
}),
Divider(),
FlatButton(
child: Container(
width: cWidth,
child: Column(
children: [
InkWell(
child: Text(
AppLocalizations.of(context)
.translate("Professional"),
style: TextStyle(
color: Colors.blue,
fontSize: 32,
fontFamily: 'Arial',
fontWeight: FontWeight.w900),
),
highlightColor: Colors.white,
),
InkWell(
child: Text(
AppLocalizations.of(context)
.translate("I am professional"),
style: TextStyle(
color: Colors.black,
fontSize: 20,
fontFamily: 'Arial',
fontWeight: FontWeight.w100),
),
highlightColor: Colors.white,
),
],
),
InkWell(
child: Text(AppLocalizations.of(context).translate("I am advanced"),
style: TextStyle(color: Colors.black,
fontSize: 20, fontFamily: 'Arial',
fontWeight: FontWeight.w100 ),),
highlightColor: Colors.white,
),
],
),
),
padding: EdgeInsets.all(10.0),
shape: getShape(changingViewModel, FitnessItem.advanced ),
onPressed:() =>
{
setState((){
selected = FitnessItem.advanced;
changingViewModel.customer.setFitnessLevel(selected);
print(selected);
}),
}
),
Divider(),
FlatButton(
child: Container(
width: cWidth,
child: Column(
children: [
InkWell(
child: Text(AppLocalizations.of(context).translate("Professional"),
style: TextStyle(color: Colors.blue,
fontSize: 32, fontFamily: 'Arial',
fontWeight: FontWeight.w900 ),),
highlightColor: Colors.white,
),
InkWell(
child: Text(AppLocalizations.of(context).translate("I am professional"),
style: TextStyle(color: Colors.black,
fontSize: 20, fontFamily: 'Arial',
fontWeight: FontWeight.w100 ),),
highlightColor: Colors.white,
),
],
),
),
padding: EdgeInsets.all(10.0),
shape: getShape(changingViewModel, FitnessItem.professional ),
onPressed:() =>
{
setState((){
selected = FitnessItem.professional;
changingViewModel.customer.setFitnessLevel(selected);
print(selected);
}),
}
),
Divider(),
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)
},
)
],
),
),
)
);
),
padding: EdgeInsets.all(10.0),
shape: getShape(
customerRepository, FitnessItem.professional),
onPressed: () => {
setState(() {
selected = FitnessItem.professional;
changeBloc.add(CustomerFitnessChange(fitness: selected));
print(selected);
}),
}),
Divider(),
RaisedButton(
color: Colors.orange,
textColor: Colors.white,
child: InkWell(
child: Text(AppLocalizations.of(context)
.translate("Next"))),
onPressed: () => {
changeBloc.add(CustomerSave()),
Navigator.of(context).pop(),
Navigator.of(context).pushNamed(
"customerBodyTypePage",
arguments: customerRepository)
},
)
],
),
),
);
})));
}
dynamic getShape( CustomerChangingViewModel changingViewModel, String fitnessLevel ) {
String selected = changingViewModel.customer.fitnessLevel;
dynamic returnCode = ( selected == fitnessLevel ) ?
RoundedRectangleBorder(
side: BorderSide(width: 4, color: Colors.orange),
)
:
RoundedRectangleBorder(
side: BorderSide(width: 1, color: Colors.blue),
);
dynamic getShape(CustomerRepository customerRepository, String fitnessLevel) {
String selected = customerRepository.fitnessLevel;
dynamic returnCode = (selected == fitnessLevel)
? RoundedRectangleBorder(
side: BorderSide(width: 4, color: Colors.orange),
)
: RoundedRectangleBorder(
side: BorderSide(width: 1, color: Colors.blue),
);
//return
return returnCode;
}
}
}
+145 -127
View File
@@ -1,41 +1,37 @@
import 'package:aitrainer_app/bloc/customer_change/customer_change_bloc.dart';
import 'package:aitrainer_app/localization/app_localization.dart';
import 'package:aitrainer_app/viewmodel/customer_changing_view_model.dart';
import 'package:aitrainer_app/repository/customer_repository.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_form_bloc/flutter_form_bloc.dart';
// ignore: must_be_immutable
class CustomerGoalPage extends StatefulWidget{
_CustomerGoalPageState _state;
_CustomerGoalPageState createState() {
_state = _CustomerGoalPageState();
return _state;
}
}
class GoalsItem{
class GoalsItem {
static String muscle = "gain_muscle";
static String weight = "weight_loss";
}
class _CustomerGoalPageState extends State<CustomerGoalPage> {
String selected;
// ignore: must_be_immutable
class CustomerGoalPage extends StatefulWidget {
initState() {
super.initState();
}
@override
State<StatefulWidget> createState() => _CustomerGoalPage();
}
class _CustomerGoalPage extends State<CustomerGoalPage> {
String selected;
@override
Widget build(BuildContext context) {
final double cWidth = MediaQuery.of(context).size.width*0.75;
final CustomerChangingViewModel changingViewModel = ModalRoute.of(context).settings.arguments;
selected = changingViewModel.customer.goal;
final double cWidth = MediaQuery.of(context).size.width * 0.75;
final CustomerRepository customerRepository =
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,
@@ -44,116 +40,138 @@ class _CustomerGoalPageState extends State<CustomerGoalPage> {
],
),
backgroundColor: Colors.transparent,
),
body: Container(
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage('asset/image/WT_light_background.png'),
fit: BoxFit.cover,
alignment: Alignment.center,
),
),
body: Container(
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage('asset/image/WT_light_background.png'),
fit: BoxFit.cover,
alignment: Alignment.center,
),
height: double.infinity,
width: double.infinity,
child: SingleChildScrollView(
child: Center(
child: Column(
children: [
Divider(),
InkWell(
child: Text(AppLocalizations.of(context).translate("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: 180,),
padding: EdgeInsets.all(0.0),
shape: getShape(changingViewModel, GoalsItem.muscle ),
onPressed:() =>
{
print("gain muscle"),
setState((){
selected = GoalsItem.muscle;
changingViewModel.customer.setGoal(GoalsItem.muscle);
}),
}
),
InkWell(
child: Text(AppLocalizations.of(context).translate("Gain Muscle"),
style: TextStyle(color: Colors.white,
fontSize: 32, fontFamily: 'Arial',
fontWeight: FontWeight.w900 ),),
highlightColor: Colors.white,
)
]
),
Divider(),
Stack(
alignment: Alignment.bottomLeft,
overflow: Overflow.visible,
children: [
FlatButton(
child: Image.asset("asset/image/WT_weight_loss.png", height: 180,),
padding: EdgeInsets.all(0.0),
shape: getShape(changingViewModel, GoalsItem.weight ),
onPressed:() =>
{
print("weight_loss"),
setState((){
selected = GoalsItem.weight;
changingViewModel.customer.setGoal(GoalsItem.weight);
}),
}
),
InkWell(
child: Text(AppLocalizations.of(context).translate("Loose Weight"),
style: TextStyle(color: Colors.white,
fontSize: 32, fontFamily: 'Arial',
fontWeight: FontWeight.w900 ),),
highlightColor: Colors.white,
)
]
),
Divider(),
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)
},
)
],
),
)
)
),
);
height: double.infinity,
width: double.infinity,
child: BlocProvider(
create: (context) =>
CustomerChangeBloc(customerRepository: customerRepository),
child: Builder(builder: (context) {
CustomerChangeBloc changeBloc =
BlocProvider.of<CustomerChangeBloc>(context);
return SingleChildScrollView(
child: Center(
child: Column(
children: [
Divider(),
InkWell(
child: Text(
AppLocalizations.of(context)
.translate("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: 180,
),
padding: EdgeInsets.all(0.0),
shape: getShape(changeBloc, GoalsItem.muscle),
onPressed: () => {
print("gain muscle"),
setState((){
selected = GoalsItem.muscle;
changeBloc.add(CustomerGoalChange(goal: GoalsItem.muscle));
}),
}),
InkWell(
child: Text(
AppLocalizations.of(context)
.translate("Gain Muscle"),
style: TextStyle(
color: Colors.white,
fontSize: 32,
fontFamily: 'Arial',
fontWeight: FontWeight.w900),
),
highlightColor: Colors.white,
)
]),
Divider(),
Stack(
alignment: Alignment.bottomLeft,
overflow: Overflow.visible,
children: [
FlatButton(
child: Image.asset(
"asset/image/WT_weight_loss.png",
height: 180,
),
padding: EdgeInsets.all(0.0),
shape: getShape(changeBloc, GoalsItem.weight),
onPressed: () => {
print("weight_loss"),
setState((){
selected = GoalsItem.muscle;
changeBloc.add(CustomerGoalChange(goal: GoalsItem.weight));
}),
}),
InkWell(
child: Text(
AppLocalizations.of(context)
.translate("Loose Weight"),
style: TextStyle(
color: Colors.white,
fontSize: 32,
fontFamily: 'Arial',
fontWeight: FontWeight.w900),
),
highlightColor: Colors.white,
)
]),
Divider(),
RaisedButton(
color: Colors.orange,
textColor: Colors.white,
child: InkWell(
child: Text(
AppLocalizations.of(context).translate("Next"))),
onPressed: () => {
//changingViewModel.saveCustomer(),
changeBloc.add(CustomerSave()),
Navigator.of(context).pop(),
Navigator.of(context).pushNamed("customerFitnessPage",
arguments: changeBloc.customerRepository)
},
)
],
),
));
}),
),
));
}
dynamic getShape( CustomerChangingViewModel changingViewModel, String goal ) {
String selectedGoal = changingViewModel.customer.goal;
dynamic returnCode = ( selectedGoal == goal ) ?
RoundedRectangleBorder(
side: BorderSide(width: 4, color: Colors.red),
)
: null;
dynamic getShape(CustomerChangeBloc customerBloc, String goal) {
String selectedGoal = customerBloc.customerRepository.goal;
dynamic returnCode = (selectedGoal == goal)
? RoundedRectangleBorder(
side: BorderSide(width: 4, color: Colors.red),
)
: null;
//return
return returnCode;
}
}
}
-93
View File
@@ -1,93 +0,0 @@
import 'package:aitrainer_app/viewmodel/customer_changing_view_model.dart';
import 'package:aitrainer_app/viewmodel/customer_view_model.dart';
import 'package:aitrainer_app/widgets/nav_drawer.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:aitrainer_app/widgets/customer_list_widget.dart';
class CustomerListPage extends StatefulWidget{
_CustomerListPageState createState() => _CustomerListPageState();
}
class _CustomerListPageState extends State<CustomerListPage> {
//final TextEditingController _controller = TextEditingController();
Future<List<CustomerViewModel>> _customers;
final _customerViewModel = CustomerChangingViewModel(null);
@override
void initState() {
super.initState();
_customers = _customerViewModel.getCustomers();
}
@override
Widget build(BuildContext context) {
//final customerViewModel = CustomerChangingViewModel(null);
return Scaffold(
drawer: NavDrawer(),
appBar: AppBar(
title: Text("Real customers")
),
body: Center(
child: FutureBuilder<List<CustomerViewModel>>(
future: _customers,
builder: (context, snapshot) {
if (snapshot.hasData) {
return CustomerListWidget(customers: _customerViewModel.customerList);
} else if (snapshot.hasError) {
return Text("${snapshot.error}");
}
// By default, show a loading spinner.
return CircularProgressIndicator();
},
),
),
/* body: Container(
padding: EdgeInsets.all(10),
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height,
child: Column(children: <Widget>[
Container(
padding: EdgeInsets.only(left: 10),
decoration: BoxDecoration(
color: Colors.grey,
borderRadius: BorderRadius.circular(10)
),
child: TextField(
controller: _controller,
onSubmitted: (value) {
if(value.isNotEmpty) {
customerViewModel.getCustomers();
_controller.clear();
}
},
style: TextStyle(color: Colors.white),
decoration: InputDecoration(
hintText: "Search",
hintStyle: TextStyle(color: Colors.white),
border: InputBorder.none
),
),
),
Expanded(
child: CustomerListWidget(customers: customerViewModel.customers)),
]),
), */
floatingActionButton: FloatingActionButton(
onPressed: () => Navigator.pushNamed(
context,
'customerNewPage',
),
child: Icon(Icons.add,),
mini: true,
)
);
}
}
+247 -223
View File
@@ -1,278 +1,302 @@
import 'package:aitrainer_app/bloc/account/account_bloc.dart';
import 'package:aitrainer_app/bloc/customer_change_form_bloc.dart';
import 'package:aitrainer_app/localization/app_localization.dart';
import 'package:aitrainer_app/viewmodel/customer_changing_view_model.dart';
import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/services.dart';
import 'package:provider/provider.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_form_bloc/flutter_form_bloc.dart';
import '../library_keys.dart';
// ignore: must_be_immutable
class CustomerModifyPage extends StatefulWidget{
_CustomerModifyPageState _state;
_CustomerModifyPageState createState() {
_state = _CustomerModifyPageState();
return _state;
}
}
class GenderItem {
GenderItem(this.dbValue,this.name);
final String dbValue;
String name;
}
class _CustomerModifyPageState extends State<CustomerModifyPage> {
class CustomerModifyPage extends StatelessWidget{
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);
CustomerChangingViewModel customerChangingViewModel = Provider.of<CustomerChangingViewModel>(context, listen: false);
customerChangingViewModel.customer.customer.sex = selectedGender.dbValue;
// ignore: close_sinks
final accountBloc = BlocProvider.of<AccountBloc>(context);
// we cannot initialize the translations in the initState
genders.forEach((GenderItem element) {
if ( element.dbValue == "m") {
/* genders.forEach((GenderItem element) {
if (element.dbValue == "m") {
element.name = AppLocalizations.of(context).translate("Man");
}
if ( element.dbValue == "w") {
if (element.dbValue == "w") {
element.name = AppLocalizations.of(context).translate("Woman");
}
});
*/
return BlocProvider(
create: (context) =>
CustomerChangeFormBloc(customerRepository: accountBloc.customerRepository),
child: Builder(builder: (context) {
// ignore: close_sinks
final customerBloc = BlocProvider.of<CustomerChangeFormBloc>(context);
return Scaffold(
resizeToAvoidBottomInset: true,
appBar: AppBar(
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: Container(
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage('asset/image/WT_light_background.png'),
fit: BoxFit.cover,
alignment: Alignment.center,
return Scaffold(
resizeToAvoidBottomInset: true,
appBar: AppBar(
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,
),
child: Form(
key: _formKey,
child: SingleChildScrollView(
scrollDirection: Axis.vertical,
padding: EdgeInsets.only(top: 40, left: 25, right: 45, bottom:100),
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: Container(
alignment: Alignment.center,
child: Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
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: customerChangingViewModel.customer.customer.email,
onFieldSubmitted: (input) => customerChangingViewModel.customer.setEmail(input)
)
)
],
),
Divider(),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded(
child:
TextFieldBlocBuilder(
key: LibraryKeys.loginEmailField,
style: TextStyle(fontSize: 12),
textFieldBloc: customerBloc.emailField,
decoration: InputDecoration(
fillColor: Colors.white24,
filled: true,
labelText: AppLocalizations.of(context)
.translate('Email'),
),
),
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)' ),
/* TextFormField(
style: TextStyle(fontSize: 12),
decoration: InputDecoration(
fillColor: Colors.white24,
filled: true,
labelText: AppLocalizations.of(context)
.translate('Email'),
), */
// initialValue: customerChangingViewModel.customer
// .customer.email,
// onFieldSubmitted: (input) =>
// customerChangingViewModel.customer.setEmail(
// input)
)
],
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded(
child:
TextFieldBlocBuilder(
style: TextStyle(fontSize: 12),
textFieldBloc: customerBloc.passwordField,
suffixButton: SuffixButton.obscureText,
decoration: InputDecoration(
fillColor: Colors.white24,
filled: true,
labelText: AppLocalizations.of(context)
.translate('Password (Leave empty if no change)'),
),
),
initialValue: customerChangingViewModel.customer.customer.password,
onFieldSubmitted: (input) => customerChangingViewModel.customer.setPassword(input)
/*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: customerChangingViewModel.customer.customer.password,
// onFieldSubmitted: (input) => customerChangingViewModel.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'),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded(
child: TextFieldBlocBuilder(
style: TextStyle(fontSize: 12),
textFieldBloc: customerBloc.nameField,
decoration: InputDecoration(
fillColor: Colors.white24,
filled: true,
labelText: AppLocalizations.of(context)
.translate('Name'),
),
),
initialValue: customerChangingViewModel.customer.customer.name,
onFieldSubmitted: (input) => customerChangingViewModel.customer.setName(input)
)
)
],
),
Divider(),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
],
),
Expanded(
child: TextFormField(
style: TextStyle(fontSize: 12),
decoration: InputDecoration(
fillColor: Colors.white24,
filled: true,
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
labelText: AppLocalizations.of(context).translate('First Name'),
Expanded(
child: TextFieldBlocBuilder(
style: TextStyle(fontSize: 12),
textFieldBloc: customerBloc.firstNameField,
decoration: InputDecoration(
fillColor: Colors.white24,
filled: true,
labelText: AppLocalizations.of(context)
.translate('First Name'),
),
),
keyboardType: TextInputType.emailAddress,
initialValue: customerChangingViewModel.customer.customer.firstname,
onFieldSubmitted: (input) => customerChangingViewModel.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
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded(
child: TextFieldBlocBuilder(
style: TextStyle(fontSize: 12),
textFieldBloc: customerBloc.birthYearField,
inputFormatters: [
FilteringTextInputFormatter(RegExp(r"[\d]"), allow: true)
],
initialValue: customerChangingViewModel.customer.customer.birthYear.toString(),
onFieldSubmitted: (input) => customerChangingViewModel.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'),
decoration: InputDecoration(
fillColor: Colors.white24,
filled: true,
labelText: AppLocalizations.of(context)
.translate('Birth Year'),
),
),
inputFormatters: <TextInputFormatter>[
WhitelistingTextInputFormatter.digitsOnly
],
initialValue: customerChangingViewModel.customer.customer.weight.toString(),
keyboardType: TextInputType.number,
onFieldSubmitted: (input) => customerChangingViewModel.customer.setWeight(int.parse(input)),
)
)
],
),
Divider(),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
],
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded(
child: DropdownButtonHideUnderline(
Expanded(
child: TextFieldBlocBuilder(
style: TextStyle(fontSize: 12),
textFieldBloc: customerBloc.weightField,
inputFormatters: [
FilteringTextInputFormatter(RegExp(r"[\d]"), allow: true)
],
decoration: InputDecoration(
fillColor: Colors.white24,
filled: true,
labelText: AppLocalizations.of(context)
.translate('Weight'),
),
),
)
],
),
Divider(),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded(
child: DropdownFieldBlocBuilder(
selectFieldBloc: customerBloc.genderField,
itemBuilder: (context, item) => item,
decoration: InputDecoration(
labelText: AppLocalizations.of(context).translate(
'Select a gender'),
)
),
)
/* child: DropdownButtonHideUnderline(
child: DropdownButton<GenderItem>(
hint: Text(AppLocalizations.of(context).translate('Select a gender')),
style: TextStyle(fontSize: 12, color: Colors.black),
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){
// value: selectedGender,
items: genders.map((GenderItem gender) {
return DropdownMenuItem<GenderItem>(
value: gender,
child: Text(gender.name)
);
}).toList(),
onChanged:(GenderItem gender) => {
setState(() {
selectedGender = gender;
customerChangingViewModel.customer.setSex(gender.dbValue);
onChanged: (GenderItem gender) => {
// setState(() {
// selectedGender = gender;
// customerChangingViewModel.customer.setSex(gender.dbValue);
print ("Gender " + gender.name);
})
//model.customer.sex =
},
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: () =>
{
customerBloc.add(SubmitFormBloc()),
Navigator.of(context).pushNamed("customerGoalPage", arguments: customerBloc.customerRepository)
},
)
)
)
],
),
],
),
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
Expanded(
child: RaisedButton(
color: Colors.orange,
textColor: Colors.white,
child: InkWell(
child: Text(AppLocalizations.of(context).translate("Next"))),
onPressed: () => {
customerChangingViewModel.saveCustomer(),
Navigator.of(context).pushNamed("customerGoalPage", arguments: customerChangingViewModel)
},
)
)
],
),
],
),
),
),
),
)
)
)
)
);
})
);
}
}
+211 -119
View File
@@ -1,153 +1,156 @@
import 'package:aitrainer_app/localization/app_language.dart';
import 'package:aitrainer_app/bloc/exercise_form_bloc.dart';
import 'package:aitrainer_app/localization/app_localization.dart';
import 'package:aitrainer_app/viewmodel/exercise_changing_view_model.dart';
import 'package:aitrainer_app/model/auth.dart';
import 'package:aitrainer_app/model/exercise_type.dart';
import 'package:aitrainer_app/repository/exercise_repository.dart';
import 'package:flutter/services.dart';
import 'package:intl/intl.dart';
import 'package:flutter_bloc/flutter_bloc.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:flutter_form_bloc/flutter_form_bloc.dart';
class ExerciseNewPage extends StatefulWidget{
_ExerciseNewPageState createState() => _ExerciseNewPageState();
}
class _ExerciseNewPageState extends State {
final List excluded = [43,44];
final _formKey = GlobalKey<FormState>();
class _ExerciseNewPageState extends State<ExerciseNewPage> {
@override
Widget build(BuildContext context) {
final ExerciseType exerciseType = ModalRoute.of(context).settings.arguments;
return Consumer<ExerciseChangingViewModel>(
builder: (context, model, child ) {
String exerciseName = "";
String customerName = "";
if ( model != null ) {
if ( model.exerciseViewModel == null ) {
model.createNewModel();
}
model.exerciseViewModel.createNew();
customerName = model != null && model.customer != null
? model.customer.name + " " +
model.customer.firstname
: "Please select a customer";
return BlocProvider(
create: (context) => ExerciseFormBloc(exerciseRepository: ExerciseRepository()),
child: Builder(builder: (context) {
// ignore: close_sinks
final exerciseBloc = BlocProvider.of<ExerciseFormBloc>(context);
exerciseName = model != null &&
model.exerciseType != null
? model.exerciseType.name
: "Please select an exercise";
}
exerciseBloc.exerciseRepository.setExerciseType(exerciseType);
String exerciseName = exerciseBloc.exerciseRepository.exerciseType.name;
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,
return Form(
autovalidate: true,
child: Scaffold(
resizeToAvoidBottomInset: false,
resizeToAvoidBottomInset: true,
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.deepOrange),
onPressed: () => {
Navigator.of(context).pop()
},
icon: Icon(Icons.arrow_back, color: Colors.white),
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(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height,
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage('asset/image/WT_login.png'),
fit: BoxFit.cover,
//height: double.infinity,
//width: double.infinity,
alignment: Alignment.center,
image: AssetImage('asset/image/WT_light_background.png'),
fit: BoxFit.fill,
alignment: Alignment.center,
),
),
child: Container(
padding: const EdgeInsets.only (top: 65, left:25, right: 100),
child: Column(
padding: const EdgeInsets.only (top: 25, left:25, right: 25),
child: SingleChildScrollView(
scrollDirection: Axis.vertical,
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
columnQuantityUnit(model),
columnQuantity(model),
Divider(color: Colors.transparent,),
Divider(color: Colors.transparent,),
Divider(color: Colors.transparent,),
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(
Text(AppLocalizations.of(context).translate(exerciseName) + " " +
AppLocalizations.of(context).translate('Save Exercise'),
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 18, color: Colors.deepOrange)),
Divider(color: Colors.transparent,),
Divider(color: Colors.transparent,),
Divider(color: Colors.transparent,),
columnQuantityUnit(exerciseBloc),
Divider(color: Colors.transparent,),
Divider(color: Colors.transparent,),
Divider(color: Colors.transparent,),
padding: EdgeInsets.only(bottom: 0),
color: Colors.transparent,
splashColor: Colors.black26,
child: Row(
children: [
columnQuantity(exerciseBloc),
Divider(),
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),
}
confirmationDialog( exerciseBloc ),
},
child: Text("Save", style: TextStyle(fontSize: 16),)
child: Text(AppLocalizations.of(context).translate("Save"), style: TextStyle(fontSize: 16),)
),
Divider(color: Colors.transparent,),
Divider(color: Colors.transparent,),
Divider(color: Colors.transparent,),
]),
)
)
),
),
);
});
);
})
);
}
Column columnQuantityUnit( ExerciseChangingViewModel model) {
Column columnQuantityUnit( ExerciseFormBloc bloc ) {
Column column = Column();
if ( model.exerciseType != null && model.exerciseType.unitQuantity == "1") {
if ( bloc.exerciseRepository.exerciseType != null &&
bloc.exerciseRepository.exerciseType.unitQuantity == "1") {
column = Column(
children: [
TextFormField(
TextFieldBlocBuilder(
textFieldBloc: bloc.unitQuantityField,
textAlign: TextAlign.center,
style: TextStyle(fontSize: 30,
color: Colors.lightBlue,
fontWeight: FontWeight.bold),
inputFormatters: [
FilteringTextInputFormatter(RegExp(r"[\d.]"), allow: true)
],
onChanged: (input) => {
print ("UnitQuantity value $input"),
bloc.exerciseRepository.setUnitQuantity(
double.parse(input))
},
decoration: InputDecoration(
fillColor: Colors.white,
filled: false,
hintStyle: TextStyle(fontSize: 16, color: Colors.black54, fontWeight: FontWeight.w100),
hintText: AppLocalizations.of(context).translate("The number of the exercise done with"),
labelStyle: TextStyle(fontSize: 16, color: Colors.lightBlue),
labelText: AppLocalizations.of(context).translate(
bloc.exerciseRepository.exerciseType.unitQuantityUnit),
),
),
/*TextFormField(
decoration: InputDecoration(
fillColor: Colors.white,
filled: false,
hintStyle: TextStyle(fontSize: 16, color: Colors.black54, fontWeight: FontWeight.w100),
hintText: AppLocalizations.of(context).translate("The number of the exercise done with"),
labelStyle: TextStyle(fontSize: 16, color: Colors.lightBlue),
labelText: AppLocalizations.of(context).translate(
bloc.exerciseRepository.exerciseType.unitQuantityUnit),
),
autovalidate: true,
textAlign: TextAlign.center,
initialValue: "0",
initialValue: "",
style: TextStyle(fontSize: 30,
color: Colors.lightBlue,
fontWeight: FontWeight.bold),
@@ -155,18 +158,19 @@ class _ExerciseNewPageState extends State {
return validateNumberInput(input);
},
inputFormatters: [
WhitelistingTextInputFormatter(RegExp(r"[\d.]"))
FilteringTextInputFormatter(RegExp(r"[\d.]"))
//WhitelistingTextInputFormatter(RegExp(r"[\d.]"))
],
onChanged: (input) => {
print ("UnitQuantity value $input"),
model.exerciseViewModel.setUnitQuantity(
bloc.exerciseRepository.setUnitQuantity(
double.parse(input))
},
),
), */
new InkWell(
child: new Text(AppLocalizations.of(context).translate(
model.exerciseType.unitQuantityUnit),
bloc.exerciseRepository.exerciseType.unitQuantityUnit),
style: TextStyle(fontSize: 16)),
),
@@ -175,16 +179,48 @@ class _ExerciseNewPageState extends State {
return column;
}
Column columnQuantity( ExerciseChangingViewModel model) {
Column column = Column();
column = Column(
Column columnQuantity( ExerciseFormBloc bloc ) {
Column column = Column(
children: [
TextFormField(
TextFieldBlocBuilder(
textFieldBloc: bloc.quantityField,
textAlign: TextAlign.center,
style: TextStyle(fontSize: 50,
color: Colors.deepOrange,
fontWeight: FontWeight.bold),
inputFormatters: [
FilteringTextInputFormatter(RegExp(r"[\d.]"), allow: true)
],
onChanged: (input) =>
{
print ("Quantity value $input"),
bloc.exerciseRepository.setQuantity(double.parse(input)),
bloc.exerciseRepository.setUnit(bloc.exerciseRepository.exerciseType.unit)
},
decoration: InputDecoration(
fillColor: Colors.white,
filled: false,
hintStyle: TextStyle(fontSize: 16, color: Colors.black54, fontWeight: FontWeight.w100),
hintText: AppLocalizations.of(context).translate("The number of the exercise"),
labelStyle: TextStyle(fontSize: 16, color: Colors.deepOrange),
labelText: AppLocalizations.of(context).translate(
bloc.exerciseRepository.exerciseType.unit),
),
),
/* TextFormField(
decoration: InputDecoration(
fillColor: Colors.white,
filled: false,
hintText: AppLocalizations.of(context).translate("The number of the exercise"),
hintStyle: TextStyle(fontSize: 16, color: Colors.black54, fontWeight: FontWeight.w100),
labelStyle: TextStyle(fontSize: 16, color: Colors.deepOrange),
labelText: AppLocalizations.of(context).translate(
bloc.exerciseRepository.exerciseType.unit),
),
autovalidate: true,
textAlign: TextAlign.center,
initialValue: "0",
style: TextStyle(fontSize: 60,
initialValue: "",
style: TextStyle(fontSize: 50,
color: Colors.deepOrange,
fontWeight: FontWeight.bold),
validator: (input) {
@@ -195,17 +231,12 @@ class _ExerciseNewPageState extends State {
],
onChanged: (input) =>
{
print ("Quantity value $input"),
model.exerciseViewModel.setQuantity(
double.parse(input)),
model.exerciseViewModel.setUnit(model.exerciseType.unit)
print ("Quantity value $input"),
bloc.exerciseRepository.setQuantity(double.parse(input)),
bloc.exerciseRepository.setUnit(bloc.exerciseRepository.exerciseType.unit)
}
),
new InkWell(
child: new Text(AppLocalizations.of(context).translate(model.exerciseType.unit),
style: TextStyle(fontSize: 16)),
),
),*/
]);
@@ -238,4 +269,65 @@ class _ExerciseNewPageState extends State {
return null;
}
void confirmationDialog( ExerciseFormBloc bloc ) {
print("exercise validated " + bloc.exerciseRepository.exercise.quantity.toString());
if ( bloc.exerciseRepository.exercise.quantity == null) {
return;
}
String quantity = bloc.exerciseRepository.exercise.quantity % 1 == 0?
bloc.exerciseRepository.exercise.quantity.round().toString() :
bloc.exerciseRepository.exercise.quantity.toString();
String unitQuantity = bloc.exerciseRepository.exercise.unitQuantity % 1 == 0?
bloc.exerciseRepository.exercise.unitQuantity.round().toString() :
bloc.exerciseRepository.exercise.unitQuantity.toString();
showCupertinoDialog(
useRootNavigator: true,
context: context,
barrierDismissible: false,
builder:(_) => CupertinoAlertDialog(
title: Text(AppLocalizations.of(context).translate("Do you save this exercise with these parameters?")),
content: Column(
children: [
Divider(),
Text(AppLocalizations.of(context).translate("Exercise") + ": " +
AppLocalizations.of(context).translate(bloc.exerciseRepository.exerciseType.name),
style: (TextStyle(color: Colors.blue)),),
Text(quantity + " " +
AppLocalizations.of(context).translate(bloc.exerciseRepository.exerciseType.unit),
style: (TextStyle(color: Colors.deepOrange)),),
Text(bloc.exerciseRepository.exerciseType.unitQuantity == "1" ?
AppLocalizations.of(context).translate("with") + " "
+ unitQuantity + " "
+ AppLocalizations.of(context).translate(bloc.exerciseRepository.exerciseType.unitQuantityUnit) :
"",
style: (TextStyle(color: Colors.deepOrange)),
),
]),
actions: [
FlatButton(
child: Text(AppLocalizations.of(context).translate("No")),
onPressed: () => Navigator.pop(context),
),
FlatButton(
child: Text(AppLocalizations.of(context).translate("Yes")),
onPressed: () => {
bloc.exerciseRepository.setCustomer(Auth().userLoggedIn),
bloc.exerciseRepository.addExercise(),
Navigator.pop(context),
Navigator.pop(context),
},
)
],
)
);
}
}
-59
View File
@@ -1,59 +0,0 @@
import 'package:aitrainer_app/viewmodel/exercise_type_changing_view_model.dart';
import 'package:aitrainer_app/viewmodel/exercise_type_view_model.dart';
import 'package:aitrainer_app/widgets/exercise_type_list_widget.dart';
import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
import 'package:aitrainer_app/widgets/nav_drawer.dart';
class ExerciseTypeListPage extends StatefulWidget{
_ExerciseTypeListPageState createState() => _ExerciseTypeListPageState();
}
class _ExerciseTypeListPageState extends State {
Future<List<ExerciseTypeViewModel>> _exerciseTypes;
final _exerciseTypeViewModel = ExerciseTypeChangingViewModel(null);
// Push the page and remove everything else
navigateToPage(BuildContext context, String page) {
Navigator.of(context).pushNamedAndRemoveUntil(page, (Route<dynamic> route) => false);
}
@override
void initState() {
super.initState();
_exerciseTypes = _exerciseTypeViewModel.getExerciseTypes();
}
@override
Widget build(BuildContext context) {
return Scaffold(
drawer: NavDrawer(),
appBar: AppBar(
title: Text('Exercises'),
),
body: Center(
child: FutureBuilder<List<ExerciseTypeViewModel>>(
future: _exerciseTypes,
builder: (context, snapshot) {
if (snapshot.hasData) {
return ExerciseTypeListWidget(exerciseTypes: _exerciseTypeViewModel.exerciseTypeList);
} else if (snapshot.hasError) {
return Text("${snapshot.error}");
}
// By default, show a loading spinner.
return CircularProgressIndicator();
},
),
),
floatingActionButton: FloatingActionButton(
onPressed: () => Navigator.pushNamed(
context,
'exerciseTypeNewPage',
),
child: Icon(Icons.add,),
mini: true,
)
);
}
}
-67
View File
@@ -1,67 +0,0 @@
import 'package:aitrainer_app/viewmodel/exercise_type_changing_view_model.dart';
import 'package:aitrainer_app/viewmodel/exercise_type_view_model.dart';
import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
import 'package:aitrainer_app/widgets/nav_drawer.dart';
// ignore: must_be_immutable
class ExerciseTypeModifyPage extends StatefulWidget{
ExerciseTypeViewModel exerciseTypeViewModel;
ExerciseTypeModifyPage({this.exerciseTypeViewModel});
_ExerciseTypeModifyPageState createState() => _ExerciseTypeModifyPageState();
}
class _ExerciseTypeModifyPageState extends State<ExerciseTypeModifyPage> {
final _formKey = GlobalKey<FormState>();
@override
Widget build(BuildContext context) {
final ExerciseTypeViewModel exerciseType = ModalRoute.of(context).settings.arguments;
ExerciseTypeChangingViewModel changeModel;
return Scaffold(
drawer: NavDrawer(),
appBar: AppBar(
title: Text('Modify "' + exerciseType.name + '"' ),
),
body: Center(
child: Form(
key:_formKey,
child: Column(
children: <Widget>[
TextFormField(
initialValue: exerciseType.name,
decoration: InputDecoration(
border: OutlineInputBorder(),
labelText: 'Exercise',
),
validator: (input) => input.length == 0 ? "Please type the name of the exercise" : null,
onChanged: (input) => exerciseType.setName(input),
) ,
TextFormField(
initialValue: exerciseType.description,
minLines: 4,
maxLines: 10,
decoration: InputDecoration(
border: OutlineInputBorder(),
labelText: 'Description',
),
onChanged: (input) => exerciseType.setDescription(input),
)
],
),
),
),
floatingActionButton: FloatingActionButton(
onPressed: () => {
if (_formKey.currentState.validate()) {
changeModel = ExerciseTypeChangingViewModel(exerciseType),
changeModel.saveExerciseType(),
Navigator.pop(context),
}
},
child: Icon(Icons.save,),
mini: true,
)
);
}
}
-64
View File
@@ -1,64 +0,0 @@
import 'package:aitrainer_app/viewmodel/exercise_type_changing_view_model.dart';
import 'package:aitrainer_app/viewmodel/exercise_type_view_model.dart';
import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
import 'package:aitrainer_app/widgets/nav_drawer.dart';
class ExerciseTypeNewPage extends StatefulWidget{
_ExerciseTypeNewPageState createState() => _ExerciseTypeNewPageState();
}
class _ExerciseTypeNewPageState extends State {
final ExerciseTypeViewModel exerciseType = ExerciseTypeViewModel();
final _formKey = GlobalKey<FormState>();
@override
Widget build(BuildContext context) {
ExerciseTypeChangingViewModel model;
exerciseType.createNew();
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: 'Exercise',
),
validator: (input) => input.length == 0 ? "Please type the name of the exercise" : null,
onChanged: (input) => exerciseType.setName(input),
) ,
TextFormField(
minLines: 4,
maxLines: 10,
decoration: InputDecoration(
border: OutlineInputBorder(),
labelText: 'Description',
),
onChanged: (input) => exerciseType.setDescription(input),
)
],
),
),
),
floatingActionButton: FloatingActionButton(
onPressed: () => {
if (_formKey.currentState.validate()) {
model = ExerciseTypeChangingViewModel(exerciseType),
model.addExerciseType(),
model.addNewExercise(exerciseType),
Navigator.pop(context),
}
},
child: Icon(Icons.save,),
mini: true,
)
);
}
}
+181 -142
View File
@@ -1,162 +1,201 @@
import 'package:aitrainer_app/bloc/login_form_bloc.dart';
import 'package:aitrainer_app/bloc/account/account_bloc.dart';
import 'package:aitrainer_app/localization/app_localization.dart';
import 'package:aitrainer_app/model/auth.dart';
import 'package:aitrainer_app/view/account.dart';
import 'package:aitrainer_app/viewmodel/customer_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:aitrainer_app/repository/user_repository.dart';
import 'package:aitrainer_app/util/common.dart';
import 'package:aitrainer_app/widgets/splash.dart';
import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
import 'package:provider/provider.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_facebook_login/flutter_facebook_login.dart';
import 'package:flutter_form_bloc/flutter_form_bloc.dart';
import '../library_keys.dart';
class LoginPage extends StatefulWidget{
_LoginPageState createState() => _LoginPageState();
class LoginPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return LoginWidget();
}
}
class _LoginPageState extends State<LoginPage> {
class LoginWidget extends StatefulWidget {
LoginWidget();
@override
State<StatefulWidget> createState() => _LoginWidget();
}
class _LoginWidget extends State<LoginWidget> {
final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
final UserViewModel user = UserViewModel();
final bool _obscureText = true;
final _formKey = GlobalKey<FormState>();
@override
Widget build(BuildContext context) {
UserChangingViewModel model = UserChangingViewModel(user);
CustomerChangingViewModel customerChangingViewModel = Provider.of<CustomerChangingViewModel>(context, listen: false);
user.createNew();
Future<dynamic> customer;
final State<AccountPage> stateAccount = ModalRoute.of(context).settings.arguments;
return Scaffold(
key: _scaffoldKey,
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,
final accountBloc = BlocProvider.of<AccountBloc>(context);
return BlocProvider(
create: (context) => LoginFormBloc(
userRepository: UserRepository(),
accountBloc: accountBloc
),
child: Builder(builder: (context) {
final loginBloc = BlocProvider.of<LoginFormBloc>(context);
return Scaffold(
key: _scaffoldKey,
body: FormBlocListener<LoginFormBloc, String, String>(
onSubmitting: (context, state) {
LoadingDialog.show(context);
},
onSuccess: (context, state) {
LoadingDialog.hide(context);
Navigator.of(context).pushNamed('home');
},
onFailure: (context, state) {
LoadingDialog.hide(context);
showInSnackBar(state.failureResponse);
},
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().then((_) =>
{
if ( stateAccount != null ) {
stateAccount.setState(() {
print("update account");
}),
},
customerChangingViewModel.customer.setCustomer(Auth().userLoggedIn),
Navigator.pop(context),
}).catchError(( error, stackTrace )=> showInSnackBar(error)
),
}
}),
]),
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),
])
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage('asset/image/WT_login.png'),
fit: BoxFit.cover,
//height: double.infinity,
//width: double.infinity,
alignment: Alignment.center,
),
),
child: buildLoginForm(loginBloc, accountBloc),
),
),
)
);
}));
}
Widget buildLoginForm(LoginFormBloc formBloc, AccountBloc accountBloc) {
final cWidth = Common.mediaSizeWidth(context);
return Form(
key: _formKey,
child: Container(
padding: const EdgeInsets.only(left: 25, right: 100),
child:
ListView(shrinkWrap: false, padding: EdgeInsets.only(top: 120.0),
children: <Widget>[
FlatButton(
child: new Image.asset(
'asset/image/login_fb.png',
width: cWidth * .85,
),
onPressed: () => {
_fbLogin(),
print("Login with FB"),
},
),
Text(AppLocalizations.of(context).translate("OR")),
Divider(),
Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
new InkWell(
child: new Text(
AppLocalizations.of(context).translate('Login'),
style: TextStyle(
fontWeight: FontWeight.bold, fontSize: 24)),
),
],
),
Divider(),
TextFieldBlocBuilder(
key: LibraryKeys.loginEmailField,
textFieldBloc: formBloc.emailField,
decoration: InputDecoration(
fillColor: Colors.white,
filled: true,
labelText: 'Email',
),
),
Divider(
color: Colors.transparent,
),
TextFieldBlocBuilder(
key: LibraryKeys.loginPasswordField,
textFieldBloc: formBloc.passwordField,
decoration: InputDecoration(
fillColor: Colors.white,
filled: true,
labelText: 'Password',
),
suffixButton: SuffixButton.obscureText,
),
Divider(
color: Colors.transparent,
),
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
new FlatButton(
key: LibraryKeys.loginOKButton,
child: Image.asset('asset/image/WT_OK.png',
width: 100, height: 100),
onPressed: () => {
formBloc.add(SubmitFormBloc())
}),
]),
Divider(
color: Colors.transparent,
),
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),
]),
])),
);
}
void showInSnackBar(String error) {
_scaffoldKey.currentState.showSnackBar(
SnackBar(
backgroundColor: Colors.orange,
content: Text(
AppLocalizations.of(context).translate("Customer does not exist or the password is wrong") + " " + error,
style: TextStyle(color: Colors.white))
)
);
_scaffoldKey.currentState.showSnackBar(SnackBar(
backgroundColor: Colors.orange,
content: Text(error, style: TextStyle(color: Colors.white))));
}
}
Future<Null> _fbLogin() async {
final FacebookLogin facebookSignIn = new FacebookLogin();
final FacebookLoginResult result = await facebookSignIn.logIn(['email']);
switch (result.status) {
case FacebookLoginStatus.loggedIn:
final FacebookAccessToken accessToken = result.accessToken;
showInSnackBar('''
Logged in!
Token: ${accessToken.token}
User id: ${accessToken.userId}
Expires: ${accessToken.expires}
Permissions: ${accessToken.permissions}
Declined permissions: ${accessToken.declinedPermissions}
''');
break;
case FacebookLoginStatus.cancelledByUser:
showInSnackBar('Login cancelled by the user.');
break;
case FacebookLoginStatus.error:
showInSnackBar('Something went wrong with the login process.\n'
'Here\'s the error Facebook gave us: ${result.errorMessage}');
break;
}
}
}
+96 -142
View File
@@ -1,161 +1,115 @@
import 'package:aitrainer_app/bloc/menu/menu_bloc.dart';
import 'package:aitrainer_app/localization/app_localization.dart';
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:aitrainer_app/widgets/menu_page_widget.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'dart:collection';
import 'package:provider/provider.dart';
import 'package:flutter/scheduler.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
// ignore: must_be_immutable
class MenuPage extends StatefulWidget {
_MenuPageState _state;
class MenuPage extends StatelessWidget {
static const routeName = '/menu_page';
int parent;
MenuBloc menuBloc;
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);
menuBloc = BlocProvider.of<MenuBloc>(context);
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.transparent,
title: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Text(AppLocalizations.of(context).translate("Tests")),
Image.asset(
'asset/image/WT_long_logo.png',
fit: BoxFit.cover,
height: 65.0,
),
],
),
leading: IconButton(
icon: Icon(Icons.arrow_back, color: Colors.white),
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,
),
appBar: AppBar(
backgroundColor: Colors.transparent,
title: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Text(AppLocalizations.of(context).translate("Tests")),
Image.asset(
'asset/image/WT_long_logo.png',
fit: BoxFit.cover,
height: 65.0,
),
child: CustomScrollView(
scrollDirection: Axis.vertical,
slivers: <Widget>[
buildMenuColumn(widget.parent, context, menu)
]
)
],
),
leading: IconButton(
icon: Icon(Icons.arrow_back, color: Colors.white),
onPressed: () =>
{
menuBloc.add(MenuTreeUp(parent: 0))
},
),
),
body: Container(
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage('asset/image/WT_menu_dark.png'),
fit: BoxFit.fill,
alignment: Alignment.center,
),
),
child: BlocConsumer<MenuBloc, MenuState>(
listener: (context, state) {
if (state is MenuError) {
Scaffold.of(context).showSnackBar(SnackBar(
backgroundColor: Colors.orange,
content: Text("error", style: TextStyle(color: Colors.white))));
} else if ( state is MenuLoading ) {
return MenuPageWidget();
}
},
// ignore: missing_return
builder: (context, state) {
if ( state is MenuInitial ) {
return LoadingMenuDialog();
} else if (state is MenuReady ) {
return MenuPageWidget();
} else if ( state is MenuLoading ) {
return LoadingMenuDialog();
}
}
)
),
bottomNavigationBar: BottomNavigator(bottomNavIndex: 0)
);
}
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.exerciseTypeId),
model.setExerciseType(exerciseType),
model.setCustomer(Auth().userLoggedIn),
if ( Auth().userLoggedIn == null ) {
Scaffold.of(context)
. showSnackBar(
SnackBar(
backgroundColor: Colors.orange,
content: Text(
AppLocalizations.of(context).translate('Please log in'),
style: TextStyle(color: Colors.white))
))
} 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;
}
}
class LoadingMenuDialog extends StatefulWidget {
LoadingMenuDialog({Key key}) : super(key: key);
@override
State<StatefulWidget> createState() => _LoadingMenuDialog();
}
class _LoadingMenuDialog extends State<LoadingMenuDialog> {
@override
void initState() {
super.initState();
/// We require the initializers to run after the loading screen is rendered
SchedulerBinding.instance.addPostFrameCallback((_) {
BlocProvider.of<MenuBloc>(context).add(MenuCreate());
});
}
@override
Widget build(BuildContext context) {
return WillPopScope(
onWillPop: () async => false,
child: Center(
child: Card(
child: Container(
width: 80,
height: 80,
padding: EdgeInsets.all(12.0),
child: CircularProgressIndicator(),
color: Colors.transparent,
),
),
),
);
}
}
+198 -124
View File
@@ -1,142 +1,216 @@
import 'package:aitrainer_app/bloc/account/account_bloc.dart';
import 'package:aitrainer_app/bloc/registration_form_bloc.dart';
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/user_changing_view_model.dart';
import 'package:aitrainer_app/viewmodel/user_view_model.dart';
import 'package:aitrainer_app/util/common.dart';
import 'package:aitrainer_app/repository/customer_repository.dart';
import 'package:aitrainer_app/repository/user_repository.dart';
import 'package:aitrainer_app/widgets/splash.dart';
import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
import 'package:provider/provider.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_facebook_login/flutter_facebook_login.dart';
import 'package:flutter_form_bloc/flutter_form_bloc.dart';
class RegistrationPage extends StatefulWidget{
_RegistrationPageState createState() => _RegistrationPageState();
import '../library_keys.dart';
class RegistrationPage extends StatelessWidget {
final UserRepository userRepository = UserRepository();
final CustomerRepository customerRepository = CustomerRepository();
@override
Widget build(BuildContext context) {
return RegistrationWidget(
userRepository: userRepository, customerRepository: customerRepository);
}
}
class _RegistrationPageState extends State<RegistrationPage> {
final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
final UserViewModel user = UserViewModel();
bool _obscureText = true;
class RegistrationWidget extends StatefulWidget {
final UserRepository userRepository;
final CustomerRepository customerRepository;
RegistrationWidget({this.userRepository, this.customerRepository});
@override
State<StatefulWidget> createState() => _RegistrationWidget();
}
class _RegistrationWidget extends State<RegistrationWidget> {
final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
final _formKey = GlobalKey<FormState>();
@override
Widget build(BuildContext context) {
UserChangingViewModel model = UserChangingViewModel(user);
CustomerChangingViewModel customerChangingViewModel = Provider.of<CustomerChangingViewModel>(context, listen: false);
user.createNew();
final cWidth = Common.mediaSizeWidth(context);
// ignore: close_sinks
final accountBloc = BlocProvider.of<AccountBloc>(context);
return BlocProvider(
create: (context) => RegistrationFormBloc(
userRepository: UserRepository(),
accountBloc: accountBloc),
child: Builder(builder: (context) {
// ignore: close_sinks
final registrationBloc = BlocProvider.of<RegistrationFormBloc>(context);
return Scaffold(
key: _scaffoldKey,
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('SignUp'),
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 24)),
),
],
),
return Scaffold(
key: _scaffoldKey,
body: FormBlocListener<RegistrationFormBloc, String, String>(
onSubmitting: (context, state) {
LoadingDialog.show(context);
},
onSuccess: (context, state) {
LoadingDialog.hide(context);
Navigator.of(context).pushNamed('customerModifyPage');
},
onFailure: (context, state) {
LoadingDialog.hide(context);
showInSnackBar(state.failureResponse);
},
child: 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: ListView(
shrinkWrap: false,
padding: EdgeInsets.only(top: 120.0),
//mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
//Spacer(flex:4),
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
FlatButton(
child: new Image.asset(
'asset/image/login_fb.png',
width: cWidth * .85,
),
onPressed: () => {
_fbLogin(),
print("Login with FB"),
},
),
onPressed:() => {
if (_formKey.currentState.validate()) {
model = UserChangingViewModel(user),
model.addUser().then((_) =>
{
Navigator.of(context).pushNamed("customerModifyPage",),
customerChangingViewModel.customer.setCustomer(Auth().userLoggedIn),
}).catchError(( error, stackTrace )=> showInSnackBar()
Text(AppLocalizations.of(context).translate("OR")),
Divider(),
Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
new InkWell(
child: new Text(
AppLocalizations.of(context)
.translate('SignUp'),
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 24)),
),
}
}),
]),
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),
])
),
),
),
);
],
),
Divider(),
TextFieldBlocBuilder(
key: LibraryKeys.loginEmailField,
textFieldBloc: registrationBloc.emailField,
decoration: InputDecoration(
fillColor: Colors.white,
filled: true,
labelText: 'Email',
),
),
Divider(
color: Colors.transparent,
),
TextFieldBlocBuilder(
key: LibraryKeys.loginPasswordField,
textFieldBloc: registrationBloc.passwordField,
decoration: InputDecoration(
fillColor: Colors.white,
filled: true,
labelText: 'Password',
),
suffixButton: SuffixButton.obscureText,
),
Divider(
color: Colors.transparent,
),
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
new FlatButton(
child: Image.asset(
'asset/image/WT_OK.png',
width: 100,
height: 100),
onPressed: () => {
registrationBloc.add(SubmitFormBloc())
}),
]),
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),
])),
),
),
),
);
}));
}
void showInSnackBar() {
_scaffoldKey.currentState.showSnackBar(
SnackBar(
backgroundColor: Colors.orange,
content: Text(
AppLocalizations.of(context).translate("Customer exists"),
style: TextStyle(color: Colors.white))
)
);
void showInSnackBar(String error) {
_scaffoldKey.currentState.showSnackBar(SnackBar(
backgroundColor: Colors.orange,
content: Text(
AppLocalizations.of(context)
.translate("There is an error: during registration:") +
" " +
error,
style: TextStyle(color: Colors.white))));
}
}
Future<Null> _fbLogin() async {
final FacebookLogin facebookSignIn = new FacebookLogin();
final FacebookLoginResult result = await facebookSignIn.logIn(['email']);
switch (result.status) {
case FacebookLoginStatus.loggedIn:
final FacebookAccessToken accessToken = result.accessToken;
showInSnackBar('''
Logged in!
Token: ${accessToken.token}
User id: ${accessToken.userId}
Expires: ${accessToken.expires}
Permissions: ${accessToken.permissions}
Declined permissions: ${accessToken.declinedPermissions}
''');
break;
case FacebookLoginStatus.cancelledByUser:
showInSnackBar('Login cancelled by the user.');
break;
case FacebookLoginStatus.error:
showInSnackBar('Something went wrong with the login process.\n'
'Here\'s the error Facebook gave us: ${result.errorMessage}');
break;
}
}
}
+44 -47
View File
@@ -1,30 +1,21 @@
import 'package:aitrainer_app/bloc/settings/settings_bloc.dart';
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:aitrainer_app/widgets/splash.dart';
import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter_bloc/flutter_bloc.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>();
class SettingsPage extends StatelessWidget{
@override
Widget build(BuildContext context) {
BottomNavigator bottomNav = BottomNavigator();
_locale = appLanguage.appLocal;
// ignore: close_sinks
SettingsBloc settingsBloc = BlocProvider.of<SettingsBloc>(context);
settingsBloc.context = context;
return Scaffold(
appBar: AppBar(
title: Row(
@@ -50,54 +41,60 @@ class _SettingsPageState extends State<SettingsPage> {
),
),
child: Form(
key: _formKey,
child:
ListView(
child: BlocConsumer<SettingsBloc, SettingsState>(
listener: (context, state) {
if ( state is SettingsError ) {
}
},
// ignore: missing_return
builder: (context, state) {
if ( state is SettingsLoading ) {
return LoadingDialog();
} else if ( state is SettingsReady || state is SettingsInitial) {
return ListView(
padding: EdgeInsets.only(top: 150),
children: <Widget>[
ListTile(
leading: Icon(Icons.language),
subtitle: Text(AppLocalizations.of(context).translate("Change App 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) {
value: state.props[0] == 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),
onChanged: (String lang) =>
settingsBloc.add(
SettingsChangeLanguage(language: lang)
),
)
),
]
]
);
} else {
return Container();
}
}
),
),
),
bottomNavigationBar: bottomNav.buildBottomNavigator(context, widget._state)
bottomNavigationBar: BottomNavigator(bottomNavIndex: 3)
);
}
_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();
});
}
}