WT1.1.2f Purchase, Product, Property, BMR, BMI, Sizes

This commit is contained in:
bossanyit 2020-11-16 15:42:40 +01:00
parent 5fa5382e3f
commit e28f1edf50
48 changed files with 2631 additions and 1441 deletions

4
.gitignore vendored
View File

@ -42,3 +42,7 @@ app.*.map.json
# Exceptions to above rules. # Exceptions to above rules.
!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages !/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages
local.properties
.gitignore
.vscode/launch.json
.vscode/settings.json

View File

@ -1,6 +1,6 @@
# aitrainer_app # aitrainer_app
The AITRAINER Mobile Application The WorkoutTest Mobile Application
Prototye 1.1.0s Prototye 1.1.2f

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.1 MiB

View File

@ -69,7 +69,7 @@
"The number of the exercise done with": "The number of the exercise done with", "The number of the exercise done with": "The number of the exercise done with",
"Please repeat with": "Please repeat with", "Please repeat with": "Please repeat with",
"Execute the": "Execute the", "Execute the": "Execute the",
". set!":". set!", "set!":"set!",
"repeat": "repeat", "repeat": "repeat",
@ -97,6 +97,8 @@
"Gain Muscle": "Gain Muscle", "Gain Muscle": "Gain Muscle",
"Loose Weight": "Loose Weight", "Loose Weight": "Loose Weight",
"Your Fitness State": "Your Fitness State", "Your Fitness State": "Your Fitness State",
"Fitness level": "Fizikai állapot",
"Fitness Activity":"Fitness Activity",
"Beginner": "Beginner", "Beginner": "Beginner",
"I am beginner": "I am beginner", "I am beginner": "I am beginner",
"Intermediate": "Intermediate", "Intermediate": "Intermediate",
@ -105,6 +107,7 @@
"I am advanced": "4+ times a week", "I am advanced": "4+ times a week",
"Professional": "Professional", "Professional": "Professional",
"I am professional": "I am a professional", "I am professional": "I am a professional",
"No item selected":"No item selected",
"Your Body Type": "Your Body Type", "Your Body Type": "Your Body Type",
"Ectomorph": "Ectomorph", "Ectomorph": "Ectomorph",
"Endomorph": "Endomorph", "Endomorph": "Endomorph",
@ -207,5 +210,18 @@
"Are you sure to delete this exercise?": "Are you sure to delete this exercise?", "Are you sure to delete this exercise?": "Are you sure to delete this exercise?",
"I forgot the password":"I forgot the password", "I forgot the password":"I forgot the password",
"Exception: Instance of 'NotFoundException'": "Customer with the email not found. Please register or reset your password" "Exception: Instance of 'NotFoundException'": "Customer with the email not found. Please register or reset your password",
"More »": "More »",
"Done": "Done",
"Height":"Height",
"Actual Height":"Actual Height",
"Actual Weight":"Actual Weight",
"Based on your weight and height your goal for BMI and weight:":"Based on your weight and height your goal for BMI and weight:",
"Body Mass Index":"Body Mass Index",
"Basal Metabolic Rate":"Basal Metabolic Rate",
"Based on your weight, height and activity your BMR value":"Based on your weight, height and activity this is your daily calory demand.",
"Your Sizes":"Your Sizes",
"Size Of Your":"Size Of Your",
"Please type the following data:":"Please type the following data:",
"Cancel": "Cancel"
} }

View File

@ -58,7 +58,7 @@
"The number of the exercise done with": "Írd be, mennyivel csináltad a gyakorlatot", "The number of the exercise done with": "Írd be, mennyivel csináltad a gyakorlatot",
"Please repeat with": "Kérlek ismételd", "Please repeat with": "Kérlek ismételd",
"Execute the": "Hajtsd végre a(z)", "Execute the": "Hajtsd végre a(z)",
". set!":". sorozatot!", "set!":"sorozatot!",
"Name": "Név", "Name": "Név",
"Exercise": "Gyakorlat", "Exercise": "Gyakorlat",
@ -97,6 +97,8 @@
"Gain Muscle": "Izomépítés", "Gain Muscle": "Izomépítés",
"Loose Weight": "Fogyás", "Loose Weight": "Fogyás",
"Your Fitness State": "Milyen a fizikai állapotod?", "Your Fitness State": "Milyen a fizikai állapotod?",
"Fitness level": "Fizikai állapot",
"Fitness Activity":"Fizikai aktivitás",
"Beginner": "Kezdő", "Beginner": "Kezdő",
"I am beginner": "Kezdő / Újrakezdő vagyok", "I am beginner": "Kezdő / Újrakezdő vagyok",
"Intermediate": "Középhaladó", "Intermediate": "Középhaladó",
@ -106,6 +108,7 @@
"Professional": "Professzionális", "Professional": "Professzionális",
"I am professional": "Professzionális sportoló vagyok", "I am professional": "Professzionális sportoló vagyok",
"Your Body Type": "Milyen a testtípusod?", "Your Body Type": "Milyen a testtípusod?",
"No item selected":"Nincs kiválasztott elem",
"Ectomorph": "Ectomorf", "Ectomorph": "Ectomorf",
"Endomorph":"Endomorf", "Endomorph":"Endomorf",
"Mesomorph":"Mezomorf", "Mesomorph":"Mezomorf",
@ -126,7 +129,7 @@
"Please add an exercise plan": "Kérlek add meg az edzéstervet a gyakorlathoz", "Please add an exercise plan": "Kérlek add meg az edzéstervet a gyakorlathoz",
"Serie": "Széria", "Serie": "Sorozat",
"Repeats": "Ismétlés", "Repeats": "Ismétlés",
"Save The Exercise To The Exercise Plan": "Gyakorlat mentése az edzéstervhez", "Save The Exercise To The Exercise Plan": "Gyakorlat mentése az edzéstervhez",
"The number of the serie done with":"Mennyi szériát csinálsz", "The number of the serie done with":"Mennyi szériát csinálsz",
@ -194,7 +197,6 @@
"Calf": "vádli", "Calf": "vádli",
"Bring me there": "Vigyél oda", "Bring me there": "Vigyél oda",
"My Body Development": "Testem fejlődése", "My Body Development": "Testem fejlődése",
"You see here your whole body development by muscle groups.": "Itt láthatod a tested fejlődését izomcsoportonként", "You see here your whole body development by muscle groups.": "Itt láthatod a tested fejlődését izomcsoportonként",
@ -209,5 +211,18 @@
"Are you sure to delete this exercise?": "Biztos, hogy törlöd a gyakorlatot?", "Are you sure to delete this exercise?": "Biztos, hogy törlöd a gyakorlatot?",
"I forgot the password":"Elfelejtett jelszó", "I forgot the password":"Elfelejtett jelszó",
"Exception: Instance of 'NotFoundException'": "Ezzel az email címmel nem található felhasználó. Kérlek regisztálj vagy kérj jelszóemlékeztetőt" "Exception: Instance of 'NotFoundException'": "Ezzel az email címmel nem található felhasználó. Kérlek regisztálj vagy kérj jelszóemlékeztetőt",
"More »": "Részletek »",
"Done": "Kész",
"Height":"Magasság",
"Actual Height":"Akt. magasság",
"Actual Weight":"Aktuális tömeg",
"Based on your weight and height your goal for BMI and weight:":"A jelenlegi tömeged és magasságod alapján kiszámoltuk, hogy mennyi legyen a célod a BMI (testtömegindex) és tömeg elérésben:",
"Body Mass Index":"Testtömegindex",
"Basal Metabolic Rate":"Alapanyagcsere érték",
"Based on your weight, height and activity your BMR value":"A tömeged, magasságod és aktivitásod alapján megközelítőleg ennyi a napi kalóriaszükségleted.",
"Your Sizes":"Méreteid",
"Size Of Your":"Testméret:",
"Please type the following data:":"Kérlek írd be a következő adatot:",
"Cancel": "Mégsem"
} }

View File

@ -10,29 +10,105 @@ part 'customer_change_state.dart';
class CustomerChangeBloc extends Bloc<CustomerChangeEvent, CustomerChangeState> { class CustomerChangeBloc extends Bloc<CustomerChangeEvent, CustomerChangeState> {
final CustomerRepository customerRepository; final CustomerRepository customerRepository;
CustomerChangeBloc({this.customerRepository}) : super(CustomerChangeInitial()); bool visiblePassword = false;
int year = 1990;
double weight = 60;
double height = 170;
CustomerChangeBloc({this.customerRepository}) : super(CustomerChangeInitial()) {
year = this.customerRepository.customer.birthYear;
weight = this.customerRepository.getWeight();
height = this.customerRepository.getHeight();
}
@override @override
Stream<CustomerChangeState> mapEventToState( Stream<CustomerChangeState> mapEventToState(
CustomerChangeEvent event, CustomerChangeEvent event,
) async* { ) async* {
try { try {
if (event is CustomerGoalChange) { if (event is CustomerLoad) {
yield CustomerChangeLoading();
yield CustomerDataChanged();
} else if (event is CustomerGoalChange) {
customerRepository.setGoal(event.goal); customerRepository.setGoal(event.goal);
yield CustomerDataChanged(); yield CustomerDataChanged();
} else if (event is CustomerChangePasswordObscure) {
visiblePassword = !visiblePassword;
yield CustomerDataChanged();
} else if (event is CustomerFitnessChange) { } else if (event is CustomerFitnessChange) {
customerRepository.setFitnessLevel(event.fitness); customerRepository.setFitnessLevel(event.fitness);
yield CustomerDataChanged(); yield CustomerDataChanged();
} else if (event is CustomerBirthYearChange) {
yield CustomerChangeLoading();
customerRepository.setBirthYear(event.year);
year = event.year;
yield CustomerDataChanged();
} else if (event is CustomerWeightChange) {
yield CustomerChangeLoading();
customerRepository.setWeight(event.weight);
weight = event.weight.toDouble();
yield CustomerDataChanged();
} else if (event is CustomerHeightChange) {
yield CustomerChangeLoading();
customerRepository.setHeight(event.height);
height = event.height.toDouble();
yield CustomerDataChanged();
} else if (event is CustomerBodyTypeChange) { } else if (event is CustomerBodyTypeChange) {
customerRepository.setBodyType(event.bodyType); customerRepository.setBodyType(event.bodyType);
yield CustomerDataChanged(); yield CustomerDataChanged();
} else if (event is CustomerEmailChange) {
customerRepository.setEmail(event.email);
yield CustomerDataChanged();
} else if (event is CustomerPasswordChange) {
customerRepository.setPassword(event.password);
yield CustomerDataChanged();
} else if (event is CustomerFirstNameChange) {
customerRepository.setFirstName(event.firstName);
yield CustomerDataChanged();
} else if (event is CustomerNameChange) {
customerRepository.setName(event.name);
yield CustomerDataChanged();
} else if (event is CustomerGenderChange) {
customerRepository.setSex(event.gender == 0 ? "m" : "w");
yield CustomerDataChanged();
} else if (event is CustomerSave) { } else if (event is CustomerSave) {
yield CustomerSaving(); yield CustomerSaving();
await customerRepository.saveCustomer(); if (validation()) {
yield CustomerSaveSuccess(); await customerRepository.saveCustomer();
yield CustomerSaveSuccess();
} else {
yield CustomerSaveError(message: "Please provide the necessary information");
}
} }
} on Exception catch(e) { } on Exception catch (e) {
yield CustomerSaveError(message: e.toString()); yield CustomerSaveError(message: e.toString());
} }
} }
bool validation() {
print("f " + customerRepository.customer.firstname);
return (emailValidation(customerRepository.customer.email) == null) &&
(passwordValidation(customerRepository.customer.password) == null) &&
(nameValidation(customerRepository.customer.firstname) == null) &&
(nameValidation(customerRepository.customer.name) == null);
}
String emailValidation(String email) {
bool emailValid = RegExp(r"^[a-zA-Z0-9.a-zA-Z0-9.!#$%&'*+-/=?^_`{|}~]+@[a-zA-Z0-9]+\.[a-zA-Z]+").hasMatch(email);
return emailValid ? null : "Please type an email address";
}
String passwordValidation(String value) {
if (value == null || value.length == 0) {
return null;
}
bool valid = 8 < value.length;
return valid ? null : "Password too short";
}
String nameValidation(String value) {
if (value == null || value.length == 0) {
return "Name too short";
}
return null;
}
} }

View File

@ -31,6 +31,78 @@ class CustomerBodyTypeChange extends CustomerChangeEvent {
List<Object> get props => [bodyType]; List<Object> get props => [bodyType];
} }
class CustomerBirthYearChange extends CustomerChangeEvent {
final int year;
const CustomerBirthYearChange({this.year});
@override
List<Object> get props => [year];
}
class CustomerWeightChange extends CustomerChangeEvent {
final int weight;
const CustomerWeightChange({this.weight});
@override
List<Object> get props => [weight];
}
class CustomerHeightChange extends CustomerChangeEvent {
final int height;
const CustomerHeightChange({this.height});
@override
List<Object> get props => [height];
}
class CustomerGenderChange extends CustomerChangeEvent {
final int gender;
const CustomerGenderChange({this.gender});
@override
List<Object> get props => [gender];
}
class CustomerEmailChange extends CustomerChangeEvent {
final String email;
const CustomerEmailChange({this.email});
@override
List<Object> get props => [email];
}
class CustomerFirstNameChange extends CustomerChangeEvent {
final String firstName;
const CustomerFirstNameChange({this.firstName});
@override
List<Object> get props => [firstName];
}
class CustomerNameChange extends CustomerChangeEvent {
final String name;
const CustomerNameChange({this.name});
@override
List<Object> get props => [name];
}
class CustomerPasswordChange extends CustomerChangeEvent {
final String password;
const CustomerPasswordChange({this.password});
@override
List<Object> get props => [password];
}
class CustomerChangePasswordObscure extends CustomerChangeEvent {
const CustomerChangePasswordObscure();
}
class CustomerLoad extends CustomerChangeEvent {
const CustomerLoad();
}
class CustomerSave extends CustomerChangeEvent { class CustomerSave extends CustomerChangeEvent {
const CustomerSave(); const CustomerSave();
} }

View File

@ -11,6 +11,10 @@ class CustomerChangeInitial extends CustomerChangeState {
const CustomerChangeInitial(); const CustomerChangeInitial();
} }
class CustomerChangeLoading extends CustomerChangeState {
const CustomerChangeLoading();
}
class CustomerSaving extends CustomerChangeState { class CustomerSaving extends CustomerChangeState {
const CustomerSaving(); const CustomerSaving();
} }

View File

@ -4,6 +4,9 @@ import 'package:flutter_form_bloc/flutter_form_bloc.dart';
class CustomerChangeFormBloc extends FormBloc<String, String> { class CustomerChangeFormBloc extends FormBloc<String, String> {
final CustomerRepository customerRepository; final CustomerRepository customerRepository;
int weight = 60;
int birthYear = 1990;
final emailField = TextFieldBloc( final emailField = TextFieldBloc(
validators: [ validators: [
FieldBlocValidators.required, FieldBlocValidators.required,
@ -22,31 +25,32 @@ class CustomerChangeFormBloc extends FormBloc<String, String> {
//FieldBlocValidators.confirmPassword(passwordField), //FieldBlocValidators.confirmPassword(passwordField),
], ],
); );
final birthYearField = TextFieldBloc(); final birthYearField = InputFieldBloc<int, Object>(initialValue: 1990);
final weightField = TextFieldBloc(); final weightField = InputFieldBloc<int, Object>(initialValue: 60);
final genderField = SelectFieldBloc(); final genderField = InputFieldBloc<int, Object>(initialValue: 0);
final goalField = TextFieldBloc(); final goalField = TextFieldBloc();
CustomerChangeFormBloc({this.customerRepository}) { CustomerChangeFormBloc({this.customerRepository}) {
addFieldBlocs(fieldBlocs: [ addFieldBlocs(fieldBlocs: [
emailField, emailField,
firstNameField, firstNameField,
nameField, nameField,
passwordField, passwordField,
birthYearField, birthYearField,
weightField, weightField,
genderField, genderField,
goalField,
goalField, ]);
]);
emailField.updateInitialValue(customerRepository.customer.email); emailField.updateInitialValue(customerRepository.customer.email);
firstNameField.updateInitialValue(customerRepository.customer.firstname); firstNameField.updateInitialValue(customerRepository.customer.firstname);
nameField.updateInitialValue(customerRepository.customer.name); nameField.updateInitialValue(customerRepository.customer.name);
birthYearField.updateInitialValue(customerRepository.customer.birthYear.toString()); birthYearField.updateInitialValue(customerRepository.customer.birthYear);
weightField.updateInitialValue(customerRepository.customer.weight.toString()); weightField.updateInitialValue(customerRepository.customer.getProperty("weight").toInt());
genderField.updateInitialValue(customerRepository.getGenderByDBValue(customerRepository.sex));
int initialGender = customerRepository.getGenderByDBValue(customerRepository.sex) == "m" ? 0 : 1;
genderField.updateInitialValue(initialGender);
firstNameField.onValueChanges(onData: (previous, current) async* { firstNameField.onValueChanges(onData: (previous, current) async* {
customerRepository.setFirstName(current.value); customerRepository.setFirstName(current.value);
@ -54,7 +58,7 @@ class CustomerChangeFormBloc extends FormBloc<String, String> {
nameField.onValueChanges(onData: (previous, current) async* { nameField.onValueChanges(onData: (previous, current) async* {
customerRepository.setName(current.value); customerRepository.setName(current.value);
}); });
birthYearField.onValueChanges(onData: (previous, current) async* { /*birthYearField.onValueChanges(onData: (previous, current) async* {
customerRepository.setBirthYear(current.valueToInt); customerRepository.setBirthYear(current.valueToInt);
}); });
weightField.onValueChanges(onData: (previous, current) async* { weightField.onValueChanges(onData: (previous, current) async* {
@ -63,24 +67,49 @@ class CustomerChangeFormBloc extends FormBloc<String, String> {
customerRepository.genders.forEach((element) { customerRepository.genders.forEach((element) {
genderField.addItem(element.name); genderField.addItem(element.name);
}); });*/
genderField.onValueChanges(onData: (previous, current) async* { genderField.onValueChanges(onData: (previous, current) async* {
String dbValue = customerRepository.getGenderByName(current.value); String dbValue = customerRepository.getGenderByName(current.value.toString());
customerRepository.setSex(dbValue); customerRepository.setSex(dbValue);
}); });
}
int getGender() {
return customerRepository.customer.sex == "M" ? 0 : 1;
}
void switchGender(int index) {
String dbValue;
if (index == 0) {
dbValue = customerRepository.getGenderByName("Man");
} else if (index == 1) {
dbValue = customerRepository.getGenderByName("Woman");
}
customerRepository.setSex(dbValue);
genderField.add(UpdateFieldBlocValue(dbValue));
}
void changeWeight(int value) {
customerRepository.setWeight(value);
weight = value;
weightField.updateValue(value);
}
changeBirthYear(int value) {
customerRepository.setBirthYear(value);
birthYear = value;
birthYearField.updateValue(value);
} }
@override @override
void onSubmitting() async { void onSubmitting() async {
print("on Submitting Custom form"); print("on Submitting Customer Change form");
try { try {
emitLoading(progress: 30); emitLoading(progress: 30);
// Emit either Loaded or Error // Emit either Loaded or Error
await customerRepository.saveCustomer(); await customerRepository.saveCustomer();
emitSuccess(canSubmitAgain: false); emitSuccess(canSubmitAgain: true);
} on Exception catch (ex) { } on Exception catch (ex) {
emitFailure(failureResponse: ex.toString()); emitFailure(failureResponse: ex.toString());
} }
@ -98,5 +127,4 @@ class CustomerChangeFormBloc extends FormBloc<String, String> {
goalField.close(); goalField.close();
return super.close(); return super.close();
} }
}
}

View File

@ -1,25 +1,212 @@
import 'dart:async'; import 'dart:async';
import 'package:aitrainer_app/bloc/menu/menu_bloc.dart'; import 'package:aitrainer_app/bloc/menu/menu_bloc.dart';
import 'package:aitrainer_app/model/cache.dart';
import 'package:aitrainer_app/model/property.dart';
import 'package:aitrainer_app/model/exercise_type.dart'; import 'package:aitrainer_app/model/exercise_type.dart';
import 'package:aitrainer_app/model/fitness_state.dart';
import 'package:aitrainer_app/repository/customer_repository.dart';
import 'package:aitrainer_app/repository/exercise_repository.dart'; import 'package:aitrainer_app/repository/exercise_repository.dart';
import 'package:bloc/bloc.dart'; import 'package:bloc/bloc.dart';
import 'package:equatable/equatable.dart'; import 'package:equatable/equatable.dart';
import 'package:flutter/animation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_form_bloc/flutter_form_bloc.dart'; import 'package:flutter_form_bloc/flutter_form_bloc.dart';
import 'package:meta/meta.dart'; import 'package:meta/meta.dart';
part 'exercise_new_event.dart'; part 'exercise_new_event.dart';
part 'exercise_new_state.dart'; part 'exercise_new_state.dart';
class ExerciseNewBloc extends Bloc<ExerciseNewEvent, ExerciseNewState> { class ExerciseNewBloc extends Bloc<ExerciseNewEvent, ExerciseNewState> {
final ExerciseRepository exerciseRepository; final ExerciseRepository exerciseRepository;
final CustomerRepository customerRepository;
final MenuBloc menuBloc; final MenuBloc menuBloc;
AnimationController bmiAnimationController;
double quantity = 12; double quantity = 12;
double unitQuantity = 30; double unitQuantity = 30;
double bmi = 0;
double bmr = 0;
double goalBMI = 0;
double goalWeight = 0;
double bmiAngle = 0;
double bmiTop = 0;
double bmiLeft = 0;
double weight;
double height;
String fitnessLevel;
bool changedWeight = false;
bool changedSizes = false;
final List<Property> womanSizes = List();
final List<Property> manSizes = List();
double mediaWidth = 0;
double mediaHeight = 0;
@override @override
ExerciseNewBloc({this.exerciseRepository, this.menuBloc, ExerciseType exerciseType}) : super(ExerciseNewInitial()) { ExerciseNewBloc({this.exerciseRepository, this.menuBloc, this.customerRepository, ExerciseType exerciseType})
: super(ExerciseNewInitial()) {
exerciseRepository.setUnit(exerciseType.unit); exerciseRepository.setUnit(exerciseType.unit);
exerciseRepository.setQuantity(quantity);
exerciseRepository.setUnitQuantity(unitQuantity);
if (Cache().userLoggedIn != null) {
customerRepository.customer = Cache().userLoggedIn;
weight = customerRepository.customer.getProperty("Weight");
height = customerRepository.customer.getProperty("Height");
fitnessLevel = customerRepository.customer.fitnessLevel;
}
}
void setMediaDimensions(double width, double height) {
this.mediaHeight = height;
this.mediaWidth = width;
this.addSizes(customerRepository.sex);
}
void addSizes(String sex) {
List<Property> properties = Cache().getProperties();
if (sex == "Man") {
properties.forEach((element) {
if (element.propertyName == "Shoulder") {
element.top = (mediaHeight * 0.131).toInt();
element.left = (mediaWidth * 0.23).toInt();
element.value = customerRepository.customer.getProperty("Shoulder");
manSizes.add(element);
} else if (element.propertyName == "Neck") {
element.top = (mediaHeight * 0.069).toInt();
element.left = (mediaWidth * 0.23).toInt();
element.value = customerRepository.customer.getProperty("Neck");
manSizes.add(element);
} else if (element.propertyName == "Biceps") {
element.top = (mediaHeight * 0.199).toInt();
element.left = (mediaWidth * 0.44).toInt();
element.value = customerRepository.customer.getProperty("Biceps");
manSizes.add(element);
} else if (element.propertyName == "Chest") {
element.top = (mediaHeight * 0.171).toInt();
element.left = (mediaWidth * 0.23).toInt();
element.value = customerRepository.customer.getProperty("Chest");
manSizes.add(element);
} else if (element.propertyName == "Belly") {
element.top = (mediaHeight * 0.275).toInt();
element.left = (mediaWidth * 0.23).toInt();
element.value = customerRepository.customer.getProperty("Belly");
manSizes.add(element);
} else if (element.propertyName == "Hip") {
element.top = (mediaHeight * 0.355).toInt();
element.left = (mediaWidth * 0.23).toInt();
element.value = customerRepository.customer.getProperty("Hip");
manSizes.add(element);
} else if (element.propertyName == "Thigh Top") {
element.top = (mediaHeight * 0.38).toInt();
element.left = (mediaWidth * 0.32).toInt();
element.value = customerRepository.customer.getProperty("Thigh Top");
manSizes.add(element);
} else if (element.propertyName == "Thigh Middle") {
element.top = (mediaHeight * 0.438).toInt();
element.left = (mediaWidth * 0.14).toInt();
element.value = customerRepository.customer.getProperty("Thigh Middle");
manSizes.add(element);
} else if (element.propertyName == "Knee") {
element.top = (mediaHeight * 0.535).toInt();
element.left = (mediaWidth * 0.14).toInt();
element.value = customerRepository.customer.getProperty("Knee");
manSizes.add(element);
} else if (element.propertyName == "Calf") {
element.top = (mediaHeight * 0.60).toInt();
element.left = (mediaWidth * 0.14).toInt();
element.value = customerRepository.customer.getProperty("Calf");
manSizes.add(element);
} else if (element.propertyName == "Ankle") {
element.top = (mediaHeight * 0.72).toInt();
element.left = (mediaWidth * 0.28).toInt();
element.value = customerRepository.customer.getProperty("Ankle");
manSizes.add(element);
} else if (element.propertyName == "Weight") {
element.top = (mediaHeight * 0.44).toInt();
element.left = (mediaWidth * 0.54).toInt();
element.value = customerRepository.customer.getProperty("Weight");
manSizes.add(element);
}
});
} else {
properties.forEach((element) {
if (element.propertyName == "Shoulder") {
element.top = (mediaHeight * 0.131).toInt();
element.left = (mediaWidth * 0.195).toInt();
element.value = customerRepository.customer.getProperty("Shoulder");
manSizes.add(element);
} else if (element.propertyName == "Neck") {
element.top = (mediaHeight * 0.081).toInt();
element.left = (mediaWidth * 0.195).toInt();
element.value = customerRepository.customer.getProperty("Neck");
manSizes.add(element);
} else if (element.propertyName == "Biceps") {
element.top = (mediaHeight * 0.199).toInt();
element.left = (mediaWidth * 0.36).toInt();
element.value = customerRepository.customer.getProperty("Biceps");
manSizes.add(element);
} else if (element.propertyName == "Chest") {
element.top = (mediaHeight * 0.168).toInt();
element.left = (mediaWidth * 0.195).toInt();
element.value = customerRepository.customer.getProperty("Chest");
manSizes.add(element);
} else if (element.propertyName == "Belly") {
element.top = (mediaHeight * 0.26).toInt();
element.left = (mediaWidth * 0.195).toInt();
element.value = customerRepository.customer.getProperty("Belly");
manSizes.add(element);
} else if (element.propertyName == "Hip") {
element.top = (mediaHeight * 0.335).toInt();
element.left = (mediaWidth * 0.195).toInt();
element.value = customerRepository.customer.getProperty("Hip");
manSizes.add(element);
} else if (element.propertyName == "Thigh Top") {
element.top = (mediaHeight * 0.385).toInt();
element.left = (mediaWidth * 0.28).toInt();
element.value = customerRepository.customer.getProperty("Thigh Top");
manSizes.add(element);
} else if (element.propertyName == "Thigh Middle") {
element.top = (mediaHeight * 0.433).toInt();
element.left = (mediaWidth * 0.12).toInt();
element.value = customerRepository.customer.getProperty("Thigh Middle");
manSizes.add(element);
} else if (element.propertyName == "Knee") {
element.top = (mediaHeight * 0.543).toInt();
element.left = (mediaWidth * 0.14).toInt();
element.value = customerRepository.customer.getProperty("Knee");
manSizes.add(element);
} else if (element.propertyName == "Calf") {
element.top = (mediaHeight * 0.608).toInt();
element.left = (mediaWidth * 0.14).toInt();
element.value = customerRepository.customer.getProperty("Calf");
manSizes.add(element);
} else if (element.propertyName == "Ankle") {
element.top = (mediaHeight * 0.725).toInt();
element.left = (mediaWidth * 0.23).toInt();
element.value = customerRepository.customer.getProperty("Ankle");
manSizes.add(element);
} else if (element.propertyName == "Weight") {
element.top = (mediaHeight * 0.44).toInt();
element.left = (mediaWidth * 0.54).toInt();
element.value = customerRepository.customer.getProperty("Weight");
manSizes.add(element);
}
});
}
}
void updateSizes(String propertyName, double value) {
List<Property> sizes;
if (customerRepository.sex == "Man") {
sizes = this.manSizes;
} else {
sizes = this.womanSizes;
}
sizes.forEach((element) {
if (element.propertyName == propertyName) {
element.value = value;
}
});
} }
@override @override
@ -28,26 +215,131 @@ class ExerciseNewBloc extends Bloc<ExerciseNewEvent, ExerciseNewState> {
if (event is ExerciseNewLoad) { if (event is ExerciseNewLoad) {
yield ExerciseNewLoading(); yield ExerciseNewLoading();
yield ExerciseNewReady(); yield ExerciseNewReady();
} else if ( event is ExerciseNewQuantityChange ) { } else if (event is ExerciseNewQuantityChange) {
yield ExerciseNewLoading(); yield ExerciseNewLoading();
exerciseRepository.setQuantity(event.quantity); exerciseRepository.setQuantity(event.quantity);
quantity = event.quantity; quantity = event.quantity;
yield ExerciseNewReady(); yield ExerciseNewReady();
} else if ( event is ExerciseNewQuantityUnitChange ) { } else if (event is ExerciseNewQuantityUnitChange) {
yield ExerciseNewLoading(); yield ExerciseNewLoading();
exerciseRepository.setUnitQuantity(event.quantity); exerciseRepository.setUnitQuantity(event.quantity);
unitQuantity = event.quantity; unitQuantity = event.quantity;
yield ExerciseNewReady(); yield ExerciseNewReady();
} else if ( event is ExerciseNewSubmit ) { } else if (event is ExerciseNewWeightChange) {
yield ExerciseNewLoading();
customerRepository.setWeight(event.value.toInt());
changedWeight = true;
weight = event.value;
getBMI();
getBMR();
yield ExerciseNewReady();
} else if (event is ExerciseNewFitnessLevelChange) {
yield ExerciseNewLoading();
customerRepository.setFitnessLevel(event.value);
fitnessLevel = event.value;
changedWeight = true;
getBMR();
yield ExerciseNewReady();
} else if (event is ExerciseNewHeightChange) {
yield ExerciseNewLoading();
customerRepository.setHeight(event.value.toInt());
changedWeight = true;
height = event.value;
getBMI();
getBMR();
yield ExerciseNewReady();
} else if (event is ExerciseNewSaveWeight) {
yield ExerciseNewLoading();
customerRepository.saveCustomer();
changedWeight = false;
this.changedSizes = false;
yield ExerciseNewReady();
} else if (event is ExerciseNewSizeChange) {
yield ExerciseNewLoading();
this.changedSizes = true;
this.updateSizes(event.propertyName, event.value);
customerRepository.setCustomerProperty(event.propertyName, event.value);
yield ExerciseNewReady();
} else if (event is ExerciseNewSubmit) {
yield ExerciseNewLoading(); yield ExerciseNewLoading();
await exerciseRepository.addExercise(); await exerciseRepository.addExercise();
menuBloc.add(MenuTreeDown(parent: 0)); menuBloc.add(MenuTreeDown(parent: 0));
yield ExerciseNewReady(); yield ExerciseNewReady();
} else if (event is ExerciseNewBMIAnimate) {
yield ExerciseNewLoading();
yield ExerciseNewReady();
} }
} on Exception catch (e) { } on Exception catch (e) {
yield ExerciseNewError(message: e.toString()); yield ExerciseNewError(message: e.toString());
} }
} }
double getBMI() {
this.bmi = weight / (height * height / 10000);
this.getGoalBMI();
return this.bmi;
}
double getBMR() {
var date = DateTime.now();
int year = int.parse(DateFormat(DateFormat.YEAR).format(date));
if (customerRepository.customer.sex == "m") {
//66.47 + ( 13.75 × tömeg kg-ban ) + ( 5.003 × magasság cm-ben ) ( 6.755 × életkor évben kifejezve )
bmr = 66.47 + (13.75 * weight) + (5.003 * height) - (6.755 * (year - customerRepository.customer.birthYear));
} else {
//BMR = 655.1 + ( 9.563 × ömeg kg-ban ) + ( 1.85 × magasság cm-ben) ( 4.676 × életkor évben kifejezve )
bmr = 655.1 + (9.563 * weight) + (1.85 * height) - (4.676 * (year - customerRepository.customer.birthYear));
}
if (customerRepository.customer.fitnessLevel == FitnessState.beginner) {
bmr *= 1.2;
} else if (customerRepository.customer.fitnessLevel == FitnessState.intermediate) {
bmr *= 1.375;
} else if (customerRepository.customer.fitnessLevel == FitnessState.advanced) {
bmr *= 1.55;
} else if (customerRepository.customer.fitnessLevel == FitnessState.professional) {
bmr *= 1.9;
}
return bmr;
}
double getGoalBMI() {
if (this.bmi == 0) {
getBMI();
}
//bmi = 15;
this.bmiAngle = (bmi * 90 / 25) - 90;
if (bmi < 18.5) {
goalBMI = 19;
this.bmiTop = 99;
this.bmiLeft = 72;
bmiAngle = -62;
} else if (bmi < 25 && 18.5 < bmi) {
goalBMI = bmi;
this.bmiTop = 46;
this.bmiLeft = 130;
bmiAngle = -21;
} else if (bmi < 30 && 24.9 < bmi) {
goalBMI = 24;
this.bmiTop = 38.0;
this.bmiLeft = 186.0;
} else if (bmi < 34.9 && 29.9 < bmi) {
goalBMI = 29;
bmiTop = 48;
bmiLeft = 211;
} else if (bmi > 35) {
goalBMI = 34;
bmiTop = 94;
bmiLeft = 260;
bmiAngle = 59;
}
this.goalWeight = goalBMI * (height * height / 10000);
//print("Angle: " + bmiAngle.toStringAsFixed(1));
return goalBMI;
}
} }

View File

@ -28,7 +28,50 @@ class ExerciseNewQuantityUnitChange extends ExerciseNewEvent {
List<Object> get props => [quantity]; List<Object> get props => [quantity];
} }
class ExerciseNewWeightChange extends ExerciseNewEvent {
final double value;
const ExerciseNewWeightChange({this.value});
@override
List<Object> get props => [value];
}
class ExerciseNewHeightChange extends ExerciseNewEvent {
final double value;
const ExerciseNewHeightChange({this.value});
@override
List<Object> get props => [value];
}
class ExerciseNewFitnessLevelChange extends ExerciseNewEvent {
final String value;
const ExerciseNewFitnessLevelChange({this.value});
@override
List<Object> get props => [value];
}
class ExerciseNewSizeChange extends ExerciseNewEvent {
final String propertyName;
final double value;
const ExerciseNewSizeChange({this.propertyName, this.value});
@override
List<Object> get props => [propertyName, value];
}
class ExerciseNewSaveWeight extends ExerciseNewEvent {
const ExerciseNewSaveWeight();
}
class ExerciseNewBMIAnimate extends ExerciseNewEvent {
final dynamic value;
const ExerciseNewBMIAnimate({this.value});
@override
List<Object> get props => [value];
}
class ExerciseNewSubmit extends ExerciseNewEvent { class ExerciseNewSubmit extends ExerciseNewEvent {
const ExerciseNewSubmit(); const ExerciseNewSubmit();
} }

View File

@ -126,8 +126,8 @@ class TreeViewChildState extends State<TreeViewChild> with Common, SingleTicker
child: Container( child: Container(
child: child:
AnimatedSwitcher( AnimatedSwitcher(
duration: Duration(milliseconds:900), duration: Duration(milliseconds:200),
reverseDuration: Duration(milliseconds:500), reverseDuration: Duration(milliseconds:200),
switchInCurve: Curves.easeIn, switchInCurve: Curves.easeIn,
child: isExpanded ? Column( child: isExpanded ? Column(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,

View File

@ -4,6 +4,7 @@ import 'package:aitrainer_app/model/exercise_plan.dart';
import 'package:aitrainer_app/model/exercise_plan_detail.dart'; import 'package:aitrainer_app/model/exercise_plan_detail.dart';
import 'package:aitrainer_app/model/exercise_tree.dart'; import 'package:aitrainer_app/model/exercise_tree.dart';
import 'package:aitrainer_app/model/exercise.dart'; import 'package:aitrainer_app/model/exercise.dart';
import 'package:aitrainer_app/model/property.dart';
import 'package:aitrainer_app/model/workout_menu_tree.dart'; import 'package:aitrainer_app/model/workout_menu_tree.dart';
import 'package:aitrainer_app/repository/exercise_repository.dart'; import 'package:aitrainer_app/repository/exercise_repository.dart';
import 'package:aitrainer_app/service/exercise_tree_service.dart'; import 'package:aitrainer_app/service/exercise_tree_service.dart';
@ -62,6 +63,7 @@ class Cache {
List<Exercise> _exercises; List<Exercise> _exercises;
ExercisePlan _myExercisePlan; ExercisePlan _myExercisePlan;
List<Property> _properties;
LinkedHashMap<int, ExercisePlanDetail> _myExercisesPlanDetails = LinkedHashMap<int, ExercisePlanDetail>(); LinkedHashMap<int, ExercisePlanDetail> _myExercisesPlanDetails = LinkedHashMap<int, ExercisePlanDetail>();
@ -82,7 +84,7 @@ class Cache {
Cache._internal() { Cache._internal() {
String testEnv = EnvironmentConfig.test_env; String testEnv = EnvironmentConfig.test_env;
if ( testEnv == "1") { if (testEnv == "1") {
baseUrl = 'http://aitrainer.app:8899/api/'; baseUrl = 'http://aitrainer.app:8899/api/';
} }
} }
@ -136,22 +138,19 @@ class Cache {
_traineeExercisePlan = null; _traineeExercisePlan = null;
_exercises = List(); _exercises = List();
_myExercisesPlanDetails = LinkedHashMap(); _myExercisesPlanDetails = LinkedHashMap();
print("Trainees is null? " + (_trainee == null).toString() ); print("Trainees is null? " + (_trainee == null).toString());
Future<SharedPreferences> prefs = SharedPreferences.getInstance(); Future<SharedPreferences> prefs = SharedPreferences.getInstance();
await setPreferences(prefs, SharePrefsChange.logout, 0, ""); await setPreferences(prefs, SharePrefsChange.logout, 0, "");
} }
setPreferences(Future<SharedPreferences> prefs, setPreferences(Future<SharedPreferences> prefs, SharePrefsChange type, int customerId, String firebaseUid) async {
SharePrefsChange type,
int customerId,
String firebaseUid) async {
SharedPreferences sharedPreferences; SharedPreferences sharedPreferences;
sharedPreferences = await prefs; sharedPreferences = await prefs;
DateTime now = DateTime.now(); DateTime now = DateTime.now();
sharedPreferences.setString(Cache.lastStoreDateKey, now.toString()); sharedPreferences.setString(Cache.lastStoreDateKey, now.toString());
ExerciseRepository exerciseRepository = ExerciseRepository(); ExerciseRepository exerciseRepository = ExerciseRepository();
if ( type == SharePrefsChange.registration ) { if (type == SharePrefsChange.registration) {
Cache().startPage = "home"; Cache().startPage = "home";
sharedPreferences.setInt(Cache.customerIdKey, customerId); sharedPreferences.setInt(Cache.customerIdKey, customerId);
sharedPreferences.setBool(Cache.isRegisteredKey, true); sharedPreferences.setBool(Cache.isRegisteredKey, true);
@ -160,7 +159,7 @@ class Cache {
await ExerciseTypeApi().getExerciseTypes(); await ExerciseTypeApi().getExerciseTypes();
await ExerciseTreeApi().getExerciseTree(); await ExerciseTreeApi().getExerciseTree();
await exerciseRepository.getExercisesByCustomer(customerId); await exerciseRepository.getExercisesByCustomer(customerId);
} else if ( type == SharePrefsChange.login ) { } else if (type == SharePrefsChange.login) {
Cache().startPage = "home"; Cache().startPage = "home";
sharedPreferences.setInt(Cache.customerIdKey, customerId); sharedPreferences.setInt(Cache.customerIdKey, customerId);
sharedPreferences.setString(Cache.firebaseUidKey, firebaseUid); sharedPreferences.setString(Cache.firebaseUidKey, firebaseUid);
@ -168,7 +167,7 @@ class Cache {
await ExerciseTypeApi().getExerciseTypes(); await ExerciseTypeApi().getExerciseTypes();
await ExerciseTreeApi().getExerciseTree(); await ExerciseTreeApi().getExerciseTree();
await exerciseRepository.getExercisesByCustomer(customerId); await exerciseRepository.getExercisesByCustomer(customerId);
} else if ( type == SharePrefsChange.logout ) { } else if (type == SharePrefsChange.logout) {
sharedPreferences.setBool(Cache.isLoggedInKey, false); sharedPreferences.setBool(Cache.isLoggedInKey, false);
sharedPreferences.setInt(Cache.customerIdKey, 0); sharedPreferences.setInt(Cache.customerIdKey, 0);
sharedPreferences.setString(Cache.firebaseUidKey, null); sharedPreferences.setString(Cache.firebaseUidKey, null);
@ -176,23 +175,23 @@ class Cache {
} }
} }
void setExerciseTypes( List<ExerciseType> exerciseTypes) { void setExerciseTypes(List<ExerciseType> exerciseTypes) {
this._exerciseTypes = exerciseTypes; this._exerciseTypes = exerciseTypes;
} }
void setExerciseTree( List<ExerciseTree> exerciseTree) { void setExerciseTree(List<ExerciseTree> exerciseTree) {
this._exerciseTree = exerciseTree; this._exerciseTree = exerciseTree;
} }
void setExercises( List<Exercise> exercises ) { void setExercises(List<Exercise> exercises) {
this._exercises = exercises; this._exercises = exercises;
} }
void setExercisesTrainee( List<Exercise> exercises ) { void setExercisesTrainee(List<Exercise> exercises) {
this._exercisesTrainee = exercises; this._exercisesTrainee = exercises;
} }
void setWorkoutMenuTree( LinkedHashMap<String, WorkoutMenuTree> tree) { void setWorkoutMenuTree(LinkedHashMap<String, WorkoutMenuTree> tree) {
this._tree = tree; this._tree = tree;
} }
@ -218,7 +217,7 @@ class Cache {
void setTrainee(Customer trainee) => _trainee = trainee; void setTrainee(Customer trainee) => _trainee = trainee;
void setTraineeExercisePlan(ExercisePlan exercisePlan) => this._traineeExercisePlan = exercisePlan; void setTraineeExercisePlan(ExercisePlan exercisePlan) => this._traineeExercisePlan = exercisePlan;
ExercisePlan getTraineesExercisePlan() => this._traineeExercisePlan; ExercisePlan getTraineesExercisePlan() => this._traineeExercisePlan;
@ -226,8 +225,8 @@ class Cache {
ExercisePlan getMyExercisePlan() => _myExercisePlan; ExercisePlan getMyExercisePlan() => _myExercisePlan;
void setMyExercisePlanDetails(LinkedHashMap<int, ExercisePlanDetail> listExercisePlanDetail) void setMyExercisePlanDetails(LinkedHashMap<int, ExercisePlanDetail> listExercisePlanDetail) =>
=> _myExercisesPlanDetails = listExercisePlanDetail; _myExercisesPlanDetails = listExercisePlanDetail;
void addToMyExercisePlanDetails(ExercisePlanDetail detail) => _myExercisesPlanDetails[detail.exerciseTypeId] = detail; void addToMyExercisePlanDetails(ExercisePlanDetail detail) => _myExercisesPlanDetails[detail.exerciseTypeId] = detail;
@ -239,16 +238,16 @@ class Cache {
this.addToMyExercisePlanDetails(detail); this.addToMyExercisePlanDetails(detail);
} }
void deleteMyExercisePlanDetail(ExercisePlanDetail detail) void deleteMyExercisePlanDetail(ExercisePlanDetail detail) => this.deleteMyExercisePlanDetailByExerciseTypeId(detail.exerciseTypeId);
=> this.deleteMyExercisePlanDetailByExerciseTypeId(detail.exerciseTypeId);
void deletedMyExercisePlanDetail(ExercisePlanDetail detail) void deletedMyExercisePlanDetail(ExercisePlanDetail detail) =>
=> this._myExercisesPlanDetails[detail.exerciseTypeId].change = ExercisePlanDetailChange.deleted; this._myExercisesPlanDetails[detail.exerciseTypeId].change = ExercisePlanDetailChange.deleted;
void deleteMyExercisePlanDetailByExerciseTypeId(int exerciseTypeId) { void deleteMyExercisePlanDetailByExerciseTypeId(int exerciseTypeId) {
this._myExercisesPlanDetails[exerciseTypeId].change = ExercisePlanDetailChange.delete; this._myExercisesPlanDetails[exerciseTypeId].change = ExercisePlanDetailChange.delete;
} }
void setProperties(List<Property> properties) => this._properties = properties;
List<Property> getProperties() => _properties;
} }

View File

@ -1,24 +1,29 @@
import 'dart:collection';
import 'customer_property.dart';
class Customer { class Customer {
String name; String name;
String email; String email;
String firstname; String firstname;
String sex; String sex;
int age; int age;
String active; String active;
int customerId; int customerId;
String password; String password;
int birthYear; int birthYear;
int weight; //int weight;
String goal; String goal;
String fitnessLevel; String fitnessLevel;
String bodyType; String bodyType;
int admin; int admin;
int trainer; int trainer;
int dataPolicyAllowed; int dataPolicyAllowed;
String firebaseUid; String firebaseUid;
LinkedHashMap<String, CustomerProperty> properties = LinkedHashMap();
Customer({this.customerId, Customer({
this.customerId,
this.name, this.name,
this.firstname, this.firstname,
this.email, this.email,
@ -30,7 +35,7 @@ class Customer {
this.bodyType, this.bodyType,
this.fitnessLevel, this.fitnessLevel,
this.goal, this.goal,
this.weight, //this.weight,
this.admin, this.admin,
this.trainer, this.trainer,
this.dataPolicyAllowed, this.dataPolicyAllowed,
@ -49,28 +54,39 @@ class Customer {
this.bodyType = json['bodyType']; this.bodyType = json['bodyType'];
this.fitnessLevel = json['fitnessLevel']; this.fitnessLevel = json['fitnessLevel'];
this.goal = json['goal']; this.goal = json['goal'];
this.weight = json['weight']; //this.weight = json['weight'];
this.admin = json['admin']; this.admin = json['admin'];
this.trainer = json['trainer']; this.trainer = json['trainer'];
this.firebaseUid = json['firebaseUid']; this.firebaseUid = json['firebaseUid'];
} }
Map<String, dynamic> toJson() => Map<String, dynamic> toJson() => {
{ "name": name,
"name": name, "firstname": firstname,
"firstname": firstname, "email": email,
"email": email, "age": age,
"age": age, "sex": sex,
"sex": sex, "active": 'Y',
"active": 'Y', "password": password,
"password": password, "birthYear": birthYear,
"birthYear": birthYear, "bodyType": bodyType,
"bodyType": bodyType, "fitnessLevel": fitnessLevel,
"fitnessLevel": fitnessLevel, "goal": goal,
"goal": goal, //"weight": weight,
"weight": weight, "admin": admin,
"admin": admin, "trainer": trainer,
"trainer": trainer, "dataPolicyAllowed": dataPolicyAllowed,
"dataPolicyAllowed": dataPolicyAllowed, };
};
double getProperty(String propertyName) {
if (this.properties[propertyName] == null) {
return 0;
} else {
return this.properties[propertyName].propertyValue;
}
}
setProperty(String propertyName, double value) {
this.properties[propertyName].propertyValue = value;
}
} }

View File

@ -1,3 +1,5 @@
import 'package:flutter_form_bloc/flutter_form_bloc.dart';
class CustomerProperty { class CustomerProperty {
int propertyId; int propertyId;
int customerId; int customerId;
@ -14,6 +16,10 @@ class CustomerProperty {
this.propertyValue = json['propertyValue']; this.propertyValue = json['propertyValue'];
} }
Map<String, dynamic> toJson() => Map<String, dynamic> toJson() => {
{"propertyId": this.propertyId, "customerId": this.customerId, "dateAdd": this.dateAdd, "propertyValue": this.propertyValue}; "propertyId": this.propertyId,
"customerId": this.customerId,
"dateAdd": DateFormat('yyyy-MM-dd HH:mm:ss').format(this.dateAdd),
"propertyValue": this.propertyValue
};
} }

View File

@ -1,20 +1,17 @@
class ExerciseTree { class Product {
int treeId; int productId;
int parentId;
String name; String name;
String imageUrl; String description;
bool active; String type;
String nameTranslation; DateTime validFrom;
DateTime validTo;
ExerciseTree.fromJson(Map json) { Product.fromJson(Map json) {
this.treeId = json['treeId']; this.productId = json['productId'];
this.name = json['name']; this.name = json['name'];
this.parentId = json['parentId']; this.description = json['description'];
this.imageUrl = json['imageUrl']; this.type = json['type'];
this.active = json['active']; this.validFrom = json['validFrom'];
this.nameTranslation = this.validTo = json['validTo'];
json['translations'] != null && (json['translations']).length > 0
? json['translations'][0]['name']
: this.name;
} }
} }

View File

@ -1,17 +1,16 @@
class Product { class ProductTest {
int productTestId;
int customerId;
int productId; int productId;
String name;
String description;
String type;
DateTime validFrom;
DateTime validTo;
Product.fromJson(Map json) { DateTime dateView;
bool purchaseClick;
ProductTest.fromJson(Map json) {
this.productTestId = json['productTestId'];
this.customerId = json['customerId'];
this.productId = json['productId']; this.productId = json['productId'];
this.name = json['name']; this.dateView = json['dateView'];
this.description = json['description']; this.purchaseClick = json['purchaseClick'];
this.type = json['type'];
this.validFrom = json['validFrom'];
this.validTo = json['validTo'];
} }
} }

View File

@ -3,14 +3,15 @@ class Property {
String propertyName; String propertyName;
String propertyUnit; String propertyUnit;
String propertyNameTranslation; String propertyNameTranslation;
int top;
int left;
double value;
Property.fromJson(Map json) { Property.fromJson(Map json) {
this.propertyId = json['propertyId']; this.propertyId = json['propertyId'];
this.propertyName = json['propertyName']; this.propertyName = json['propertyName'];
this.propertyUnit = json['propertyUnit']; this.propertyUnit = json['propertyUnit'];
this.propertyNameTranslation = this.propertyNameTranslation =
json['translations'] != null && (json['translations']).length > 0 json['translations'] != null && (json['translations']).length > 0 ? json['translations'][0]['propertyName'] : this.propertyName;
? json['translations'][0]['propertyName']
: this.propertyName;
} }
} }

View File

@ -1,17 +1,30 @@
class Product { import 'package:flutter_form_bloc/flutter_form_bloc.dart';
int productId;
String name;
String description;
String type;
DateTime validFrom;
DateTime validTo;
Product.fromJson(Map json) { class Purchase {
int purchaseId;
int customerId;
int productId;
DateTime dateAdd;
double purchaseSum;
String currency;
Purchase.fromJson(Map json) {
this.purchaseId = json['purchaseId'];
this.customerId = json['customerId'];
this.productId = json['productId']; this.productId = json['productId'];
this.name = json['name']; this.dateAdd = json['dateAdd'];
this.description = json['description']; this.purchaseSum = json['purchaseSum'];
this.type = json['type']; this.customerId = json['currency'];
this.validFrom = json['validFrom'];
this.validTo = json['validTo'];
} }
Map<String, dynamic> toJson() =>
{
"purchaseId": purchaseId,
"customerId": customerId,
"productId": productId,
"purchaseSum": purchaseSum,
"dateAdd": DateFormat('yyyy-MM-dd HH:mm:ss').format(this.dateAdd),
"currency": currency,
};
} }

View File

@ -1,9 +1,13 @@
import 'dart:collection';
import 'package:aitrainer_app/model/cache.dart'; import 'package:aitrainer_app/model/cache.dart';
import 'package:aitrainer_app/model/customer.dart'; import 'package:aitrainer_app/model/customer.dart';
import 'package:aitrainer_app/model/customer_property.dart';
import 'package:aitrainer_app/repository/property_repository.dart';
import 'package:aitrainer_app/service/customer_service.dart'; import 'package:aitrainer_app/service/customer_service.dart';
class GenderItem { class GenderItem {
GenderItem(this.dbValue,this.name); GenderItem(this.dbValue, this.name);
final String dbValue; final String dbValue;
String name; String name;
} }
@ -12,6 +16,8 @@ class CustomerRepository {
Customer customer; Customer customer;
Customer _trainee; Customer _trainee;
List<Customer> _trainees; List<Customer> _trainees;
List<CustomerProperty> _allProperties;
final PropertyRepository propertyRepository = PropertyRepository();
//List<CustomerRepository> customerList = List<CustomerRepository>(); //List<CustomerRepository> customerList = List<CustomerRepository>();
bool visibleDetails = false; bool visibleDetails = false;
@ -76,11 +82,12 @@ class CustomerRepository {
setName(String name) { setName(String name) {
this.customer.name = name; this.customer.name = name;
} }
setFirstName(String firstName) { setFirstName(String firstName) {
this.customer.firstname = firstName; this.customer.firstname = firstName;
} }
setPassword( String password ) { setPassword(String password) {
this.customer.password = password; this.customer.password = password;
} }
@ -88,24 +95,58 @@ class CustomerRepository {
this.customer.email = email; this.customer.email = email;
} }
setSex(String sex) { setSex(String sex) {
this.customer.sex = sex; this.customer.sex = sex;
} }
setWeight( int weight) { setWeight(int weight) {
this.customer.weight = weight; final propertyName = "Weight";
this.setCustomerProperty(propertyName, weight.toDouble());
} }
setBirthYear( int birthYear ) { setHeight(int height) {
final propertyName = "Height";
this.setCustomerProperty(propertyName, height.toDouble());
}
setCustomerProperty(String propertyName, double value) {
if (this.customer.properties[propertyName] == null) {
this.customer.properties[propertyName] = CustomerProperty(
propertyId: propertyRepository.getPropertyByName("Height").propertyId,
customerId: this.customer.customerId,
propertyValue: value);
} else {
this.customer.properties[propertyName].propertyValue = value;
}
this.customer.properties[propertyName].dateAdd = DateTime.now();
this.customer.properties[propertyName].newData = true;
}
double getWeight() {
return getCustomerProperty("Weight");
}
double getHeight() {
return getCustomerProperty("Height");
}
double getCustomerProperty(String propertyName) {
if (this.customer.properties[propertyName] == null) {
return 0.0;
} else {
return this.customer.properties[propertyName].propertyValue;
}
}
setBirthYear(int birthYear) {
this.customer.birthYear = birthYear; this.customer.birthYear = birthYear;
} }
setFitnessLevel( String level ) { setFitnessLevel(String level) {
this.customer.fitnessLevel = level; this.customer.fitnessLevel = level;
} }
setGoal( String goal ) { setGoal(String goal) {
this.customer.goal = goal; this.customer.goal = goal;
} }
@ -121,7 +162,7 @@ class CustomerRepository {
return this.customer; return this.customer;
} }
void setCustomer ( Customer customer ) { void setCustomer(Customer customer) {
this.customer = customer; this.customer = customer;
} }
@ -133,32 +174,51 @@ class CustomerRepository {
Future<void> saveCustomer() async { Future<void> saveCustomer() async {
final Customer modelCustomer = customer; final Customer modelCustomer = customer;
await CustomerApi().saveCustomer(modelCustomer); await CustomerApi().saveCustomer(modelCustomer);
await this.saveProperties(modelCustomer.properties);
}
Future<void> saveProperties(LinkedHashMap<String, CustomerProperty> properties) async {
properties.forEach((propertyName, property) async {
if (property.newData == true) {
await CustomerApi().addProperty(property);
property.newData = false;
}
});
} }
Future<Customer> getTraineeAsCustomer() async { Future<Customer> getTraineeAsCustomer() async {
this._trainee = await CustomerApi().getTrainee( this._trainee = await CustomerApi().getTrainee(Cache().userLoggedIn.customerId);
Cache().userLoggedIn.customerId
);
return _trainee; return _trainee;
} }
Future<List<Customer>> getTrainees() async { Future<List<Customer>> getTrainees() async {
int trainerId = Cache().userLoggedIn.customerId; int trainerId = Cache().userLoggedIn.customerId;
final results = await CustomerApi().getTrainees(trainerId); final results = await CustomerApi().getTrainees(trainerId);
this._trainees = results; this._trainees = results;
return results; return results;
} }
Future<List<CustomerProperty>> getAllCustomerProperties() async {
int customerId = Cache().userLoggedIn.customerId;
final results = await CustomerApi().getAllProperties(customerId);
this._allProperties = results;
return results;
}
List<CustomerProperty> getAllProperties() {
return this._allProperties;
}
List<Customer> getTraineesList() { List<Customer> getTraineesList() {
return _trainees; return _trainees;
} }
void setTrainee(int traineeId ) { void setTrainee(int traineeId) {
if ( _trainees == null ) { if (_trainees == null) {
return; return;
} }
_trainees.forEach((element) { _trainees.forEach((element) {
if ( traineeId == element.customerId) { if (traineeId == element.customerId) {
this._trainee = element; this._trainee = element;
} }
}); });
@ -178,7 +238,7 @@ class CustomerRepository {
return null; return null;
} }
_trainees.forEach((element) { _trainees.forEach((element) {
if ( customerId == element.customerId) { if (customerId == element.customerId) {
this._trainee = element; this._trainee = element;
} }
}); });

View File

@ -34,13 +34,13 @@ class UserRepository {
Future<void> getUser() async { Future<void> getUser() async {
final User modelUser = this.user; final User modelUser = this.user;
String rc = await FirebaseApi().signInEmail(modelUser.email, modelUser.password); String rc = await FirebaseApi().signInEmail(modelUser.email, modelUser.password);
if ( rc == FirebaseApi.SIGN_IN_NOT_FOUND ) {
rc = await FirebaseApi().registerEmail(modelUser.email, modelUser.password);
}
if ( rc == FirebaseApi.SIGN_IN_OK ) { if ( rc == FirebaseApi.SIGN_IN_OK ) {
print("Firebase login ok"); print("Firebase login ok");
await CustomerApi().getUserByEmail(modelUser.email); await CustomerApi().getUserByEmail(modelUser.email);
Cache().afterFirebaseLogin(); Cache().afterFirebaseLogin();
} else {
throw Exception("Exception: Customer does not exist or the password is wrong");
} }
} }

View File

@ -1,5 +1,8 @@
import 'dart:collection';
import 'dart:convert'; import 'dart:convert';
import 'package:aitrainer_app/model/customer.dart'; import 'package:aitrainer_app/model/customer.dart';
import 'package:aitrainer_app/model/customer_property.dart';
import 'package:aitrainer_app/model/property.dart';
import 'package:aitrainer_app/model/user.dart'; import 'package:aitrainer_app/model/user.dart';
import 'package:aitrainer_app/service/api.dart'; import 'package:aitrainer_app/service/api.dart';
import 'package:aitrainer_app/model/cache.dart'; import 'package:aitrainer_app/model/cache.dart';
@ -10,43 +13,32 @@ class CustomerApi {
Future<List<Customer>> getRealCustomers(String param) async { Future<List<Customer>> getRealCustomers(String param) async {
final body = await _client.get("customers/", param); final body = await _client.get("customers/", param);
final Iterable json = jsonDecode(body); final Iterable json = jsonDecode(body);
final List<Customer> customers = json.map((customer) => final List<Customer> customers = json.map((customer) => Customer.fromJson(customer)).toList();
Customer.fromJson(customer)).toList();
return customers; return customers;
} }
Future<void> saveCustomer(Customer customer) async { Future<void> saveCustomer(Customer customer) async {
String body = JsonEncoder().convert(customer.toJson()); String body = JsonEncoder().convert(customer.toJson());
print(" ===== saving customer id: " + customer.customerId.toString() + ":" + print(" ===== saving customer id: " + customer.customerId.toString() + ":" + body);
body); await _client.post("customers/" + customer.customerId.toString(), body);
await _client.post(
"customers/" + customer.customerId.toString(),
body);
} }
Future<void> updateFirebaseUid(int customerId, String uid) async { Future<void> updateFirebaseUid(int customerId, String uid) async {
print(" ===== update Firebase uid : " + customerId.toString() + ": " + print(" ===== update Firebase uid : " + customerId.toString() + ": " + uid);
uid); await _client.post("customers/update_firebase_uid/" + customerId.toString(), uid);
await _client.post(
"customers/update_firebase_uid/" + customerId.toString(),
uid);
} }
Future<void> addCustomer(Customer customer) async { Future<void> addCustomer(Customer customer) async {
String body = JsonEncoder().convert(customer.toJson()); String body = JsonEncoder().convert(customer.toJson());
print(" ===== add new customer: " + body); print(" ===== add new customer: " + body);
await _client.post( await _client.post("customers", body);
"customers",
body);
} }
Future<void> addUser(User user) async { Future<void> addUser(User user) async {
String body = JsonEncoder().convert(user.toJson()); String body = JsonEncoder().convert(user.toJson());
print(" ===== add new user: " + body); print(" ===== add new user: " + body);
final String responseBody = await _client.post( final String responseBody = await _client.post("registration", body);
"registration",
body);
Customer customer; Customer customer;
try { try {
int status = jsonDecode(responseBody)['status']; int status = jsonDecode(responseBody)['status'];
@ -64,9 +56,7 @@ class CustomerApi {
Future<void> getUser(User user) async { Future<void> getUser(User user) async {
String body = JsonEncoder().convert(user.toJson()); String body = JsonEncoder().convert(user.toJson());
print(" ===== login the user: " + body); print(" ===== login the user: " + body);
final String responseBody = await _client.post( final String responseBody = await _client.post("login", body);
"login",
body);
Customer customer; Customer customer;
try { try {
customer = Customer.fromJson(jsonDecode(responseBody)); customer = Customer.fromJson(jsonDecode(responseBody));
@ -78,13 +68,11 @@ class CustomerApi {
Future<void> getUserByEmail(String email) async { Future<void> getUserByEmail(String email) async {
print(" ===== User getByEmail : " + email); print(" ===== User getByEmail : " + email);
final String responseBody = await _client.get( final String responseBody = await _client.get("customers/find_by_email/" + email, "");
"customers/find_by_email/" + email,
"");
Customer customer; Customer customer;
try { try {
customer = Customer.fromJson(jsonDecode(responseBody)); customer = Customer.fromJson(jsonDecode(responseBody));
if ( customer.firebaseUid == null ) { if (customer.firebaseUid == null) {
await this.updateFirebaseUid(customer.customerId, Cache().firebaseUid); await this.updateFirebaseUid(customer.customerId, Cache().firebaseUid);
} }
Cache().userLoggedIn = customer; Cache().userLoggedIn = customer;
@ -93,17 +81,17 @@ class CustomerApi {
} }
} }
Future<void> getCustomer(int customerId) async { Future<void> getCustomer(int customerId) async {
String body = ""; String body = "";
print(" ===== get the customer by id: " + customerId.toString()); print(" ===== get the customer by id: " + customerId.toString());
try { try {
final String responseBody = await _client.get( final String responseBody = await _client.get("customers/" + customerId.toString(), body);
"customers/" + customerId.toString(),
body);
Customer customer = Customer.fromJson(jsonDecode(responseBody)); Customer customer = Customer.fromJson(jsonDecode(responseBody));
print(" --- Customer: " + customer.toJson().toString()); print(" --- Customer: " + customer.toJson().toString());
final List properties = await this.getActualProperties(customerId);
print(" ---- Props: " + properties.toString());
Cache().afterRegistration(customer); Cache().afterRegistration(customer);
this._initProperties(properties);
} catch (exception) { } catch (exception) {
print("Exception: " + exception.toString()); print("Exception: " + exception.toString());
print(" === go to registration "); print(" === go to registration ");
@ -112,14 +100,33 @@ class CustomerApi {
} }
} }
void _initProperties(List<CustomerProperty> customerProperties) {
List<Property> properties = Cache().getProperties();
Customer customer = Cache().userLoggedIn;
customer.properties = LinkedHashMap<String, CustomerProperty>();
// reset Properties
properties.forEach((property) {
CustomerProperty customerProperty =
CustomerProperty(propertyId: property.propertyId, customerId: customer.customerId, dateAdd: null, propertyValue: 0);
customer.properties[property.propertyName] = customerProperty;
});
customerProperties.forEach((customerProperty) {
properties.forEach((property) {
if (customerProperty.propertyId == property.propertyId) {
customer.properties[property.propertyName] = customerProperty;
}
});
});
}
Future<Customer> getTrainee(int customerId) async { Future<Customer> getTrainee(int customerId) async {
String body = ""; String body = "";
Customer customer; Customer customer;
print(" ===== get Trainee customer by id: " + customerId.toString()); print(" ===== get Trainee customer by id: " + customerId.toString());
try { try {
final String responseBody = await _client.get( final String responseBody = await _client.get("customers/" + customerId.toString(), body);
"customers/" + customerId.toString(),
body);
customer = Customer.fromJson(jsonDecode(responseBody)); customer = Customer.fromJson(jsonDecode(responseBody));
print(" --- Trainee: " + customer.toJson().toString()); print(" --- Trainee: " + customer.toJson().toString());
} catch (exception) { } catch (exception) {
@ -134,10 +141,7 @@ class CustomerApi {
print("Get trainees list"); print("Get trainees list");
try { try {
String body = ""; String body = "";
final String responseBody = await _client.get( final String responseBody = await _client.get("customers/trainees/" + trainerId.toString(), body);
"customers/trainees/" + trainerId.toString(),
body
);
final Iterable json = jsonDecode(responseBody); final Iterable json = jsonDecode(responseBody);
trainees = json.map((customer) => Customer.fromJson(customer)).toList(); trainees = json.map((customer) => Customer.fromJson(customer)).toList();
} catch (exception) { } catch (exception) {
@ -146,4 +150,39 @@ class CustomerApi {
} }
return trainees; return trainees;
} }
}
Future<List<CustomerProperty>> getAllProperties(int customerId) async {
final body = await _client.get("customer_property/", customerId.toString());
final Iterable json = jsonDecode(body);
final List<CustomerProperty> properties = json.map((property) => CustomerProperty.fromJson(property)).toList();
return properties;
}
Future<List<CustomerProperty>> getActualProperties(int customerId) async {
final body = await _client.get("customer_property/last/", customerId.toString());
final Iterable json = jsonDecode(body);
final List<CustomerProperty> properties = json.map((property) => CustomerProperty.fromJson(property)).toList();
return properties;
}
Future<void> addProperty(CustomerProperty property) async {
String body = JsonEncoder().convert(property.toJson());
print(" ===== add new customer property: " + body);
final String responseBody = await _client.post("customer_property", body);
try {
int status = jsonDecode(responseBody)['status'];
if (status != null) {
throw new Exception(jsonDecode(responseBody)['error']);
} else {
CustomerProperty customerProperty = CustomerProperty.fromJson(jsonDecode(responseBody));
if (customerProperty == null) {
throw new Exception("Property Insert was not successful");
}
}
} on FormatException {
throw new Exception(responseBody);
}
}
}

View File

@ -22,8 +22,6 @@ class FirebaseApi {
_instance = this; _instance = this;
} }
// Define an async function to initialize FlutterFire // Define an async function to initialize FlutterFire
Future<void> initializeFlutterFire() async { Future<void> initializeFlutterFire() async {
try { try {
@ -38,10 +36,7 @@ class FirebaseApi {
Future<String> signInEmail(String email, String password) async { Future<String> signInEmail(String email, String password) async {
String rc = SIGN_IN_OK; String rc = SIGN_IN_OK;
try { try {
userCredential = await FirebaseAuth.instance.signInWithEmailAndPassword( userCredential = await FirebaseAuth.instance.signInWithEmailAndPassword(email: email, password: password);
email: email,
password: password
);
Cache().firebaseUid = userCredential.user.uid; Cache().firebaseUid = userCredential.user.uid;
} on FirebaseAuthException catch (e) { } on FirebaseAuthException catch (e) {
if (e.code == 'user-not-found') { if (e.code == 'user-not-found') {
@ -60,10 +55,7 @@ class FirebaseApi {
Future<String> registerEmail(String email, String password) async { Future<String> registerEmail(String email, String password) async {
String rc = SIGN_IN_OK; String rc = SIGN_IN_OK;
try { try {
userCredential = await FirebaseAuth.instance.createUserWithEmailAndPassword( userCredential = await FirebaseAuth.instance.createUserWithEmailAndPassword(email: email, password: password);
email: email,
password: password
);
Cache().firebaseUid = userCredential.user.uid; Cache().firebaseUid = userCredential.user.uid;
} on FirebaseAuthException catch (e) { } on FirebaseAuthException catch (e) {
if (e.code == 'weak-password') { if (e.code == 'weak-password') {
@ -73,12 +65,9 @@ class FirebaseApi {
} else if (e.code == 'email-already-in-use') { } else if (e.code == 'email-already-in-use') {
print('The account already exists for that email.'); print('The account already exists for that email.');
rc = REGISTER_EMAIL_IN_USE; rc = REGISTER_EMAIL_IN_USE;
userCredential = await FirebaseAuth.instance.signInWithEmailAndPassword( userCredential = await FirebaseAuth.instance.signInWithEmailAndPassword(email: email, password: password);
email: email, if (rc != null) {
password: password rc = SIGN_IN_OK;
);
if ( rc != null ) {
String rc = SIGN_IN_OK;
} }
} }
} catch (e) { } catch (e) {
@ -93,8 +82,7 @@ class FirebaseApi {
final LoginResult result = await FacebookAuth.instance.login(); final LoginResult result = await FacebookAuth.instance.login();
// Create a credential from the access token // Create a credential from the access token
final FacebookAuthCredential facebookAuthCredential = final FacebookAuthCredential facebookAuthCredential = FacebookAuthProvider.credential(result.accessToken.token);
FacebookAuthProvider.credential(result.accessToken.token);
// Once signed in, return the UserCredential // Once signed in, return the UserCredential
return await FirebaseAuth.instance.signInWithCredential(facebookAuthCredential); return await FirebaseAuth.instance.signInWithCredential(facebookAuthCredential);
@ -107,4 +95,4 @@ class FirebaseApi {
Future<void> resetPassword(String email) async { Future<void> resetPassword(String email) async {
await FirebaseAuth.instance.sendPasswordResetEmail(email: email); await FirebaseAuth.instance.sendPasswordResetEmail(email: email);
} }
} }

View File

@ -6,6 +6,7 @@ import 'package:aitrainer_app/service/customer_service.dart';
import 'package:aitrainer_app/service/exercise_tree_service.dart'; import 'package:aitrainer_app/service/exercise_tree_service.dart';
import 'package:aitrainer_app/service/exercisetype_service.dart'; import 'package:aitrainer_app/service/exercisetype_service.dart';
import 'package:aitrainer_app/service/firebase_api.dart'; import 'package:aitrainer_app/service/firebase_api.dart';
import 'package:aitrainer_app/service/property_service.dart';
import 'package:devicelocale/devicelocale.dart'; import 'package:devicelocale/devicelocale.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:shared_preferences/shared_preferences.dart'; import 'package:shared_preferences/shared_preferences.dart';
@ -14,34 +15,29 @@ import 'package:firebase_core/firebase_core.dart';
//import '../push_notifications.dart'; //import '../push_notifications.dart';
class Session { class Session {
Future<SharedPreferences> _prefs = SharedPreferences.getInstance(); Future<SharedPreferences> _prefs = SharedPreferences.getInstance();
SharedPreferences _sharedPreferences; SharedPreferences _sharedPreferences;
fetchSessionAndNavigate( ) async { fetchSessionAndNavigate() async {
print (" -- Session: await prefs.."); print(" -- Session: await prefs..");
_sharedPreferences = await _prefs; _sharedPreferences = await _prefs;
if (Cache().firstLoad) {
if ( Cache().firstLoad ) { print(" -- Session: fetch locale..");
print (" -- Session: fetch locale..");
await AppLanguage().getLocale(_sharedPreferences); await AppLanguage().getLocale(_sharedPreferences);
await AppLocalizations.delegate.load(AppLanguage().appLocal); await AppLocalizations.delegate.load(AppLanguage().appLocal);
print (" -- Session: fetch token.."); print(" -- Session: fetch token..");
await _fetchToken(_sharedPreferences); await _fetchToken(_sharedPreferences);
print (" -- FireBase init.."); print(" -- FireBase init..");
await FirebaseApi().initializeFlutterFire(); await FirebaseApi().initializeFlutterFire();
//initDeviceLocale(); //initDeviceLocale();
// Create the initialization Future outside of `build`: // Create the initialization Future outside of `build`:
// PushNotificationsManager().init();
// PushNotificationsManager().init();
} }
} }
Future<void> initDeviceLocale() async { Future<void> initDeviceLocale() async {
@ -53,7 +49,6 @@ class Session {
languages = await Devicelocale.preferredLanguages; languages = await Devicelocale.preferredLanguages;
Cache().deviceLanguages = languages; Cache().deviceLanguages = languages;
print("device langs " + languages.toString()); print("device langs " + languages.toString());
} on PlatformException { } on PlatformException {
print("Error obtaining preferred languages"); print("Error obtaining preferred languages");
} }
@ -69,14 +64,10 @@ class Session {
Auth flow of the user, see auth.dart Auth flow of the user, see auth.dart
*/ */
_fetchToken(SharedPreferences prefs) async { _fetchToken(SharedPreferences prefs) async {
var responseJson = await APIClient.authenticateUser(Cache.username, Cache.password);
var responseJson = await APIClient.authenticateUser(
Cache.username,
Cache.password
);
int customerId = 0; int customerId = 0;
print("--- Lang: " + AppLanguage().appLocal.toString()); print("--- Lang: " + AppLanguage().appLocal.toString());
if(responseJson['error'] != null) { if (responseJson['error'] != null) {
print("************** Here big error - no authentication"); print("************** Here big error - no authentication");
} else if (responseJson['token'] != null) { } else if (responseJson['token'] != null) {
prefs.setString(Cache.authTokenKey, responseJson['token']); prefs.setString(Cache.authTokenKey, responseJson['token']);
@ -89,8 +80,7 @@ class Session {
Cache().startPage = "registration"; Cache().startPage = "registration";
} else { } else {
DateTime now = DateTime.now(); DateTime now = DateTime.now();
DateTime lastStoreDate = DateTime.parse( DateTime lastStoreDate = DateTime.parse(prefs.get(Cache.lastStoreDateKey));
prefs.get(Cache.lastStoreDateKey));
DateTime minStoreDate = now.add(Duration(days: -10)); DateTime minStoreDate = now.add(Duration(days: -10));
if (lastStoreDate == null || if (lastStoreDate == null ||
@ -100,14 +90,14 @@ class Session {
print("************* Login"); print("************* Login");
Cache().startPage = "login"; Cache().startPage = "login";
} else { } else {
// only // only
if ( Cache().firebaseUid == null) { if (Cache().firebaseUid == null) {
print("************* firebaseUid is null, Login"); print("************* firebaseUid is null, Login");
Cache().startPage = "login"; Cache().startPage = "login";
} else { } else {
// get API customer // get API customer
customerId = prefs.getInt(Cache.customerIdKey); customerId = prefs.getInt(Cache.customerIdKey);
await PropertyApi().getProperties();
await CustomerApi().getCustomer(customerId); await CustomerApi().getCustomer(customerId);
Cache().startPage = "home"; Cache().startPage = "home";
} }
@ -115,13 +105,12 @@ class Session {
await ExerciseTypeApi().getExerciseTypes(); await ExerciseTypeApi().getExerciseTypes();
await ExerciseTreeApi().getExerciseTree(); await ExerciseTreeApi().getExerciseTree();
if ( customerId > 0) { if (customerId > 0) {
ExerciseRepository exerciseRepository = ExerciseRepository(); ExerciseRepository exerciseRepository = ExerciseRepository();
await exerciseRepository.getExercisesByCustomer(customerId); await exerciseRepository.getExercisesByCustomer(customerId);
} }
print("--- Session finished"); print("--- Session finished");
} }
} }
} }
} }

View File

@ -10,4 +10,6 @@ mixin Trans {
String t(String text) { String t(String text) {
return AppLocalizations.of(context).translate(text); return AppLocalizations.of(context).translate(text);
} }
} }

View File

@ -2,6 +2,7 @@ import 'package:aitrainer_app/bloc/account/account_bloc.dart';
import 'package:aitrainer_app/localization/app_language.dart'; import 'package:aitrainer_app/localization/app_language.dart';
import 'package:aitrainer_app/model/customer.dart'; import 'package:aitrainer_app/model/customer.dart';
import 'package:aitrainer_app/util/trans.dart'; import 'package:aitrainer_app/util/trans.dart';
import 'package:aitrainer_app/widgets/app_bar_min.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:aitrainer_app/widgets/bottom_nav.dart'; import 'package:aitrainer_app/widgets/bottom_nav.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
@ -17,17 +18,8 @@ class AccountPage extends StatelessWidget with Trans {
setContext(context); setContext(context);
accountBloc = BlocProvider.of<AccountBloc>(context); accountBloc = BlocProvider.of<AccountBloc>(context);
return Scaffold( return Scaffold(
appBar: AppBar( appBar: AppBarMin(),
title: Text(t('Account')),
backgroundColor: Colors.transparent,
),
body: Container( body: Container(
foregroundDecoration: BoxDecoration(
image: DecorationImage(
image: AssetImage('asset/image/WT_long_logo.png'),
alignment: Alignment.topRight,
),
),
decoration: BoxDecoration( decoration: BoxDecoration(
image: DecorationImage( image: DecorationImage(
image: AssetImage('asset/image/WT_light_background.png'), image: AssetImage('asset/image/WT_light_background.png'),
@ -35,79 +27,64 @@ class AccountPage extends StatelessWidget with Trans {
alignment: Alignment.center, alignment: Alignment.center,
), ),
), ),
child: BlocConsumer<AccountBloc, AccountState>( child: BlocConsumer<AccountBloc, AccountState>(listener: (context, state) {
listener: (context, state) { if (state is AccountError) {
if (state is AccountError) { Scaffold.of(context).showSnackBar(
Scaffold.of(context).showSnackBar(SnackBar( SnackBar(backgroundColor: Colors.orange, content: Text(state.message, style: TextStyle(color: Colors.white))));
backgroundColor: Colors.orange, } else if (state is AccountLoading) {}
content: }, builder: (context, state) {
Text(state.message, style: TextStyle(color: Colors.white)))); if (state is AccountInitial) {
} else if (state is AccountLoading) { 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;
builder: (context, state) { return accountWidget(context, customerName, accountBloc);
if ( state is AccountInitial ) { } else if (state is AccountLoggedOut) {
String customerName = accountBloc.customerRepository.firstName + String customerName = "";
" " + accountBloc.customerRepository.name; return accountWidget(context, customerName, accountBloc);
return accountWidget(context, customerName, accountBloc); } else if (state is AccountReady) {
} else if ( state is AccountLoggedIn ) { String customerName = accountBloc.customerRepository.firstName + " " + accountBloc.customerRepository.name;
String customerName = accountBloc.customerRepository.firstName + return accountWidget(context, customerName, accountBloc);
" " + accountBloc.customerRepository.name; } else {
return accountWidget(context, customerName, accountBloc); return accountWidget(context, "", 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);
}
} }
), }),
), ),
bottomNavigationBar: BottomNavigator(bottomNavIndex: 3)); bottomNavigationBar: BottomNavigator(bottomNavIndex: 3));
} }
ListView accountWidget(BuildContext context, String customerName, AccountBloc accountBloc) { ListView accountWidget(BuildContext context, String customerName, AccountBloc accountBloc) {
return ListView(padding: EdgeInsets.only(top: 135), children: <Widget>[ return ListView(padding: EdgeInsets.only(top: 35), children: <Widget>[
ListTile( ListTile(
leading: Icon(Icons.perm_identity), leading: Icon(Icons.perm_identity),
subtitle: subtitle: Text(t("Profile")),
Text(t("Profile")),
title: FlatButton( title: FlatButton(
child: Row( child: Row(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [
mainAxisAlignment: MainAxisAlignment.spaceBetween, Text(customerName, style: TextStyle(color: Colors.blue)),
children: [ Icon(Icons.arrow_forward_ios),
Text(customerName, ]),
style: TextStyle(color: Colors.blue)),
Icon(Icons.arrow_forward_ios),
]),
textColor: Colors.grey, textColor: Colors.grey,
color: Colors.white, color: Colors.white,
onPressed: () => { onPressed: () => {
if (accountBloc.customerRepository.customer != null) { if (accountBloc.customerRepository.customer != null)
Navigator.of(context).pushNamed('customerModifyPage'), {
print("Profile"), Navigator.of(context).pushNamed('customerModifyPage'),
} }
}, },
), ),
), ),
loginOut( context, accountBloc ), loginOut(context, accountBloc),
getMyTrainees(context, accountBloc), getMyTrainees(context, accountBloc),
]); ]);
} }
ListTile loginOut( BuildContext context, AccountBloc accountBloc ) { ListTile loginOut(BuildContext context, AccountBloc accountBloc) {
ListTile element = ListTile(); ListTile element = ListTile();
String text = "Logout"; String text = "Logout";
Color buttonColor = Colors.orange; Color buttonColor = Colors.orange;
if ( accountBloc.customerRepository.customer == null || accountBloc.customerRepository.customer.email == null) { if (accountBloc.customerRepository.customer == null || accountBloc.customerRepository.customer.email == null) {
text = "Login"; text = "Login";
buttonColor = Colors.blue; buttonColor = Colors.blue;
} }
@ -116,25 +93,22 @@ class AccountPage extends StatelessWidget with Trans {
enabled: true, enabled: true,
leading: Icon(Icons.input), leading: Icon(Icons.input),
title: FlatButton( title: FlatButton(
child: Row( child: Row(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [
mainAxisAlignment: MainAxisAlignment.spaceBetween, Text(t(text), style: TextStyle(color: buttonColor)),
children: [ Icon(Icons.arrow_forward_ios),
Text(t(text), ]),
style: TextStyle(
color: buttonColor
)),
Icon(Icons.arrow_forward_ios),
]),
textColor: buttonColor, textColor: buttonColor,
color: Colors.white, color: Colors.white,
onPressed: () => { onPressed: () => {
if ( accountBloc.loggedIn ) { if (accountBloc.loggedIn)
confirmationDialog( accountBloc ), {
} else { confirmationDialog(accountBloc),
accountBloc.add(AccountLogin()), }
Navigator.of(context).pushNamed('login'), else
} {
accountBloc.add(AccountLogin()),
Navigator.of(context).pushNamed('login'),
}
}, },
), ),
); );
@ -142,17 +116,17 @@ class AccountPage extends StatelessWidget with Trans {
return element; return element;
} }
Widget getMyTrainees( BuildContext context, AccountBloc accountBloc ) { Widget getMyTrainees(BuildContext context, AccountBloc accountBloc) {
if ( accountBloc.customerRepository.customer == null ) { if (accountBloc.customerRepository.customer == null) {
return Container(); return Container();
} }
if ( accountBloc.customerRepository.customer.trainer == 0 ) { if (accountBloc.customerRepository.customer.trainer == 0) {
return ListTile( return ListTile(
title: Container(), title: Container(),
); );
} }
if (accountBloc.customerRepository.getTraineesList() == null ) { if (accountBloc.customerRepository.getTraineesList() == null) {
return ListTile( return ListTile(
leading: Icon(Icons.people), leading: Icon(Icons.people),
title: RaisedButton( title: RaisedButton(
@ -161,7 +135,6 @@ class AccountPage extends StatelessWidget with Trans {
child: Text("See my trainees"), child: Text("See my trainees"),
), ),
); );
} }
List<Widget> elements = List<Widget>(); List<Widget> elements = List<Widget>();
@ -169,74 +142,64 @@ class AccountPage extends StatelessWidget with Trans {
Customer trainee = element; Customer trainee = element;
String name = trainee.name; String name = trainee.name;
String firstName = trainee.firstname; String firstName = trainee.firstname;
String nodeName = AppLanguage().appLocal == Locale("en") ? String nodeName = AppLanguage().appLocal == Locale("en") ? firstName + " " + name : name + " " + firstName;
firstName + " " + name : name + " " + firstName;
bool selected = accountBloc.traineeId == trainee.customerId; bool selected = accountBloc.traineeId == trainee.customerId;
Widget widget = FlatButton( Widget widget = FlatButton(
padding: EdgeInsets.all(10), padding: EdgeInsets.all(10),
shape:RoundedRectangleBorder( shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(8)), borderRadius: BorderRadius.all(Radius.circular(8)),
side: BorderSide(width: 2, color: selected ? Colors.blue : Colors.black26 ), side: BorderSide(width: 2, color: selected ? Colors.blue : Colors.black26),
), ),
onPressed: () { onPressed: () {
accountBloc.add(AccountSelectTrainee(traineeId: trainee.customerId)); accountBloc.add(AccountSelectTrainee(traineeId: trainee.customerId));
//Navigator.of(context).pushNamed('login'); //Navigator.of(context).pushNamed('login');
}, },
child: Row( child: Row(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [
mainAxisAlignment: MainAxisAlignment.spaceBetween, Text(
children: [ nodeName,
Text(nodeName, style: style: TextStyle(color: selected ? Colors.blue : Colors.black54, fontWeight: selected ? FontWeight.bold : FontWeight.normal),
TextStyle( ),
color: selected ? Colors.blue : Colors.black54, Icon(Icons.arrow_forward_ios),
fontWeight: selected ? FontWeight.bold : FontWeight.normal ]),
),
),
Icon(Icons.arrow_forward_ios),
]),
); );
elements.add(widget); elements.add(widget);
}); });
return ListTile( return ListTile(
leading: Icon(Icons.people), leading: Icon(Icons.people),
subtitle: Text("My Trainees"), subtitle: Text("My Trainees"),
title: Column( title: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.spaceAround, mainAxisAlignment: MainAxisAlignment.spaceAround,
children: elements, children: elements,
) ));
);
} }
void confirmationDialog(AccountBloc accountBloc) { void confirmationDialog(AccountBloc accountBloc) {
showCupertinoDialog( showCupertinoDialog(
useRootNavigator: true, useRootNavigator: true,
context: context, context: context,
//barrierDismissible: false, //barrierDismissible: false,
builder:(_) => CupertinoAlertDialog( builder: (_) => CupertinoAlertDialog(
title: Text(t("Are you sure to logout?")), title: Text(t("Are you sure to logout?")),
content: Column( content: Column(children: [
Divider(),
children: [ ]),
Divider(), actions: [
]), FlatButton(
actions: [ child: Text(t("No")),
FlatButton( onPressed: () => Navigator.pop(context),
child: Text(t("No")), ),
onPressed: () => Navigator.pop(context), FlatButton(
), child: Text(t("Yes")),
FlatButton( onPressed: () => {
child: Text(t("Yes")), accountBloc.add(AccountLogout()),
onPressed: () => { Navigator.pop(context),
accountBloc.add(AccountLogout()), },
Navigator.pop(context), )
}, ],
) ));
],
)
);
} }
} }

View File

@ -1,6 +1,7 @@
import 'package:aitrainer_app/bloc/customer_change/customer_change_bloc.dart'; import 'package:aitrainer_app/bloc/customer_change/customer_change_bloc.dart';
import 'package:aitrainer_app/localization/app_localization.dart'; import 'package:aitrainer_app/localization/app_localization.dart';
import 'package:aitrainer_app/repository/customer_repository.dart'; import 'package:aitrainer_app/repository/customer_repository.dart';
import 'package:aitrainer_app/model/fitness_state.dart';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart'; import 'package:flutter/rendering.dart';
@ -16,13 +17,13 @@ class CustomerFitnessPage extends StatefulWidget {
} }
} }
class FitnessItem { /* class FitnessItem {
static String beginner = "beginner"; static String beginner = "beginner";
static String intermediate = "intermediate"; static String intermediate = "intermediate";
static String advanced = "advanced"; static String advanced = "advanced";
static String professional = "professional"; static String professional = "professional";
} }
*/
//TODO //TODO
// dropbox for professional sport // dropbox for professional sport
@ -32,8 +33,7 @@ class _CustomerFitnessPageState extends State<CustomerFitnessPage> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final double cWidth = MediaQuery.of(context).size.width * 0.75; final double cWidth = MediaQuery.of(context).size.width * 0.75;
final CustomerRepository customerRepository = final CustomerRepository customerRepository = ModalRoute.of(context).settings.arguments;
ModalRoute.of(context).settings.arguments;
selected = customerRepository.customer.fitnessLevel; selected = customerRepository.customer.fitnessLevel;
return Scaffold( return Scaffold(
appBar: AppBar( appBar: AppBar(
@ -50,12 +50,10 @@ class _CustomerFitnessPageState extends State<CustomerFitnessPage> {
backgroundColor: Colors.transparent, backgroundColor: Colors.transparent,
), ),
body: BlocProvider( body: BlocProvider(
create: (context) => create: (context) => CustomerChangeBloc(customerRepository: customerRepository),
CustomerChangeBloc(customerRepository: customerRepository),
child: Builder(builder: (context) { child: Builder(builder: (context) {
// ignore: close_sinks // ignore: close_sinks
CustomerChangeBloc changeBloc = CustomerChangeBloc changeBloc = BlocProvider.of<CustomerChangeBloc>(context);
BlocProvider.of<CustomerChangeBloc>(context);
return SingleChildScrollView( return SingleChildScrollView(
scrollDirection: Axis.vertical, scrollDirection: Axis.vertical,
@ -77,14 +75,9 @@ class _CustomerFitnessPageState extends State<CustomerFitnessPage> {
alignment: WrapAlignment.center, alignment: WrapAlignment.center,
children: [ children: [
Text( Text(
AppLocalizations.of(context) AppLocalizations.of(context).translate("Your Fitness State"),
.translate("Your Fitness State"),
textAlign: TextAlign.center, textAlign: TextAlign.center,
style: TextStyle( style: TextStyle(color: Colors.orange, fontSize: 42, fontFamily: 'Arial', fontWeight: FontWeight.w900),
color: Colors.orange,
fontSize: 42,
fontFamily: 'Arial',
fontWeight: FontWeight.w900),
) )
]), ]),
Divider(), Divider(),
@ -93,33 +86,20 @@ class _CustomerFitnessPageState extends State<CustomerFitnessPage> {
width: cWidth, width: cWidth,
child: Column( child: Column(
children: [ children: [
Text(AppLocalizations.of(context).translate("Beginner"),
textWidthBasis: TextWidthBasis.longestLine,
style: TextStyle(color: Colors.blue, fontSize: 32, fontFamily: 'Arial', fontWeight: FontWeight.w900)),
Text( Text(
AppLocalizations.of(context) AppLocalizations.of(context).translate("I am beginner"),
.translate("Beginner"), style: TextStyle(color: Colors.black, fontSize: 20, fontFamily: 'Arial', fontWeight: FontWeight.w100),
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), padding: EdgeInsets.all(10.0),
shape: getShape( shape: getShape(customerRepository, FitnessState.beginner),
customerRepository, FitnessItem.beginner),
onPressed: () => { onPressed: () => {
setState(() { setState(() {
selected = FitnessItem.beginner; selected = FitnessState.beginner;
changeBloc.add(CustomerFitnessChange(fitness: selected)); changeBloc.add(CustomerFitnessChange(fitness: selected));
print(selected); print(selected);
}), }),
@ -132,25 +112,15 @@ class _CustomerFitnessPageState extends State<CustomerFitnessPage> {
children: [ children: [
InkWell( InkWell(
child: Text( child: Text(
AppLocalizations.of(context) AppLocalizations.of(context).translate("Intermediate"),
.translate("Intermediate"), style: TextStyle(color: Colors.blue, fontSize: 32, fontFamily: 'Arial', fontWeight: FontWeight.w900),
style: TextStyle(
color: Colors.blue,
fontSize: 32,
fontFamily: 'Arial',
fontWeight: FontWeight.w900),
), ),
highlightColor: Colors.white, highlightColor: Colors.white,
), ),
InkWell( InkWell(
child: Text( child: Text(
AppLocalizations.of(context) AppLocalizations.of(context).translate("I am intermediate"),
.translate("I am intermediate"), style: TextStyle(color: Colors.black, fontSize: 20, fontFamily: 'Arial', fontWeight: FontWeight.w100),
style: TextStyle(
color: Colors.black,
fontSize: 20,
fontFamily: 'Arial',
fontWeight: FontWeight.w100),
), ),
highlightColor: Colors.white, highlightColor: Colors.white,
), ),
@ -158,11 +128,10 @@ class _CustomerFitnessPageState extends State<CustomerFitnessPage> {
), ),
), ),
padding: EdgeInsets.all(10.0), padding: EdgeInsets.all(10.0),
shape: getShape( shape: getShape(customerRepository, FitnessState.intermediate),
customerRepository, FitnessItem.intermediate),
onPressed: () => { onPressed: () => {
setState(() { setState(() {
selected = FitnessItem.intermediate; selected = FitnessState.intermediate;
changeBloc.add(CustomerFitnessChange(fitness: selected)); changeBloc.add(CustomerFitnessChange(fitness: selected));
print(selected); print(selected);
}), }),
@ -175,25 +144,15 @@ class _CustomerFitnessPageState extends State<CustomerFitnessPage> {
children: [ children: [
InkWell( InkWell(
child: Text( child: Text(
AppLocalizations.of(context) AppLocalizations.of(context).translate("Advanced"),
.translate("Advanced"), style: TextStyle(color: Colors.blue, fontSize: 32, fontFamily: 'Arial', fontWeight: FontWeight.w900),
style: TextStyle(
color: Colors.blue,
fontSize: 32,
fontFamily: 'Arial',
fontWeight: FontWeight.w900),
), ),
highlightColor: Colors.white, highlightColor: Colors.white,
), ),
InkWell( InkWell(
child: Text( child: Text(
AppLocalizations.of(context) AppLocalizations.of(context).translate("I am advanced"),
.translate("I am advanced"), style: TextStyle(color: Colors.black, fontSize: 20, fontFamily: 'Arial', fontWeight: FontWeight.w100),
style: TextStyle(
color: Colors.black,
fontSize: 20,
fontFamily: 'Arial',
fontWeight: FontWeight.w100),
), ),
highlightColor: Colors.white, highlightColor: Colors.white,
), ),
@ -201,11 +160,10 @@ class _CustomerFitnessPageState extends State<CustomerFitnessPage> {
), ),
), ),
padding: EdgeInsets.all(10.0), padding: EdgeInsets.all(10.0),
shape: getShape( shape: getShape(customerRepository, FitnessState.advanced),
customerRepository, FitnessItem.advanced),
onPressed: () => { onPressed: () => {
setState(() { setState(() {
selected = FitnessItem.advanced; selected = FitnessState.advanced;
changeBloc.add(CustomerFitnessChange(fitness: selected)); changeBloc.add(CustomerFitnessChange(fitness: selected));
print(selected); print(selected);
}), }),
@ -218,25 +176,15 @@ class _CustomerFitnessPageState extends State<CustomerFitnessPage> {
children: [ children: [
InkWell( InkWell(
child: Text( child: Text(
AppLocalizations.of(context) AppLocalizations.of(context).translate("Professional"),
.translate("Professional"), style: TextStyle(color: Colors.blue, fontSize: 32, fontFamily: 'Arial', fontWeight: FontWeight.w900),
style: TextStyle(
color: Colors.blue,
fontSize: 32,
fontFamily: 'Arial',
fontWeight: FontWeight.w900),
), ),
highlightColor: Colors.white, highlightColor: Colors.white,
), ),
InkWell( InkWell(
child: Text( child: Text(
AppLocalizations.of(context) AppLocalizations.of(context).translate("I am professional"),
.translate("I am professional"), style: TextStyle(color: Colors.black, fontSize: 20, fontFamily: 'Arial', fontWeight: FontWeight.w100),
style: TextStyle(
color: Colors.black,
fontSize: 20,
fontFamily: 'Arial',
fontWeight: FontWeight.w100),
), ),
highlightColor: Colors.white, highlightColor: Colors.white,
), ),
@ -244,11 +192,10 @@ class _CustomerFitnessPageState extends State<CustomerFitnessPage> {
), ),
), ),
padding: EdgeInsets.all(10.0), padding: EdgeInsets.all(10.0),
shape: getShape( shape: getShape(customerRepository, FitnessState.professional),
customerRepository, FitnessItem.professional),
onPressed: () => { onPressed: () => {
setState(() { setState(() {
selected = FitnessItem.professional; selected = FitnessState.professional;
changeBloc.add(CustomerFitnessChange(fitness: selected)); changeBloc.add(CustomerFitnessChange(fitness: selected));
print(selected); print(selected);
}), }),
@ -257,15 +204,11 @@ class _CustomerFitnessPageState extends State<CustomerFitnessPage> {
RaisedButton( RaisedButton(
color: Colors.orange, color: Colors.orange,
textColor: Colors.white, textColor: Colors.white,
child: InkWell( child: InkWell(child: Text(AppLocalizations.of(context).translate("Next"))),
child: Text(AppLocalizations.of(context)
.translate("Next"))),
onPressed: () => { onPressed: () => {
changeBloc.add(CustomerSave()), changeBloc.add(CustomerSave()),
Navigator.of(context).pop(), Navigator.of(context).pop(),
Navigator.of(context).pushNamed( Navigator.of(context).pushNamed("customerBodyTypePage", arguments: customerRepository)
"customerBodyTypePage",
arguments: customerRepository)
}, },
) )
], ],

View File

@ -1,17 +1,21 @@
import 'package:aitrainer_app/bloc/account/account_bloc.dart'; import 'package:aitrainer_app/bloc/account/account_bloc.dart';
import 'package:aitrainer_app/bloc/customer_change_form_bloc.dart'; import 'package:aitrainer_app/bloc/customer_change/customer_change_bloc.dart';
import 'package:aitrainer_app/library/numberpicker.dart';
import 'package:aitrainer_app/util/trans.dart'; import 'package:aitrainer_app/util/trans.dart';
import 'package:aitrainer_app/widgets/app_bar_min.dart';
import 'package:aitrainer_app/widgets/splash.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:flutter/services.dart'; import 'package:flutter/widgets.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_form_bloc/flutter_form_bloc.dart';
import 'package:toggle_switch/toggle_switch.dart';
import '../library_keys.dart'; import '../library_keys.dart';
// ignore: must_be_immutable // ignore: must_be_immutable
class CustomerModifyPage extends StatelessWidget with Trans { class CustomerModifyPage extends StatelessWidget with Trans {
final _formKey = GlobalKey<FormState>(); final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@ -20,180 +24,268 @@ class CustomerModifyPage extends StatelessWidget with Trans {
final accountBloc = BlocProvider.of<AccountBloc>(context); final accountBloc = BlocProvider.of<AccountBloc>(context);
return BlocProvider( return BlocProvider(
create: (context) => CustomerChangeFormBloc(customerRepository: accountBloc.customerRepository), create: (context) => CustomerChangeBloc(customerRepository: accountBloc.customerRepository)..add(CustomerLoad()),
child: Builder(builder: (context) { child: Builder(builder: (context) {
// ignore: close_sinks // ignore: close_sinks
final customerBloc = BlocProvider.of<CustomerChangeFormBloc>(context); final customerBloc = BlocProvider.of<CustomerChangeBloc>(context);
return Scaffold( return Scaffold(
resizeToAvoidBottomInset: true, resizeToAvoidBottomInset: true,
appBar: AppBar( appBar: AppBarMin(
title: Row( back: true,
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( body: Container(
decoration: BoxDecoration( decoration: BoxDecoration(
image: DecorationImage( image: DecorationImage(
image: AssetImage('asset/image/WT_light_background.png'), image: AssetImage('asset/image/WT_light_background.png'),
fit: BoxFit.cover, fit: BoxFit.fill,
alignment: Alignment.center, alignment: Alignment.center,
), ),
), ),
child: Form( child: BlocConsumer<CustomerChangeBloc, CustomerChangeState>(
key: _formKey, listener: (context, state) {
child: SingleChildScrollView( if (state is CustomerChangeLoading) {
scrollDirection: Axis.vertical, LoadingDialog();
padding: EdgeInsets.only(top: 40, left: 25, right: 45, bottom: 100), } else if (state is CustomerSaveError) {
child: Container( Scaffold.of(context).showSnackBar(
alignment: Alignment.center, SnackBar(backgroundColor: Colors.orange, content: Text(state.message, style: TextStyle(color: Colors.white))));
child: Column( } else if (state is CustomerSaveSuccess) {
children: [ Navigator.of(context).pushNamed("customerGoalPage", arguments: customerBloc.customerRepository);
Row( }
mainAxisAlignment: MainAxisAlignment.spaceBetween, },
children: [ builder: (context, state) {
Expanded( return loadForm(customerBloc);
child: TextFieldBlocBuilder( },
key: LibraryKeys.loginEmailField,
style: TextStyle(fontSize: 12),
textFieldBloc: customerBloc.emailField,
decoration: InputDecoration(
fillColor: Colors.white24,
filled: true,
labelText: t('Email'),
),
),
)
],
),
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: t('Password (Leave empty if no change)'),
),
),
)
],
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded(
child: TextFieldBlocBuilder(
style: TextStyle(fontSize: 12),
textFieldBloc: customerBloc.nameField,
decoration: InputDecoration(
fillColor: Colors.white24,
filled: true,
labelText: t('Name'),
),
),
)
],
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded(
child: TextFieldBlocBuilder(
style: TextStyle(fontSize: 12),
textFieldBloc: customerBloc.firstNameField,
decoration: InputDecoration(
fillColor: Colors.white24,
filled: true,
labelText: t('First Name'),
),
),
)
],
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded(
child: TextFieldBlocBuilder(
style: TextStyle(fontSize: 12),
textFieldBloc: customerBloc.birthYearField,
inputFormatters: [FilteringTextInputFormatter.allow(RegExp(r"[\d]"))],
decoration: InputDecoration(
fillColor: Colors.white24,
filled: true,
labelText: t('Birth Year'),
),
),
)
],
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded(
child: TextFieldBlocBuilder(
style: TextStyle(fontSize: 12),
textFieldBloc: customerBloc.weightField,
inputFormatters: [FilteringTextInputFormatter.allow(RegExp(r"[\d]"))],
decoration: InputDecoration(
fillColor: Colors.white24,
filled: true,
labelText: t('Weight'),
),
),
)
],
),
Divider(),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded(
child: DropdownFieldBlocBuilder(
selectFieldBloc: customerBloc.genderField,
itemBuilder: (context, item) => item,
decoration: InputDecoration(
labelText: t('Select a gender'),
)),
)
],
),
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
Expanded(
child: RaisedButton(
color: Colors.orange,
textColor: Colors.white,
child: InkWell(child: Text(t("Next"))),
onPressed: () => {
customerBloc.add(SubmitFormBloc()),
Navigator.of(context)
.pushNamed("customerGoalPage", arguments: customerBloc.customerRepository)
},
))
],
),
],
),
),
),
))); )));
})); }));
} }
Widget loadForm(CustomerChangeBloc customerBloc) {
return Form(
key: _scaffoldKey,
autovalidateMode: AutovalidateMode.always,
child: SingleChildScrollView(
scrollDirection: Axis.vertical,
padding: EdgeInsets.only(top: 40, left: 25, right: 25, bottom: 250),
child: Container(
alignment: Alignment.center,
child: Column(
children: [
TextFormField(
key: LibraryKeys.loginEmailField,
decoration: InputDecoration(
contentPadding: EdgeInsets.only(left: 15, top: 15, bottom: 15),
labelText: t('Email'),
fillColor: Colors.white24,
filled: true,
border: OutlineInputBorder(
gapPadding: 4.0,
borderRadius: BorderRadius.circular(12.0),
borderSide: BorderSide(color: Colors.green[50], width: 0.4),
),
),
initialValue: customerBloc.customerRepository.customer.email,
autovalidateMode: AutovalidateMode.always,
validator: (val) {
return customerBloc.emailValidation(val);
},
keyboardType: TextInputType.emailAddress,
style: new TextStyle(fontSize: 16, color: Colors.indigo),
),
Divider(
color: Colors.transparent,
),
TextFormField(
key: LibraryKeys.loginPasswordField,
obscureText: true,
decoration: InputDecoration(
labelStyle: TextStyle(fontSize: 14),
contentPadding: EdgeInsets.only(left: 15, top: 15, bottom: 15),
suffixIcon: IconButton(
onPressed: () => {customerBloc.add(CustomerChangePasswordObscure())},
icon: Icon(Icons.remove_red_eye),
),
labelText: t('Password (Leave empty if no change)'),
fillColor: Colors.white24,
filled: true,
border: OutlineInputBorder(
gapPadding: 1.0,
borderRadius: BorderRadius.circular(12.0),
borderSide: BorderSide(color: Colors.green[50], width: 0.4),
),
),
initialValue: customerBloc.customerRepository.customer.password,
autovalidateMode: AutovalidateMode.always,
validator: (val) {
return customerBloc.passwordValidation(val);
},
keyboardType: TextInputType.visiblePassword,
style: new TextStyle(fontSize: 16, color: Colors.indigo),
),
Divider(
color: Colors.transparent,
),
TextFormField(
decoration: InputDecoration(
contentPadding: EdgeInsets.only(left: 15, top: 15, bottom: 15),
labelText: t('Name'),
fillColor: Colors.white24,
filled: true,
border: OutlineInputBorder(
gapPadding: 1.0,
borderRadius: BorderRadius.circular(12.0),
borderSide: BorderSide(color: Colors.green[50], width: 0.4),
),
),
initialValue: customerBloc.customerRepository.customer.name,
autovalidateMode: AutovalidateMode.always,
validator: (val) {
return customerBloc.nameValidation(val);
},
keyboardType: TextInputType.name,
style: new TextStyle(fontSize: 16, color: Colors.indigo),
onChanged: (value) => {customerBloc.add(CustomerNameChange(name: value))}),
Divider(
color: Colors.transparent,
),
TextFormField(
decoration: InputDecoration(
contentPadding: EdgeInsets.only(left: 15, top: 15, bottom: 15),
labelText: t('First Name'),
fillColor: Colors.white24,
filled: true,
border: OutlineInputBorder(
gapPadding: 2.0,
borderRadius: BorderRadius.circular(12.0),
borderSide: BorderSide(color: Colors.green[50], width: 0.4),
),
),
initialValue: customerBloc.customerRepository.customer.firstname,
autovalidateMode: AutovalidateMode.always,
validator: (val) {
return customerBloc.nameValidation(val);
},
keyboardType: TextInputType.name,
style: new TextStyle(fontSize: 16, color: Colors.indigo),
onChanged: (value) => {customerBloc.add(CustomerFirstNameChange(firstName: value))}),
Divider(
color: Colors.transparent,
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded(
flex: 4,
child: Text(t("Birth Year"), style: TextStyle(fontWeight: FontWeight.normal, fontSize: 14)),
),
Flexible(
fit: FlexFit.tight,
flex: 8,
child: NumberPicker.horizontal(
highlightSelectedValue: true,
initialValue: customerBloc.year,
minValue: 1930,
maxValue: 2100,
step: 1,
textStyle: TextStyle(fontWeight: FontWeight.bold),
textStyleHighlighted: TextStyle(fontSize: 16, color: Colors.indigo, fontWeight: FontWeight.bold),
onChanged: (value) => {customerBloc.add(CustomerBirthYearChange(year: value))},
listViewHeight: 60,
//decoration: _decoration,
),
),
SizedBox(width: 80),
],
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Expanded(
flex: 4,
child: Text(t("Weight"), style: TextStyle(fontWeight: FontWeight.normal, fontSize: 14)),
),
Flexible(
fit: FlexFit.tight,
flex: 8,
child: NumberPicker.horizontal(
highlightSelectedValue: true,
initialValue: customerBloc.weight.toInt(),
minValue: 0,
maxValue: 200,
step: 1,
textStyle: TextStyle(fontWeight: FontWeight.bold),
textStyleHighlighted: TextStyle(fontSize: 18, color: Colors.indigo, fontWeight: FontWeight.bold),
onChanged: (value) => {customerBloc.add(CustomerWeightChange(weight: value))},
listViewHeight: 60,
),
),
SizedBox(width: 80),
],
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Expanded(
flex: 4,
child: Text(t("Height"), style: TextStyle(fontWeight: FontWeight.normal, fontSize: 14)),
),
Flexible(
fit: FlexFit.tight,
flex: 8,
child: NumberPicker.horizontal(
highlightSelectedValue: true,
initialValue: customerBloc.height.toInt(),
minValue: 0,
maxValue: 230,
step: 1,
textStyle: TextStyle(fontWeight: FontWeight.bold),
textStyleHighlighted: TextStyle(fontSize: 18, color: Colors.indigo, fontWeight: FontWeight.bold),
onChanged: (value) => {customerBloc.add(CustomerHeightChange(height: value))},
listViewHeight: 60,
),
),
SizedBox(width: 80),
],
),
Divider(),
ToggleSwitch(
minWidth: 50.0,
minHeight: 50.0,
fontSize: 14.0,
initialLabelIndex: customerBloc.customerRepository.customer.sex == "m" ? 0 : 1,
activeBgColor: Colors.indigo,
activeFgColor: Colors.white,
inactiveBgColor: Colors.white30,
inactiveFgColor: Colors.grey[900],
labels: [t('Man'), t('Woman')],
onToggle: (index) {
customerBloc.add(CustomerGenderChange(gender: index));
},
),
Divider(),
FlatButton(
onPressed: () => {customerBloc.add(CustomerSave())},
child: Stack(
alignment: Alignment.center,
children: [
Image.asset('asset/icon/gomb_orange_a.png', width: 140, height: 60),
Text(
t("Next"),
style: TextStyle(fontSize: 16, color: Colors.white),
),
],
),
),
],
),
),
),
);
}
void showInSnackBar(String error) {
_scaffoldKey.currentState
.showSnackBar(SnackBar(backgroundColor: Colors.orange, content: Text(error, style: TextStyle(color: Colors.white))));
}
} }

View File

@ -1,8 +1,9 @@
import 'package:aitrainer_app/localization/app_localization.dart'; import 'package:aitrainer_app/localization/app_localization.dart';
import 'package:aitrainer_app/widgets/app_bar_min.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
// ignore: must_be_immutable // ignore: must_be_immutable
class CustomerWelcomePage extends StatefulWidget{ class CustomerWelcomePage extends StatefulWidget {
_CustomerWelcomePageState _state; _CustomerWelcomePageState _state;
_CustomerWelcomePageState createState() { _CustomerWelcomePageState createState() {
@ -14,9 +15,9 @@ class CustomerWelcomePage extends StatefulWidget{
class _CustomerWelcomePageState extends State<CustomerWelcomePage> { class _CustomerWelcomePageState extends State<CustomerWelcomePage> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
appBar: AppBar( appBar: AppBarMin(),
/*
title: Row( title: Row(
mainAxisAlignment: MainAxisAlignment.end, mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[ children: <Widget>[
@ -28,40 +29,34 @@ class _CustomerWelcomePageState extends State<CustomerWelcomePage> {
), ),
], ],
), ),
backgroundColor: Colors.transparent, */
), //backgroundColor: Colors.transparent,
body: Container( //),
decoration: BoxDecoration( body: Container(
image: DecorationImage( decoration: BoxDecoration(
image: AssetImage('asset/image/WT_welcome.png'), image: DecorationImage(
fit: BoxFit.cover, image: AssetImage('asset/image/WT_welcome.png'),
alignment: Alignment.center, fit: BoxFit.fill,
), alignment: Alignment.center,
), ),
child: Center(
child: Column(
children: [
Divider(color: Colors.transparent,),
Divider(color: Colors.transparent,),
Divider(color: Colors.transparent,),
Divider(color: Colors.transparent,),
RaisedButton(
color: Colors.orange,
textColor: Colors.white,
child: InkWell(
child: Text(AppLocalizations.of(context).translate("Next"))),
onPressed: () => {
Navigator.of(context).pop(),
Navigator.of(context).pushNamed("home")
},
)
],
),
)
), ),
child: SafeArea(
bottom: false,
child: Center(
child: Column(
children: [
Divider(
color: Colors.transparent,
),
RaisedButton(
color: Colors.orange,
textColor: Colors.white,
child: InkWell(child: Text(AppLocalizations.of(context).translate("Next"))),
onPressed: () => {Navigator.of(context).pop(), Navigator.of(context).pushNamed("home")},
)
],
),
))),
); );
} }
}
}

View File

@ -12,6 +12,7 @@ import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/scheduler.dart'; import 'package:flutter/scheduler.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:google_fonts/google_fonts.dart';
class ExerciseExecutePage extends StatefulWidget { class ExerciseExecutePage extends StatefulWidget {
@override @override
@ -109,7 +110,8 @@ class _ExerciseExecutePage extends State<ExerciseExecutePage> with Trans {
child: child:
Text( Text(
t("Execute your active Exercise Plan!"), t("Execute your active Exercise Plan!"),
style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold), style: GoogleFonts.archivoBlack(fontSize: 20,),
maxLines: 2,
), ),
), ),
@ -167,13 +169,17 @@ class _ExerciseExecutePage extends State<ExerciseExecutePage> with Trans {
), ),
SizedBox(width: 20), SizedBox(width: 20),
Flexible( Flexible(
fit:FlexFit.tight,
child: child:
InkWell( InkWell(
child: child:
Text( Text(
element.name, element.name,
textAlign: TextAlign.start, textAlign: TextAlign.start,
style: TextStyle(fontSize: 12, color: Colors.black), style: GoogleFonts.inter(
fontSize: 17,
color: Colors.black),
), ),
onTap: () => { onTap: () => {
addExerciseByPlanEvent(bloc, element) addExerciseByPlanEvent(bloc, element)

View File

@ -135,8 +135,17 @@ class _ExerciseExecuteAddPage extends State<ExerciseExecutePlanAddPage> with Tra
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
Divider(color: Colors.transparent,), Divider(color: Colors.transparent,),
Text(t("Execute the") + " " + (i+1).toString() + t(". set!"), Row(
style: TextStyle(),), mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.baseline,
children: [
Text(t("Execute the") + " ",style: TextStyle(fontWeight: FontWeight.bold),),
Text((i+1).toString() + ". ",style: TextStyle(fontSize:24, fontWeight: FontWeight.bold),),
Text(t("set!"),style: TextStyle(fontWeight: FontWeight.bold),),
],
),
Divider(color: Colors.transparent,), Divider(color: Colors.transparent,),
Text(t("Please repeat with") + " "+ exerciseBloc.unitQuantity.toStringAsFixed(0) + " " + Text(t("Please repeat with") + " "+ exerciseBloc.unitQuantity.toStringAsFixed(0) + " " +
exerciseBloc.exerciseRepository.exerciseType.unitQuantityUnit + " " + exerciseBloc.exerciseRepository.exerciseType.unitQuantityUnit + " " +

View File

@ -5,21 +5,73 @@ import 'package:aitrainer_app/bloc/menu/menu_bloc.dart';
import 'package:aitrainer_app/localization/app_language.dart'; import 'package:aitrainer_app/localization/app_language.dart';
import 'package:aitrainer_app/model/cache.dart'; import 'package:aitrainer_app/model/cache.dart';
import 'package:aitrainer_app/model/exercise_type.dart'; import 'package:aitrainer_app/model/exercise_type.dart';
import 'package:aitrainer_app/repository/customer_repository.dart';
import 'package:aitrainer_app/repository/exercise_repository.dart'; import 'package:aitrainer_app/repository/exercise_repository.dart';
import 'package:aitrainer_app/util/trans.dart'; import 'package:aitrainer_app/util/trans.dart';
import 'package:aitrainer_app/widgets/app_bar.dart'; import 'package:aitrainer_app/widgets/app_bar.dart';
import 'package:aitrainer_app/widgets/bmi_widget.dart';
import 'package:aitrainer_app/widgets/bmr_widget.dart';
import 'package:aitrainer_app/widgets/size_widget.dart';
import 'package:aitrainer_app/widgets/splash.dart'; import 'package:aitrainer_app/widgets/splash.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_form_bloc/flutter_form_bloc.dart'; import 'package:flutter_form_bloc/flutter_form_bloc.dart';
import 'package:aitrainer_app/library/numberpicker.dart'; import 'package:google_fonts/google_fonts.dart';
import 'package:keyboard_actions/keyboard_actions.dart';
class ExerciseNewPage extends StatefulWidget{ class ExerciseNewPage extends StatefulWidget {
_ExerciseNewPageState createState() => _ExerciseNewPageState(); _ExerciseNewPageState createState() => _ExerciseNewPageState();
} }
class _ExerciseNewPageState extends State<ExerciseNewPage> with Trans{ class _ExerciseNewPageState extends State<ExerciseNewPage> with Trans {
final FocusNode _nodeText1 = FocusNode();
final FocusNode _nodeText2 = FocusNode();
KeyboardActionsConfig _buildConfig(BuildContext context) {
return KeyboardActionsConfig(
keyboardActionsPlatform: KeyboardActionsPlatform.ALL,
keyboardBarColor: Colors.grey[200],
keyboardSeparatorColor: Colors.black26,
nextFocus: true,
actions: [
KeyboardActionsItem(focusNode: _nodeText2, toolbarButtons: [
(node) {
return GestureDetector(
onTap: () => node.unfocus(),
child: Container(
padding: EdgeInsets.all(8.0),
color: Colors.orange[500],
child: Text(
t("Done"),
style: TextStyle(color: Colors.white),
),
),
);
}
]),
KeyboardActionsItem(
focusNode: _nodeText1,
toolbarButtons: [
//button 2
(node) {
return GestureDetector(
onTap: () => node.unfocus(),
child: Container(
color: Colors.orange,
padding: EdgeInsets.all(8.0),
child: Text(
t("Done"),
style: TextStyle(color: Colors.white),
),
),
);
}
],
),
],
);
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@ -29,251 +81,267 @@ class _ExerciseNewPageState extends State<ExerciseNewPage> with Trans{
setContext(context); setContext(context);
return BlocProvider( return BlocProvider(
create: (context) => ExerciseNewBloc(exerciseRepository: ExerciseRepository(), menuBloc: menuBloc, exerciseType: exerciseType).. create: (context) => ExerciseNewBloc(
add(ExerciseNewLoad()), exerciseRepository: ExerciseRepository(),
child: BlocConsumer<ExerciseNewBloc, ExerciseNewState>( menuBloc: menuBloc,
listener: (context, state) { customerRepository: CustomerRepository(),
if ( state is ExerciseNewLoading ) { exerciseType: exerciseType)
return LoadingDialog(); ..add(ExerciseNewLoad()),
} else if ( state is ExerciseNewError ) { child: BlocConsumer<ExerciseNewBloc, ExerciseNewState>(
Scaffold.of(context).showSnackBar(SnackBar( listener: (context, state) {
backgroundColor: Colors.orange, if (state is ExerciseNewLoading) {
content: return LoadingDialog();
Text(state.message, style: TextStyle(color: Colors.white)))); } else if (state is ExerciseNewError) {
} Scaffold.of(context).showSnackBar(
}, SnackBar(backgroundColor: Colors.orange, content: Text(state.message, style: TextStyle(color: Colors.white))));
builder: (context, state) { }
final exerciseBloc = BlocProvider.of<ExerciseNewBloc>(context); },
if ( state is ExerciseNewReady ) { builder: (context, state) {
final exerciseBloc = BlocProvider.of<ExerciseNewBloc>(context);
double width = MediaQuery.of(context).size.width;
double height = MediaQuery.of(context).size.height;
exerciseBloc.setMediaDimensions(width, height);
return getExerciseWidget(exerciseBloc, exerciseType); return getExerciseWidget(exerciseBloc, exerciseType);
} else { },
return getExerciseWidget(exerciseBloc, exerciseType); ));
}
},
)
);
} }
Widget getExerciseWidget(ExerciseNewBloc exerciseBloc, ExerciseType exerciseType) { Widget getExerciseWidget(ExerciseNewBloc exerciseBloc, ExerciseType exerciseType) {
exerciseBloc.exerciseRepository.setExerciseType(exerciseType); exerciseBloc.exerciseRepository.setExerciseType(exerciseType);
String exerciseName = AppLanguage().appLocal == Locale("en") ? final String exerciseName = AppLanguage().appLocal == Locale("en")
exerciseBloc.exerciseRepository.exerciseType.name : ? exerciseBloc.exerciseRepository.exerciseType.name
exerciseBloc.exerciseRepository.exerciseType.nameTranslation; : exerciseBloc.exerciseRepository.exerciseType.nameTranslation;
String exerciseDescription = AppLanguage().appLocal == Locale("en")
? exerciseBloc.exerciseRepository.exerciseType.description
: exerciseBloc.exerciseRepository.exerciseType.descriptionTranslation;
if (exerciseDescription == null) {
exerciseDescription = "";
}
print(exerciseBloc.exerciseRepository.exerciseType.name);
if (exerciseBloc.exerciseRepository.exerciseType.name == "BMR") {
return BMR(exerciseBloc: exerciseBloc);
}
if (exerciseBloc.exerciseRepository.exerciseType.name == "BMI") {
return BMI(exerciseBloc: exerciseBloc);
}
if (exerciseBloc.exerciseRepository.exerciseType.name == "Sizes") {
return SizeWidget(exerciseBloc: exerciseBloc);
}
return Form( return Form(
child: Scaffold( //autovalidateMode: AutovalidateMode.disabled,
resizeToAvoidBottomInset: true, child: Scaffold(
appBar: AppBarNav(depth: 1), resizeToAvoidBottomInset: true,
body: Container( appBar: AppBarNav(depth: 1),
width: MediaQuery body: Container(
.of(context) width: MediaQuery.of(context).size.width,
.size height: MediaQuery.of(context).size.height,
.width, decoration: BoxDecoration(
height: MediaQuery image: DecorationImage(
.of(context) image: AssetImage('asset/image/WT_black_background.png'),
.size fit: BoxFit.fill,
.height, alignment: Alignment.center,
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage('asset/image/WT_light_background.png'),
fit: BoxFit.fill,
alignment: Alignment.center,
),
), ),
child: Container(
padding: const EdgeInsets.only (top: 25, left: 25, right: 25),
child: SingleChildScrollView(
scrollDirection: Axis.vertical,
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
/*Divider(color: Colors.transparent,),
Divider(color: Colors.transparent,),*/
Text(t('Save Exercise'),
style: TextStyle(fontSize: 14, color: Colors.blueAccent)),
Text(exerciseName,
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 18, color: Colors.deepOrange),
overflow: TextOverflow.fade,
maxLines: 1,
softWrap: true,
),
//Divider(color: Colors.transparent,),
FlatButton(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Icon(Icons.description),
Text(t("Description"),
style: TextStyle(
color: Colors.blueAccent, fontWeight: FontWeight.normal, fontSize: 14)),
Icon(Icons.arrow_forward_ios),
]),
textColor: Colors.blueAccent,
color: Colors.transparent,
onPressed: () =>
{
Navigator.of(context).pushNamed(
'exerciseTypeDescription', arguments: exerciseBloc.exerciseRepository),
},
),
//Divider(color: Colors.transparent,),
columnQuantityUnit(exerciseBloc),
Divider(color: Colors.transparent,),
columnQuantity(exerciseBloc),
Divider(),
Divider(color: Colors.transparent,),
Divider(color: Colors.transparent,),
Divider(color: Colors.transparent,),
RaisedButton(
textColor: Colors.white,
color: Colors.deepOrange,
focusColor: Colors.white,
onPressed: () =>
{
confirmationDialog(exerciseBloc),
},
child: Text(t("Save"), style: TextStyle(fontSize: 16),)
),
]),
)
)
), ),
child: KeyboardActions(
config: _buildConfig(context),
child: Container(
padding: const EdgeInsets.only(top: 5, left: 75, right: 75),
child: SingleChildScrollView(
scrollDirection: Axis.vertical,
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Text(t('Save Exercise'), style: TextStyle(fontSize: 14, color: Colors.blue[200])),
Divider(),
Text(
exerciseName,
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 18, color: Colors.orange),
overflow: TextOverflow.fade,
maxLines: 2,
softWrap: true,
textAlign: TextAlign.center,
),
SizedBox(
height: 15,
),
Text(
exerciseDescription,
style: GoogleFonts.inter(fontSize: 12, color: Colors.yellow[300]),
maxLines: 8,
overflow: TextOverflow.fade,
softWrap: true,
),
InkWell(
child: Text(
t("More »"),
style: GoogleFonts.inter(fontSize: 12, color: Colors.blue[200]),
),
onTap: () => {
Navigator.of(context).pushNamed('exerciseTypeDescription', arguments: exerciseBloc.exerciseRepository),
},
),
Divider(
color: Colors.transparent,
),
columnQuantityUnit(exerciseBloc),
Divider(
color: Colors.transparent,
),
columnQuantity(exerciseBloc),
Divider(),
Divider(
color: Colors.transparent,
),
Divider(
color: Colors.transparent,
),
Divider(
color: Colors.transparent,
),
FlatButton(
onPressed: () => {
confirmationDialog(exerciseBloc),
},
child: Stack(
alignment: Alignment.center,
children: [
Image.asset('asset/icon/gomb_orange_a.png', width: 140, height: 60),
Text(
t("Save"),
style: TextStyle(fontSize: 16, color: Colors.white),
),
],
)),
]),
))),
), ),
); ));
} }
Row columnQuantityUnit( ExerciseNewBloc bloc ) { Column columnQuantityUnit(ExerciseNewBloc bloc) {
Row row = Row(); Column row = Column();
if ( bloc.exerciseRepository.exerciseType != null && if (bloc.exerciseRepository.exerciseType != null && bloc.exerciseRepository.exerciseType.unitQuantity == "1") {
bloc.exerciseRepository.exerciseType.unitQuantity == "1") { row = Column(mainAxisAlignment: MainAxisAlignment.spaceAround, children: [
row = Row( TextFormField(
mainAxisAlignment: MainAxisAlignment.spaceAround, focusNode: _nodeText1,
children: [ decoration: InputDecoration(
NumberPicker.horizontal( contentPadding: EdgeInsets.only(left: 25, top: 5, bottom: 5),
highlightSelectedValue: true, labelText: t(bloc.exerciseRepository.exerciseType.unitQuantityUnit),
initialValue: bloc.unitQuantity.toInt(), labelStyle: GoogleFonts.inter(fontSize: 20, color: Colors.yellow[50]),
minValue: 0, fillColor: Colors.black38,
maxValue: 200, filled: true,
step: 1, border: OutlineInputBorder(
onChanged: (value) => { gapPadding: 8.0,
bloc.add(ExerciseNewQuantityUnitChange(quantity: value.toDouble())) borderRadius: BorderRadius.circular(12.0),
}, borderSide: BorderSide(color: Colors.white12, width: 0.4),
listViewHeight: 80, ),
textStyle: TextStyle(fontSize: 24), ),
textStyleHighlighted: TextStyle(fontSize: 38, color: Colors.orange, fontWeight: FontWeight.bold), initialValue: "30",
//decoration: _decoration, keyboardType: TextInputType.numberWithOptions(decimal: true),
), textInputAction: TextInputAction.done,
style: GoogleFonts.archivoBlack(fontSize: 80, color: Colors.yellow[300]),
new InkWell( onChanged: (value) => {bloc.add(ExerciseNewQuantityUnitChange(quantity: double.parse(value)))}),
child: new Text(t(bloc.exerciseRepository.exerciseType.unitQuantityUnit), //] ),
style: TextStyle(fontSize: 16)), ]);
),
]);
} }
return row; return row;
} }
Row columnQuantity( ExerciseNewBloc bloc ) { Column columnQuantity(ExerciseNewBloc bloc) {
Row row = Row( Column row = Column(mainAxisAlignment: MainAxisAlignment.spaceAround, children: [
mainAxisAlignment: MainAxisAlignment.spaceAround, TextFormField(
children: [ focusNode: _nodeText2,
NumberPicker.horizontal( decoration: InputDecoration(
highlightSelectedValue: true, contentPadding: EdgeInsets.only(left: 25, top: 5, bottom: 5),
initialValue: bloc.quantity.toInt(), labelText: t(bloc.exerciseRepository.exerciseType.unit),
minValue: 0, labelStyle: GoogleFonts.inter(fontSize: 20, color: Colors.orange[50], decorationColor: Colors.black12),
maxValue: 200, fillColor: Colors.black38,
step: 1, filled: true,
onChanged: (value) => { border: OutlineInputBorder(
bloc.add(ExerciseNewQuantityChange(quantity: value.toDouble())) gapPadding: 8.0,
}, borderRadius: BorderRadius.circular(12.0),
listViewHeight: 80, borderSide: BorderSide(color: Colors.black26, width: 0.4),
textStyle: TextStyle(fontSize: 24), ),
textStyleHighlighted: TextStyle(fontSize: 38, color: Colors.orange, fontWeight: FontWeight.bold), ),
//decoration: _decoration, initialValue: "12",
), keyboardType: TextInputType.number,
textInputAction: TextInputAction.next,
Text(t(bloc.exerciseRepository.exerciseType.unit), style: GoogleFonts.archivoBlack(fontSize: 80, color: Colors.orange[200]),
style: TextStyle(fontSize: 16)), onChanged: (value) => {bloc.add(ExerciseNewQuantityChange(quantity: double.parse(value)))},
]); ),
]);
return row; return row;
} }
void confirmationDialog( ExerciseNewBloc bloc ) { void confirmationDialog(ExerciseNewBloc bloc) {
LinkedHashMap args = LinkedHashMap(); LinkedHashMap args = LinkedHashMap();
print("exercise validated " + bloc.exerciseRepository.exercise.quantity.toString()); print("exercise validated " + bloc.exerciseRepository.exercise.quantity.toString());
if ( bloc.exerciseRepository.exercise.quantity == null) { if (bloc.exerciseRepository.exercise.quantity == null) {
return; return;
} }
String quantity = bloc.exerciseRepository.exercise.quantity % 1 == 0? String quantity = bloc.exerciseRepository.exercise.quantity % 1 == 0
bloc.exerciseRepository.exercise.quantity.round().toString() : ? bloc.exerciseRepository.exercise.quantity.round().toString()
bloc.exerciseRepository.exercise.quantity.toString(); : bloc.exerciseRepository.exercise.quantity.toString();
String unitQuantity = ""; String unitQuantity = "";
if ( bloc.exerciseRepository.exercise.unitQuantity != null ) { if (bloc.exerciseRepository.exercise.unitQuantity != null) {
unitQuantity = bloc.exerciseRepository.exercise.unitQuantity % 1 == 0 ? unitQuantity = bloc.exerciseRepository.exercise.unitQuantity % 1 == 0
bloc.exerciseRepository.exercise.unitQuantity.round().toString() : ? bloc.exerciseRepository.exercise.unitQuantity.round().toString()
bloc.exerciseRepository.exercise.unitQuantity.toString(); : bloc.exerciseRepository.exercise.unitQuantity.toString();
} }
showCupertinoDialog( showCupertinoDialog(
useRootNavigator: true, useRootNavigator: true,
context: context, context: context,
//barrierDismissible: false, //barrierDismissible: false,
builder:(_) => CupertinoAlertDialog( builder: (_) => CupertinoAlertDialog(
title: Text(t("Do you save this exercise with these parameters?")), title: Text(t("Do you save this exercise with these parameters?")),
content: Column( content: Column(children: [
Divider(),
children: [ Text(
Divider(), t("Exercise") + ": " + bloc.exerciseRepository.exerciseType.name,
Text(t("Exercise") + ": " + style: (TextStyle(color: Colors.blue)),
bloc.exerciseRepository.exerciseType.name, ),
style: (TextStyle(color: Colors.blue)),), Text(
Text(quantity + " " + quantity + " " + t(bloc.exerciseRepository.exerciseType.unit),
t(bloc.exerciseRepository.exerciseType.unit), style: (TextStyle(color: Colors.deepOrange)),
style: (TextStyle(color: Colors.deepOrange)),), ),
Text(bloc.exerciseRepository.exerciseType.unitQuantity == "1" ? Text(
t("with") + " " bloc.exerciseRepository.exerciseType.unitQuantity == "1"
+ unitQuantity + " " ? t("with") + " " + unitQuantity + " " + t(bloc.exerciseRepository.exerciseType.unitQuantityUnit)
+ t(bloc.exerciseRepository.exerciseType.unitQuantityUnit) : : "",
"", style: (TextStyle(color: Colors.deepOrange)),
style: (TextStyle(color: Colors.deepOrange)), ),
), ]),
actions: [
]), FlatButton(
actions: [ child: Text(t("No")),
FlatButton( onPressed: () => Navigator.pop(context),
child: Text(t("No")), ),
onPressed: () => Navigator.pop(context), FlatButton(
), child: Text(t("Yes")),
FlatButton( onPressed: () => {
child: Text(t("Yes")), bloc.exerciseRepository.setCustomer(Cache().userLoggedIn),
onPressed: () => { bloc.exerciseRepository.addExercise(),
bloc.exerciseRepository.setCustomer(Cache().userLoggedIn), Navigator.pop(context),
bloc.exerciseRepository.addExercise(), Navigator.pop(context),
Navigator.pop(context), if (bloc.exerciseRepository.exerciseType.is1RM)
Navigator.pop(context), {
if ( bloc.exerciseRepository.exerciseType.is1RM ) { args['exerciseRepository'] = bloc.exerciseRepository,
args['exerciseRepository'] = bloc.exerciseRepository, args['percent'] = 0.75,
args['percent'] = 0.75, args['readonly'] = false,
args['readonly'] = false, Navigator.of(context).pushNamed('exerciseControlPage', arguments: args)
Navigator.of(context).pushNamed('exerciseControlPage', }
arguments: args ) },
} )
}, ],
) ));
],
)
);
} }
} }

View File

@ -2,7 +2,6 @@ import 'dart:collection';
import 'package:aitrainer_app/bloc/exercise_plan/exercise_plan_bloc.dart'; import 'package:aitrainer_app/bloc/exercise_plan/exercise_plan_bloc.dart';
import 'package:aitrainer_app/bloc/exercise_plan_custom_add/exercise_plan_custom_add_bloc.dart'; import 'package:aitrainer_app/bloc/exercise_plan_custom_add/exercise_plan_custom_add_bloc.dart';
import 'package:aitrainer_app/library/numberpicker.dart';
import 'package:aitrainer_app/localization/app_language.dart'; import 'package:aitrainer_app/localization/app_language.dart';
import 'package:aitrainer_app/model/workout_menu_tree.dart'; import 'package:aitrainer_app/model/workout_menu_tree.dart';
import 'package:aitrainer_app/repository/exercise_plan_repository.dart'; import 'package:aitrainer_app/repository/exercise_plan_repository.dart';
@ -13,6 +12,10 @@ import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_form_bloc/flutter_form_bloc.dart'; import 'package:flutter_form_bloc/flutter_form_bloc.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:keyboard_actions/keyboard_actions.dart';
import 'package:keyboard_actions/keyboard_actions_config.dart';
import 'package:keyboard_actions/keyboard_actions_item.dart';
class ExercisePlanDetailAddPage extends StatefulWidget { class ExercisePlanDetailAddPage extends StatefulWidget {
@override @override
@ -20,6 +23,73 @@ class ExercisePlanDetailAddPage extends StatefulWidget {
} }
class _ExercisePlanDetailAddPage extends State<ExercisePlanDetailAddPage> with Trans { class _ExercisePlanDetailAddPage extends State<ExercisePlanDetailAddPage> with Trans {
final FocusNode _nodeText1 = FocusNode();
final FocusNode _nodeText2 = FocusNode();
final FocusNode _nodeText3 = FocusNode();
KeyboardActionsConfig _buildConfig(BuildContext context) {
return KeyboardActionsConfig(
keyboardActionsPlatform: KeyboardActionsPlatform.ALL,
keyboardBarColor: Colors.grey[200],
nextFocus: true,
actions: [
KeyboardActionsItem(focusNode: _nodeText2, toolbarButtons: [
(node) {
return GestureDetector(
onTap: () => node.unfocus(),
child: Container(
padding: EdgeInsets.all(8.0),
color: Colors.orange[500],
child: Text(
t("Done"),
style: TextStyle(color: Colors.white),
),
),
);
}
]),
KeyboardActionsItem(
focusNode: _nodeText1,
toolbarButtons: [
//button 2
(node) {
return GestureDetector(
onTap: () => node.unfocus(),
child: Container(
color: Colors.orange,
padding: EdgeInsets.all(8.0),
child: Text(
t("Done"),
style: TextStyle(color: Colors.white),
),
),
);
}
],
),
KeyboardActionsItem(
focusNode: _nodeText3,
toolbarButtons: [
//button 2
(node) {
return GestureDetector(
onTap: () => node.unfocus(),
child: Container(
color: Colors.orange,
padding: EdgeInsets.all(8.0),
child: Text(
t("Done"),
style: TextStyle(color: Colors.white),
),
),
);
}
],
),
],
);
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
LinkedHashMap args = ModalRoute.of(context).settings.arguments; LinkedHashMap args = ModalRoute.of(context).settings.arguments;
@ -38,8 +108,8 @@ class _ExercisePlanDetailAddPage extends State<ExercisePlanDetailAddPage> with T
if (state is ExercisePlanCustomAddLoading) { if (state is ExercisePlanCustomAddLoading) {
return LoadingDialog(); return LoadingDialog();
} else if (state is ExercisePlanCustomAddError) { } else if (state is ExercisePlanCustomAddError) {
Scaffold.of(context).showSnackBar(SnackBar( Scaffold.of(context).showSnackBar(
backgroundColor: Colors.orange, content: Text(state.message, style: TextStyle(color: Colors.white)))); SnackBar(backgroundColor: Colors.orange, content: Text(state.message, style: TextStyle(color: Colors.white))));
} }
}, },
builder: (context, state) { builder: (context, state) {
@ -50,8 +120,6 @@ class _ExercisePlanDetailAddPage extends State<ExercisePlanDetailAddPage> with T
)); ));
} }
Widget getForm(ExercisePlanCustomAddBloc bloc, WorkoutMenuTree workoutMenuTree) { Widget getForm(ExercisePlanCustomAddBloc bloc, WorkoutMenuTree workoutMenuTree) {
String exerciseName = ""; String exerciseName = "";
if (bloc != null) { if (bloc != null) {
@ -60,162 +128,158 @@ class _ExercisePlanDetailAddPage extends State<ExercisePlanDetailAddPage> with T
: bloc.exercisePlanRepository.getActualPlanDetail().exerciseType.nameTranslation; : bloc.exercisePlanRepository.getActualPlanDetail().exerciseType.nameTranslation;
} }
return Form( return Form(
autovalidate: true, child: Scaffold(
child: Scaffold( resizeToAvoidBottomInset: true,
resizeToAvoidBottomInset: true, appBar: AppBarNav(depth: 1),
appBar: AppBarNav(depth: 1), body: Container(
body: Container( width: MediaQuery.of(context).size.width,
width: MediaQuery.of(context).size.width, height: MediaQuery.of(context).size.height,
height: MediaQuery.of(context).size.height, decoration: BoxDecoration(
decoration: BoxDecoration( image: DecorationImage(
image: DecorationImage( image: AssetImage('asset/image/WT_black_background.png'),
image: AssetImage('asset/image/WT_light_background.png'), fit: BoxFit.fill,
fit: BoxFit.fill, alignment: Alignment.center,
alignment: Alignment.center,
),
), ),
child: Container( ),
padding: const EdgeInsets.only(top: 25, left: 25, right: 25), child: KeyboardActions(
child: SingleChildScrollView( config: _buildConfig(context),
scrollDirection: Axis.vertical, child: Container(
child: Column(mainAxisAlignment: MainAxisAlignment.spaceAround, children: <Widget>[ child: SingleChildScrollView(
Text(t('Save The Exercise To The Exercise Plan'), padding: const EdgeInsets.only(top: 25, left: 95, right: 95),
style: TextStyle(fontSize: 14, color: Colors.blueAccent)), scrollDirection: Axis.vertical,
Text( child: Column(mainAxisAlignment: MainAxisAlignment.spaceAround, children: <Widget>[
exerciseName, Text(t('Save The Exercise To The Exercise Plan'),
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 18, color: Colors.deepOrange), textAlign: TextAlign.center,
overflow: TextOverflow.fade, style: GoogleFonts.inter(
maxLines: 1, fontSize: 14,
softWrap: true, color: Colors.white,
), )),
Divider(color: Colors.transparent,height: 30,), Text(
Row( exerciseName,
mainAxisAlignment: MainAxisAlignment.start, textAlign: TextAlign.center,
children: [ style: GoogleFonts.archivoBlack(fontSize: 18, color: Colors.deepOrange),
Flexible( overflow: TextOverflow.fade,
fit: FlexFit.tight, maxLines: 3,
flex: 8, softWrap: true,
child: ),
Divider(
color: Colors.transparent,
height: 30,
),
TextFormField(
decoration: InputDecoration(
contentPadding: EdgeInsets.only(left: 25, top: 5, bottom: 5),
labelText: t('Serie'),
labelStyle: GoogleFonts.inter(fontSize: 20, color: Colors.yellow[50], decorationColor: Colors.black12),
fillColor: Colors.white24,
filled: true,
border: OutlineInputBorder(
gapPadding: 8.0,
borderRadius: BorderRadius.circular(12.0),
borderSide: BorderSide(color: Colors.black26, width: 0.4),
),
),
initialValue: bloc.serie.toStringAsFixed(0),
focusNode: _nodeText1,
keyboardType: TextInputType.number,
style: GoogleFonts.archivoBlack(fontSize: 60, color: Colors.yellow[200]),
onChanged: (value) => {bloc.add(ExercisePlanCustomAddChangeSerie(quantity: double.parse(value)))}),
//] ),
Divider(),
TextFormField(
decoration: InputDecoration(
contentPadding: EdgeInsets.only(left: 25, top: 5, bottom: 5),
labelText: t('Repeats'),
fillColor: Colors.white24,
labelStyle: GoogleFonts.inter(fontSize: 20, color: Colors.yellow[50]),
filled: true,
border: OutlineInputBorder(
gapPadding: 4.0,
borderRadius: BorderRadius.circular(12.0),
borderSide: BorderSide(color: Colors.green[50], width: 0.4),
),
),
focusNode: _nodeText2,
initialValue: bloc.quantity.toStringAsFixed(0),
keyboardType: TextInputType.number,
style: GoogleFonts.archivoBlack(fontSize: 60, color: Colors.yellow[200]),
onChanged: (value) => {bloc.add(ExercisePlanCustomAddChangeQuantity(quantity: double.parse(value)))}),
//]),
Divider(),
TextFormField(
decoration: InputDecoration(
contentPadding: EdgeInsets.only(left: 25, top: 5, bottom: 5),
labelText: t('Weight'),
fillColor: Colors.white24,
labelStyle: GoogleFonts.inter(fontSize: 20, color: Colors.yellow[50]),
filled: true,
border: OutlineInputBorder(
gapPadding: 2.0,
borderRadius: BorderRadius.circular(12.0),
borderSide: BorderSide(color: Colors.green[50], width: 0.4),
),
),
focusNode: _nodeText3,
initialValue: bloc.quantityUnit.toStringAsFixed(0),
keyboardType: TextInputType.numberWithOptions(decimal: true),
style: GoogleFonts.archivoBlack(fontSize: 60, color: Colors.yellow[200]),
onChanged: (value) => {bloc.add(ExercisePlanCustomAddChangeQuantityUnit(quantity: double.parse(value)))}),
//]),
Divider(),
Text(
bloc.serie.toStringAsFixed(0) +
" x " +
bloc.quantity.toStringAsFixed(0) +
" x " +
bloc.quantityUnit.toStringAsFixed(0) +
" kg",
style: TextStyle(fontSize: 24, fontWeight: FontWeight.normal, color: Colors.yellow[50]),
),
Divider(),
Column(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
FlatButton(
onPressed: () => {
bloc.add(ExercisePlanCustomAddRemove()),
Navigator.of(context).pop(),
},
child: Stack(
alignment: Alignment.center,
children: [
Image.asset('asset/icon/gomb_pink_b.png', width: 140, height: 60),
Text( Text(
t("Serie"), t("Delete"),
style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold), style: TextStyle(fontSize: 16, color: Colors.white),
), ),
],
), ),
NumberPicker.horizontal( ),
highlightSelectedValue: true, FlatButton(
initialValue: bloc.serie.toInt(),
itemExtent: 85,
minValue: 1,
maxValue: 20,
//decoration: _decoration,
step: 1,
onChanged: (value) => {
bloc.add(ExercisePlanCustomAddChangeSerie(quantity: value.toDouble()))
},
listViewHeight: 80,
textStyle: TextStyle(fontSize: 24),
textStyleHighlighted: TextStyle(fontSize: 36, color: Colors.orange, fontWeight: FontWeight.bold),
//decoration: _decoration,
),
]
),
Divider(),
Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Flexible(
fit: FlexFit.tight,
flex: 8,
child:
Text(t("Repeats"),
style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),),
),
NumberPicker.horizontal(
highlightSelectedValue: true,
initialValue: bloc.quantity.toInt(),
itemExtent: 85,
minValue: 0,
maxValue: 200,
step: 1,
onChanged: (value) => {
bloc.add(ExercisePlanCustomAddChangeQuantity(quantity: value.toDouble()))
},
listViewHeight: 80,
textStyle: TextStyle(fontSize: 24),
textStyleHighlighted: TextStyle(fontSize: 36, color: Colors.orange, fontWeight: FontWeight.bold),
//decoration: _decoration,
),
]),
Divider(),
Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Flexible(
fit: FlexFit.tight,
flex: 8,
child:
Text(t("Weight") + " (" + bloc.exercisePlanRepository.getActualPlanDetail().exerciseType.unitQuantityUnit + ")",
style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),),
),
NumberPicker.horizontal(
highlightSelectedValue: true,
initialValue: bloc.quantityUnit.toInt(),
//decoration: _decoration,
itemExtent: 85,
minValue: 0,
maxValue: 650,
step: 1,
onChanged: (value) => {
bloc.add(ExercisePlanCustomAddChangeQuantityUnit(quantity: value.toDouble()))
},
listViewHeight: 80,
textStyle: TextStyle(fontSize: 24),
textStyleHighlighted: TextStyle(fontSize: 36, color: Colors.orange, fontWeight: FontWeight.bold),
//decoration: _decoration,
),
]),
Divider(),
Text(
bloc.serie.toStringAsFixed(0) + " x " + bloc.quantity.toStringAsFixed(0) + " x " + bloc.quantityUnit.toStringAsFixed(0) + " kg" ,
style: TextStyle(fontSize: 28, fontWeight: FontWeight.normal),
),
Divider(),
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
RaisedButton(
textColor: Colors.white,
color: Colors.red.shade300,
focusColor: Colors.white,
onPressed: () => { onPressed: () => {
bloc.add(ExercisePlanCustomAddRemove()), bloc.add(ExercisePlanCustomAddSubmit()),
Navigator.of(context).pop(), Navigator.of(context).pop(),
}, },
child: Text(t( child: Stack(
"Delete")), //Text(AppLocalizations.of(context).translate("Delete"), style: TextStyle(fontSize: 16),) alignment: Alignment.center,
), children: [
RaisedButton( Image.asset('asset/icon/gomb_zold_b-1.png', width: 140, height: 60),
textColor: Colors.white, Text(
color: Colors.blueAccent, t("Save"),
focusColor: Colors.white, style: TextStyle(fontSize: 16, color: Colors.white),
onPressed: () => { ),
bloc.add(ExercisePlanCustomAddSubmit()), ],
Navigator.of(context).pop(), )),
}, ],
child: Text( ),
t("Save"), ]),
style: TextStyle(fontSize: 16), )))),
)), ));
],
),
]),
))),
),
);
} }
} }

View File

@ -14,6 +14,7 @@ import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/scheduler.dart'; import 'package:flutter/scheduler.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:google_fonts/google_fonts.dart';
class ExercisePlanCustomPage extends StatefulWidget { class ExercisePlanCustomPage extends StatefulWidget {
@override @override
@ -109,7 +110,7 @@ class _ExercisePlanCustomPage extends State<ExercisePlanCustomPage> with Trans {
Text(" "), Text(" "),
Text( Text(
t("Custom Exercise Plan"), t("Custom Exercise Plan"),
style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold), style: GoogleFonts.archivoBlack(fontSize: 20),
), ),
], ],
), ),
@ -118,7 +119,7 @@ class _ExercisePlanCustomPage extends State<ExercisePlanCustomPage> with Trans {
), ),
Text( Text(
t("Select manually the exercises what you would like to have in your plan. At the end don't forget to save."), t("Select manually the exercises what you would like to have in your plan. At the end don't forget to save."),
style: TextStyle(fontSize: 12, fontWeight: FontWeight.normal), style: GoogleFonts.inter(fontSize: 12, fontWeight: FontWeight.normal),
), ),
], ],
@ -131,7 +132,7 @@ class _ExercisePlanCustomPage extends State<ExercisePlanCustomPage> with Trans {
exerciseTypes.add(Container( exerciseTypes.add(Container(
margin: const EdgeInsets.only(left: 4.0), margin: const EdgeInsets.only(left: 4.0),
child: TreeViewChild( child: TreeViewChild(
startExpanded: true, startExpanded: false,
parent: TreeviewParentWidget(text: name), parent: TreeviewParentWidget(text: name),
children: _getChildList(list, bloc), children: _getChildList(list, bloc),
))); )));
@ -157,8 +158,8 @@ class _ExercisePlanCustomPage extends State<ExercisePlanCustomPage> with Trans {
mainAxisAlignment: MainAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.start,
children: [ children: [
IconButton( IconButton(
icon: element.selected ? Icon(Icons.check, color: Colors.greenAccent.shade700,) icon: element.selected ? Icon(Icons.check, color: Colors.green[600],)
: Icon(Icons.add, color: Colors.blue.shade400,), : Icon(Icons.add, color: Colors.indigo,),
onPressed: () => clickAddDetail(bloc, element), onPressed: () => clickAddDetail(bloc, element),
), ),
SizedBox(width: 10), SizedBox(width: 10),
@ -171,7 +172,7 @@ class _ExercisePlanCustomPage extends State<ExercisePlanCustomPage> with Trans {
Text( Text(
element.name, element.name,
textAlign: TextAlign.start, textAlign: TextAlign.start,
style: TextStyle(fontSize: 12, color: Colors.black), style: GoogleFonts.inter(fontSize: 16, color: Colors.black),
), ),
onTap: () => clickAddDetail(bloc, element), onTap: () => clickAddDetail(bloc, element),
), ),

View File

@ -1,5 +1,6 @@
import 'package:aitrainer_app/localization/app_language.dart'; import 'package:aitrainer_app/localization/app_language.dart';
import 'package:aitrainer_app/repository/exercise_repository.dart'; import 'package:aitrainer_app/repository/exercise_repository.dart';
import 'package:aitrainer_app/widgets/app_bar_min.dart';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
@ -18,23 +19,7 @@ class ExerciseTypeDescription extends StatelessWidget {
exerciseRepository.exerciseType.nameTranslation; exerciseRepository.exerciseType.nameTranslation;
return Scaffold( return Scaffold(
appBar: AppBar( appBar: AppBarMin(back: true,),
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: Container( body: Container(
width: MediaQuery.of(context).size.width, width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height, height: MediaQuery.of(context).size.height,

View File

@ -6,34 +6,18 @@ class Gdpr extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
body: Container( body: Container(
padding: const EdgeInsets.only (left:15, right: 15), padding: const EdgeInsets.only(left: 15, right: 15),
child: ListView( child: ListView(
children: <Widget>[ children: <Widget>[
new InkWell( new InkWell(
child: new Text( child: new Text(
AppLocalizations.of(context).translate('gdpr_text'), AppLocalizations.of(context).translate('gdpr_text'),
),
), customBorder: Border.all(color: Colors.teal, width: 1),
),
customBorder: Border.all(color:Colors.teal, width:1), Spacer(flex: 2),
),
Spacer(flex:2),
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
FlatButton(
textColor: Colors.black,
onPressed: () { },
)
], ],
) )));
],
)
)
);
} }
}
}

View File

@ -29,7 +29,6 @@ class LoginWidget extends StatefulWidget {
class _LoginWidget extends State<LoginWidget> with Common, Trans { class _LoginWidget extends State<LoginWidget> with Common, Trans {
final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>(); final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
final _formKey = GlobalKey<FormState>();
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@ -57,29 +56,36 @@ class _LoginWidget extends State<LoginWidget> with Common, Trans {
LoadingDialog.hide(context); LoadingDialog.hide(context);
showInSnackBar(t(state.failureResponse)); showInSnackBar(t(state.failureResponse));
}, },
child: SafeArea( onLoaded: (context, state ) {
top: false,
bottom: false, },
child: Container( child: loadForm(loginBloc, accountBloc)
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage('asset/image/WT_login.png'),
fit: BoxFit.cover,
alignment: Alignment.center,
),
),
child: buildLoginForm(loginBloc, accountBloc),
),
)
), ),
); );
})); }));
} }
Widget loadForm(LoginFormBloc loginBloc, AccountBloc accountBloc) {
return SafeArea(
top: false,
bottom: false,
child: Container(
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage('asset/image/WT_login.png'),
fit: BoxFit.cover,
alignment: Alignment.center,
),
),
child: buildLoginForm(loginBloc, accountBloc),
),
);
}
Widget buildLoginForm(LoginFormBloc formBloc, AccountBloc accountBloc) { Widget buildLoginForm(LoginFormBloc formBloc, AccountBloc accountBloc) {
return Form( return Form(
key: _formKey, key: _scaffoldKey,
child: Container( child: Container(
padding: const EdgeInsets.only(left: 15, right: 50), padding: const EdgeInsets.only(left: 15, right: 50),
child: child:

View File

@ -12,8 +12,10 @@ import 'package:percent_indicator/linear_percent_indicator.dart';
import 'package:rainbow_color/rainbow_color.dart'; import 'package:rainbow_color/rainbow_color.dart';
// ignore: must_be_immutable
class AppBarMin extends StatefulWidget implements PreferredSizeWidget { class AppBarMin extends StatefulWidget implements PreferredSizeWidget {
const AppBarMin(); bool back = false;
AppBarMin({this.back = false });
@override @override
_AppBarNav createState() => _AppBarNav(); _AppBarNav createState() => _AppBarNav();
@ -44,10 +46,12 @@ class _AppBarNav extends State<AppBarMin> with Common {
], ],
), ),
leading: IconButton( leading: IconButton(
icon: Icon(Icons.arrow_back, color: Colors.black), icon: Icon(Icons.arrow_back, color: widget.back ? Colors.white : Colors.black),
onPressed: () => onPressed: () =>
{ {
if ( widget.back ) {
Navigator.of(context).pop()
}
}, },
) )
); );

View File

@ -0,0 +1,246 @@
import 'package:aitrainer_app/bloc/exercise_new/exercise_new_bloc.dart';
import 'package:aitrainer_app/localization/app_localization.dart';
import 'package:aitrainer_app/util/trans.dart';
import 'package:animated_widgets/widgets/rotation_animated.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:google_fonts/google_fonts.dart';
import 'app_bar.dart';
import 'package:keyboard_actions/keyboard_actions.dart';
// ignore: must_be_immutable
class BMI extends StatefulWidget {
final ExerciseNewBloc exerciseBloc;
BMI({this.exerciseBloc});
@override
_BMIState createState() => _BMIState();
}
class _BMIState extends State<BMI> with Trans {
final FocusNode _nodeText1 = FocusNode();
final FocusNode _nodeText2 = FocusNode();
KeyboardActionsConfig _buildConfig(BuildContext context) {
return KeyboardActionsConfig(
keyboardActionsPlatform: KeyboardActionsPlatform.ALL,
keyboardBarColor: Colors.grey[200],
keyboardSeparatorColor: Colors.black26,
nextFocus: true,
actions: [
KeyboardActionsItem(focusNode: _nodeText2, toolbarButtons: [
(node) {
return GestureDetector(
onTap: () => node.unfocus(),
child: Container(
padding: EdgeInsets.all(8.0),
color: Colors.orange[500],
child: Text(
AppLocalizations.of(context).translate("Done"),
style: TextStyle(color: Colors.white),
),
),
);
}
]),
KeyboardActionsItem(
focusNode: _nodeText1,
toolbarButtons: [
//button 2
(node) {
return GestureDetector(
onTap: () => node.unfocus(),
child: Container(
color: Colors.orange,
padding: EdgeInsets.all(8.0),
child: Text(
AppLocalizations.of(context).translate("Done"),
style: TextStyle(color: Colors.white),
),
),
);
}
],
),
],
);
}
@override
Widget build(BuildContext context) {
setContext(context);
widget.exerciseBloc.getBMI();
return Form(
child: Scaffold(
resizeToAvoidBottomInset: true,
appBar: AppBarNav(depth: 1),
body: Container(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height,
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage('asset/image/WT_black_background.png'),
fit: BoxFit.fill,
alignment: Alignment.center,
),
),
child: KeyboardActions(
config: _buildConfig(context),
child: SingleChildScrollView(
child:
Column(crossAxisAlignment: CrossAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center, children: [
getWeightInput(),
Text(AppLocalizations.of(context).translate("Body Mass Index"),
style: GoogleFonts.archivoBlack(
shadows: <Shadow>[
Shadow(
offset: Offset(5.0, 5.0),
blurRadius: 3.0,
color: Colors.black54,
),
],
fontSize: 30,
color: Colors.orange[500],
)),
Text(widget.exerciseBloc.bmi.toStringAsFixed(1) + "%",
style: GoogleFonts.archivoBlack(
shadows: <Shadow>[
Shadow(
offset: Offset(5.0, 5.0),
blurRadius: 3.0,
color: Colors.black54,
),
],
fontSize: 60,
color: Colors.orange[500],
)),
Divider(color: Colors.transparent),
Stack(alignment: Alignment.center, children: [
Container(
padding: EdgeInsets.only(left: 30, right: 30),
child: Image.asset(
"asset/image/BMI_graph_c.png",
),
),
Positioned(
top: widget.exerciseBloc.bmiTop,
left: widget.exerciseBloc.bmiLeft,
child: RotationAnimatedWidget.tween(
enabled: true,
duration: const Duration(milliseconds: 1000),
rotationDisabled: Rotation.deg(),
rotationEnabled: Rotation.deg(z: widget.exerciseBloc.bmiAngle),
child: Image.asset(
"asset/image/BMI_mutato.png",
width: 65,
)))
]),
Divider(color: Colors.transparent),
Container(
padding: EdgeInsets.only(left: 65, right: 65),
alignment: Alignment.center,
child: Text(t("Based on your weight and height your goal for BMI and weight:"),
textAlign: TextAlign.center,
style: GoogleFonts.inter(
fontSize: 16,
color: Colors.yellow[200],
)),
),
Text("BMI" + ": " + widget.exerciseBloc.goalBMI.toStringAsFixed(0),
style: GoogleFonts.archivoBlack(
fontSize: 40,
color: Colors.orange[500],
)),
Text(t("Weight") + ": " + widget.exerciseBloc.goalWeight.toStringAsFixed(0) + " kg",
style: GoogleFonts.archivoBlack(
fontSize: 30,
color: Colors.orange[200],
)),
]))))));
}
Widget buildAnimatedPointer() {
return TweenAnimationBuilder(
tween: IntTween(begin: 0, end: 30),
duration: Duration(milliseconds: 2000),
curve: Curves.linear,
builder: (context, val, child) {
return Image.asset(
"asset/image/BMI_mutato.png",
width: 65,
);
},
);
}
Widget getHeightInput() {
if (widget.exerciseBloc.customerRepository.customer.birthYear < 2003) {
return Flexible(
child: TextFormField(
focusNode: _nodeText2,
decoration: InputDecoration(
contentPadding: EdgeInsets.only(left: 15, top: 5, bottom: 5),
labelText: AppLocalizations.of(context).translate("Actual Height"),
labelStyle: GoogleFonts.inter(fontSize: 16, color: Colors.yellow[50]),
fillColor: Colors.black38,
filled: true,
border: OutlineInputBorder(
gapPadding: 4.0,
borderRadius: BorderRadius.circular(12.0),
borderSide: BorderSide(color: Colors.white12, width: 0.4),
),
),
initialValue: widget.exerciseBloc.height.toStringAsFixed(0),
keyboardType: TextInputType.numberWithOptions(decimal: true),
textInputAction: TextInputAction.done,
style: GoogleFonts.archivoBlack(fontSize: 20, color: Colors.yellow[300]),
onChanged: (value) => {widget.exerciseBloc.add(ExerciseNewHeightChange(value: double.parse(value)))}),
);
} else {
return Container();
}
}
Widget getWeightInput() {
return Container(
padding: EdgeInsets.only(top: 15, left: 65, right: 65, bottom: 10),
alignment: Alignment.center,
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
getHeightInput(),
SizedBox(
width: 10,
),
Flexible(
child: TextFormField(
focusNode: _nodeText1,
decoration: InputDecoration(
contentPadding: EdgeInsets.only(left: 15, top: 5, bottom: 5),
labelText: AppLocalizations.of(context).translate("Actual Weight"),
labelStyle: GoogleFonts.inter(fontSize: 16, color: Colors.yellow[50]),
fillColor: Colors.black38,
filled: true,
border: OutlineInputBorder(
gapPadding: 2.0,
borderRadius: BorderRadius.circular(12.0),
borderSide: BorderSide(color: Colors.white12, width: 0.4),
),
),
initialValue: widget.exerciseBloc.weight.toStringAsFixed(0),
keyboardType: TextInputType.numberWithOptions(decimal: true),
textInputAction: TextInputAction.done,
style: GoogleFonts.archivoBlack(fontSize: 20, color: Colors.yellow[300]),
onChanged: (value) => {widget.exerciseBloc.add(ExerciseNewWeightChange(value: double.parse(value)))},
),
),
IconButton(
icon: Icon(Icons.save),
hoverColor: Colors.blueAccent,
color: widget.exerciseBloc.changedWeight ? Colors.blue[200] : Colors.black54,
onPressed: () => {print("Save"), widget.exerciseBloc.add(ExerciseNewSaveWeight())})
],
));
}
}

View File

@ -14,8 +14,6 @@ class BottomNavigator extends StatefulWidget {
} }
class _NawDrawerWidget extends State<BottomNavigator> { class _NawDrawerWidget extends State<BottomNavigator> {
@override @override
void initState() { void initState() {
super.initState(); super.initState();
@ -34,7 +32,8 @@ class _NawDrawerWidget extends State<BottomNavigator> {
// //
return GradientBottomNavigationBar( return GradientBottomNavigationBar(
currentIndex: widget.bottomNavIndex, // this will be set when a new tab is tapped currentIndex:
widget.bottomNavIndex, // this will be set when a new tab is tapped
backgroundColorStart: bgrColorEnd, backgroundColorStart: bgrColorEnd,
backgroundColorEnd: bgrColor, backgroundColorEnd: bgrColor,
fixedColor: active, fixedColor: active,
@ -46,77 +45,91 @@ class _NawDrawerWidget extends State<BottomNavigator> {
BottomNavigationBarItem( BottomNavigationBarItem(
backgroundColor: bgrColor, backgroundColor: bgrColor,
icon: new Icon(Icons.home, color: inactive), icon: new Icon(Icons.home, color: inactive),
activeIcon: new Icon(Icons.home, color: active,), activeIcon: new Icon(
Icons.home,
color: active,
),
title: new Text(AppLocalizations.of(context).translate("Home"), title: new Text(AppLocalizations.of(context).translate("Home"),
style: TextStyle(fontSize: 9)), style: TextStyle(fontSize: 9)),
), ),
BottomNavigationBarItem( BottomNavigationBarItem(
backgroundColor: bgrColor, backgroundColor: bgrColor,
icon: new Icon(Icons.trending_up, color: inactive), icon: new Icon(Icons.trending_up, color: inactive),
activeIcon: new Icon(Icons.trending_up, color: active,), activeIcon: new Icon(
title: new Text(AppLocalizations.of(context).translate("My Development"), Icons.trending_up,
style: TextStyle(fontSize: 9),), color: active,
),
title: new Text(
AppLocalizations.of(context).translate("My Development"),
style: TextStyle(fontSize: 9),
),
), ),
BottomNavigationBarItem( BottomNavigationBarItem(
backgroundColor: bgrColor, backgroundColor: bgrColor,
icon: new Icon(Icons.featured_play_list, color: inactive), icon: new Icon(Icons.featured_play_list, color: inactive),
activeIcon: new Icon(Icons.featured_play_list, color: active,), activeIcon: new Icon(
title: new Text(AppLocalizations.of(context).translate("My Training Plan"), Icons.featured_play_list,
style: TextStyle(fontSize: 9),), color: active,
),
title: new Text(
AppLocalizations.of(context).translate("My Training Plan"),
style: TextStyle(fontSize: 9),
),
), ),
BottomNavigationBarItem( BottomNavigationBarItem(
backgroundColor: bgrColor, backgroundColor: bgrColor,
icon: Icon(Icons.person, color: inactive,), icon: Icon(
activeIcon: new Icon(Icons.person, color: active,), Icons.person,
title: Text(AppLocalizations.of(context).translate("Account"), color: inactive,
style: TextStyle(fontSize: 9),) ),
), activeIcon: new Icon(
Icons.person,
color: active,
),
title: Text(
AppLocalizations.of(context).translate("Account"),
style: TextStyle(fontSize: 9),
)),
BottomNavigationBarItem( BottomNavigationBarItem(
backgroundColor: bgrColor, backgroundColor: bgrColor,
icon: Icon(Icons.settings, color: inactive), icon: Icon(Icons.settings, color: inactive),
activeIcon: new Icon(Icons.settings, color: active,), activeIcon: new Icon(
Icons.settings,
color: active,
),
title: Text(AppLocalizations.of(context).translate("Settings"), title: Text(AppLocalizations.of(context).translate("Settings"),
style: TextStyle(fontSize: 9)) style: TextStyle(fontSize: 9)))
)
], ],
onTap:(index) { onTap: (index) {
setState(() { setState(() {
widget.bottomNavIndex = index; widget.bottomNavIndex = index;
switch (index) { switch (index) {
case 0: case 0:
Navigator.of(context).pop(); Navigator.of(context).pop();
Navigator.of(context).pushNamed('home'); Navigator.of(context).pushNamed('home');
break; break;
case 1: case 1:
Navigator.of(context).pop(); Navigator.of(context).pop();
Navigator.of(context).pushNamed('myDevelopment'); Navigator.of(context).pushNamed('myDevelopment');
break; break;
case 2: case 2:
Navigator.of(context).pop();
Navigator.of(context).pushNamed('myExercisePlan');
Navigator.of(context).pop(); break;
Navigator.of(context).pushNamed('myExercisePlan'); case 3:
Navigator.of(context).pop();
Navigator.of(context).pushNamed('account');
break; break;
case 3: case 4:
Navigator.of(context).pop(); Navigator.of(context).pop();
Navigator.of(context).pushNamed('account'); Navigator.of(context).pushNamed('settings');
break; break;
case 4: }
Navigator.of(context).pop(); });
Navigator.of(context).pushNamed('settings'); });
break;
}
});
}
);
} }
}
}

View File

@ -3,6 +3,7 @@ import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:bloc/bloc.dart'; import 'package:bloc/bloc.dart';
// ignore: must_be_immutable
class ImageButton extends StatelessWidget { class ImageButton extends StatelessWidget {
final String text; final String text;
TextStyle style = TextStyle(fontSize: 14); TextStyle style = TextStyle(fontSize: 14);
@ -17,62 +18,64 @@ class ImageButton extends StatelessWidget {
final VoidCallback onTap; final VoidCallback onTap;
bool isLocked; bool isLocked;
ImageButton({ ImageButton(
this.text, {this.text,
this.style, this.style,
this.image, this.image,
this.top, this.top,
this.left, this.left,
this.height, this.height,
this.width, this.width,
this.bloc, this.bloc,
this.isShape, this.isShape,
this.textAlignment, this.textAlignment,
this.onTap, this.onTap,
@required this.isLocked @required this.isLocked}) {
}) {
width = width ?? 180; width = width ?? 180;
style = style ?? TextStyle(fontSize: 14, fontFamily: "Roboto Mono"); style = style ?? TextStyle(fontSize: 14, fontFamily: "Roboto Mono");
} }
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
double top = width - (style.fontSize - 5) * text.length - 2 * left < 0 ? width - 2 * style.fontSize - 10 : width - style.fontSize - 10; double top = width - (style.fontSize - 5) * text.length - 2 * left < 0
print ("Top: " + top.toStringAsFixed(0) + " length: " + ((style.fontSize - 5) * text.length).toString()); ? width - 2 * style.fontSize - 10
: width - style.fontSize - 10;
print("Top: " +
top.toStringAsFixed(0) +
" length: " +
((style.fontSize - 5) * text.length).toString());
return Stack( return Stack(
//alignment: textAlignment, //alignment: textAlignment,
fit: StackFit.passthrough, fit: StackFit.passthrough,
overflow: Overflow.clip, overflow: Overflow.clip,
children: [ children: [
FlatButton( FlatButton(
child: image == null ? child: image == null
_getButtonImage("asset/image/WT_menu_dark.png") : ? _getButtonImage("asset/image/WT_menu_dark.png")
_getButtonImage(image), : _getButtonImage(image),
padding: EdgeInsets.only(left: 0.0, bottom: 0), padding: EdgeInsets.only(left: 0.0, bottom: 0),
shape: getShape(isShape), shape: getShape(isShape),
onPressed: onTap ?? onTap, onPressed: onTap ?? onTap,
), ),
Stack( Stack(alignment: Alignment.topLeft, children: [
alignment: Alignment.topLeft,
children: [
Positioned( Positioned(
top: 50, top: 50,
left: 50, left: 50,
child: this.isLocked? child: this.isLocked
Image.asset( ? Image.asset(
'asset/image/lock.png', 'asset/image/lock.png',
height: 60, height: 60,
width: 60, width: 60,
) )
: Container(), : Container(),
)] )
), ]),
Positioned( Positioned(
top: top, top: top,
left: left, left: left,
child: Container( child: Container(
height: width - 2 * left, height: width - 2 * left,
width: width - 2 * left, width: width - 2 * left,
child: InkWell( child: InkWell(
onTap: onTap ?? onTap, onTap: onTap ?? onTap,
child: Text( child: Text(

View File

@ -1,6 +1,61 @@
import 'package:aitrainer_app/util/trans.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:keyboard_actions/keyboard_actions.dart';
/// Dialog for input any data and call of an [Event] of a [Bloc]
class InputDialog<Event> extends StatefulWidget {
final ValueChanged<dynamic> onChanged;
final double initialValue;
/// Dialog title
final String title;
final String subtitle;
const InputDialog({this.onChanged, this.initialValue, this.title, this.subtitle});
@override
_InputDialogState<Event> createState() => _InputDialogState<Event>();
}
class _InputDialogState<Event> extends State<InputDialog<Event>> with Trans {
final FocusNode _nodeText1 = FocusNode();
double inputValue = 0;
KeyboardActionsConfig _buildConfig(BuildContext context) {
setContext(context);
return KeyboardActionsConfig(
keyboardActionsPlatform: KeyboardActionsPlatform.ALL,
keyboardBarColor: Colors.grey[200],
keyboardSeparatorColor: Colors.black26,
nextFocus: true,
actions: [
KeyboardActionsItem(
focusNode: _nodeText1,
toolbarButtons: [
//button 2
(node) {
return GestureDetector(
onTap: () => node.unfocus(),
child: Container(
color: Colors.orange,
padding: EdgeInsets.all(8.0),
child: Text(
t("Done"),
style: TextStyle(color: Colors.white),
),
),
);
}
],
),
],
);
}
class InputDialog extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Dialog( return Dialog(
@ -12,54 +67,105 @@ class InputDialog extends StatelessWidget {
} }
_buildChild(BuildContext context) => Container( _buildChild(BuildContext context) => Container(
height: 350, height: 350,
decoration: BoxDecoration(color: Colors.redAccent, shape: BoxShape.rectangle, borderRadius: BorderRadius.all(Radius.circular(12))), decoration: BoxDecoration(color: Colors.white60, shape: BoxShape.rectangle, borderRadius: BorderRadius.all(Radius.circular(12))),
child: KeyboardActions(
config: _buildConfig(context),
child: Column( child: Column(
children: <Widget>[ children: <Widget>[
Container( Container(
child: Padding( padding: const EdgeInsets.all(12.0),
padding: const EdgeInsets.all(12.0), child: Column(children: [
child: Image.asset( Text(
'assets/image/lock.png', widget.title,
height: 120, style: GoogleFonts.archivoBlack(
width: 120, shadows: <Shadow>[
Shadow(
offset: Offset(3.0, 3.0),
blurRadius: 3.0,
color: Colors.black54,
),
],
fontSize: 25,
color: Colors.orange[500],
),
), ),
), Text(
widget.subtitle,
style: GoogleFonts.archivoBlack(
shadows: <Shadow>[
Shadow(
offset: Offset(3.0, 3.0),
blurRadius: 3.0,
color: Colors.black54,
),
],
fontSize: 30,
color: Colors.orange[500],
),
),
]),
width: double.infinity, width: double.infinity,
decoration: BoxDecoration( decoration: BoxDecoration(
color: Colors.white, color: Colors.white70,
shape: BoxShape.rectangle, shape: BoxShape.rectangle,
borderRadius: BorderRadius.only(topLeft: Radius.circular(12), topRight: Radius.circular(12))), borderRadius: BorderRadius.only(topLeft: Radius.circular(12), topRight: Radius.circular(12))),
), ),
SizedBox(
height: 24,
),
Text(
'Do you want to exit?',
style: TextStyle(fontSize: 20, color: Colors.white, fontWeight: FontWeight.bold),
),
SizedBox( SizedBox(
height: 8, height: 8,
), ),
Padding( Padding(
padding: const EdgeInsets.only(right: 16, left: 16), padding: const EdgeInsets.only(top: 20, right: 16, left: 16),
child: Text( child: Text(
'If back button is pressed by mistake then click on no to continue.', t("Please type the following data:"),
style: TextStyle(color: Colors.white), style: GoogleFonts.inter(fontSize: 16, color: Colors.yellow[200], shadows: <Shadow>[
Shadow(
offset: Offset(2.0, 2.0),
blurRadius: 3.0,
color: Colors.black54,
)
]),
textAlign: TextAlign.center, textAlign: TextAlign.center,
), ),
), ),
SizedBox( SizedBox(
height: 24, height: 24,
), ),
Padding(
padding: const EdgeInsets.only(left: 90, right: 90),
child: TextFormField(
focusNode: _nodeText1,
decoration: InputDecoration(
contentPadding: EdgeInsets.only(left: 15, top: 5, bottom: 5),
labelText: widget.subtitle,
labelStyle: GoogleFonts.inter(fontSize: 16, color: Colors.yellow[50]),
fillColor: Colors.black38,
filled: true,
border: OutlineInputBorder(
gapPadding: 2.0,
borderRadius: BorderRadius.circular(12.0),
borderSide: BorderSide(color: Colors.white12, width: 0.4),
),
),
initialValue: widget.initialValue.toStringAsFixed(0),
keyboardType: TextInputType.numberWithOptions(decimal: true),
textInputAction: TextInputAction.done,
style: GoogleFonts.archivoBlack(fontSize: 20, color: Colors.yellow[300]),
onChanged: (value) => this.inputValue = double.parse(value),
),
),
SizedBox(
height: 24,
),
Row( Row(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: <Widget>[ children: <Widget>[
FlatButton( RaisedButton(
onPressed: () { onPressed: () {
Navigator.of(context).pop(); Navigator.of(context).pop();
}, },
child: Text('No'), child: Text(t('Cancel')),
color: Colors.black26,
textColor: Colors.white, textColor: Colors.white,
), ),
SizedBox( SizedBox(
@ -67,15 +173,16 @@ class InputDialog extends StatelessWidget {
), ),
RaisedButton( RaisedButton(
onPressed: () { onPressed: () {
widget.onChanged(this.inputValue);
return Navigator.of(context).pop(true); return Navigator.of(context).pop(true);
}, },
child: Text('Yes'), child: Text(t('Save')),
color: Colors.white, color: Colors.orange[600],
textColor: Colors.redAccent, textColor: Colors.white,
) )
], ],
) )
], ],
), ),
); ));
} }

View File

@ -42,75 +42,72 @@ class MenuInfoWidget extends StatelessWidget with Common {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
int length = title.length + text2.length + text3.length + link.length; return Container(
return /* Container( padding: EdgeInsets.only(top: 10.0, left: 15, right: 10, bottom: 5),
height: length > 100? 350 : 250,
width: 180,
padding: EdgeInsets.all(25.0),
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage(
"asset/menu/3.bcs1.png",
),
fit: BoxFit.contain),
),
child: BackdropFilter(
filter: ImageFilter.blur(sigmaX: 9, sigmaY: 9),
child:*/ Container(
padding: EdgeInsets.only(top: 10.0, left: 15, right: 10, bottom: 5),
decoration: BoxDecoration( decoration: BoxDecoration(
color: Colors.black.withOpacity(0.5), color: Colors.black.withOpacity(0.5),
border: Border.all(color: Colors.white60), border: Border.all(color: Colors.white60),
borderRadius: BorderRadius.all(Radius.circular(10.0)), borderRadius: BorderRadius.all(Radius.circular(10.0)),
), ),
child: Column( child: Column(
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center,
children: [ children: [
Text( Text(
title, title,
maxLines: 4, maxLines: 4,
textAlign: TextAlign.center, textAlign: TextAlign.center,
style: style: TextStyle(
TextStyle(color: titleColor, fontSize: titleSize, fontWeight: titleWeight), color: titleColor,
), fontSize: titleSize,
Divider(), fontWeight: titleWeight),
Text( ),
text, Divider(),
maxLines: 6, Text(
style: TextStyle(color: textColor, fontSize: textSize, fontWeight: textWeight), text,
), maxLines: 6,
Divider(), style: TextStyle(
Text( color: textColor, fontSize: textSize, fontWeight: textWeight),
text2, ),
maxLines: 6, Divider(),
style: TextStyle(color: textColor, fontSize: textSize, fontWeight: textWeight), Text(
), text2,
Divider(), maxLines: 6,
Text( style: TextStyle(
text3, color: textColor, fontSize: textSize, fontWeight: textWeight),
maxLines: 6, ),
style: TextStyle(color: textColor, fontSize: textSize, fontWeight: textWeight), Divider(),
), Text(
getLink(), text3,
], maxLines: 6,
), style: TextStyle(
//), color: textColor, fontSize: textSize, fontWeight: textWeight),
// ) ),
getLink(),
],
),
//),
// )
); );
} }
Widget getLink() { Widget getLink() {
int missingId; int missingId;
return InkWell( return InkWell(
child: new Text(link, style: TextStyle(color: Colors.lightBlueAccent, fontSize: textSize, fontFamily: 'Arial', fontWeight: textWeight),), child: new Text(
onTap: () => link,
{ style: TextStyle(
missingId = bloc.menuTreeRepository.getMissingTreeIdByName(bloc.missingTreeName), color: Colors.lightBlueAccent,
print("menu " + missingId.toString()), fontSize: textSize,
bloc.add(MenuTreeJump(parent: missingId)) fontFamily: 'Arial',
} fontWeight: textWeight),
); ),
onTap: () => {
missingId = bloc.menuTreeRepository
.getMissingTreeIdByName(bloc.missingTreeName),
print("menu " + missingId.toString()),
bloc.add(MenuTreeJump(parent: missingId))
});
} }
} }

View File

@ -9,6 +9,7 @@ import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/painting.dart'; import 'package:flutter/painting.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:google_fonts/google_fonts.dart';
import 'menu_info_widget.dart'; import 'menu_info_widget.dart';
@ -70,7 +71,7 @@ class MenuPageWidget extends StatelessWidget with Trans {
onPressed: () => menuClick(workoutTree, menuBloc, context), onPressed: () => menuClick(workoutTree, menuBloc, context),
), ),
Positioned( Positioned(
top: workoutTree.name.length > 15 ? 140 : 150, top: workoutTree.name.length > 20 ? 130 : 145,
left: 5, left: 5,
child: Container( child: Container(
height: 300, height: 300,
@ -80,11 +81,10 @@ class MenuPageWidget extends StatelessWidget with Trans {
child: Text( child: Text(
" " + workoutTree.name, " " + workoutTree.name,
maxLines: 2, maxLines: 2,
style: TextStyle( style: GoogleFonts.archivoBlack(
color: workoutTree.color, color: workoutTree.color,
fontSize: workoutTree.fontSize, fontSize: workoutTree.fontSize,
fontFamily: 'Arial', ),
fontWeight: FontWeight.w900),
), ),
highlightColor: workoutTree.color, highlightColor: workoutTree.color,

View File

@ -1,12 +1,13 @@
import 'package:aitrainer_app/bloc/exercise_new/exercise_new_bloc.dart'; import 'package:aitrainer_app/bloc/exercise_new/exercise_new_bloc.dart';
import 'package:aitrainer_app/localization/app_localization.dart'; import 'package:aitrainer_app/library/custom_icon_icons.dart';
import 'package:aitrainer_app/model/property.dart';
import 'package:aitrainer_app/util/trans.dart'; import 'package:aitrainer_app/util/trans.dart';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart'; import 'package:flutter/widgets.dart';
import 'package:google_fonts/google_fonts.dart'; import 'package:google_fonts/google_fonts.dart';
import 'app_bar.dart'; import 'app_bar.dart';
import 'package:keyboard_actions/keyboard_actions.dart'; import 'input_dialog_widget.dart';
// ignore: must_be_immutable // ignore: must_be_immutable
class SizeWidget extends StatefulWidget { class SizeWidget extends StatefulWidget {
@ -19,122 +20,126 @@ class SizeWidget extends StatefulWidget {
} }
class _SizeState extends State<SizeWidget> with Trans { class _SizeState extends State<SizeWidget> with Trans {
double bmr = 0;
final FocusNode _nodeText1 = FocusNode();
KeyboardActionsConfig _buildConfig(BuildContext context) {
return KeyboardActionsConfig(
keyboardActionsPlatform: KeyboardActionsPlatform.ALL,
keyboardBarColor: Colors.grey[200],
keyboardSeparatorColor: Colors.black26,
nextFocus: true,
actions: [
KeyboardActionsItem(
focusNode: _nodeText1,
toolbarButtons: [
//button 2
(node) {
return GestureDetector(
onTap: () => node.unfocus(),
child: Container(
color: Colors.orange,
padding: EdgeInsets.all(8.0),
child: Text(
AppLocalizations.of(context).translate("Done"),
style: TextStyle(color: Colors.white),
),
),
);
}
],
),
],
);
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
setContext(context); setContext(context);
print("sex " + widget.exerciseBloc.customerRepository.sex);
return Form( return Form(
child: Scaffold( child: Scaffold(
resizeToAvoidBottomInset: true, resizeToAvoidBottomInset: true,
appBar: AppBarNav(depth: 1), appBar: AppBarNav(depth: 1),
body: Container( body: Container(
width: MediaQuery.of(context).size.width, width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height, height: MediaQuery.of(context).size.height,
decoration: BoxDecoration( decoration: BoxDecoration(
image: DecorationImage( image: DecorationImage(
image: AssetImage('asset/image/WT_black_background.png'), image: AssetImage('asset/image/WT_black_background.png'),
fit: BoxFit.fill, fit: BoxFit.fill,
alignment: Alignment.center, alignment: Alignment.center,
),
), ),
child: KeyboardActions( ),
config: _buildConfig(context), child: SafeArea(
child: Container( child: Container(
padding: EdgeInsets.only(top: 10), padding: EdgeInsets.only(top: 10),
child: child: Column(crossAxisAlignment: CrossAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center, children: [
Column(crossAxisAlignment: CrossAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center, children: [ Stack(
Stack( children: getSizeFigure(),
children: [ )
widget.exerciseBloc.customerRepository.sex == "Man" ]))),
? Image.asset( )));
"asset/image/man_sizes.png",
height: MediaQuery.of(context).size.height * .85,
)
: Image.asset(
"asset/image/woman_sizes.png",
height: MediaQuery.of(context).size.height * .85,
),
Positioned(
top: 30,
left: 175,
child: Image.asset(
"asset/image/sizes_empty.png",
),
)
],
)
]))))));
} }
Widget getWeightInput() { List<Widget> getSizeFigure() {
return Container( //print("w " + MediaQuery.of(context).size.width.toString() + "h " + MediaQuery.of(context).size.height.toString());
padding: EdgeInsets.only(top: 15, left: 65, right: 65, bottom: 10), List<Widget> list = List();
alignment: Alignment.center, list.add(SizedBox(
child: Row( width: MediaQuery.of(context).size.width * .80,
mainAxisAlignment: MainAxisAlignment.start, height: MediaQuery.of(context).size.height * .80,
children: [ ));
Flexible( list.add(
child: TextFormField( Positioned(
focusNode: _nodeText1, top: 20,
decoration: InputDecoration( left: 160,
contentPadding: EdgeInsets.only(left: 15, top: 5, bottom: 5), child: Stack(
labelText: AppLocalizations.of(context).translate("Actual Weight"), alignment: Alignment.topLeft,
labelStyle: GoogleFonts.inter(fontSize: 16, color: Colors.yellow[50]), children: [
fillColor: Colors.black38, SizedBox(height: 80, width: 100),
filled: true, Text(t("Your Sizes"),
border: OutlineInputBorder( style: GoogleFonts.archivoBlack(
gapPadding: 2.0, shadows: <Shadow>[
borderRadius: BorderRadius.circular(12.0), Shadow(
borderSide: BorderSide(color: Colors.white12, width: 0.4), offset: Offset(5.0, 5.0),
), blurRadius: 3.0,
), color: Colors.black54,
initialValue: widget.exerciseBloc.weight.toStringAsFixed(0), ),
keyboardType: TextInputType.numberWithOptions(decimal: true), ],
textInputAction: TextInputAction.done, fontSize: 22,
style: GoogleFonts.archivoBlack(fontSize: 20, color: Colors.yellow[300]), color: Colors.orange[500],
onChanged: (value) => {widget.exerciseBloc.add(ExerciseNewWeightChange(value: double.parse(value)))}, )),
), Positioned(
), top: 30,
IconButton( left: 60,
icon: Icon(Icons.save), child: IconButton(
hoverColor: Colors.blueAccent, padding: EdgeInsets.zero,
color: widget.exerciseBloc.changedWeight ? Colors.blue[200] : Colors.black54, icon: Icon(Icons.save),
onPressed: () => {print("Save"), widget.exerciseBloc.add(ExerciseNewSaveWeight())}) iconSize: 40,
], hoverColor: Colors.blueAccent,
)); color: widget.exerciseBloc.changedSizes ? Colors.orange[300] : Colors.black54,
onPressed: () => {print("Save"), widget.exerciseBloc.add(ExerciseNewSaveWeight())}))
],
)),
);
list.add(widget.exerciseBloc.customerRepository.sex == "Man"
? Image.asset(
"asset/image/man_sizes.png",
height: MediaQuery.of(context).size.height * .80,
)
: Image.asset(
"asset/image/woman_sizes.png",
height: MediaQuery.of(context).size.height * .80,
));
list.addAll(getSizeElements());
return list;
}
List<Widget> getSizeElements() {
List<Widget> list = List();
widget.exerciseBloc.manSizes.forEach((element) {
list.add(
Positioned(
top: element.top.toDouble(),
left: element.left.toDouble(),
child: element.value != 0
? IconButton(
icon: Icon(CustomIcon.ok_circled),
padding: EdgeInsets.zero,
color: Colors.green[200],
onPressed: () => onPressed(element),
)
: IconButton(
icon: Icon(CustomIcon.question),
padding: EdgeInsets.zero,
color: Colors.red[800],
onPressed: () => onPressed(element),
)),
);
});
return list;
}
void onPressed(Property element) {
print(element.propertyName);
showDialog(
context: context,
builder: (context) => InputDialog(
title: t("Size Of Your"),
subtitle: element.propertyNameTranslation,
initialValue: element.value,
onChanged: (value) {
widget.exerciseBloc.add(ExerciseNewSizeChange(propertyName: element.propertyName, value: value));
},
));
} }
} }

View File

@ -1,5 +1,6 @@
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:google_fonts/google_fonts.dart';
class TreeviewParentWidget extends StatelessWidget { class TreeviewParentWidget extends StatelessWidget {
final String text; final String text;
@ -11,7 +12,7 @@ class TreeviewParentWidget extends StatelessWidget {
Widget build(BuildContext context) { Widget build(BuildContext context) {
Widget parentWidget = Text( Widget parentWidget = Text(
this.text, this.text,
style: TextStyle(fontWeight: FontWeight.w800, color: Colors.blueAccent, backgroundColor: Colors.transparent), style: GoogleFonts.archivoBlack(fontSize: 24, color: Colors.blue[800], backgroundColor: Colors.transparent),
); );
Icon icon = Icon(Icons.person); Icon icon = Icon(Icons.person);
@ -27,4 +28,4 @@ class TreeviewParentWidget extends StatelessWidget {
), ),
); );
} }
} }

View File

@ -14,7 +14,14 @@ packages:
name: analyzer name: analyzer
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.40.5" version: "0.40.6"
animated_widgets:
dependency: "direct main"
description:
name: animated_widgets
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.6"
archive: archive:
dependency: transitive dependency: transitive
description: description:
@ -84,7 +91,7 @@ packages:
name: build_resolvers name: build_resolvers
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.4.2" version: "1.4.3"
build_runner: build_runner:
dependency: "direct dev" dependency: "direct dev"
description: description:
@ -175,7 +182,7 @@ packages:
name: coverage name: coverage
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.14.1" version: "0.14.2"
crypto: crypto:
dependency: transitive dependency: transitive
description: description:
@ -196,7 +203,7 @@ packages:
name: dart_style name: dart_style
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.3.8" version: "1.3.9"
devicelocale: devicelocale:
dependency: "direct main" dependency: "direct main"
description: description:
@ -204,6 +211,13 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.3.3" version: "0.3.3"
dropdown_search:
dependency: "direct main"
description:
name: dropdown_search
url: "https://pub.dartlang.org"
source: hosted
version: "0.4.6"
equatable: equatable:
dependency: "direct main" dependency: "direct main"
description: description:
@ -280,7 +294,7 @@ packages:
name: firebase_core_web name: firebase_core_web
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.2.0" version: "0.2.1"
fixnum: fixnum:
dependency: transitive dependency: transitive
description: description:
@ -306,7 +320,7 @@ packages:
name: flutter_bloc name: flutter_bloc
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "6.0.6" version: "6.1.1"
flutter_driver: flutter_driver:
dependency: "direct dev" dependency: "direct dev"
description: flutter description: flutter
@ -332,7 +346,7 @@ packages:
name: flutter_keyboard_visibility name: flutter_keyboard_visibility
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "3.2.2" version: "3.3.0"
flutter_launcher_icons: flutter_launcher_icons:
dependency: "direct dev" dependency: "direct dev"
description: description:
@ -436,7 +450,7 @@ packages:
name: image name: image
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.1.18" version: "2.1.19"
infinite_listview: infinite_listview:
dependency: "direct main" dependency: "direct main"
description: description:
@ -479,6 +493,13 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.2.2" version: "2.2.2"
keyboard_actions:
dependency: "direct main"
description:
name: keyboard_actions
url: "https://pub.dartlang.org"
source: hosted
version: "3.3.1+1"
logging: logging:
dependency: transitive dependency: transitive
description: description:
@ -527,7 +548,7 @@ packages:
name: node_interop name: node_interop
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.1.1" version: "1.2.0"
node_io: node_io:
dependency: transitive dependency: transitive
description: description:
@ -576,7 +597,7 @@ packages:
name: path_provider name: path_provider
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.6.22" version: "1.6.24"
path_provider_linux: path_provider_linux:
dependency: transitive dependency: transitive
description: description:
@ -590,21 +611,21 @@ packages:
name: path_provider_macos name: path_provider_macos
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.0.4+4" version: "0.0.4+6"
path_provider_platform_interface: path_provider_platform_interface:
dependency: transitive dependency: transitive
description: description:
name: path_provider_platform_interface name: path_provider_platform_interface
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.0.3" version: "1.0.4"
path_provider_windows: path_provider_windows:
dependency: transitive dependency: transitive
description: description:
name: path_provider_windows name: path_provider_windows
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.0.4+1" version: "0.0.4+3"
pedantic: pedantic:
dependency: transitive dependency: transitive
description: description:
@ -681,7 +702,7 @@ packages:
name: quiver name: quiver
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.1.4+1" version: "2.1.5"
rainbow_color: rainbow_color:
dependency: "direct main" dependency: "direct main"
description: description:
@ -716,21 +737,21 @@ packages:
name: shared_preferences name: shared_preferences
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.5.12+2" version: "0.5.12+4"
shared_preferences_linux: shared_preferences_linux:
dependency: transitive dependency: transitive
description: description:
name: shared_preferences_linux name: shared_preferences_linux
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.0.2+2" version: "0.0.2+4"
shared_preferences_macos: shared_preferences_macos:
dependency: transitive dependency: transitive
description: description:
name: shared_preferences_macos name: shared_preferences_macos
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.0.1+10" version: "0.0.1+11"
shared_preferences_platform_interface: shared_preferences_platform_interface:
dependency: transitive dependency: transitive
description: description:
@ -751,7 +772,7 @@ packages:
name: shared_preferences_windows name: shared_preferences_windows
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.0.1+1" version: "0.0.1+3"
shelf: shelf:
dependency: transitive dependency: transitive
description: description:
@ -931,7 +952,7 @@ packages:
name: vm_service name: vm_service
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "5.3.1" version: "5.5.0"
vm_service_client: vm_service_client:
dependency: transitive dependency: transitive
description: description:
@ -966,7 +987,7 @@ packages:
name: webkit_inspection_protocol name: webkit_inspection_protocol
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.7.3" version: "0.7.4"
win32: win32:
dependency: transitive dependency: transitive
description: description:

View File

@ -39,11 +39,14 @@ dependencies:
fl_chart: ^0.12.0 fl_chart: ^0.12.0
infinite_listview: ^1.0.1+1 infinite_listview: ^1.0.1+1
toggle_switch: ^0.1.8 toggle_switch: ^0.1.8
keyboard_actions: ^3.3.1+1
dropdown_search: ^0.4.6
firebase_core: 0.5.0+1 firebase_core: 0.5.0+1
#firebase_analytics: ^6.0.2 #firebase_analytics: ^6.0.2
firebase_auth: ^0.18.1+2 firebase_auth: ^0.18.1+2
flutter_facebook_auth: ^0.3.3 flutter_facebook_auth: ^0.3.3
animated_widgets: ^1.0.6
mockito: ^4.1.1 mockito: ^4.1.1
@ -74,7 +77,10 @@ flutter_icons:
# The following section is specific to Flutter. # The following section is specific to Flutter.
flutter: flutter:
fonts:
- family: CustomIcon
fonts:
- asset: asset/font/CustomIcon.ttf
# The following line ensures that the Material Icons font is # The following line ensures that the Material Icons font is
# included with your application, so that you can use the icons in # included with your application, so that you can use the icons in
# the material Icons class. # the material Icons class.
@ -82,9 +88,16 @@ flutter:
# To add assets to your application, add an assets section, like this: # To add assets to your application, add an assets section, like this:
assets: assets:
- asset/icon/gomb_kek_a-2.png
- asset/icon/gomb_orange_a.png
- asset/icon/gomb_pink_a.png
- asset/icon/gomb_pink_b.png
- asset/icon/gomb_zold_b-1.png
- asset/icon/gomb_sarga_a.png
- asset/image/WT_menu_welcome.png - asset/image/WT_menu_welcome.png
- asset/image/WT01_loading_layers.png - asset/image/WT01_loading_layers.png
- asset/image/WT_menu_backround.png - asset/image/WT_menu_backround.png
- asset/image/WT_black_background.png
- asset/image/WT_menu.png - asset/image/WT_menu.png
- asset/image/WT_login.png - asset/image/WT_login.png
- asset/image/WT_OK.png - asset/image/WT_OK.png
@ -107,6 +120,11 @@ flutter:
- asset/image/exercise_plan_custom.jpg - asset/image/exercise_plan_custom.jpg
- asset/image/exercise_plan_suggested.jpg - asset/image/exercise_plan_suggested.jpg
- asset/image/predictions.jpg - asset/image/predictions.jpg
- asset/image/man_sizes.png
- asset/image/woman_sizes.png
- asset/image/BMI_diagram_b.png
- asset/image/BMI_graph_c.png
- asset/image/BMI_mutato.png
- asset/menu/1.cardio.png - asset/menu/1.cardio.png
- asset/menu/1.1.aerob.png - asset/menu/1.1.aerob.png
- asset/menu/1.2.anaerob.png - asset/menu/1.2.anaerob.png