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

This commit is contained in:
bossanyit 2020-11-16 15:41:34 +01:00
parent cffc397d70
commit 5fa5382e3f
33 changed files with 12524 additions and 0 deletions

BIN
asset/font/CustomIcon.ttf Normal file

Binary file not shown.

BIN
asset/icon/gomb_kek_a-2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 55 KiB

BIN
asset/icon/gomb_kek_a.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 55 KiB

BIN
asset/icon/gomb_kek_b.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

BIN
asset/icon/gomb_lila_b.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

BIN
asset/icon/gomb_pink_a.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 65 KiB

BIN
asset/icon/gomb_pink_b.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

BIN
asset/icon/gomb_sarga_a.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 51 KiB

BIN
asset/icon/gomb_zold_a.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 64 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 272 KiB

BIN
asset/image/BMI_graph_c.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 MiB

BIN
asset/image/BMI_mutato.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 MiB

BIN
asset/image/man_sizes.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 70 KiB

BIN
asset/image/woman_sizes.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 65 KiB

10090
lib/library/config.json Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,19 @@
class CustomerProperty {
int propertyId;
int customerId;
DateTime dateAdd;
double propertyValue;
bool newData = false;
CustomerProperty({this.propertyId, this.customerId, this.dateAdd, this.propertyValue});
CustomerProperty.fromJson(Map json) {
this.propertyId = json['propertyId'];
this.customerId = json['customerId'];
this.dateAdd = json['propertyName'];
this.propertyValue = json['propertyValue'];
}
Map<String, dynamic> toJson() =>
{"propertyId": this.propertyId, "customerId": this.customerId, "dateAdd": this.dateAdd, "propertyValue": this.propertyValue};
}

View File

@ -0,0 +1,70 @@
import 'package:flutter/semantics.dart';
class FitnessState {
final String value;
final String stateText;
final String explanation;
static String beginner = "beginner";
static String intermediate = "intermediate";
static String advanced = "advanced";
static String professional = "professional";
FitnessState({this.value, this.stateText, this.explanation});
bool isEqual(FitnessState state) {
if (state == null) {
return false;
}
return state.value == this.value;
}
@override
String toString() {
return stateText;
}
}
class FitnessItem {
static final FitnessItem _singleton = FitnessItem._internal();
List<FitnessState> elements = List();
factory FitnessItem() {
return _singleton;
}
FitnessItem._internal() {
elements.add(FitnessState(
value: FitnessState.beginner, stateText: _capitalize(FitnessState.beginner), explanation: "I am " + FitnessState.beginner));
elements.add(FitnessState(
value: FitnessState.intermediate,
stateText: _capitalize(FitnessState.intermediate),
explanation: "I am " + FitnessState.intermediate));
elements.add(FitnessState(
value: FitnessState.advanced, stateText: _capitalize(FitnessState.advanced), explanation: "I am " + FitnessState.advanced));
elements.add(FitnessState(
value: FitnessState.professional,
stateText: _capitalize(FitnessState.professional),
explanation: "I am " + FitnessState.professional));
}
String _capitalize(String value) {
return "${value[0].toUpperCase()}${value.substring(1)}";
}
List<FitnessState> toList() => elements;
FitnessState getItem(String value) {
if (value == null || value.length == 0) {
return elements[0];
}
FitnessState selected;
elements.forEach((element) {
if (element.value == value) {
print("selected " + element.value);
selected = element;
}
});
return selected;
}
}

20
lib/model/product.dart Normal file
View File

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

View File

@ -0,0 +1,17 @@
class Product {
int productId;
String name;
String description;
String type;
DateTime validFrom;
DateTime validTo;
Product.fromJson(Map json) {
this.productId = json['productId'];
this.name = json['name'];
this.description = json['description'];
this.type = json['type'];
this.validFrom = json['validFrom'];
this.validTo = json['validTo'];
}
}

16
lib/model/property.dart Normal file
View File

@ -0,0 +1,16 @@
class Property {
int propertyId;
String propertyName;
String propertyUnit;
String propertyNameTranslation;
Property.fromJson(Map json) {
this.propertyId = json['propertyId'];
this.propertyName = json['propertyName'];
this.propertyUnit = json['propertyUnit'];
this.propertyNameTranslation =
json['translations'] != null && (json['translations']).length > 0
? json['translations'][0]['propertyName']
: this.propertyName;
}
}

17
lib/model/purchase.dart Normal file
View File

@ -0,0 +1,17 @@
class Product {
int productId;
String name;
String description;
String type;
DateTime validFrom;
DateTime validTo;
Product.fromJson(Map json) {
this.productId = json['productId'];
this.name = json['name'];
this.description = json['description'];
this.type = json['type'];
this.validFrom = json['validFrom'];
this.validTo = json['validTo'];
}
}

View File

@ -0,0 +1,31 @@
import 'dart:collection';
import 'package:aitrainer_app/model/cache.dart';
import 'package:aitrainer_app/model/property.dart';
import 'package:aitrainer_app/service/property_service.dart';
class PropertyRepository {
List<Property> _properties;
Future<List<Property>> getDBProperties() async {
this._properties = await PropertyApi().getProperties();
return this._properties;
}
List<Property> getProperties() {
return this._properties;
}
Property getPropertyByName(String name) {
Property property;
if (_properties == null) {
_properties = Cache().getProperties();
}
this._properties.forEach((element) {
if (name == element.propertyName) {
property = element;
}
});
return property;
}
}

View File

@ -0,0 +1,17 @@
import 'dart:convert';
import 'package:aitrainer_app/model/cache.dart';
import 'package:aitrainer_app/model/property.dart';
import 'package:aitrainer_app/service/api.dart';
class PropertyApi {
final APIClient _client = new APIClient();
Future<List<Property>> getProperties() async {
final body = await _client.get("property/", "");
final Iterable json = jsonDecode(body);
final List<Property> properties = json.map((property) => Property.fromJson(property)).toList();
Cache().setProperties(properties);
return properties;
}
}

View File

296
lib/widgets/bmr_widget.dart Normal file
View File

@ -0,0 +1,296 @@
import 'package:aitrainer_app/bloc/exercise_new/exercise_new_bloc.dart';
import 'package:aitrainer_app/localization/app_localization.dart';
import 'package:aitrainer_app/model/fitness_state.dart';
import 'package:aitrainer_app/util/trans.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';
import 'package:dropdown_search/dropdown_search.dart';
// ignore: must_be_immutable
class BMR extends StatefulWidget {
final ExerciseNewBloc exerciseBloc;
BMR({this.exerciseBloc});
@override
_BMRState createState() => _BMRState();
}
class _BMRState extends State<BMR> with Trans {
double bmr = 0;
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);
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(
padding: EdgeInsets.only(top: 100),
child:
Column(crossAxisAlignment: CrossAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center, children: [
getWeightInput(),
getFitnessLevel(),
Divider(),
Container(
padding: EdgeInsets.only(left: 35, right: 35),
child: Text(t("Basal Metabolic Rate"),
textAlign: TextAlign.center,
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.getBMR().toStringAsFixed(0) + " kCal",
style: GoogleFonts.archivoBlack(
shadows: <Shadow>[
Shadow(
offset: Offset(5.0, 5.0),
blurRadius: 3.0,
color: Colors.black54,
),
],
fontSize: 50,
color: Colors.orange[500],
)),
Container(
padding: EdgeInsets.only(left: 65, right: 65),
alignment: Alignment.center,
child: Text(t("Based on your weight, height and activity your BMR value"),
textAlign: TextAlign.center,
style: GoogleFonts.inter(
fontSize: 16,
color: Colors.yellow[200],
)),
),
]))))));
}
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 getFitnessLevel() {
String fitnessLevel = widget.exerciseBloc.fitnessLevel;
print("sel " + fitnessLevel + FitnessItem().getItem(fitnessLevel).stateText);
return Container(
padding: EdgeInsets.only(left: 65, right: 65),
child: DropdownSearch<FitnessState>(
dropdownSearchDecoration: InputDecoration(
contentPadding: EdgeInsets.only(left: 15, top: 5, bottom: 5),
labelText: t("Fitness Activity"),
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),
),
),
mode: Mode.MENU,
compareFn: (FitnessState i, FitnessState s) => i.isEqual(s),
showSelectedItem: true,
selectedItem: FitnessItem().getItem(fitnessLevel),
itemAsString: (data) => t(data.stateText),
onChanged: (data) {
print(data);
widget.exerciseBloc.add(ExerciseNewFitnessLevelChange(value: data.value));
},
dropdownBuilder: _customDropDownItem,
popupItemBuilder: _customMenuBuilder,
items: FitnessItem().toList(),
dropDownButton: Icon(
Icons.arrow_drop_down,
color: Colors.yellow[200],
),
));
//items: FitnessItem().toList()));
}
Widget _customMenuBuilder(BuildContext context, FitnessState item, bool isSelected) {
bool selected = item.value == widget.exerciseBloc.fitnessLevel;
return Container(
decoration: !selected
? BoxDecoration(color: Colors.black54)
: BoxDecoration(
border: Border.all(color: Colors.blue),
borderRadius: BorderRadius.circular(5),
color: Colors.black38,
),
child: ListTile(
selected: selected,
title: Text(
t(item.stateText),
style: GoogleFonts.archivoBlack(fontSize: 20, color: Colors.yellow[300]),
),
subtitle: Text(
t(item.explanation),
style: GoogleFonts.inter(fontSize: 12, color: Colors.yellow[300]),
),
),
);
}
Widget _customDropDownItem(BuildContext context, FitnessState item, String itemDesignation) {
return Container(
child: (item == null)
? ListTile(
contentPadding: EdgeInsets.all(0),
title: Text(
t("No item selected"),
style: GoogleFonts.inter(fontSize: 14, color: Colors.yellow[300]),
),
)
: ListTile(
contentPadding: EdgeInsets.all(0),
title: Text(
t(item.stateText),
style: GoogleFonts.archivoBlack(fontSize: 20, color: Colors.yellow[300]),
),
subtitle: Text(
t(item.explanation),
style: GoogleFonts.inter(fontSize: 12, color: Colors.yellow[300]),
),
),
);
}
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

@ -0,0 +1,81 @@
import 'package:flutter/material.dart';
class InputDialog extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Dialog(
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(16)),
elevation: 0,
backgroundColor: Colors.transparent,
child: _buildChild(context),
);
}
_buildChild(BuildContext context) => Container(
height: 350,
decoration: BoxDecoration(color: Colors.redAccent, shape: BoxShape.rectangle, borderRadius: BorderRadius.all(Radius.circular(12))),
child: Column(
children: <Widget>[
Container(
child: Padding(
padding: const EdgeInsets.all(12.0),
child: Image.asset(
'assets/image/lock.png',
height: 120,
width: 120,
),
),
width: double.infinity,
decoration: BoxDecoration(
color: Colors.white,
shape: BoxShape.rectangle,
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(
height: 8,
),
Padding(
padding: const EdgeInsets.only(right: 16, left: 16),
child: Text(
'If back button is pressed by mistake then click on no to continue.',
style: TextStyle(color: Colors.white),
textAlign: TextAlign.center,
),
),
SizedBox(
height: 24,
),
Row(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
FlatButton(
onPressed: () {
Navigator.of(context).pop();
},
child: Text('No'),
textColor: Colors.white,
),
SizedBox(
width: 8,
),
RaisedButton(
onPressed: () {
return Navigator.of(context).pop(true);
},
child: Text('Yes'),
color: Colors.white,
textColor: Colors.redAccent,
)
],
)
],
),
);
}

View File

@ -0,0 +1,140 @@
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: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 SizeWidget extends StatefulWidget {
final ExerciseNewBloc exerciseBloc;
SizeWidget({this.exerciseBloc});
@override
_SizeState createState() => _SizeState();
}
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
Widget build(BuildContext context) {
setContext(context);
print("sex " + widget.exerciseBloc.customerRepository.sex);
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: Container(
padding: EdgeInsets.only(top: 10),
child:
Column(crossAxisAlignment: CrossAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center, children: [
Stack(
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() {
return Container(
padding: EdgeInsets.only(top: 15, left: 65, right: 65, bottom: 10),
alignment: Alignment.center,
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
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())})
],
));
}
}