diff --git a/android/app/build.gradle b/android/app/build.gradle
index 7fb27d7..65cff7c 100644
--- a/android/app/build.gradle
+++ b/android/app/build.gradle
@@ -8,7 +8,7 @@ if (localPropertiesFile.exists()) {
def flutterRoot = localProperties.getProperty('flutter.sdk')
if (flutterRoot == null) {
- throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.")
+ throw new Exception("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.")
}
def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
@@ -26,6 +26,12 @@ apply plugin: 'kotlin-android'
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
apply plugin: 'com.google.gms.google-services'
+def keystoreProperties = new Properties()
+def keystorePropertiesFile = rootProject.file('key.properties')
+if (keystorePropertiesFile.exists()) {
+ keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
+}
+
android {
compileSdkVersion 28
@@ -46,11 +52,20 @@ android {
versionName flutterVersionName
}
+ signingConfigs {
+ release {
+ keyAlias keystoreProperties['keyAlias']
+ keyPassword keystoreProperties['keyPassword']
+ storeFile keystoreProperties['storeFile'] ? file(keystoreProperties['storeFile']) : null
+ storePassword keystoreProperties['storePassword']
+ }
+ }
+
buildTypes {
release {
// TODO: Add your own signing config for the release build.
// Signing with the debug keys for now, so `flutter run --release` works.
- signingConfig signingConfigs.debug
+ signingConfig signingConfigs.release
}
}
}
@@ -62,4 +77,5 @@ flutter {
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation 'com.google.firebase:firebase-analytics:17.2.2'
+ implementation 'com.facebook.android:facebook-login:[5,6)'
}
diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml
index 55aec36..7f52f63 100644
--- a/android/app/src/main/AndroidManifest.xml
+++ b/android/app/src/main/AndroidManifest.xml
@@ -48,5 +48,23 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/android/app/src/main/res/values/strings.xml b/android/app/src/main/res/values/strings.xml
new file mode 100644
index 0000000..432c9c7
--- /dev/null
+++ b/android/app/src/main/res/values/strings.xml
@@ -0,0 +1,13 @@
+
+
+ WorkoutTest
+
+
+ 584181112271127
+
+
+ fb584181112271127
+
\ No newline at end of file
diff --git a/android/gradle/wrapper/gradle-wrapper.properties b/android/gradle/wrapper/gradle-wrapper.properties
index 296b146..bc24dcf 100644
--- a/android/gradle/wrapper/gradle-wrapper.properties
+++ b/android/gradle/wrapper/gradle-wrapper.properties
@@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.2-all.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.4-all.zip
diff --git a/android/key.properties b/android/key.properties
new file mode 100644
index 0000000..39725b5
--- /dev/null
+++ b/android/key.properties
@@ -0,0 +1,4 @@
+storePassword=tbi6012Andi
+keyPassword=tbi6012Andi
+keyAlias=key
+storeFile=c:/Users/bossa/.ssh/key.jks
\ No newline at end of file
diff --git a/android/settings_aar.gradle b/android/settings_aar.gradle
new file mode 100644
index 0000000..e7b4def
--- /dev/null
+++ b/android/settings_aar.gradle
@@ -0,0 +1 @@
+include ':app'
diff --git a/asset/icon/WT_long_logo_1024x500.png b/asset/icon/WT_long_logo_1024x500.png
new file mode 100644
index 0000000..732c026
Binary files /dev/null and b/asset/icon/WT_long_logo_1024x500.png differ
diff --git a/asset/icon/icon_512.png b/asset/icon/icon_512.png
new file mode 100644
index 0000000..3cbab01
Binary files /dev/null and b/asset/icon/icon_512.png differ
diff --git a/asset/image/login_fb.png b/asset/image/login_fb.png
new file mode 100644
index 0000000..d51e0a9
Binary files /dev/null and b/asset/image/login_fb.png differ
diff --git a/i18n/en.json b/i18n/en.json
index 7644033..b1c5100 100644
--- a/i18n/en.json
+++ b/i18n/en.json
@@ -23,8 +23,9 @@
"gdpr_text": "Kik vagyunk\nA weboldalunk a https://andio.biz (blogbejegyzések) és https://natur-haztartas.hu webáruház.\n\nCélunk a természetes és natúr életmód népszerűsítése, hogy az vásárlóinkat és érdeklődőinket segítsünk a vegyszermentes és natúr életmód felé vezető úton.\n\nMelyek azok a személyes adatok amiket gyűjtünk, és milyen céllal gyűjtjük azokat\nVásárlás\nMegrendelés esetén elkérjük a következő adatokat:\n\na nevet: hogy azonosítsunk csomagszállítás esetén, illetve a számlára is rákerül a vásárló neve\nemail címet: megrendelés visszaigazoláshoz, a csomag állapotának a közléséhez. Emellett, ha engedélyt kapunk, hírleveleket is küldünk natúr életmód tippekről, ajánlatokról. Ezekről a levelekről bármikor, egy kattintással le tudsz iratkozni, a levél alján.\ncímet: A csomag szállításához fontos a pontos cím. A számlára is ez a cím kerül, de lehetőséged van itt egy másik, csak számlázási címet megadni.\ntelefonszámot: SMS értesítőt küldünk a csomag kiszállítása előtt egy munkanappal. Ha valamilyen más probléma merül fel a csomag összeállításakor, akkor lehetséges, hogy telefonon megkeresünk és tisztázzuk a problémákat (pl. áruhiány, rosszul megadott adatok kijavítása, stb).\nHozzászólások\nHozzászólás beküldésekor a hozzászólási űrlapban megadottakon kívül begyűjtésre kerül a hozzászóló IP címe és a böngészőazonosító karakterlánc a kéretlen tartalmak kiszűrése céljából.\n\nEgy személytelenített, az e-mail címből előállított karakterlánc (hashnek szokás nevezni) kerül továbbításra a Gravatar szolgáltatás felé, ha ez az oldalon használatban van. A Gravatar szolgáltatás feltételei az alábbi címen tekinthetőek meg: https://automattic.com/privacy/. A hozzászólás elfogadása után, a hozzászólásunk tartalma és a profil képünk is megjelenik nyilvánosan.\n\nKapcsolatfelvételi űrlapok\nAmennyiben szeretnél, feliratkozhatsz hírlevelünkre weboldalunkon az ott található regisztrációs űrlap kitöltésével. (pl: https://natur-haztartas.hu/login?back=my-account)\n\nHa kitöltöd a regisztrációs űrlapot és rendelkezésünkre bocsátod személyes adataidat vagy a vevőként történő regisztrációjakor hozzájárultál ahhoz, hogy hírlevelet küldjünk az számodra, e-mailt fogsz kapni tőlünk a megadott e-mail címre.\n\nA regisztrációs űrlapon megadott személyes adatok kezelésére kizárólag a hírlevélnek az e-mail címre történő küldése céljából kerül.\n\nA hírleveleinkben található linkek nyomon követési információkat tartalmaznak, melyek segítségével megállapíthatjuk, hogy különösen mely linkek érdekeltek téged, amelyekre rákattintottál.\n\nA nyomon követési link segítségével a következő adatok tárolása történik a hírlevélkezelő rendszerünkbe: e-mail cím, hírlevél, link, dátum és idő. Az személyes adataidat csak addig tároljuk, amíg a „leiratkozás” linkre kattintva le nem iratkozol a hírlevélről. E link megtalálható minden egyes tőlünk kapott hírlevél alján. Amennyiben leiratkozol személyes adataid késedelem nélkül törlésre kerülnek. Felhívjuk a figyelmed arra, hogy személyes adatok törlését követően nem fogsz tőlünk több hírlevelet vagy kupont kapni.\n\nHa üzenetet küldesz az Andió Facebook messengerére, akkor jogosultak vagyunk az Andió által viszontüzenetet küldeni a Te messengeredre. Ezekről az üzeneteket bármikor leállíthatod, ha a messengerbe beírod a STOP szót és utána megnyomod a „leiratkozok” gombot.\n\nSütik és nyomon követés\nHozzászólás írása után a honlap a megadott nevet, e-mail és web címet sütiben eltárolja. A tárolás csak kényelmi célokat szolgál, hogy a következő hozzászóláskor ne kelljen automatikusan kitölteni. A sütik lejárati ideje 1 év.\n\nHa rendelkezel felhasználói fiókkal és be is vagy jelentkezve erre a honlapra, akkor átmeneti sütiket állítunk be, annak érdekében, hogy megállapítsuk, hogy a böngésző elfogadja-e a sütiket. Ezek a sütik nem tartalmaznak személyes információt, és törlődnek, ahogy bezárjuk a böngészőt.\n\nA honlapra történő bejelentkezéskor több sütit hozunk létre, amely elmenti a bejelentkezési információt és a szerkesztőfelület megjelenítési opcióit. A bejelentkezési sütik két napig érvényesek, a szerkesztőfelület megjelenítési opcióit tároló süti egy évig. Amennyiben az “Emlékezz rám” opciót bejelöljük, a bejelentkezés két hétig folytatódik. Kijelentkezéskor a bejelentkezési sütik eltávolításra kerülnek.\n\nHa a webáruházban jársz, akkor a kosarad tartalmát és a bejelentkezési állapotodat is a süti tartalmazza. Így ha kikapcsolod a sütiket a böngésződben, akkor nem tudsz a honlapon rendelni, így azt ímélen vagy telefonon tudod megtenni.\n\nA Google Inc. („Google”) által biztosított Google Analytics internetes elemző szolgáltatást is igénybe vesszük. A Google Analytics szintén sütiket használ. A sütik által a weboldalhasználattal kapcsolatban létrehozott információk általában egy USA-beli Google-szerverre kerülnek, és ott tárolják őket. Ezt megelőzően a Google lerövidíti az IP-címedet az Európai Unió tagállamain és az Európai Gazdasági Térségről szóló megállapodás részes államain belül. Teljes IP-címet csak kivételes esetekben továbbítanak lerövidítés céljából a Google USA-ban található szervereire. A Google a weboldal üzemeltetője megbízásából ezen információk alapján értékeli az weboldalhasználatod, és weboldalaktivitással kapcsolatos jelentéseket készít, valamint további weboldal- és internethasználattal kapcsolatos szolgáltatásokat nyújt a weboldal üzemeltetője számára. Az böngésződ által a Google Analytics szolgáltatása révén továbbított IP-címet nem kapcsolják össze a Google más adataival. A böngésződ megfelelő beállításainak kiválasztásával elutasíthatod a sütik használatát. Megtilthatod azt is, hogy a Google gyűjtse és feldolgozza a sütik által létrehozott és a weboldalhasználatodra vonatkozó adatokat (beleértve az IP-címet). Ehhez töltsd le és telepítse a következő linken található beépülő böngészőmodult: https://tools.google.com/dlpage/gaoptout?hl=en\n\nA Facebook által biztosított adatelemzést és követést is használjuk. Így ha a honlapon jársz, később találkozhatsz egy hirdetéssel, amely a meglátogatott honlap oldalról szól, mert feltételezzük, hogy érdekel Téged a téma, és még többet szeretnél megtudni róla.\n\nVásárlás után véleményt kérünk a vásárolt termékről a Yotpo.com szolgáltatásán keresztül. Itt megírhatod a véleményed, amely kikerül a termék weboldalára esetleg az Andió facebook oldalára is. A vásárlás után kb. 2 héttel egy emailt kapsz, hogy írd meg a véleményed. Erről a véleménykérő emailről is leiratkozhatsz a levél alján látható leiratkozási linkkel.\n\nNéhány weboldalunkat elemezzük, hogy minél jobban követhető, olvasható és használható legyen. Ez az elemzés a Hotjar.com szolgáltatásával személyes adatok gyűjtése és felhasználása nélkül rögzíti a tevékenységedet az oldalon és a sok látogató össztevékenységét összevetve tudjuk az oldal minőségét javítani.\n\nMás honlapokról származó beágyazott tartalmak\nA honlapon elérhető bejegyzések külső forrásból származó beágyazott tartalmakat (pl. videók, képek, cikkek stb.) használhatnak. A külső forrásból származó beágyazott tartalmak pontosan úgy viselkednek, mintha meglátogattunk volna egy másik honlapot.\n\nEzek a webhelyek lehetséges, hogy adatot gyűjtenek a látogatókról, sütiket vagy harmadik féltől származó követőkódot használnak, figyelik a beágyazott tartalommal kapcsolatos felhasználói viselkedést, ha rendelkezünk felhasználói fiókkal és be vagyunk jelentkezve az oldalra.\n\nKivel osztjuk meg és hová továbbítjuk a felhasználói adatokat\nAz elkért és tárolt adatokat a webtárhelyen adatbázisban őrizzük. A webtárhely tulajdonosa a Magyar Hosting Kft (Székhely: 1132 Budapest, Victor Hugo u. 18, Postacím: ua. Telefon: (1) 700 2323 Web: https://www.mhosting.hu/ )\n\nA nevet és a címet csomagszállítás esetén továbbítjuk a futárszolgálat felé, amely kiszállítja a címedre a csomagot.\n\nBelföldi szállítás esetén: Complexpress Logisztika Kft.,1033 Budapest, Szentendrei út 89-95. Telefon: 06-1-203-4681\n\nKülföldi szállítás esetén: GLS General Logistics Systems Hungary Csomag-Logisztikai Kft. 2351 Alsónémedi GLS Európa u. 2. info@gls-hungary.com.\n\nA vásárláshoz minden esetben számlát adunk ki, amelyet bármikor letölthetsz a webáruház felhasználó fiókodból: https://natur-haztartas.hu/ugyfelfiok. A számlán levő adatokat (név és cím) elküldjük a könyvelőirodának, amelyet törvényi kötelezettségünk 8 évig megőrizni.\n\nA könyvelőiroda: Adókalkulátor Kft. Cím: Budapest, Szigligeti u. 44, 1205 Telefon: (20) 292 1072\n\nMennyi ideig őrizzük a személyes adatot\nHa hozzászólsz egy blogbejegyzéshez, hozzászólás és annak metaadatai nem meghatározható ideig a rendszerben maradnak. Ennek célja, hogy az összes ezt követő bármely hozzászólás általunk megismertté és jóváhagyottá váljon, azaz ne kerüljön fel a moderálandó hozzászólások listájára.\n\nA honlapon regisztrált felhasználók személyes adatai a felhasználói profiljukban is tárolásra kerülnek. (https://natur-haztartas.hu/ugyfelfiok)\n\nA vásárláskor megadott adatokat a törvény szerint 8 év őrizzük.\n\nA hírlevél feliratkozáskor ill. kapcsolati űrlapon megadott adatokat nem töröljük, csak kérésre. Ezt egy kattintással megteheted minden hírlevél alján, ill. az ügyfelszolgálati email címen is kérheted a törlést.\n\nMilyen jogokkal rendelkezik a felhasználó a saját adatai kapcsán\nA weboldalon regisztrált fiók vagy hozzászólás írása esetén kérhető a személyes adatok export fájlban történő megküldése, amely bármilyen adatot tartalmaz, amit korábban a felhasználó rendelkezésünkre bocsátott.\n\nKérhető továbbá, hogy bármilyen korábban megadott személyes adatot töröljük. Ezt megteheted minden hírlevél alján levő leiratkozás gombbal, vagy ügyfélszolgálati elérhetőségeink egyikén. A törlés nem vonatkozik azokra az adatokra, amelyeket adminisztrációs, jogi vagy biztonsági okokból kötelező megőriznünk.\n\nAdathelyesbítés: ha pontatlanok az adataid (név, email cím, szállítási cím), megteheted az ugyfelszolgalat@andio.biz email címen keresztül\n\nKapcsolati adatok\nÜgyfélszolgálat:\n\nemail: ugyfelszolgalat@andio.biz\n\ntelefon munkaidőben: +36 30 580 0499",
"Please log in": "Please log in",
- "Customer does not exist or the password is wrong": "Customer does not exist or the password is wrong",
+ "Exception: Customer does not exist or the password is wrong": "Customer does not exist or the password is wrong",
"Customer exists": "The email address has been registered already",
+ "There is an error: during registration:": "There is an error: during registration:",
"Please select an exercise": "Please select an exercise",
"Cardio": "Cardio",
"400m": "400m",
@@ -58,17 +59,26 @@
"Unit": "Unit",
"Exercise date and time": "Exercise date and time",
"Please type the right quantity 0-1000": "Please type the right quantity 0-10000",
+ "Yes": "Yes",
+ "No": "No",
+ "with": "with",
+ "Do you save this exercise with these parameters?":"Do you save this exercise with these parameters?",
+ "The number of the exercise": "The number of the exercise",
+ "The number of the exercise done with": "The number of the exercise done with",
+
"repeat": "repeat",
"meter": "meter",
"percent": "percent",
"kg": "kg",
+ "kilogram": "kilogram",
"lbs": "lbs",
"second": "second",
"Email": "Email",
"Password": "Password",
- "Password (Leave empty if you don't want to change)":"Password (Leave empty if you don't want to change)",
+ "OR": "OR",
+ "Password (Leave empty if no change)":"Password (Leave empty if no change)",
"First Name": "First Name",
"Birth Year": "Birty Year",
"Weight": "Weight",
diff --git a/i18n/hu.json b/i18n/hu.json
index e03577c..a16b510 100644
--- a/i18n/hu.json
+++ b/i18n/hu.json
@@ -23,8 +23,9 @@
"gdpr_text": "",
"Please log in": "Kérlek jelentkezz be",
- "Customer does not exist or the password is wrong": "A felhasználónév nem létezik vagy a jelszó rossz.",
+ "Exception: Customer does not exist or the password is wrong": "A felhasználónév nem létezik vagy a jelszó rossz.",
"Please select an exercise": "Válassz ki egy gyakorlatot",
+ "There is an error: during registration:": "Hiba lépett fel a regisztráció során:",
"Customer exists": "Ez az email cím már regisztrálva van",
"Cardio": "Kardió",
"400m": "400m",
@@ -50,7 +51,10 @@
"BMR": "Alapanyagcsere",
"Sizes": "Méretek",
"Save Exercise": "gyakorlat mentése",
- "Save": "Save",
+ "Save": "Mentés",
+ "The number of the exercise": "Írd be a gyakorlat számát",
+ "The number of the exercise done with": "Írd be, mennyivel csináltad a gyakorlatot",
+
"Name": "Név",
"Exercise": "Gyakorlat",
@@ -58,17 +62,23 @@
"Unit": "Egység",
"Exercise date and time": "A gyakorlat időpontja",
"Please type the right quantity 0-1000": "Kérlek írj be egy helyes számot 0-10000 között",
+ "Yes": "Igen",
+ "No": "Nem",
+ "with": "",
+ "Do you save this exercise with these parameters?":"Elmented a gyakorlatot ezekkel az adatokkal?",
"repeat": "ismétlés",
"meter": "meter",
"percent": "százalék",
"kg": "kg",
+ "kilogram": "kilogramm",
"lbs": "lbs",
"second": "másodperc",
"Email": "Email",
"Password": "Jelszó",
- "Password (Leave empty if you don't want to change)":"Jelszó (hagyd üresen, ha nem akarod megváltoztatni)",
+ "OR": "VAGY",
+ "Password (Leave empty if no change)":"Jelszó (üres, ha nincs változás)",
"First Name": "Keresztnév",
"Birth Year": "Születési év",
"Weight": "Tömeg",
diff --git a/lib/bloc/account/account_bloc.dart b/lib/bloc/account/account_bloc.dart
new file mode 100644
index 0000000..e637e96
--- /dev/null
+++ b/lib/bloc/account/account_bloc.dart
@@ -0,0 +1,46 @@
+import 'dart:async';
+
+import 'package:aitrainer_app/model/auth.dart';
+import 'package:aitrainer_app/model/customer.dart';
+import 'package:aitrainer_app/repository/customer_repository.dart';
+import 'package:bloc/bloc.dart';
+import 'package:equatable/equatable.dart';
+import 'package:meta/meta.dart';
+
+part 'account_event.dart';
+part 'account_state.dart';
+
+class AccountBloc extends Bloc {
+ final CustomerRepository customerRepository;
+ bool loggedIn = false;
+ AccountBloc({this.customerRepository}) : super(AccountInitial()) {
+ if ( Auth().userLoggedIn != null ) {
+ customerRepository.customer = Auth().userLoggedIn;
+ loggedIn = true;
+ }
+ }
+
+ @override
+ Stream mapEventToState(
+ AccountEvent event,
+ ) async* {
+ try {
+ if (event is AccountChangeCustomer) {
+ // route to Customer Change page
+ yield AccountReady();
+ } else if (event is AccountLogin) {
+ //route to Login Page
+ } else if (event is AccountLogInFinished) {
+ customerRepository.customer = event.customer;
+ yield AccountLoggedIn();
+ } else if (event is AccountLogout) {
+ await Auth().logout();
+ customerRepository.customer = null;
+ loggedIn = false;
+ yield AccountLoggedOut();
+ }
+ } on Exception catch(e) {
+ yield AccountError(message: e.toString());
+ }
+ }
+}
diff --git a/lib/bloc/account/account_event.dart b/lib/bloc/account/account_event.dart
new file mode 100644
index 0000000..a433b05
--- /dev/null
+++ b/lib/bloc/account/account_event.dart
@@ -0,0 +1,46 @@
+part of 'account_bloc.dart';
+
+@immutable
+abstract class AccountEvent extends Equatable {
+ const AccountEvent();
+
+ @override
+ List get props => [];
+}
+
+class AccountChangeCustomer extends AccountEvent {
+ final Customer customer;
+
+ const AccountChangeCustomer({this.customer});
+
+ @override
+ List get props => [customer];
+}
+
+class AccountLogout extends AccountEvent {
+ final Customer customer;
+
+ const AccountLogout({this.customer});
+
+ @override
+ List get props => [customer];
+
+}
+
+class AccountLogin extends AccountEvent {
+ final Customer customer;
+
+ const AccountLogin({this.customer});
+
+ @override
+ List get props => [customer];
+}
+
+class AccountLogInFinished extends AccountEvent {
+ final Customer customer;
+
+ const AccountLogInFinished({this.customer});
+
+ @override
+ List get props => [customer];
+}
\ No newline at end of file
diff --git a/lib/bloc/account/account_state.dart b/lib/bloc/account/account_state.dart
new file mode 100644
index 0000000..8fa858d
--- /dev/null
+++ b/lib/bloc/account/account_state.dart
@@ -0,0 +1,36 @@
+part of 'account_bloc.dart';
+
+@immutable
+abstract class AccountState extends Equatable {
+ const AccountState();
+ @override
+ List get props => [];
+}
+
+class AccountInitial extends AccountState {
+ const AccountInitial();
+}
+
+class AccountLoading extends AccountState {
+ const AccountLoading();
+}
+
+class AccountReady extends AccountState {
+ const AccountReady();
+}
+
+class AccountLoggedOut extends AccountState {
+ const AccountLoggedOut();
+}
+
+class AccountLoggedIn extends AccountState {
+ const AccountLoggedIn();
+}
+
+class AccountError extends AccountState {
+ final String message;
+ const AccountError({this.message});
+
+ @override
+ List get props => [message];
+}
diff --git a/lib/bloc/custom_exercise_form_bloc.dart b/lib/bloc/custom_exercise_form_bloc.dart
new file mode 100644
index 0000000..4f7675a
--- /dev/null
+++ b/lib/bloc/custom_exercise_form_bloc.dart
@@ -0,0 +1,127 @@
+import 'dart:math';
+
+import 'package:aitrainer_app/repository/exercise_repository.dart';
+import 'package:flutter_form_bloc/flutter_form_bloc.dart';
+
+class CustomExerciseFormBloc extends FormBloc {
+ final ExerciseRepository exerciseRepository;
+ final quantityField = TextFieldBloc(
+ validators: [
+ FieldBlocValidators.required,
+ ],
+ );
+
+ final unitQuantityField = TextFieldBloc(
+ validators: [
+ FieldBlocValidators.required,
+ ],
+ );
+
+ //1RM calculated Fields
+ final rmWendlerField = TextFieldBloc( initialValue: "0",);
+ final rmMcGothlinField = TextFieldBloc( initialValue: "0");
+ final rmLombardiField = TextFieldBloc( initialValue: "0");
+ final rmMayhewField = TextFieldBloc( initialValue: "0");
+ final rmOconnerField = TextFieldBloc( initialValue: "0");
+ final rmWathenField = TextFieldBloc( initialValue: "0");
+ final rmAverageField = TextFieldBloc( initialValue: "0");
+ final rm90Field = TextFieldBloc( initialValue: "0");
+ final rm80Field = TextFieldBloc( initialValue: "0");
+ final rm70Field = TextFieldBloc( initialValue: "0");
+ final rm60Field = TextFieldBloc( initialValue: "0");
+ final rm50Field = TextFieldBloc( initialValue: "0");
+
+ CustomExerciseFormBloc({this.exerciseRepository}) {
+ addFieldBlocs(fieldBlocs: [
+ quantityField,
+ unitQuantityField,
+ rmWendlerField,
+ rmMcGothlinField,
+ rmLombardiField,
+ rmMayhewField,
+ rmOconnerField,
+ rmWathenField,
+ rmAverageField,
+ rm90Field,
+ rm80Field,
+ rm70Field,
+ rm60Field,
+ rm50Field
+ ]);
+
+ quantityField.onValueChanges(onData: (previous, current) async* {
+ exerciseRepository.setQuantity(current.valueToDouble);
+ calculate1RM();
+ });
+
+ unitQuantityField.onValueChanges(onData: (previous, current) async* {
+ exerciseRepository.setUnitQuantity(current.valueToDouble);
+ calculate1RM();
+ });
+ }
+
+ @override
+ void onSubmitting() async {
+ print("on Submitting Custom form");
+ try {
+ emitLoading(progress: 30);
+ // Emit either Loaded or Error
+
+ emitSuccess(canSubmitAgain: false);
+ } on Exception catch (ex) {
+ emitFailure(failureResponse: ex.toString());
+ }
+ }
+
+ void calculate1RM() {
+ double weight = exerciseRepository.exercise.unitQuantity;
+ double repeat = exerciseRepository.exercise.quantity;
+ if ( weight == 0 || repeat == 0) {
+ return;
+ }
+ print("Calculating 1RM");
+ exerciseRepository.rmWendler = weight * repeat * 0.0333 + weight;
+ rmWendlerField.updateValue(exerciseRepository.rmWendler.toString());
+ exerciseRepository.rmMcglothlin = 100 * weight / (101.3 - 2.67123 * repeat);
+ rmMcGothlinField.updateValue(exerciseRepository.rmMcglothlin.toString());
+ exerciseRepository.rmLombardi = pow(weight * repeat, 0.1);
+ rmLombardiField.updateValue(exerciseRepository.rmLombardi.toString());
+ exerciseRepository.rmOconner = weight * (1 + repeat / 40);
+ rmOconnerField.updateValue(exerciseRepository.rmOconner.toString());
+ exerciseRepository.rmMayhew =
+ 100 * weight / (52.2 + 41.9 * pow(e, -0.055 * repeat));
+ rmMayhewField.updateValue(exerciseRepository.rmMayhew.toString());
+ exerciseRepository.rmWathen =
+ 100 * weight / (48.8 + 53.8 * pow(e, -0.075 * repeat));
+ rmWathenField.updateValue(exerciseRepository.rmWathen.toString());
+ double average = (exerciseRepository.rmWendler + exerciseRepository.rmWathen +
+ exerciseRepository.rmMayhew + exerciseRepository.rmOconner +
+ exerciseRepository.rmMcglothlin)/5;
+ rmAverageField.updateValue(average.toString());
+ rm90Field.updateValue((average*0.9).toString());
+ rm80Field.updateValue((average*0.8).toString());
+ rm70Field.updateValue((average*0.7).toString());
+ rm60Field.updateValue((average*0.6).toString());
+ rm50Field.updateValue((average*0.5).toString());
+ }
+
+ //@override
+ Future close() {
+ quantityField.close();
+ unitQuantityField.close();
+
+ rmWendlerField.close();
+ rmMcGothlinField.close();
+ rmLombardiField.close();
+ rmMayhewField.close();
+ rmOconnerField.close();
+ rmWathenField.close();
+ rmAverageField.close();
+ rm90Field.close();
+ rm80Field.close();
+ rm70Field.close();
+ rm60Field.close();
+ rm50Field.close();
+ return super.close();
+ }
+}
diff --git a/lib/bloc/customer_change/customer_change_bloc.dart b/lib/bloc/customer_change/customer_change_bloc.dart
new file mode 100644
index 0000000..13516ca
--- /dev/null
+++ b/lib/bloc/customer_change/customer_change_bloc.dart
@@ -0,0 +1,38 @@
+import 'dart:async';
+
+import 'package:aitrainer_app/repository/customer_repository.dart';
+import 'package:bloc/bloc.dart';
+import 'package:equatable/equatable.dart';
+import 'package:meta/meta.dart';
+
+part 'customer_change_event.dart';
+part 'customer_change_state.dart';
+
+class CustomerChangeBloc extends Bloc {
+ final CustomerRepository customerRepository;
+ CustomerChangeBloc({this.customerRepository}) : super(CustomerChangeInitial());
+
+ @override
+ Stream mapEventToState(
+ CustomerChangeEvent event,
+ ) async* {
+ try {
+ if (event is CustomerGoalChange) {
+ customerRepository.setGoal(event.goal);
+ yield CustomerDataChanged();
+ } else if (event is CustomerFitnessChange) {
+ customerRepository.setFitnessLevel(event.fitness);
+ yield CustomerDataChanged();
+ } else if (event is CustomerBodyTypeChange) {
+ customerRepository.setBodyType(event.bodyType);
+ yield CustomerDataChanged();
+ } else if (event is CustomerSave) {
+ yield CustomerSaving();
+ await customerRepository.saveCustomer();
+ yield CustomerSaveSuccess();
+ }
+ } on Exception catch(e) {
+ yield CustomerSaveError(message: e.toString());
+ }
+ }
+}
diff --git a/lib/bloc/customer_change/customer_change_event.dart b/lib/bloc/customer_change/customer_change_event.dart
new file mode 100644
index 0000000..7ae94b0
--- /dev/null
+++ b/lib/bloc/customer_change/customer_change_event.dart
@@ -0,0 +1,36 @@
+part of 'customer_change_bloc.dart';
+
+@immutable
+abstract class CustomerChangeEvent extends Equatable {
+ const CustomerChangeEvent();
+ @override
+ List get props => [];
+}
+
+class CustomerGoalChange extends CustomerChangeEvent {
+ final String goal;
+ const CustomerGoalChange({this.goal});
+
+ @override
+ List get props => [goal];
+}
+
+class CustomerFitnessChange extends CustomerChangeEvent {
+ final String fitness;
+ const CustomerFitnessChange({this.fitness});
+
+ @override
+ List get props => [fitness];
+}
+
+class CustomerBodyTypeChange extends CustomerChangeEvent {
+ final String bodyType;
+ const CustomerBodyTypeChange({this.bodyType});
+
+ @override
+ List get props => [bodyType];
+}
+
+class CustomerSave extends CustomerChangeEvent {
+ const CustomerSave();
+}
diff --git a/lib/bloc/customer_change/customer_change_state.dart b/lib/bloc/customer_change/customer_change_state.dart
new file mode 100644
index 0000000..5506468
--- /dev/null
+++ b/lib/bloc/customer_change/customer_change_state.dart
@@ -0,0 +1,32 @@
+part of 'customer_change_bloc.dart';
+
+@immutable
+abstract class CustomerChangeState extends Equatable {
+ const CustomerChangeState();
+ @override
+ List get props => [];
+}
+
+class CustomerChangeInitial extends CustomerChangeState {
+ const CustomerChangeInitial();
+}
+
+class CustomerSaving extends CustomerChangeState {
+ const CustomerSaving();
+}
+
+class CustomerDataChanged extends CustomerChangeState {
+ const CustomerDataChanged();
+}
+
+class CustomerSaveSuccess extends CustomerChangeState {
+ const CustomerSaveSuccess();
+}
+
+class CustomerSaveError extends CustomerChangeState {
+ final String message;
+ const CustomerSaveError({this.message});
+
+ @override
+ List get props => [message];
+}
diff --git a/lib/bloc/customer_change_form_bloc.dart b/lib/bloc/customer_change_form_bloc.dart
new file mode 100644
index 0000000..0ccac4b
--- /dev/null
+++ b/lib/bloc/customer_change_form_bloc.dart
@@ -0,0 +1,101 @@
+import 'package:aitrainer_app/repository/customer_repository.dart';
+import 'package:flutter_form_bloc/flutter_form_bloc.dart';
+
+class CustomerChangeFormBloc extends FormBloc {
+ final CustomerRepository customerRepository;
+
+ final emailField = TextFieldBloc(
+ validators: [
+ FieldBlocValidators.required,
+ ],
+ );
+
+ final firstNameField = TextFieldBloc(
+ validators: [
+ FieldBlocValidators.required,
+ ],
+ );
+
+ final nameField = TextFieldBloc();
+ final passwordField = TextFieldBloc(
+ validators: [
+ //FieldBlocValidators.confirmPassword(passwordField),
+ ],
+ );
+ final birthYearField = TextFieldBloc();
+ final weightField = TextFieldBloc();
+ final genderField = SelectFieldBloc();
+
+ final goalField = TextFieldBloc();
+
+ CustomerChangeFormBloc({this.customerRepository}) {
+ addFieldBlocs(fieldBlocs: [
+ emailField,
+ firstNameField,
+ nameField,
+ passwordField,
+ birthYearField,
+ weightField,
+ genderField,
+
+ goalField,
+ ]);
+
+ emailField.updateInitialValue(customerRepository.customer.email);
+ firstNameField.updateInitialValue(customerRepository.customer.firstname);
+ nameField.updateInitialValue(customerRepository.customer.name);
+ birthYearField.updateInitialValue(customerRepository.customer.birthYear.toString());
+ weightField.updateInitialValue(customerRepository.customer.weight.toString());
+ genderField.updateInitialValue(customerRepository.getGenderByDBValue(customerRepository.sex));
+
+ firstNameField.onValueChanges(onData: (previous, current) async* {
+ customerRepository.setFirstName(current.value);
+ });
+ nameField.onValueChanges(onData: (previous, current) async* {
+ customerRepository.setName(current.value);
+ });
+ birthYearField.onValueChanges(onData: (previous, current) async* {
+ customerRepository.setBirthYear(current.valueToInt);
+ });
+ weightField.onValueChanges(onData: (previous, current) async* {
+ customerRepository.setWeight(current.valueToInt);
+ });
+
+ customerRepository.genders.forEach((element) {
+ genderField.addItem(element.name);
+ });
+
+ genderField.onValueChanges(onData: (previous, current) async* {
+ String dbValue = customerRepository.getGenderByName(current.value);
+ customerRepository.setSex(dbValue);
+ });
+
+
+ }
+
+ @override
+ void onSubmitting() async {
+ print("on Submitting Custom form");
+ try {
+ emitLoading(progress: 30);
+ // Emit either Loaded or Error
+ await customerRepository.saveCustomer();
+ emitSuccess(canSubmitAgain: false);
+ } on Exception catch (ex) {
+ emitFailure(failureResponse: ex.toString());
+ }
+ }
+
+ @override
+ Future close() {
+ emailField.close();
+ firstNameField.close();
+ nameField.close();
+ passwordField.close();
+ birthYearField.close();
+ weightField.close();
+ genderField.close();
+ return super.close();
+ }
+
+}
\ No newline at end of file
diff --git a/lib/bloc/exercise_form_bloc.dart b/lib/bloc/exercise_form_bloc.dart
new file mode 100644
index 0000000..ebb6a3b
--- /dev/null
+++ b/lib/bloc/exercise_form_bloc.dart
@@ -0,0 +1,64 @@
+import 'package:aitrainer_app/repository/exercise_repository.dart';
+import 'package:flutter_form_bloc/flutter_form_bloc.dart';
+
+class ExerciseFormBloc extends FormBloc {
+ final ExerciseRepository exerciseRepository;
+
+ final quantityField = TextFieldBloc(
+ validators: [
+ FieldBlocValidators.required,
+ ],
+ );
+
+ final unitField = TextFieldBloc(
+ validators: [
+ FieldBlocValidators.required,
+ ],
+ );
+
+ final unitQuantityField = TextFieldBloc();
+ final unitQuantityUnitField = TextFieldBloc();
+
+ ExerciseFormBloc({this.exerciseRepository}) {
+ addFieldBlocs(fieldBlocs: [
+ quantityField,
+ unitField,
+ unitQuantityField,
+ unitQuantityUnitField
+ ]);
+
+ quantityField.onValueChanges(onData: (previous, current) async* {
+ exerciseRepository.setQuantity(current.valueToDouble);
+ });
+
+ unitField.onValueChanges(onData: (previous, current) async* {
+ exerciseRepository.setUnit(current.value);
+ });
+
+ unitQuantityField.onValueChanges(onData: (previous, current) async* {
+ exerciseRepository.setUnitQuantity(current.valueToDouble);
+ });
+ }
+
+ @override
+ void onSubmitting() async {
+ try {
+ emitLoading(progress: 30);
+ // Emit either Loaded or Error
+ await exerciseRepository.addExercise();
+ emitSuccess(canSubmitAgain: false);
+
+ } on Exception catch (ex) {
+ emitFailure(failureResponse: ex.toString());
+
+ }
+ }
+
+ @override
+ Future close() {
+ unitQuantityField.close();
+ unitQuantityUnitField.close();
+ return super.close();
+ }
+
+}
\ No newline at end of file
diff --git a/lib/bloc/login_form_bloc.dart b/lib/bloc/login_form_bloc.dart
new file mode 100644
index 0000000..7a720ec
--- /dev/null
+++ b/lib/bloc/login_form_bloc.dart
@@ -0,0 +1,61 @@
+import 'package:aitrainer_app/bloc/account/account_bloc.dart';
+import 'package:aitrainer_app/model/auth.dart';
+import 'package:aitrainer_app/repository/user_repository.dart';
+import 'package:aitrainer_app/util/common.dart';
+import 'package:flutter_form_bloc/flutter_form_bloc.dart';
+
+class LoginFormBloc extends FormBloc {
+ final AccountBloc accountBloc;
+ final UserRepository userRepository;
+
+ final emailField = TextFieldBloc(
+ validators: [
+ FieldBlocValidators.required,
+ ],
+ );
+ final passwordField = TextFieldBloc(
+ validators: [
+ FieldBlocValidators.required,
+ ]
+ );
+
+
+ LoginFormBloc({this.userRepository, this.accountBloc}) {
+ addFieldBlocs(fieldBlocs: [
+ emailField,
+ passwordField
+ ]);
+
+ emailField.onValueChanges(onData: (previous, current) async* {
+ userRepository.setEmail(current.value);
+ });
+
+ passwordField.onValueChanges(onData: (previous, current) async* {
+ userRepository.setPassword(current.value);
+ });
+
+ }
+
+ @override
+ void onSubmitting() async {
+ try {
+ emitLoading(progress: 30);
+ if ( ! Common.validateEmail(userRepository)) {
+ emailField.addFieldError(Common.EMAIL_ERROR, isPermanent: true);
+
+ emitFailure(failureResponse: Common.EMAIL_ERROR);
+ } else if ( ! Common.validatePassword(userRepository)) {
+ passwordField.addFieldError(Common.PASSWORD_ERROR, isPermanent: true);
+ emitFailure(failureResponse: Common.PASSWORD_ERROR);
+ } else {
+ // Emit either Loaded or Error
+ await userRepository.getUser();
+ emitSuccess(canSubmitAgain: false);
+ accountBloc.add(AccountLogInFinished(customer: Auth().userLoggedIn));
+ }
+ } on Exception catch (ex) {
+ emitFailure(failureResponse: ex.toString());
+
+ }
+ }
+}
diff --git a/lib/bloc/menu/menu_bloc.dart b/lib/bloc/menu/menu_bloc.dart
new file mode 100644
index 0000000..630799a
--- /dev/null
+++ b/lib/bloc/menu/menu_bloc.dart
@@ -0,0 +1,51 @@
+import 'dart:async';
+
+import 'package:aitrainer_app/model/workout_tree.dart';
+import 'package:aitrainer_app/repository/menu_tree_repository.dart';
+import 'package:bloc/bloc.dart';
+import 'package:equatable/equatable.dart';
+import 'package:meta/meta.dart';
+
+part 'menu_event.dart';
+part 'menu_state.dart';
+
+class MenuBloc extends Bloc {
+ final MenuTreeRepository menuTreeRepository;
+ int parent;
+
+ MenuBloc({this.menuTreeRepository}) : super(MenuInitial()) {
+ parent = 0;
+ }
+
+ @override
+ Stream mapEventToState(
+ MenuEvent event,
+ ) async* {
+ try {
+ if ( event is MenuCreate ) {
+ yield MenuLoading();
+ await menuTreeRepository.createTree();
+ yield MenuReady();
+ } else if (event is MenuTreeDown) {
+ // get child menus or exercises
+ yield MenuLoading();
+ parent = event.parent;
+ menuTreeRepository.getBranch(event.parent);
+ yield MenuReady();
+ } else if (event is MenuTreeUp) {
+ yield MenuLoading();
+ // get parent menus or exercises
+ parent = event.parent;
+ menuTreeRepository.getBranch(parent);
+
+ yield MenuReady();
+ } else if (event is MenuClickExercise) {
+ yield MenuLoading();
+ // get exercise page
+ yield MenuReady();
+ }
+ } on Exception catch(ex) {
+ yield MenuError(message: ex.toString());
+ }
+ }
+}
diff --git a/lib/bloc/menu/menu_event.dart b/lib/bloc/menu/menu_event.dart
new file mode 100644
index 0000000..ac87f26
--- /dev/null
+++ b/lib/bloc/menu/menu_event.dart
@@ -0,0 +1,41 @@
+part of 'menu_bloc.dart';
+
+@immutable
+abstract class MenuEvent extends Equatable {
+ const MenuEvent();
+
+ @override
+ List get props => [];
+}
+
+class MenuCreate extends MenuEvent {
+ const MenuCreate();
+
+ @override
+ List get props => [];
+}
+
+class MenuTreeDown extends MenuEvent {
+ final int parent;
+ const MenuTreeDown({this.parent});
+
+ @override
+ List get props => [parent];
+}
+
+class MenuTreeUp extends MenuEvent {
+ final int parent;
+ const MenuTreeUp({this.parent});
+
+ @override
+ List get props => [parent];
+}
+
+class MenuClickExercise extends MenuEvent {
+ final int exerciseTypeId;
+ const MenuClickExercise({this.exerciseTypeId});
+
+ @override
+ List get props => [exerciseTypeId];
+}
+
diff --git a/lib/bloc/menu/menu_state.dart b/lib/bloc/menu/menu_state.dart
new file mode 100644
index 0000000..8408f41
--- /dev/null
+++ b/lib/bloc/menu/menu_state.dart
@@ -0,0 +1,34 @@
+part of 'menu_bloc.dart';
+
+@immutable
+abstract class MenuState extends Equatable {
+ const MenuState();
+
+ @override
+ List get props => [];
+}
+
+class MenuInitial extends MenuState {
+ const MenuInitial();
+}
+
+class MenuLoading extends MenuState {
+
+}
+
+class MenuReady extends MenuState {
+ final WorkoutTree workoutTree;
+
+ const MenuReady({this.workoutTree});
+
+ @override
+ List get props => [workoutTree];
+}
+
+class MenuError extends MenuState {
+ final String message;
+ const MenuError({this.message});
+
+ @override
+ List get props => [message];
+}
diff --git a/lib/bloc/registration_form_bloc.dart b/lib/bloc/registration_form_bloc.dart
new file mode 100644
index 0000000..79c407f
--- /dev/null
+++ b/lib/bloc/registration_form_bloc.dart
@@ -0,0 +1,61 @@
+import 'package:aitrainer_app/model/auth.dart';
+import 'package:aitrainer_app/repository/user_repository.dart';
+import 'package:aitrainer_app/util/common.dart';
+import 'package:flutter_form_bloc/flutter_form_bloc.dart';
+import 'account/account_bloc.dart';
+
+class RegistrationFormBloc extends FormBloc {
+ final AccountBloc accountBloc;
+ final emailField = TextFieldBloc(
+ validators: [
+ FieldBlocValidators.required,
+ ],
+ );
+ final passwordField = TextFieldBloc(
+ validators: [
+ FieldBlocValidators.required,
+ ]
+ );
+ final UserRepository userRepository;
+
+ RegistrationFormBloc({this.userRepository, this.accountBloc}) {
+ addFieldBlocs(fieldBlocs: [
+ emailField,
+ passwordField
+ ]);
+
+ emailField.onValueChanges(onData: (previous, current) async* {
+ userRepository.setEmail(current.value);
+ });
+
+ passwordField.onValueChanges(onData: (previous, current) async* {
+ userRepository.setPassword(current.value);
+ });
+
+ }
+
+ @override
+ void onSubmitting() async {
+ try {
+ emitLoading(progress: 30);
+ if ( ! Common.validateEmail(userRepository)) {
+ emailField.addFieldError(Common.EMAIL_ERROR, isPermanent: true);
+
+ emitFailure(failureResponse: Common.EMAIL_ERROR);
+ } else if ( ! Common.validatePassword(userRepository)) {
+ passwordField.addFieldError(Common.PASSWORD_ERROR, isPermanent: true);
+ emitFailure(failureResponse: Common.PASSWORD_ERROR);
+ } else {
+ // Emit either Loaded or Error
+ await userRepository.addUser();
+ emitSuccess(canSubmitAgain: false);
+ accountBloc.add(AccountLogInFinished(customer: Auth().userLoggedIn));
+ }
+ } on Exception catch (ex) {
+ emitFailure(failureResponse: ex.toString());
+
+ }
+ }
+
+
+}
\ No newline at end of file
diff --git a/lib/bloc/session/session_bloc.dart b/lib/bloc/session/session_bloc.dart
new file mode 100644
index 0000000..e7136d3
--- /dev/null
+++ b/lib/bloc/session/session_bloc.dart
@@ -0,0 +1,35 @@
+import 'dart:async';
+
+import 'package:aitrainer_app/util/session.dart';
+import 'package:bloc/bloc.dart';
+import 'package:equatable/equatable.dart';
+import 'package:meta/meta.dart';
+
+part 'session_event.dart';
+part 'session_state.dart';
+
+class SessionBloc extends Bloc {
+ final Session session;
+ SessionBloc({this.session}) : super(SessionInitial());
+
+ @override
+ Stream mapEventToState(
+ SessionEvent event,
+ ) async* {
+ try {
+ if (event is SessionStart) {
+ yield SessionLoading();
+ await session.fetchSessionAndNavigate();
+ yield SessionReady();
+ }
+ } on Exception catch(ex) {
+ yield SessionFailure(message: ex.toString());
+ }
+
+ }
+
+ @override
+ Future close() async {
+ await this.close(); super.close();
+ }
+}
diff --git a/lib/bloc/session/session_event.dart b/lib/bloc/session/session_event.dart
new file mode 100644
index 0000000..04f34a2
--- /dev/null
+++ b/lib/bloc/session/session_event.dart
@@ -0,0 +1,16 @@
+part of 'session_bloc.dart';
+
+@immutable
+abstract class SessionEvent extends Equatable {
+ const SessionEvent();
+
+ @override
+ List get props => [];
+}
+
+class SessionStart extends SessionEvent {
+ const SessionStart();
+
+ @override
+ List get props => [];
+}
diff --git a/lib/bloc/session/session_state.dart b/lib/bloc/session/session_state.dart
new file mode 100644
index 0000000..82822c9
--- /dev/null
+++ b/lib/bloc/session/session_state.dart
@@ -0,0 +1,32 @@
+part of 'session_bloc.dart';
+
+@immutable
+abstract class SessionState extends Equatable {
+ const SessionState();
+
+ @override
+ List get props => [];
+}
+
+class SessionInitial extends SessionState {
+ const SessionInitial();
+}
+
+class SessionLoading extends SessionState {
+ const SessionLoading();
+}
+
+class SessionReady extends SessionState {
+ const SessionReady();
+}
+
+class SessionFailure extends SessionState {
+ final String message;
+ const SessionFailure({this.message});
+
+ @override
+ List get props => [message];
+
+}
+
+
diff --git a/lib/bloc/settings/settings_bloc.dart b/lib/bloc/settings/settings_bloc.dart
new file mode 100644
index 0000000..f6d64c6
--- /dev/null
+++ b/lib/bloc/settings/settings_bloc.dart
@@ -0,0 +1,55 @@
+import 'dart:async';
+
+import 'package:aitrainer_app/localization/app_language.dart';
+import 'package:aitrainer_app/localization/app_localization.dart';
+import 'package:bloc/bloc.dart';
+import 'package:equatable/equatable.dart';
+import 'package:flutter/cupertino.dart';
+import 'package:meta/meta.dart';
+
+part 'settings_event.dart';
+part 'settings_state.dart';
+
+class SettingsBloc extends Bloc {
+ String language;
+ Locale _locale;
+ BuildContext context;
+
+ SettingsBloc({this.context}) : super(SettingsInitial());
+
+ @override
+ Stream mapEventToState(
+ SettingsEvent event,
+ ) async* {
+ if (event is SettingsChangeLanguage) {
+ yield SettingsLoading();
+ await _changeLang( event.language);
+ yield SettingsReady(_locale);
+ }
+ }
+
+ Future _changeLang( String lang ) async{
+
+ switch ( lang ) {
+ case "English":
+ case "Angol":
+ _locale = Locale('en');
+ break;
+ case "Hungarian":
+ case "Magyar":
+ _locale = Locale('hu');
+ break;
+ }
+ this.language = lang;
+ await loadLang();
+ }
+
+ Future loadLang() async{
+ final AppLanguage appLanguage = AppLanguage();
+ appLanguage.changeLanguage(_locale);
+ if ( context != null ) {
+ AppLocalizations.of(context).setLocale(_locale);
+ await AppLocalizations.of(context).load();
+ }
+ }
+}
diff --git a/lib/bloc/settings/settings_event.dart b/lib/bloc/settings/settings_event.dart
new file mode 100644
index 0000000..31a8279
--- /dev/null
+++ b/lib/bloc/settings/settings_event.dart
@@ -0,0 +1,13 @@
+part of 'settings_bloc.dart';
+
+@immutable
+abstract class SettingsEvent extends Equatable {
+ const SettingsEvent();
+ @override
+ List get props => [];
+}
+
+class SettingsChangeLanguage extends SettingsEvent {
+ final String language;
+ const SettingsChangeLanguage({this.language});
+}
diff --git a/lib/bloc/settings/settings_state.dart b/lib/bloc/settings/settings_state.dart
new file mode 100644
index 0000000..6935d0f
--- /dev/null
+++ b/lib/bloc/settings/settings_state.dart
@@ -0,0 +1,46 @@
+part of 'settings_bloc.dart';
+
+@immutable
+abstract class SettingsState extends Equatable {
+ const SettingsState();
+
+ @override
+ List get props => [];
+}
+
+// ignore: must_be_immutable
+class SettingsInitial extends SettingsState {
+ Locale locale;
+ SettingsInitial();
+
+ setLocale(locale) {
+ this.locale = locale;
+ }
+
+ @override
+ List get props => [locale];
+}
+
+class SettingsLoading extends SettingsState {
+ final Locale locale;
+ const SettingsLoading({this.locale});
+
+ @override
+ List get props => [locale];
+}
+
+class SettingsReady extends SettingsState {
+ final Locale locale;
+ const SettingsReady(this.locale);
+
+ @override
+ List get props => [locale];
+}
+
+class SettingsError extends SettingsState {
+ final String message;
+ const SettingsError(this.message);
+
+ @override
+ List get props => [message];
+}
\ No newline at end of file
diff --git a/lib/library_keys.dart b/lib/library_keys.dart
new file mode 100644
index 0000000..528b334
--- /dev/null
+++ b/lib/library_keys.dart
@@ -0,0 +1,9 @@
+import 'package:flutter/widgets.dart';
+
+class LibraryKeys {
+
+ // Login
+ static final loginEmailField = const Key('__loginEmailField__');
+ static final loginPasswordField = const Key('__loginPasswordField__');
+ static final loginOKButton = const Key('__loginOKButton__');
+}
\ No newline at end of file
diff --git a/lib/localization/app_localization.dart b/lib/localization/app_localization.dart
index afc6a58..181ba08 100644
--- a/lib/localization/app_localization.dart
+++ b/lib/localization/app_localization.dart
@@ -6,8 +6,9 @@ import 'package:flutter/services.dart';
class AppLocalizations {
Locale locale;
+ bool isTest;
- AppLocalizations(this.locale);
+ AppLocalizations(this.locale, {this.isTest = false});
// Helper method to keep the code in the widgets concise
// Localizations are accessed using an InheritedWidget "of" syntax
@@ -17,7 +18,7 @@ class AppLocalizations {
// Static member to have a simple access to the delegate from the MaterialApp
static const LocalizationsDelegate delegate =
- _AppLocalizationsDelegate();
+ AppLocalizationsDelegate();
Map _localizedStrings;
@@ -38,18 +39,24 @@ class AppLocalizations {
return true;
}
+ Future loadTest(Locale locale) async {
+ return AppLocalizations(locale);
+ }
+
// This method will be called from every widget which needs a localized text
String translate(String key) {
+ if (isTest) return key;
return _localizedStrings[key];
}
}
-class _AppLocalizationsDelegate
+class AppLocalizationsDelegate
extends LocalizationsDelegate {
+ final bool isTest;
// This delegate instance will never change (it doesn't even have fields!)
// It can provide a constant constructor.
- const _AppLocalizationsDelegate();
+ const AppLocalizationsDelegate({this.isTest = false});
@override
bool isSupported(Locale locale) {
@@ -60,11 +67,16 @@ class _AppLocalizationsDelegate
@override
Future load(Locale locale) async {
// AppLocalizations class is where the JSON loading actually runs
- AppLocalizations localizations = new AppLocalizations(locale);
- await localizations.load();
+ AppLocalizations localizations = new AppLocalizations(locale, isTest: this.isTest);
+ if (isTest) {
+ await localizations.loadTest(locale);
+ } else {
+ await localizations.load();
+ }
return localizations;
}
+
@override
- bool shouldReload(_AppLocalizationsDelegate old) => false;
+ bool shouldReload(AppLocalizationsDelegate old) => false;
}
\ No newline at end of file
diff --git a/lib/main.dart b/lib/main.dart
index f21b3ae..bb8f67a 100644
--- a/lib/main.dart
+++ b/lib/main.dart
@@ -1,33 +1,33 @@
import 'dart:async';
+import 'package:aitrainer_app/repository/customer_repository.dart';
+import 'package:aitrainer_app/repository/menu_tree_repository.dart';
+import 'package:aitrainer_app/util/session.dart';
import 'package:aitrainer_app/view/account.dart';
+import 'package:aitrainer_app/view/custom_exercise_page.dart';
import 'package:aitrainer_app/view/customer_bodytype_page.dart';
import 'package:aitrainer_app/view/customer_fitness_page.dart';
import 'package:aitrainer_app/view/customer_goal_page.dart';
import 'package:aitrainer_app/view/customer_modify_page.dart';
-import 'package:aitrainer_app/view/customer_new_page.dart';
import 'package:aitrainer_app/view/customer_welcome_page.dart';
import 'package:aitrainer_app/view/gdpr.dart';
import 'package:aitrainer_app/view/login.dart';
import 'package:aitrainer_app/view/exercise_new_page.dart';
-import 'package:aitrainer_app/view/exercise_type_modify_page.dart';
-import 'package:aitrainer_app/view/exercise_type_new_page.dart';
import 'package:aitrainer_app/view/menu_page.dart';
import 'package:aitrainer_app/view/registration.dart';
import 'package:aitrainer_app/view/settings.dart';
-import 'package:aitrainer_app/viewmodel/customer_changing_view_model.dart';
-import 'package:aitrainer_app/viewmodel/exercise_changing_view_model.dart';
import 'package:aitrainer_app/widgets/home.dart';
-import 'package:aitrainer_app/widgets/loading.dart';
import 'package:flutter/material.dart';
-import 'package:aitrainer_app/view/customer_list_page.dart';
-import 'package:aitrainer_app/view/exercise_type_list_page.dart';
import 'package:flutter/services.dart';
import 'package:flutter/widgets.dart';
-import 'package:provider/provider.dart';
+import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:aitrainer_app/localization/app_localization.dart';
import 'package:sentry/sentry.dart';
+import 'bloc/account/account_bloc.dart';
+import 'bloc/menu/menu_bloc.dart';
+import 'bloc/session/session_bloc.dart';
+import 'bloc/settings/settings_bloc.dart';
final SentryClient _sentry = new SentryClient(dsn: 'https://5fac40cbfcfb4c15aa80c7a8638d7310@o418565.ingest.sentry.io/5322520');
@@ -95,17 +95,25 @@ Future main() async {
// - https://www.dartlang.org/articles/libraries/zones
runZonedGuarded>(() async {
runApp(
- MultiProvider(
- // Initialize the model in the builder. That way, Provider
- // can own Models's lifecycle, making sure to call `dispose`
- // when not needed anymore.
+ MultiBlocProvider(
providers: [
- ChangeNotifierProvider(create: (context) => ExerciseChangingViewModel(null)),
- ChangeNotifierProvider(create: (context) => CustomerChangingViewModel(null)),
+ BlocProvider(
+ create: (BuildContext context) => SessionBloc(session: Session()),
+ ),
+ BlocProvider(
+ create: (BuildContext context) => MenuBloc( menuTreeRepository: MenuTreeRepository()),
+ ),
+ BlocProvider(
+ create: (BuildContext context) => SettingsBloc(),
+ ),
+ BlocProvider(
+ create: (BuildContext context) => AccountBloc(customerRepository: CustomerRepository()),
+ ),
],
- child: AitrainerApp(),
- ));
+ child: AitrainerApp(),
+ )
+ );
}, (error, stackTrace) async {
await _reportError(error, stackTrace);
});
@@ -147,18 +155,13 @@ class AitrainerApp extends StatelessWidget {
},
routes: {
'home': (context) => AitrainerHome(),
- 'loading': (context) => LoadingScreenMain(),
- 'customersPage': (context) => CustomerListPage(),
- 'customerNewPage': (context) => CustomerNewPage(),
'customerModifyPage': (context) => CustomerModifyPage(),
'customerGoalPage': (context) => CustomerGoalPage(),
'customerFitnessPage': (context) => CustomerFitnessPage(),
'customerBodyTypePage': (context) => CustomerBodyTypePage(),
'customerWelcomePage': (context) => CustomerWelcomePage(),
- 'exerciseTypeListPage': (context) => ExerciseTypeListPage(),
- 'exerciseTypeNewPage': (context) => ExerciseTypeNewPage(),
- 'exerciseTypeModifyPage': (context) => ExerciseTypeModifyPage(),
'exerciseNewPage': (context) => ExerciseNewPage(),
+ 'exerciseCustomPage': (context) => CustomExercisePage(),
'login': (context) => LoginPage(),
'registration': (context) => RegistrationPage(),
'gdpr': (context) => Gdpr(),
@@ -166,7 +169,7 @@ class AitrainerApp extends StatelessWidget {
'account': (context) => AccountPage(),
'settings': (context) => SettingsPage(),
},
- initialRoute: 'loading',
+ initialRoute: 'home',
title: 'Aitrainer',
theme: ThemeData(
brightness: Brightness.light,
@@ -176,7 +179,7 @@ class AitrainerApp extends StatelessWidget {
bodyText1: TextStyle(fontSize: 14.0),
)
),
- home: LoadingScreenMain(),
+ home: AitrainerHome(),
);
}
diff --git a/lib/model/auth.dart b/lib/model/auth.dart
index fb920f1..14862c3 100644
--- a/lib/model/auth.dart
+++ b/lib/model/auth.dart
@@ -1,4 +1,6 @@
import 'package:aitrainer_app/model/customer.dart';
+import 'package:aitrainer_app/model/exercise_tree.dart';
+import 'package:aitrainer_app/service/exercise_tree_service.dart';
import 'package:aitrainer_app/service/exercisetype_service.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:aitrainer_app/model/exercise_type.dart';
@@ -35,7 +37,8 @@ class Auth {
static final String isRegisteredKey = 'is_registered';
static final String isLoggedInKey = 'is_logged_in';
- static final String _baseUrl = 'http://andio.eu:8888/api/';
+ static final String baseUrl = 'http://aitrainer.info:8888/api/';
+ static final String mediaUrl = 'https://aitrainer.info:4343/media/';
static final String username = 'bosi';
static final String password = 'andio2009';
@@ -43,7 +46,9 @@ class Auth {
Customer userLoggedIn;
bool firstLoad = true;
List _exerciseTypes;
+ List _exerciseTree;
List deviceLanguages;
+ String startPage;
factory Auth() {
return _singleton;
@@ -60,7 +65,11 @@ class Auth {
}
static String getBaseUrl() {
- return _baseUrl;
+ return baseUrl;
+ }
+
+ static String getMediaUrl() {
+ return mediaUrl;
}
afterRegistration(Customer customer) {
@@ -70,20 +79,19 @@ class Auth {
setPreferences(prefs, SharePrefsChange.registration, customer.customerId);
}
- afterLogin(Customer customer) {
+ afterLogin(Customer customer) async {
Future prefs = SharedPreferences.getInstance();
userLoggedIn = customer;
- setPreferences(prefs, SharePrefsChange.login, customer.customerId);
+ await setPreferences(prefs, SharePrefsChange.login, customer.customerId);
}
- logout(){
+ logout() async {
userLoggedIn = null;
authToken = "";
//firstLoad = true;
Future prefs = SharedPreferences.getInstance();
- setPreferences(prefs, SharePrefsChange.logout, 0);
-
+ await setPreferences(prefs, SharePrefsChange.logout, 0);
}
setPreferences(Future prefs,
@@ -95,18 +103,21 @@ class Auth {
DateTime now = DateTime.now();
sharedPreferences.setString(Auth.lastStoreDateKey, now.toString());
if ( type == SharePrefsChange.registration ) {
+ Auth().startPage = "home";
sharedPreferences.setInt(Auth.customerIdKey, customerId);
sharedPreferences.setBool(Auth.isRegisteredKey, true);
sharedPreferences.setBool(Auth.isLoggedInKey, true);
- await ExerciseTypeApi().getExerciseTypes("");
+ await ExerciseTypeApi().getExerciseTypes();
+ await ExerciseTreeApi().getExerciseTree();
} else if ( type == SharePrefsChange.login ) {
-
+ Auth().startPage = "home";
sharedPreferences.setInt(Auth.customerIdKey, customerId);
sharedPreferences.setBool(Auth.isLoggedInKey, true);
- await ExerciseTypeApi().getExerciseTypes("");
+ await ExerciseTypeApi().getExerciseTypes();
+ await ExerciseTreeApi().getExerciseTree();
} else if ( type == SharePrefsChange.logout ) {
sharedPreferences.setBool(Auth.isLoggedInKey, false);
- //sharedPreferences.setInt(Auth.customerIdKey, 0);
+ sharedPreferences.setInt(Auth.customerIdKey, 0);
sharedPreferences.setString(authTokenKey, "");
}
}
@@ -115,7 +126,15 @@ class Auth {
this._exerciseTypes = exerciseTypes;
}
+ void setExerciseTree( List exerciseTree) {
+ this._exerciseTree = exerciseTree;
+ }
+
List getExerciseTypes() {
return this._exerciseTypes;
}
+
+ List getExerciseTree() {
+ return this._exerciseTree;
+ }
}
\ No newline at end of file
diff --git a/lib/model/exercise_tree.dart b/lib/model/exercise_tree.dart
new file mode 100644
index 0000000..417190e
--- /dev/null
+++ b/lib/model/exercise_tree.dart
@@ -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;
+ }
+}
diff --git a/lib/model/exercise_type.dart b/lib/model/exercise_type.dart
index 3f11e0b..4301a58 100644
--- a/lib/model/exercise_type.dart
+++ b/lib/model/exercise_type.dart
@@ -2,22 +2,32 @@ import 'package:flutter/services.dart';
class ExerciseType {
int exerciseTypeId;
+ int treeId;
String name;
String description;
BinaryCodec video;
String unit;
String unitQuantity;
String unitQuantityUnit;
+ bool active;
+ String imageUrl;
+ String nameTranslation;
+ String descriptionTranslation;
ExerciseType({this.name, this.description});
ExerciseType.fromJson(Map json) {
this.exerciseTypeId = json['exerciseTypeId'];
+ this.treeId = json['treeId'];
this.name = json['name'];
this.description = json['description'];
this.unit = json['unit'];
this.unitQuantity = json['unitQuantity'];
this.unitQuantityUnit = json['unitQuantityUnit'];
+ this.active = json['active'];
+ this.imageUrl = json['images'][0]['url'];
+ this.nameTranslation = json['translations'][0]['name'];
+ this.descriptionTranslation = json['translations'][0]['description'];
}
Map toJson() =>
@@ -26,6 +36,7 @@ class ExerciseType {
"description": description,
"unit": unit,
"unitQuantity": unitQuantity,
- "unitQuantityUnit": unitQuantityUnit
+ "unitQuantityUnit": unitQuantityUnit,
+ "active": active
};
}
\ No newline at end of file
diff --git a/lib/model/workout_tree.dart b/lib/model/workout_tree.dart
index 48f8253..17b17df 100644
--- a/lib/model/workout_tree.dart
+++ b/lib/model/workout_tree.dart
@@ -1,5 +1,7 @@
import 'dart:ui';
+import 'exercise_type.dart';
+
class WorkoutTree {
int id;
int parent;
@@ -9,7 +11,8 @@ class WorkoutTree {
double fontSize;
bool child;
int exerciseTypeId;
+ ExerciseType exerciseType;
- WorkoutTree(this.id, this.parent, this.name, this.imageName, this.color, this.fontSize, this.child, this.exerciseTypeId);
+ WorkoutTree(this.id, this.parent, this.name, this.imageName, this.color, this.fontSize, this.child, this.exerciseTypeId, this.exerciseType);
}
diff --git a/lib/repository/customer_repository.dart b/lib/repository/customer_repository.dart
new file mode 100644
index 0000000..4226a2c
--- /dev/null
+++ b/lib/repository/customer_repository.dart
@@ -0,0 +1,143 @@
+import 'package:aitrainer_app/model/customer.dart';
+import 'package:aitrainer_app/service/customer_service.dart';
+
+class GenderItem {
+ GenderItem(this.dbValue,this.name);
+ final String dbValue;
+ String name;
+}
+
+class CustomerRepository {
+ Customer customer;
+ //List customerList = List();
+ bool visibleDetails = false;
+ List genders;
+
+ CustomerRepository({this.customer}) {
+ customer = Customer();
+ genders = [
+ GenderItem("m", "Man"),
+ GenderItem("w", "Woman"),
+ ];
+ }
+
+ String getGenderByName(String name) {
+ String dbValue;
+ genders.forEach((element) {
+ if (element.name == name) {
+ dbValue = element.dbValue;
+ }
+ });
+ return dbValue;
+ }
+
+ String getGenderByDBValue(String dbValue) {
+ String name;
+ genders.forEach((element) {
+ if (element.dbValue == dbValue) {
+ name = element.name;
+ }
+ });
+ return name;
+ }
+
+ String get name {
+ return this.customer.name != null ? this.customer.name : "";
+ }
+
+ String get firstName {
+ return this.customer.firstname != null ? this.customer.firstname : "";
+ }
+
+ String get sex {
+ return this.customer.sex == "m" ? "Man" : "Woman";
+ }
+
+ int get birthYear {
+ return this.customer.birthYear;
+ }
+
+ String get goal {
+ return this.customer.goal;
+ }
+
+ String get fitnessLevel {
+ return this.customer.fitnessLevel;
+ }
+
+ String get bodyType {
+ return this.customer.bodyType;
+ }
+
+ setName(String name) {
+ this.customer.name = name;
+ }
+ setFirstName(String firstName) {
+ this.customer.firstname = firstName;
+ }
+
+ setPassword( String password ) {
+ this.customer.password = password;
+ }
+
+ setEmail(String email) {
+ this.customer.email = email;
+ }
+
+
+ setSex(String sex) {
+ this.customer.sex = sex;
+ }
+
+ setWeight( int weight) {
+ this.customer.weight = weight;
+ }
+
+ setBirthYear( int birthYear ) {
+ this.customer.birthYear = birthYear;
+ }
+
+ setFitnessLevel( String level ) {
+ this.customer.fitnessLevel = level;
+ }
+
+ setGoal( String goal ) {
+ this.customer.goal = goal;
+ }
+
+ setBodyType(String bodyType) {
+ this.customer.bodyType = bodyType;
+ }
+
+ createNew() {
+ this.customer = Customer();
+ }
+
+ Customer getCustomer() {
+ return this.customer;
+ }
+
+ void setCustomer ( Customer customer ) {
+ this.customer = customer;
+ }
+
+ Future addCustomer() async {
+ final Customer modelCustomer = customer;
+ await CustomerApi().addCustomer(modelCustomer);
+ }
+
+ Future saveCustomer() async {
+ final Customer modelCustomer = customer;
+ await CustomerApi().saveCustomer(modelCustomer);
+ }
+
+ /* Future> getCustomers() async {
+ final results = await CustomerApi().getRealCustomers("");
+ this.customerList = results.map((item) => CustomerRepository(customer: item)).toList();
+ return this.customerList;
+ }
+
+ addNewCustomerToList(CustomerRepository customerViewModel) {
+ customerList.add(customerViewModel);
+ }*/
+}
diff --git a/lib/repository/exercise_repository.dart b/lib/repository/exercise_repository.dart
new file mode 100644
index 0000000..4bc949c
--- /dev/null
+++ b/lib/repository/exercise_repository.dart
@@ -0,0 +1,88 @@
+import 'package:aitrainer_app/model/customer.dart';
+import 'package:aitrainer_app/model/exercise.dart';
+import 'package:aitrainer_app/model/exercise_type.dart';
+import 'package:aitrainer_app/service/exercise_service.dart';
+
+class ExerciseRepository {
+ Exercise exercise;
+ Customer customer;
+ ExerciseType exerciseType;
+
+ double rmWendler = 0;
+ double rmMcglothlin = 0;
+ double rmLombardi = 0;
+ double rmMayhew = 0;
+ double rmOconner = 0;
+ double rmWathen = 0;
+
+ createNew() {
+ this.exercise = Exercise();
+ exercise.dateAdd = DateTime.now();
+ }
+
+ setQuantity(double quantity) {
+ if ( this.exercise == null ) {
+ this.createNew();
+ }
+ this.exercise.quantity = quantity;
+ }
+
+ setUnitQuantity(double unitQuantity) {
+ if ( this.exercise == null ) {
+ this.createNew();
+ }
+
+ this.exercise.unitQuantity = unitQuantity;
+ }
+
+ setUnit( String unit) {
+ if ( this.exercise == null ) {
+ this.createNew();
+ }
+
+ this.exercise.unit = unit;
+ }
+
+ setDatetimeExercise(DateTime datetimeExercise) {
+ if ( this.exercise == null ) {
+ this.createNew();
+ }
+
+ this.exercise.dateAdd = datetimeExercise;
+ }
+
+ double get unitQuantity {
+ return this.exercise.unitQuantity;
+ }
+
+ double get quantity {
+ return this.exercise.quantity;
+ }
+
+ Exercise getExercise() {
+ return this.exercise;
+ }
+
+ Future addExercise() async {
+ final Exercise modelExercise = this.exercise;
+ modelExercise.customerId = this.customer.customerId;
+ modelExercise.exerciseTypeId = this.exerciseType.exerciseTypeId;
+ await ExerciseApi().addExercise(modelExercise);
+ }
+
+
+ setCustomer(Customer customer) {
+ this.customer = customer;
+ }
+
+ setExerciseType( ExerciseType exerciseType) {
+ this.exerciseType = exerciseType;
+ }
+
+/*
+ Future> getExercisesByCustomer( int customerId ) async {
+ final results = await ExerciseApi().getExercisesByCustomer(customerId);
+ this.exerciseList = results.map((item) => ExerciseRepository(exercise: item)).toList();
+ return this.exerciseList;
+ } */
+}
\ No newline at end of file
diff --git a/lib/repository/menu_tree_repository.dart b/lib/repository/menu_tree_repository.dart
new file mode 100644
index 0000000..860cac8
--- /dev/null
+++ b/lib/repository/menu_tree_repository.dart
@@ -0,0 +1,73 @@
+import 'dart:collection';
+import 'package:aitrainer_app/localization/app_language.dart';
+import 'package:aitrainer_app/model/auth.dart';
+import 'package:aitrainer_app/model/exercise_tree.dart';
+import 'package:aitrainer_app/model/exercise_type.dart';
+import 'package:aitrainer_app/model/workout_tree.dart';
+import 'package:aitrainer_app/service/exercise_tree_service.dart';
+import 'package:aitrainer_app/service/exercisetype_service.dart';
+import 'package:flutter/material.dart';
+
+class MenuTreeRepository {
+ final LinkedHashMap tree = LinkedHashMap();
+
+ Future createTree() async {
+
+ final AppLanguage appLanguage = AppLanguage();
+ bool isEnglish = appLanguage.appLocal == Locale('en');
+
+ List exerciseTree = Auth().getExerciseTree();
+ if ( exerciseTree == null || exerciseTree.length == 0) {
+ await ExerciseTreeApi().getExerciseTree();
+ }
+
+ exerciseTree.forEach( (treeItem) async {
+ String treeName = isEnglish ? treeItem.name : treeItem.nameTranslation;
+ String assetImage = 'asset/menu/' + treeItem.imageUrl.substring(7);
+ this.tree[treeItem.name] = WorkoutTree(
+ treeItem.treeId,
+ treeItem.parentId,
+ treeName,
+ assetImage, Colors.white,
+ 32,
+ false,
+ 0,
+ null
+ );
+ });
+
+ List exerciseTypes = Auth().getExerciseTypes();
+ if ( exerciseTypes == null || exerciseTypes.length == 0) {
+ await ExerciseTypeApi().getExerciseTypes();
+ }
+
+ exerciseTypes.forEach( (exerciseType) {
+ String exerciseTypeName = isEnglish ?
+ exerciseType.name : exerciseType.nameTranslation;
+ String assetImage = 'asset/menu/' + exerciseType.imageUrl.substring(7);
+ this.tree[exerciseType.name] = WorkoutTree(
+ exerciseType.exerciseTypeId,
+ exerciseType.treeId,
+ exerciseTypeName,
+ assetImage,
+ Colors.white,
+ 16,
+ true,
+ exerciseType.exerciseTypeId,
+ exerciseType
+ );
+ });
+ }
+
+
+ LinkedHashMap getBranch(int parent) {
+ LinkedHashMap branch = LinkedHashMap();
+ tree.forEach((key, value) {
+ WorkoutTree workoutTree = value as WorkoutTree;
+ if ( parent == workoutTree.parent) {
+ branch[key] = value;
+ }
+ });
+ return branch;
+ }
+}
\ No newline at end of file
diff --git a/lib/repository/user_repository.dart b/lib/repository/user_repository.dart
new file mode 100644
index 0000000..4a7a94a
--- /dev/null
+++ b/lib/repository/user_repository.dart
@@ -0,0 +1,32 @@
+import 'package:aitrainer_app/model/user.dart';
+import 'package:aitrainer_app/service/customer_service.dart';
+
+class UserRepository {
+ User user;
+
+ UserRepository() {
+ this.createNewUser();
+ }
+
+ setEmail(String email) {
+ this.user.email = email;
+ }
+
+ setPassword(String password) {
+ this.user.password = password;
+ }
+
+ createNewUser() {
+ this.user = User();
+ }
+
+ Future addUser() async {
+ final User modelUser = this.user;
+ await CustomerApi().addUser(modelUser);
+ }
+
+ Future getUser() async {
+ final User modelUser = this.user;
+ await CustomerApi().getUser(modelUser);
+ }
+}
diff --git a/lib/service/customer_service.dart b/lib/service/customer_service.dart
index f0b154c..b8da324 100644
--- a/lib/service/customer_service.dart
+++ b/lib/service/customer_service.dart
@@ -39,8 +39,13 @@ class CustomerApi {
body);
Customer customer;
try {
- customer = Customer.fromJson(jsonDecode(responseBody));
- Auth().afterRegistration(customer);
+ int status = jsonDecode(responseBody)['status'];
+ if ( status != null ) {
+ throw new Exception(jsonDecode(responseBody)['error']);
+ } else {
+ customer = Customer.fromJson(jsonDecode(responseBody));
+ Auth().afterRegistration(customer);
+ }
} on FormatException catch(exception) {
throw new Exception(responseBody);
}
@@ -56,7 +61,7 @@ class CustomerApi {
Customer customer;
try {
customer = Customer.fromJson(jsonDecode(responseBody));
- Auth().afterRegistration(customer);
+ await Auth().afterLogin(customer);
} on FormatException catch(exception) {
throw new Exception(responseBody);
}
@@ -66,10 +71,17 @@ class CustomerApi {
Future getCustomer(int customerId) async {
String body = "";
print(" ===== get the customer by id: " + customerId.toString() );
- final String responseBody = await _client.get(
- "customers/"+customerId.toString(),
- body);
- Customer customer = Customer.fromJson(jsonDecode(responseBody));
- Auth().afterRegistration(customer);
+ try {
+ final String responseBody = await _client.get(
+ "customers/"+customerId.toString(),
+ body);
+ Customer customer = Customer.fromJson(jsonDecode(responseBody));
+ Auth().afterRegistration(customer);
+ } catch (exception) {
+ print ("Exception: " + exception.toString());
+ print (" === go to registration ");
+ Auth().logout();
+ Auth().startPage = "registration";
+ }
}
}
\ No newline at end of file
diff --git a/lib/service/exercise_tree_service.dart b/lib/service/exercise_tree_service.dart
new file mode 100644
index 0000000..943c1b1
--- /dev/null
+++ b/lib/service/exercise_tree_service.dart
@@ -0,0 +1,19 @@
+import 'dart:convert';
+
+import 'package:aitrainer_app/model/auth.dart';
+import 'package:aitrainer_app/model/exercise_tree.dart';
+import 'api.dart';
+
+class ExerciseTreeApi {
+ final APIClient _client = new APIClient();
+
+ Future> getExerciseTree() async {
+ final body = await _client.get("exercise_tree", "");
+ final Iterable json = jsonDecode(body);
+ final List exerciseTree = json.map((exerciseTree) =>
+ ExerciseTree.fromJson(exerciseTree)).toList();
+ Auth().setExerciseTree(exerciseTree);
+ return exerciseTree;
+ }
+
+}
diff --git a/lib/service/exercisetype_service.dart b/lib/service/exercisetype_service.dart
index d7178e4..997839d 100644
--- a/lib/service/exercisetype_service.dart
+++ b/lib/service/exercisetype_service.dart
@@ -7,8 +7,8 @@ import 'package:aitrainer_app/service/api.dart';
class ExerciseTypeApi {
final APIClient _client=new APIClient();
- Future> getExerciseTypes(String param) async {
- final body = await _client.get("exercise_type", param);
+ Future> getExerciseTypes() async {
+ final body = await _client.get("exercise_type/active", "");
final Iterable json = jsonDecode(body);
final List exerciseTypes = json.map( (exerciseType) => ExerciseType.fromJson(exerciseType) ).toList();
Auth().setExerciseTypes(exerciseTypes);
diff --git a/lib/util/common.dart b/lib/util/common.dart
index e1ec8fd..12c664c 100644
--- a/lib/util/common.dart
+++ b/lib/util/common.dart
@@ -3,10 +3,16 @@ import 'dart:convert';
import 'package:aitrainer_app/localization/app_language.dart';
import 'package:aitrainer_app/model/auth.dart';
import 'package:aitrainer_app/model/exercise_type.dart';
+import 'package:aitrainer_app/repository/user_repository.dart';
+import 'package:flutter/cupertino.dart';
import 'package:intl/intl.dart';
class Common {
+ static const EMAIL_ERROR = "Please type a right email address here.";
+ static const PASSWORD_ERROR = "The password must have at least 8 characters.";
+
+
static String toJson( Map map ) {
String rc = "{";
@@ -47,4 +53,26 @@ class Common {
List bytes = text.toString().codeUnits;
return utf8.decode(bytes);
}
+
+ static double mediaSizeWidth( BuildContext context ) {
+ return MediaQuery.of(context).size.width;
+ }
+
+ static bool validateEmail(UserRepository userRepository) {
+ final String email = userRepository.user.email;
+ final RegExp _emailRegExp = RegExp(
+ r'^[a-zA-Z0-9._-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$',
+ );
+ return _emailRegExp.hasMatch(email);
+ }
+
+ static bool validatePassword(UserRepository userRepository) {
+ final password = userRepository.user.password;
+ final RegExp _passwordRegExp =
+ RegExp(r'^(?=.*[A-Za-z0-9])(?=.*\d)[A-Za-z\d]{7,}$');
+
+ return _passwordRegExp.hasMatch(password);
+ }
+
+
}
\ No newline at end of file
diff --git a/lib/util/loading_screen.dart b/lib/util/loading_screen.dart
deleted file mode 100644
index 619d04f..0000000
--- a/lib/util/loading_screen.dart
+++ /dev/null
@@ -1,61 +0,0 @@
-import 'package:aitrainer_app/util/loading_screen_state.dart';
-import 'package:flutter/material.dart';
-
-
-/// Loading Screen Widget that updates the screen once all inistializer methods
-/// are called
-// ignore: must_be_immutable
-class LoadingScreen extends StatefulWidget {
- /// List of methods that are called once the Loading Screen is rendered
- /// for the first time. These are the methods that can update the messages
- /// that are shown under the loading symbol
- final List initializers;
-
- /// The name of the application that is shown at the top of the loading screen
- RichText title = RichText(text: TextSpan(text: 'AI Trainer'));
- //final Text title;
-
- /// The background colour which is used as a filler when the image doesn't
- /// occupy the full screen
- final Color backgroundColor;
-
- /// The styling that is used with the text (messages) that are displayed under
- /// the loader symbol
- final TextStyle styleTextUnderTheLoader;
-
- /// The Layout/Scaffold Widget that is loaded once all the initializer methods
- /// have been executed
- final dynamic navigateToWidget;
-
- /// The colour that is used for the loader symbol
- final Color loaderColor;
-
- /// The image widget that is used as a background cover to the loading screen
- final Image image;
-
- /// The message that is displayed on the first load of the widget
- final String initialMessage;
-
- /// Constructor for the LoadingScreen widget with all the required
- /// initializers
- LoadingScreen(
- {this.initializers,
- this.navigateToWidget,
- this.loaderColor,
- this.image,
- //this.title = Text("Welcome"),
- this.backgroundColor = Colors.white,
- this.styleTextUnderTheLoader = const TextStyle(
- fontSize: 18.0, fontWeight: FontWeight.bold, color: Colors.black),
- this.initialMessage})
- // The Widget depends on the initializers and navigateToWidget to have a
- // valid value. Thus we assert that the values passed are valid and
- // not null
- : assert(initializers != null && initializers.length > 0),
- assert(navigateToWidget != null);
-
- /// Bind the Widget to the custom State object
- @override
- LoadingScreenState createState() => LoadingScreenState();
-}
-
diff --git a/lib/util/loading_screen_state.dart b/lib/util/loading_screen_state.dart
deleted file mode 100644
index 3ce3534..0000000
--- a/lib/util/loading_screen_state.dart
+++ /dev/null
@@ -1,129 +0,0 @@
-import 'dart:core';
-import 'dart:async';
-import 'package:aitrainer_app/util/loading_screen.dart';
-import 'package:aitrainer_app/widgets/home.dart';
-import 'package:flutter/material.dart';
-import 'package:flutter/scheduler.dart';
-import 'package:aitrainer_app/util/message_state.dart';
-
-/// The custom state that is used by the Loading Screen widget to handle the
-/// messages that are provided by the initializer methods.
-///
-/// Note: Although the class is not exported from the package as not required by
-/// the implementers using the package, the protected metatag is added to make
-/// the code clearer.
-@protected
-class LoadingScreenState extends MessageState {
-
- /// Initialise the state
- @override
- void initState() {
- super.initState();
-
- /// If the LoadingScreen widget has an initial message set, then the default
- /// message in the MessageState class needs to be updated
- if (widget.initialMessage != null) {
- initialMessage = widget.initialMessage;
- }
-
- /// We require the initializers to run after the loading screen is rendered
- SchedulerBinding.instance.addPostFrameCallback((_) {
- runInitTasks();
- });
- }
-
- /// This method calls the initializers and once they complete redirects to
- /// the widget provided in navigateAfterInit
- @protected
- Future runInitTasks() async {
- print(" ----- runInitTasks");
- /// Run each initializer method sequentially
- Future.forEach(widget.initializers, (init) => init(this, callbackFunction)).whenComplete(() {
- // When all the initializers has been called and terminated their
- // execution. The screen is navigated to the next scaffolding widget
- if (widget.navigateToWidget is String) {
- // It's fairly safe to assume this is using the in-built material
- // named route component
- print(" ----- navigate to " + widget.navigateToWidget);
- Navigator.of(context).pushReplacementNamed(widget.navigateToWidget);
- } else if (widget.navigateToWidget is Widget) {
- Navigator.of(context).pushReplacement(new MaterialPageRoute(
- builder: (BuildContext context) => widget.navigateToWidget));
- print(" ----- navigate to main ");
-
-
- } else {
- throw new ArgumentError(
- 'widget.navigateAfterSeconds must either be a String or Widget');
- }
- });
- }
-
- void callbackFunction() {
- print("Call Home callback if widget");
- if (widget.navigateToWidget is Widget) {
- AitrainerHome home = widget.navigateToWidget as AitrainerHome;
- home.callback();
- }
- }
-
- /// Render the LoadingScreen widget
- @override
- Widget build(BuildContext context) {
- return Scaffold(
- backgroundColor: widget.backgroundColor,
- body: new InkWell(
- child: new Stack(
- fit: StackFit.expand,
- children: [
- /// Paint the area where the inner widgets are loaded with the
- /// background to keep consistency with the screen background
- new Container(
- decoration: BoxDecoration(color: widget.backgroundColor),
- ),
- /// Render the background image
- new Container(
- child: widget.image,
- ),
- /// Render the Title widget, loader and messages below each other
- new Column(
- mainAxisAlignment: MainAxisAlignment.start,
- children: [
- new Expanded(
- flex: 3,
- child: new Container(
- child: new Column(
- mainAxisAlignment: MainAxisAlignment.start,
- children: [
- new Padding(
- padding: const EdgeInsets.only(top: 30.0),
- ),
- widget.title,
- ],
- )),
- ),
- Expanded(
- flex: 1,
- child: Column(
- mainAxisAlignment: MainAxisAlignment.center,
- children: [
- /// Loader Animation Widget
- CircularProgressIndicator(
- valueColor: new AlwaysStoppedAnimation(
- widget.loaderColor),
- ),
- Padding(
- padding: const EdgeInsets.only(top: 20.0),
- ),
- Text(getMessage, style: widget.styleTextUnderTheLoader),
- ],
- ),
- ),
- ],
- ),
- ],
- ),
- ),
- );
- }
-}
diff --git a/lib/util/menu_tests.dart b/lib/util/menu_tests.dart
deleted file mode 100644
index c53e126..0000000
--- a/lib/util/menu_tests.dart
+++ /dev/null
@@ -1,93 +0,0 @@
-import 'dart:collection';
-import 'package:aitrainer_app/localization/app_localization.dart';
-import 'package:aitrainer_app/model/workout_tree.dart';
-import 'package:flutter/material.dart';
-
-class MenuTests {
- LinkedHashMap tree = LinkedHashMap();
-
- MenuTests(BuildContext context) {
- this.tree['Cardio']= WorkoutTree(1, 0, AppLocalizations.of(context).translate("Cardio"),
- 'asset/menu/1.cardio.png',
- Colors.white, 32, false,0);
- this.tree['Aerobic']= WorkoutTree(2, 1, AppLocalizations.of(context).translate("Aerobic"),
- 'asset/menu/1.1.aerob.png',
- Colors.white, 32, false,0);
- this.tree['Cooper']= WorkoutTree(21, 2, AppLocalizations.of(context).translate("Cooper"),
- 'asset/menu/1.1.1.cooper.png',
- Colors.white, 32, true,30);
- this.tree['Anaerobic']= WorkoutTree(3, 1, AppLocalizations.of(context).translate("Anaerobic"),
- 'asset/menu/1.2.anaerob.png',
- Colors.white, 32, false,0);
- this.tree['300m']= WorkoutTree(22, 3, "300m",
- 'asset/menu/1.2.1.300m.png',
- Colors.white, 32, true,31);
- this.tree['400m']= WorkoutTree(24, 3, "400m",
- 'asset/menu/1.2.2.400m.png',
- Colors.white, 32, true,32);
-
- this.tree['Strength']= WorkoutTree(4, 0, AppLocalizations.of(context).translate("Strength"),
- 'asset/menu/2.strength.png',
- Colors.white, 32, false,0);
- this.tree['Endurance']= WorkoutTree(5, 4, AppLocalizations.of(context).translate("Endurance"),
- 'asset/menu/2.1.endurance.png',
- Colors.white, 36, false,0);
- this.tree['Pullups']= WorkoutTree(6, 5, AppLocalizations.of(context).translate("Pull Ups"),
- 'asset/menu/2.1.1.pull-ups.png',
- Colors.white, 32, true,38);
- this.tree['Pushups']= WorkoutTree(7, 5, AppLocalizations.of(context).translate("Pushups"),
- 'asset/menu/2.1.2.pushup.png',
- Colors.white, 32, true,33);
- this.tree['Situps']= WorkoutTree(10, 5, AppLocalizations.of(context).translate("Sit-ups"),
- 'asset/menu/2.1.3.sit-ups.png',
- Colors.white, 32, true,36);
- this.tree['Squats']= WorkoutTree(11, 5, AppLocalizations.of(context).translate("Squats"),
- 'asset/menu/2.1.4.squats.png',
- Colors.white, 32, true,35);
- this.tree['TimedPushups']= WorkoutTree(12, 5, AppLocalizations.of(context).translate("Timed Pushups"),
- 'asset/menu/2.1.5.timedpushup.png',
- Colors.white, 32, true,34);
- this.tree['Core']= WorkoutTree(43, 5, AppLocalizations.of(context).translate("Core"),
- 'asset/menu/2.1.6.core.png',
- Colors.white, 32, true,45);
-
- this.tree['1RM']= WorkoutTree(8, 4, AppLocalizations.of(context).translate("1RM"),
- 'asset/menu/2.2.1.1RM.png',
- Colors.white, 32, false,0);
- this.tree['Chestpress']= WorkoutTree(13, 8, AppLocalizations.of(context).translate("Chest Press"),
- 'asset/menu/2.2.1.1.chestpress.png',
- Colors.white, 32, true,37);
- this.tree['PullUps1rm']= WorkoutTree(14, 8, AppLocalizations.of(context).translate("Pull Ups"),
- 'asset/menu/2.2.1.2.pullups.png',
- Colors.white, 32, true, 38);
- this.tree['Biceps']= WorkoutTree(15, 8, AppLocalizations.of(context).translate("Biceps"),
- 'asset/menu/2.2.1.3.biceps.png',
- Colors.white, 32, true, 39);
- this.tree['Triceps']= WorkoutTree(16, 8, AppLocalizations.of(context).translate("Triceps"),
- 'asset/menu/2.2.1.4.triceps.png',
- Colors.white, 32, true, 40);
- this.tree['Shoulders']= WorkoutTree(17, 8, AppLocalizations.of(context).translate("Shoulders"),
- 'asset/menu/2.2.1.5.shoulders.png',
- Colors.white, 32, true, 41);
-
- this.tree['BodyCompositions']= WorkoutTree(9, 0, AppLocalizations.of(context).translate("Body Compositions"),
- 'asset/menu/3.bcs1.png',
- Colors.white, 32, false,0);
- this.tree['BMI']= WorkoutTree(18, 9, AppLocalizations.of(context).translate("BMI"),
- 'asset/menu/3.1.BMI.png',
- Colors.white, 32, true,42);
- this.tree['BMR']= WorkoutTree(19, 9, AppLocalizations.of(context).translate("BMR"),
- 'asset/menu/3.2.BMR.png',
- Colors.white, 32, true, 43);
- this.tree['Sizes']= WorkoutTree(20, 9, AppLocalizations.of(context).translate("Sizes"),
- 'asset/menu/3.3.sizes.png',
- Colors.white, 32, true, 44);
-
- }
-
- LinkedHashMap getMenuItems() {
- return this.tree;
- }
-
-
-}
\ No newline at end of file
diff --git a/lib/util/message_state.dart b/lib/util/message_state.dart
deleted file mode 100644
index 2f83923..0000000
--- a/lib/util/message_state.dart
+++ /dev/null
@@ -1,32 +0,0 @@
-import 'package:flutter/widgets.dart';
-
-/// An extension class to the Flutter standard State. The class provides getter
-/// and setters for updating the message section of the loading screen
-///
-/// Note: The class is marked as abstract to avoid IDE issues that expects
-/// protected methods to be overloaded
-abstract class MessageState extends State {
- /// The state variable that will hold the latest message that needs to be
- /// displayed.
- ///
- /// Note: Although Flutter standard allow member variables to be used from
- /// instance object reference, this is not a best practice with OOP. OOP
- /// design proposes that member variables should be accessed through getter
- /// and setter methods.
- @protected
- String _message = 'Loading . . .';
-
- /// The member variable is set as protected this it is not exposed to the
- /// widget state class. As a workaround a protected setter is set so it is
- /// not used outside the package
- @protected
- set initialMessage(String message) => _message = message;
-
- /// Setter for the message variable
- set setMessage(String message) => setState(() {
- _message = message;
- });
-
- /// Getter for the message variable
- String get getMessage => _message;
-}
diff --git a/lib/util/session.dart b/lib/util/session.dart
index 880a5b8..f62a256 100644
--- a/lib/util/session.dart
+++ b/lib/util/session.dart
@@ -1,6 +1,8 @@
import 'package:aitrainer_app/localization/app_language.dart';
+import 'package:aitrainer_app/localization/app_localization.dart';
import 'package:aitrainer_app/service/api.dart';
import 'package:aitrainer_app/service/customer_service.dart';
+import 'package:aitrainer_app/service/exercise_tree_service.dart';
import 'package:aitrainer_app/service/exercisetype_service.dart';
import 'package:devicelocale/devicelocale.dart';
import 'package:flutter/services.dart';
@@ -12,18 +14,24 @@ import '../push_notifications.dart';
class Session {
Future _prefs = SharedPreferences.getInstance();
- Auth _auth = Auth();
+
SharedPreferences _sharedPreferences;
final AppLanguage appLanguage = AppLanguage();
- fetchSessionAndNavigate(Function callback ) async {
+ fetchSessionAndNavigate( ) async {
+ print (" -- Session: await prefs..");
_sharedPreferences = await _prefs;
- if ( _auth.firstLoad ) {
- _fetchToken(_sharedPreferences, callback);
+ if ( Auth().firstLoad ) {
+
+ print (" -- Session: fetch locale..");
+ await appLanguage.fetchLocale();
+ await AppLocalizations.delegate.load(appLanguage.appLocal);
+ print (" -- Session: fetch token..");
+ await _fetchToken(_sharedPreferences);
initDeviceLocale();
- appLanguage.fetchLocale();
+
PushNotificationsManager().init();
}
@@ -53,7 +61,7 @@ class Session {
/*
Auth flow of the user, see auth.dart
*/
- _fetchToken(SharedPreferences prefs, Function callback) async {
+ _fetchToken(SharedPreferences prefs) async {
var responseJson = await APIClient.authenticateUser(
Auth.username,
@@ -71,6 +79,7 @@ class Session {
// registration
//Navigator.of(context).pushNamed('registration');
prefs.setBool(Auth.isRegisteredKey, true);
+ Auth().startPage = "registration";
} else {
DateTime now = DateTime.now();
DateTime lastStoreDate = DateTime.parse(
@@ -83,16 +92,17 @@ class Session {
prefs.get(Auth.isLoggedInKey) == false) {
print("************* Login");
//Navigator.of(context).pushNamed('login');
-
+ Auth().startPage = "login";
} else {
print("************** Store SharedPreferences");
// get API customer
await CustomerApi().getCustomer(prefs.getInt(Auth.customerIdKey));
+ Auth().startPage = "home";
}
- await ExerciseTypeApi().getExerciseTypes("");
- print("--- Session finished, call callback ");
- callback();
+ await ExerciseTypeApi().getExerciseTypes();
+ await ExerciseTreeApi().getExerciseTree();
+ print("--- Session finished");
}
}
diff --git a/lib/view/account.dart b/lib/view/account.dart
index 46039d9..e695569 100644
--- a/lib/view/account.dart
+++ b/lib/view/account.dart
@@ -1,142 +1,110 @@
-import 'package:aitrainer_app/localization/app_language.dart';
+import 'package:aitrainer_app/bloc/account/account_bloc.dart';
import 'package:aitrainer_app/localization/app_localization.dart';
-import 'package:aitrainer_app/model/auth.dart';
-import 'package:aitrainer_app/util/common.dart';
-import 'package:aitrainer_app/viewmodel/customer_changing_view_model.dart';
-import 'package:aitrainer_app/viewmodel/customer_view_model.dart';
-import 'package:aitrainer_app/viewmodel/exercise_changing_view_model.dart';
-import 'package:aitrainer_app/viewmodel/exercise_view_model.dart';
-import 'package:shared_preferences/shared_preferences.dart';
-import 'package:aitrainer_app/viewmodel/user_view_model.dart';
+import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:aitrainer_app/widgets/bottom_nav.dart';
import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
-import 'package:provider/provider.dart';
-
-class AccountPage extends StatefulWidget{
- _AccountPagePageState _state;
-
- _AccountPagePageState createState() {
- _state = new _AccountPagePageState();
- return _state;
- }
-
- State getState() {
- return _state;
- }
-}
-
-class _AccountPagePageState extends State {
- final UserViewModel user = UserViewModel();
- final AppLanguage appLanguage = AppLanguage();
- final Future _prefs = SharedPreferences.getInstance();
- final BottomNavigator bottomNav = BottomNavigator();
- Future> _exercises;
- ExerciseChangingViewModel exerciseChangingViewModel;
-
-
-
- @override
- void initState() {
- exerciseChangingViewModel = Provider.of(context, listen: false);
- super.initState();
- }
+// ignore: must_be_immutable
+class AccountPage extends StatelessWidget {
+ // ignore: close_sinks
+ AccountBloc accountBloc;
@override
Widget build(BuildContext context) {
- return Consumer(
- builder: (context, model, child ) {
- if ( model.customer == null ) {
- CustomerViewModel customerViewModel = CustomerViewModel();
- model.customer = customerViewModel;
- if ( model.customer.getCustomer() == null ) {
- model.customer.setCustomer(Auth().userLoggedIn);
+ accountBloc = BlocProvider.of(context);
+ return Scaffold(
+ appBar: AppBar(
+ title: Text(AppLocalizations.of(context).translate('Account')),
+ backgroundColor: Colors.transparent,
+ ),
+ body: Container(
+ foregroundDecoration: BoxDecoration(
+ image: DecorationImage(
+ image: AssetImage('asset/image/WT_long_logo.png'),
+ alignment: Alignment.topRight,
+ ),
+ ),
+ decoration: BoxDecoration(
+ image: DecorationImage(
+ image: AssetImage('asset/image/WT_light_background.png'),
+ fit: BoxFit.cover,
+ alignment: Alignment.center,
+ ),
+ ),
+ child: BlocConsumer(
+ listener: (context, state) {
+ if (state is AccountError) {
+ Scaffold.of(context).showSnackBar(SnackBar(
+ backgroundColor: Colors.orange,
+ content:
+ Text(state.message, style: TextStyle(color: Colors.white))));
+ } else if (state is AccountLoading) {
+
+ }
+ },
+ builder: (context, state) {
+ if ( state is AccountInitial ) {
+ String customerName = accountBloc.customerRepository.firstName +
+ " " + accountBloc.customerRepository.name;
+ return accountWidget(context, customerName, accountBloc);
+ } else if ( state is AccountLoggedIn ) {
+ String customerName = accountBloc.customerRepository.firstName +
+ " " + accountBloc.customerRepository.name;
+ return accountWidget(context, customerName, accountBloc);
+ } else if ( state is AccountLoggedOut ) {
+ String customerName = "";
+ return accountWidget(context, customerName, accountBloc);
+ } else if ( state is AccountReady ) {
+ String customerName = accountBloc.customerRepository.firstName +
+ " " + accountBloc.customerRepository.name;
+ return accountWidget(context, customerName, accountBloc);
+ } else {
+ return accountWidget(context, "", accountBloc);
+ }
+
}
- }
-
- if ( Auth().userLoggedIn != null ) {
- _exercises =
- exerciseChangingViewModel.getExercisesByCustomer(
- Auth().userLoggedIn.customerId);
- }
-
-
- return Scaffold(
- appBar: AppBar(
- title: Text(AppLocalizations.of(context).translate('Account')),
- backgroundColor: Colors.transparent,
),
- body: Container(
- foregroundDecoration: BoxDecoration(
- image: DecorationImage(
- image: AssetImage('asset/image/WT_long_logo.png'),
- alignment: Alignment.topRight,
- ),
- ),
- decoration: BoxDecoration(
- image: DecorationImage(
- image: AssetImage('asset/image/WT_light_background.png'),
- fit: BoxFit.cover,
- alignment: Alignment.center,
- ),
- ),
- child:
- ListView(
- padding: EdgeInsets.only(top: 135),
- children: [
- ListTile(
- leading: Icon(Icons.perm_identity),
- subtitle: Text(
- AppLocalizations.of(context).translate("Profile")),
- title: FlatButton(
- child: Row(
- mainAxisAlignment: MainAxisAlignment.spaceBetween,
- children: [
- Text(Auth().userLoggedIn != null ?
- Auth().userLoggedIn.name + " " +
- Auth().userLoggedIn.firstname : "",
- style: TextStyle(color: Colors.blue)),
- Icon(Icons.arrow_forward_ios),
- ]),
- textColor: Colors.grey,
- color: Colors.white,
- onPressed: () => {
- if (model.customer.getCustomer() != null) {
- Navigator.of(context).pushNamed(
- 'customerModifyPage'),
- print("Profile"),
- }
- },
- ),
-
- ),
- ListTile(
- leading: Icon(Icons.language),
- title: Text(appLanguage.appLocal == Locale('en') ?
- AppLocalizations.of(context).translate("English") :
- AppLocalizations.of(context).translate("Hungarian")),
- subtitle: Text(AppLocalizations.of(context).translate(
- "Selected Language")),
- ),
- loginOut( model ),
- exercises(exerciseChangingViewModel),
- ]
- )
- ),
- bottomNavigationBar: bottomNav.buildBottomNavigator(
- context, widget._state)
- );
- });
+ ),
+ bottomNavigationBar: BottomNavigator(bottomNavIndex: 2));
}
- ListTile loginOut( CustomerChangingViewModel model ) {
+ ListView accountWidget(BuildContext context, String customerName, AccountBloc accountBloc) {
+ return ListView(padding: EdgeInsets.only(top: 135), children: [
+ ListTile(
+ leading: Icon(Icons.perm_identity),
+ subtitle:
+ Text(AppLocalizations.of(context).translate("Profile")),
+ title: FlatButton(
+ child: Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ Text(customerName,
+ style: TextStyle(color: Colors.blue)),
+ Icon(Icons.arrow_forward_ios),
+ ]),
+ textColor: Colors.grey,
+ color: Colors.white,
+ onPressed: () => {
+ if (accountBloc.customerRepository.customer != null) {
+ Navigator.of(context).pushNamed('customerModifyPage'),
+ print("Profile"),
+ }
+ },
+ ),
+ ),
+ loginOut( context, accountBloc ),
+ //exercises(exerciseChangingViewModel),
+ ]);
+ }
+
+ ListTile loginOut( BuildContext context, AccountBloc accountBloc ) {
ListTile element = ListTile();
String text = "Logout";
Color buttonColor = Colors.orange;
- if ( model.customer.getCustomer() == null ) {
+ if ( accountBloc.customerRepository.customer == null || accountBloc.customerRepository.customer.email == null) {
text = "Login";
buttonColor = Colors.blue;
}
@@ -149,25 +117,20 @@ class _AccountPagePageState extends State {
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(AppLocalizations.of(context).translate(text),
- style: TextStyle(
- color: buttonColor
- )),
+ style: TextStyle(
+ color: buttonColor
+ )),
Icon(Icons.arrow_forward_ios),
]),
textColor: buttonColor,
color: Colors.white,
onPressed: () => {
- setState(() {
- if ( model.customer.getCustomer() == null ) {
- print("Login");
- Navigator.of(context).pushNamed("login", arguments: widget._state);
- } else {
- print("Logout");
- Auth().logout();
- model.customer.setCustomer(null);
- }
-
- })
+ if ( accountBloc.loggedIn ) {
+ accountBloc.add(AccountLogout())
+ } else {
+ accountBloc.add(AccountLogin()),
+ Navigator.of(context).pushNamed('login'),
+ }
},
),
);
@@ -175,7 +138,7 @@ class _AccountPagePageState extends State {
return element;
}
- ListTile exercises( ExerciseChangingViewModel model ) {
+ /* ListTile exercises( ExerciseChangingViewModel model ) {
ListTile element = ListTile();
if ( Auth().userLoggedIn == null ) {
return element;
@@ -202,7 +165,8 @@ class _AccountPagePageState extends State {
return element;
}
-
+*/
+ /*
Widget getExercises( ExerciseChangingViewModel model ) {
List exercises = model.exerciseList;
@@ -262,5 +226,5 @@ class _AccountPagePageState extends State {
return element;
- }
-}
\ No newline at end of file
+ } */
+}
diff --git a/lib/view/custom_exercise_page.dart b/lib/view/custom_exercise_page.dart
new file mode 100644
index 0000000..820f8eb
--- /dev/null
+++ b/lib/view/custom_exercise_page.dart
@@ -0,0 +1,346 @@
+import 'package:aitrainer_app/bloc/custom_exercise_form_bloc.dart';
+import 'package:aitrainer_app/localization/app_localization.dart';
+import 'package:aitrainer_app/model/exercise_type.dart';
+import 'package:aitrainer_app/repository/exercise_repository.dart';
+import 'package:aitrainer_app/widgets/splash.dart';
+import 'package:flutter/cupertino.dart';
+import 'package:flutter/material.dart';
+import 'package:flutter/services.dart';
+import 'package:flutter_bloc/flutter_bloc.dart';
+import 'package:flutter_form_bloc/flutter_form_bloc.dart';
+
+class CustomExercisePage extends StatefulWidget {
+ _CustomExerciseNewPageState createState() => _CustomExerciseNewPageState();
+}
+
+class _CustomExerciseNewPageState extends State {
+ final GlobalKey _scaffoldKey = new GlobalKey();
+
+ @override
+ Widget build(BuildContext context) {
+ final ExerciseType exerciseType = ModalRoute.of(context).settings.arguments;
+
+ return BlocProvider(
+ create: (context) =>
+ CustomExerciseFormBloc(exerciseRepository: ExerciseRepository()),
+ child: Builder(builder: (context) {
+ // ignore: close_sinks
+ final exerciseBloc = BlocProvider.of(context);
+ exerciseBloc.exerciseRepository.setExerciseType(exerciseType);
+
+ return Scaffold(
+ key: _scaffoldKey,
+ resizeToAvoidBottomInset: true,
+ appBar: AppBar(
+ backgroundColor: Colors.transparent,
+ title: Row(
+ mainAxisAlignment: MainAxisAlignment.end,
+ children: [
+ Image.asset(
+ 'asset/image/WT_long_logo.png',
+ fit: BoxFit.cover,
+ height: 65.0,
+ ),
+ ],
+ ),
+ leading: IconButton(
+ icon: Icon(Icons.arrow_back, color: Colors.white),
+ onPressed: () => Navigator.of(context).pop(),
+ ),
+ ),
+ body: FormBlocListener(
+ onSubmitting: (context, state) {
+ LoadingDialog.show(context);
+ },
+ onSuccess: (context, state) {
+ LoadingDialog.hide(context);
+ },
+ onFailure: (context, state) {
+ LoadingDialog.hide(context);
+ Scaffold.of(context).showSnackBar(SnackBar(
+ backgroundColor: Colors.orange,
+ content: Text(state.failureResponse,
+ style: TextStyle(color: Colors.white))));
+ },
+ child: Container(
+ width: MediaQuery.of(context).size.width,
+ height: MediaQuery.of(context).size.height,
+ decoration: BoxDecoration(
+ image: DecorationImage(
+ image:
+ AssetImage('asset/image/WT_light_background.png'),
+ fit: BoxFit.fill,
+ alignment: Alignment.center,
+ ),
+ ),
+ child: CustomScrollView(
+ scrollDirection: Axis.vertical,
+ slivers: [
+ SliverList(
+ delegate: SliverChildListDelegate(
+ [
+ Container(
+ padding: EdgeInsets.only(top:20,left:25, right:25),
+ alignment: Alignment.center,
+ child: Column(
+ mainAxisAlignment: MainAxisAlignment.center,
+ children: [
+ Text("Custom Exercise",
+ style: TextStyle(
+ fontWeight: FontWeight.bold,
+ fontSize: 14,
+ color: Colors.deepOrange)),
+ columnQuantityUnit(exerciseBloc),
+ columnQuantity(exerciseBloc),
+ ]
+ )
+ ),
+ ]
+ ),
+
+ ),
+ gridCalculation(exerciseBloc)
+ ]
+ )
+ )
+ )
+ );
+ }));
+ }
+
+ Column columnQuantityUnit(CustomExerciseFormBloc bloc) {
+ Column column = Column();
+ if (bloc.exerciseRepository.exerciseType != null &&
+ bloc.exerciseRepository.exerciseType.unitQuantity == "1") {
+ column = Column(children: [
+ TextFieldBlocBuilder(
+ textFieldBloc: bloc.unitQuantityField,
+ textAlign: TextAlign.center,
+ style: TextStyle(
+ fontSize: 16,
+ color: Colors.lightBlue,
+ fontWeight: FontWeight.bold),
+ inputFormatters: [
+ FilteringTextInputFormatter(RegExp(r"[\d.]"), allow: true)
+ ],
+ onChanged: (input) => {
+ print("UnitQuantity value $input"),
+ bloc.exerciseRepository.setUnitQuantity(double.parse(input))
+ },
+ decoration: InputDecoration(
+ fillColor: Colors.white,
+ filled: false,
+ hintStyle: TextStyle(
+ fontSize: 12,
+ color: Colors.black54,
+ fontWeight: FontWeight.w100),
+ hintText: AppLocalizations.of(context)
+ .translate("The number of the exercise done with"),
+ labelStyle: TextStyle(fontSize: 12, color: Colors.lightBlue),
+ labelText: AppLocalizations.of(context).translate(
+ bloc.exerciseRepository.exerciseType.unitQuantityUnit),
+ ),
+ ),
+ new InkWell(
+ child: new Text(
+ AppLocalizations.of(context).translate(
+ bloc.exerciseRepository.exerciseType.unitQuantityUnit),
+ style: TextStyle(fontSize: 12)),
+ ),
+ ]);
+ }
+ ;
+ return column;
+ }
+
+ Column columnQuantity(CustomExerciseFormBloc bloc) {
+ Column column = Column(children: [
+ TextFieldBlocBuilder(
+ textFieldBloc: bloc.quantityField,
+ textAlign: TextAlign.center,
+ style: TextStyle(
+ fontSize: 20,
+ color: Colors.deepOrange,
+ fontWeight: FontWeight.bold),
+ inputFormatters: [
+ FilteringTextInputFormatter(RegExp(r"[\d.]"), allow: true)
+ ],
+ onChanged: (input) => {
+ print("Quantity value $input"),
+ bloc.exerciseRepository.setQuantity(double.parse(input)),
+ bloc.exerciseRepository
+ .setUnit(bloc.exerciseRepository.exerciseType.unit)
+ },
+ decoration: InputDecoration(
+ fillColor: Colors.white,
+ filled: false,
+ hintStyle: TextStyle(
+ fontSize: 12, color: Colors.black54, fontWeight: FontWeight.w100),
+ hintText: AppLocalizations.of(context)
+ .translate("The number of the exercise"),
+ labelStyle: TextStyle(fontSize: 12, color: Colors.deepOrange),
+ labelText: AppLocalizations.of(context)
+ .translate(bloc.exerciseRepository.exerciseType.unit),
+ ),
+ ),
+ ]);
+
+ return column;
+ }
+
+ SliverGrid gridCalculation(CustomExerciseFormBloc bloc) {
+ return SliverGrid(
+ gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
+ crossAxisCount: 2,
+ mainAxisSpacing: 10.0,
+ crossAxisSpacing: 10.0,
+ childAspectRatio: 4.0,
+ ),
+ delegate: SliverChildListDelegate(
+ [
+ TextFieldBlocBuilder(
+ isEnabled: false,
+ textFieldBloc: bloc.rmWendlerField,
+ padding: EdgeInsets.only(left:30),
+ style: TextStyle(color: Colors.deepOrange, fontSize: 12),
+ decoration: InputDecoration(
+ border: InputBorder.none,
+ fillColor: Colors.white,
+ filled: false,
+ labelText: "1RM by Wendler: ",
+ )),
+ TextFieldBlocBuilder(
+ isEnabled: false,
+ padding: EdgeInsets.only(left:30),
+ textFieldBloc: bloc.rmMcGothlinField,
+ style: TextStyle(color: Colors.deepOrange, fontSize: 12),
+ decoration: InputDecoration(
+ border: InputBorder.none,
+ fillColor: Colors.white,
+ filled: false,
+ labelText: "1RM by McGlothin: ",
+ )),
+ TextFieldBlocBuilder(
+ isEnabled: false,
+ padding: EdgeInsets.only(left:30),
+ maxLines: 1,
+ textFieldBloc: bloc.rmLombardiField,
+ style: TextStyle(color: Colors.deepOrange, fontSize: 12),
+ decoration: InputDecoration(
+ border: InputBorder.none,
+ fillColor: Colors.white,
+ filled: false,
+ labelText: "1RM by Lambordini: ",
+ )),
+ TextFieldBlocBuilder(
+ isEnabled: false,
+ padding: EdgeInsets.only(left:30),
+ maxLines: 1,
+ textFieldBloc: bloc.rmWathenField,
+ style: TextStyle(color: Colors.deepOrange, fontSize: 12),
+ decoration: InputDecoration(
+ border: InputBorder.none,
+ fillColor: Colors.white,
+ filled: false,
+ labelText: "1RM by Wahten: ",
+ )),
+ TextFieldBlocBuilder(
+ isEnabled: false,
+ padding: EdgeInsets.only(left:30),
+ maxLines: 1,
+ textFieldBloc: bloc.rmOconnerField,
+ style: TextStyle(color: Colors.deepOrange, fontSize: 12),
+ decoration: InputDecoration(
+ border: InputBorder.none,
+ fillColor: Colors.white,
+ filled: false,
+ labelText: "1RM by O'Conner: ",
+ )),
+ TextFieldBlocBuilder(
+ isEnabled: false,
+ padding: EdgeInsets.only(left:30),
+ maxLines: 1,
+ textFieldBloc: bloc.rmMayhewField,
+ style: TextStyle(color: Colors.deepOrange, fontSize: 12),
+ decoration: InputDecoration(
+ border: InputBorder.none,
+ fillColor: Colors.white,
+ filled: false,
+ labelText: "1RM by Mayhew: ",
+ )),
+ TextFieldBlocBuilder(
+ isEnabled: false,
+ padding: EdgeInsets.only(left:30),
+ maxLines: 1,
+ textFieldBloc: bloc.rmAverageField,
+ style: TextStyle(color: Colors.blueAccent, fontSize: 12),
+ decoration: InputDecoration(
+ border: InputBorder.none,
+ fillColor: Colors.white,
+ filled: false,
+ labelText: "1RM Average: ",
+ )),
+ TextFieldBlocBuilder(
+ isEnabled: false,
+ padding: EdgeInsets.only(left:30),
+ maxLines: 1,
+ textFieldBloc: bloc.rm90Field,
+ style: TextStyle(color: Colors.deepOrange, fontSize: 12),
+ decoration: InputDecoration(
+ border: InputBorder.none,
+ fillColor: Colors.white,
+ filled: false,
+ labelText: "1RM 90%: ",
+ )),
+ TextFieldBlocBuilder(
+ isEnabled: false,
+ padding: EdgeInsets.only(left:30),
+ maxLines: 1,
+ textFieldBloc: bloc.rm80Field,
+ style: TextStyle(color: Colors.deepOrange, fontSize: 12),
+ decoration: InputDecoration(
+ border: InputBorder.none,
+ fillColor: Colors.white,
+ filled: false,
+ labelText: "1RM 80%: ",
+ )),
+ TextFieldBlocBuilder(
+ isEnabled: false,
+ padding: EdgeInsets.only(left:30),
+ maxLines: 1,
+ textFieldBloc: bloc.rm70Field,
+ style: TextStyle(color: Colors.deepOrange, fontSize: 12),
+ decoration: InputDecoration(
+ border: InputBorder.none,
+ fillColor: Colors.white,
+ filled: false,
+ labelText: "1RM 70%: ",
+ )),
+ TextFieldBlocBuilder(
+ isEnabled: false,
+ padding: EdgeInsets.only(left:30),
+ maxLines: 1,
+ textFieldBloc: bloc.rm60Field,
+ style: TextStyle(color: Colors.deepOrange, fontSize: 12),
+ decoration: InputDecoration(
+ border: InputBorder.none,
+ fillColor: Colors.white,
+ filled: false,
+ labelText: "1RM 60%: ",
+ )),
+ TextFieldBlocBuilder(
+ isEnabled: false,
+ padding: EdgeInsets.only(left:30),
+ maxLines: 1,
+ textFieldBloc: bloc.rm50Field,
+ style: TextStyle(color: Colors.deepOrange, fontSize: 12),
+ decoration: InputDecoration(
+ border: InputBorder.none,
+ fillColor: Colors.white,
+ filled: false,
+ labelText: "1RM 50%: ",
+ ))
+ ])
+ );
+ }
+}
diff --git a/lib/view/customer_bodytype_page.dart b/lib/view/customer_bodytype_page.dart
index a3dcba8..70c8f0f 100644
--- a/lib/view/customer_bodytype_page.dart
+++ b/lib/view/customer_bodytype_page.dart
@@ -1,9 +1,11 @@
+import 'package:aitrainer_app/bloc/customer_change/customer_change_bloc.dart';
import 'package:aitrainer_app/localization/app_localization.dart';
-import 'package:aitrainer_app/viewmodel/customer_changing_view_model.dart';
+import 'package:aitrainer_app/repository/customer_repository.dart';
import 'package:flutter/material.dart';
+import 'package:flutter_bloc/flutter_bloc.dart';
// ignore: must_be_immutable
-class CustomerBodyTypePage extends StatefulWidget{
+class CustomerBodyTypePage extends StatefulWidget {
_CustomerBodyTypePageState _state;
_CustomerBodyTypePageState createState() {
@@ -13,7 +15,6 @@ class CustomerBodyTypePage extends StatefulWidget{
}
class BodyTypeItem {
-
static String endomorph = "endomorph";
static String ectomorph = "ectomorph";
static String mesomorph = "mesomorph";
@@ -23,15 +24,15 @@ class _CustomerBodyTypePageState extends State {
String selected;
@override
Widget build(BuildContext context) {
- final CustomerChangingViewModel changingViewModel = ModalRoute.of(context).settings.arguments;
- final double cWidth = MediaQuery.of(context).size.width*0.75;
+ final CustomerRepository customerRepository =
+ ModalRoute.of(context).settings.arguments;
+ final double cWidth = MediaQuery.of(context).size.width * 0.75;
return Scaffold(
appBar: AppBar(
title: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
-
Image.asset(
'asset/image/WT_long_logo.png',
fit: BoxFit.cover,
@@ -40,151 +41,160 @@ class _CustomerBodyTypePageState extends State {
],
),
backgroundColor: Colors.transparent,
- ),
- body: Container(
- decoration: BoxDecoration(
- image: DecorationImage(
- image: AssetImage('asset/image/WT_light_background.png'),
- fit: BoxFit.cover,
- alignment: Alignment.center,
- ),
+ ),
+ body: Container(
+ decoration: BoxDecoration(
+ image: DecorationImage(
+ image: AssetImage('asset/image/WT_light_background.png'),
+ fit: BoxFit.cover,
+ alignment: Alignment.center,
),
- child: Column(
- mainAxisAlignment: MainAxisAlignment.center,
- children: [
- Divider(),
- Wrap(
- //runAlignment: WrapAlignment.center,
- alignment: WrapAlignment.center,
+ ),
+ child: BlocProvider(
+ create: (context) =>
+ CustomerChangeBloc(customerRepository: customerRepository),
+ child: Builder(builder: (context) {
+ // ignore: close_sinks
+ CustomerChangeBloc changeBloc =
+ BlocProvider.of(context);
+
+ return Column(
+ mainAxisAlignment: MainAxisAlignment.center,
children: [
- Text(
- AppLocalizations.of(context).translate("Your Body Type"),
- textAlign: TextAlign.center,
- style: TextStyle(color: Colors.orange,
- fontSize: 42, fontFamily: 'Arial',
- fontWeight: FontWeight.w900 ),)
- ]
- ),
-
-
- Divider(),
- FlatButton(
- child: Container(
- width: cWidth,
- child: Column(
+ Divider(),
+ Wrap(
+ //runAlignment: WrapAlignment.center,
+ alignment: WrapAlignment.center,
children: [
- Text(AppLocalizations.of(context).translate("Endomorph"),
- textWidthBasis: TextWidthBasis.longestLine,
- style: TextStyle(color: Colors.blue,
- fontSize: 32, fontFamily: 'Arial',
- fontWeight: FontWeight.w900 )),
-
- ],
- )
- ),
- padding: EdgeInsets.all(10.0),
- shape: getShape(changingViewModel, BodyTypeItem.endomorph ),
- onPressed:() =>
- {
- setState((){
- selected = BodyTypeItem.endomorph;
- changingViewModel.customer.setBodyType(selected);
- print(selected);
- }),
-
- }
-
- ),
- Divider(),
- FlatButton(
- child: Container(
- width: cWidth,
- child: Column(
- children: [
- InkWell(
- child: Text(AppLocalizations.of(context).translate("Ectomorph"),
- style: TextStyle(color: Colors.blue,
- fontSize: 32, fontFamily: 'Arial',
- fontWeight: FontWeight.w900 ),),
- highlightColor: Colors.white,
+ Text(
+ AppLocalizations.of(context)
+ .translate("Your Body Type"),
+ textAlign: TextAlign.center,
+ style: TextStyle(
+ color: Colors.orange,
+ fontSize: 42,
+ fontFamily: 'Arial',
+ fontWeight: FontWeight.w900),
+ )
+ ]),
+ Divider(),
+ FlatButton(
+ child: Container(
+ width: cWidth,
+ child: Column(
+ children: [
+ Text(
+ AppLocalizations.of(context)
+ .translate("Endomorph"),
+ textWidthBasis: TextWidthBasis.longestLine,
+ style: TextStyle(
+ color: Colors.blue,
+ fontSize: 32,
+ fontFamily: 'Arial',
+ fontWeight: FontWeight.w900)),
+ ],
+ )),
+ padding: EdgeInsets.all(10.0),
+ shape: getShape(
+ customerRepository, BodyTypeItem.endomorph),
+ onPressed: () => {
+ setState(() {
+ selected = BodyTypeItem.endomorph;
+ changeBloc.add(CustomerBodyTypeChange(bodyType: selected));
+ print(selected);
+ }),
+ }),
+ Divider(),
+ FlatButton(
+ child: Container(
+ width: cWidth,
+ child: Column(
+ children: [
+ InkWell(
+ child: Text(
+ AppLocalizations.of(context)
+ .translate("Ectomorph"),
+ style: TextStyle(
+ color: Colors.blue,
+ fontSize: 32,
+ fontFamily: 'Arial',
+ fontWeight: FontWeight.w900),
+ ),
+ highlightColor: Colors.white,
+ ),
+ ],
+ ),
),
+ padding: EdgeInsets.all(10.0),
+ shape: getShape(customerRepository, BodyTypeItem.ectomorph ),
- ],
- ),
- ),
- padding: EdgeInsets.all(10.0),
- shape: getShape(changingViewModel, BodyTypeItem.ectomorph ),
-
- onPressed:() =>
- {
- setState((){
- selected = BodyTypeItem.ectomorph;
- changingViewModel.customer.setBodyType(selected);
- print(selected);
- }),
-
- }
- ),
- Divider(),
- FlatButton(
- child: Container(
- width: cWidth,
- child: Column(
- children: [
- InkWell(
- child: Text(AppLocalizations.of(context).translate("Mesomorph"),
- style: TextStyle(color: Colors.blue,
- fontSize: 32, fontFamily: 'Arial',
- fontWeight: FontWeight.w900 ),),
- highlightColor: Colors.white,
+ onPressed: () => {
+ setState(() {
+ selected = BodyTypeItem.ectomorph;
+ changeBloc.add(CustomerBodyTypeChange(bodyType: selected));
+ print(selected);
+ }),
+ }),
+ Divider(),
+ FlatButton(
+ child: Container(
+ width: cWidth,
+ child: Column(
+ children: [
+ InkWell(
+ child: Text(
+ AppLocalizations.of(context)
+ .translate("Mesomorph"),
+ style: TextStyle(
+ color: Colors.blue,
+ fontSize: 32,
+ fontFamily: 'Arial',
+ fontWeight: FontWeight.w900),
+ ),
+ highlightColor: Colors.white,
+ ),
+ ],
+ ),
),
+ padding: EdgeInsets.all(10.0),
+ shape: getShape(customerRepository, BodyTypeItem.mesomorph ),
+ onPressed: () => {
+ setState(() {
+ selected = BodyTypeItem.mesomorph;
+ changeBloc.add(CustomerBodyTypeChange(bodyType: selected));
- ],
- ),
- ),
- padding: EdgeInsets.all(10.0),
- shape: getShape(changingViewModel, BodyTypeItem.mesomorph ),
- onPressed:() =>
- {
- setState((){
- selected = BodyTypeItem.mesomorph;
- changingViewModel.customer.setBodyType(selected);
- print(selected);
- }),
-
- }
- ),
-
- Divider(),
- RaisedButton(
-
- color: Colors.orange,
- textColor: Colors.white,
- child: InkWell(
- child: Text(AppLocalizations.of(context).translate("Next"))),
- onPressed: () => {
- changingViewModel.saveCustomer(),
- Navigator.of(context).pop(),
- Navigator.of(context).pushNamed("customerWelcomePage", arguments: changingViewModel)
- },
- )
- ],
- ),
- ),
- );
+ print(selected);
+ }),
+ }),
+ Divider(),
+ RaisedButton(
+ color: Colors.orange,
+ textColor: Colors.white,
+ child: InkWell(
+ child: Text(
+ AppLocalizations.of(context).translate("Next"))),
+ onPressed: () => {
+ changeBloc.add(CustomerSave()),
+ Navigator.of(context).pop(),
+ Navigator.of(context).pushNamed("customerWelcomePage", arguments: customerRepository)
+ },
+ )
+ ],
+ );
+ })),
+ ));
}
- dynamic getShape( CustomerChangingViewModel changingViewModel, String fitnessLevel ) {
- String selected = changingViewModel.customer.bodyType;
- dynamic returnCode = ( selected == fitnessLevel ) ?
- RoundedRectangleBorder(
- side: BorderSide(width: 4, color: Colors.orange),
- )
- :
- RoundedRectangleBorder(
- side: BorderSide(width: 1, color: Colors.blue),
- );
+ dynamic getShape(CustomerRepository customerRepository, String fitnessLevel) {
+ String selected = customerRepository.bodyType;
+ dynamic returnCode = (selected == fitnessLevel)
+ ? RoundedRectangleBorder(
+ side: BorderSide(width: 4, color: Colors.orange),
+ )
+ : RoundedRectangleBorder(
+ side: BorderSide(width: 1, color: Colors.blue),
+ );
//return
return returnCode;
}
-}
\ No newline at end of file
+}
diff --git a/lib/view/customer_fitness_page.dart b/lib/view/customer_fitness_page.dart
index 22d7156..e71bc77 100644
--- a/lib/view/customer_fitness_page.dart
+++ b/lib/view/customer_fitness_page.dart
@@ -1,11 +1,13 @@
+import 'package:aitrainer_app/bloc/customer_change/customer_change_bloc.dart';
import 'package:aitrainer_app/localization/app_localization.dart';
-import 'package:aitrainer_app/viewmodel/customer_changing_view_model.dart';
+import 'package:aitrainer_app/repository/customer_repository.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
+import 'package:flutter_bloc/flutter_bloc.dart';
// ignore: must_be_immutable
-class CustomerFitnessPage extends StatefulWidget{
+class CustomerFitnessPage extends StatefulWidget {
_CustomerFitnessPageState _state;
_CustomerFitnessPageState createState() {
@@ -29,15 +31,15 @@ class _CustomerFitnessPageState extends State {
@override
Widget build(BuildContext context) {
- final double cWidth = MediaQuery.of(context).size.width*0.75;
- final CustomerChangingViewModel changingViewModel = ModalRoute.of(context).settings.arguments;
- selected = changingViewModel.customer.fitnessLevel;
+ final double cWidth = MediaQuery.of(context).size.width * 0.75;
+ final CustomerRepository customerRepository =
+ ModalRoute.of(context).settings.arguments;
+ selected = customerRepository.customer.fitnessLevel;
return Scaffold(
appBar: AppBar(
title: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
-
Image.asset(
'asset/image/WT_long_logo.png',
fit: BoxFit.cover,
@@ -46,206 +48,243 @@ class _CustomerFitnessPageState extends State {
],
),
backgroundColor: Colors.transparent,
- ),
- body: SingleChildScrollView(
- scrollDirection: Axis.vertical,
- child: Container(
+ ),
+ body: BlocProvider(
+ create: (context) =>
+ CustomerChangeBloc(customerRepository: customerRepository),
+ child: Builder(builder: (context) {
+ // ignore: close_sinks
+ CustomerChangeBloc changeBloc =
+ BlocProvider.of(context);
- padding: EdgeInsets.only(bottom: 200),
- decoration: BoxDecoration(
- image: DecorationImage(
- image: AssetImage('asset/image/WT_light_background.png'),
- fit: BoxFit.cover,
- alignment: Alignment.center,
- ),
- ),
- child: Column(
- mainAxisAlignment: MainAxisAlignment.center,
- children: [
- Divider(),
- Wrap(
- //runAlignment: WrapAlignment.center,
- alignment: WrapAlignment.center,
- children: [
- Text(
- AppLocalizations.of(context).translate("Your Fitness State"),
- textAlign: TextAlign.center,
- style: TextStyle(color: Colors.orange,
- fontSize: 42, fontFamily: 'Arial',
- fontWeight: FontWeight.w900 ),)
- ]
+ return SingleChildScrollView(
+ scrollDirection: Axis.vertical,
+ child: Container(
+ padding: EdgeInsets.only(bottom: 200),
+ decoration: BoxDecoration(
+ image: DecorationImage(
+ image: AssetImage('asset/image/WT_light_background.png'),
+ fit: BoxFit.cover,
+ alignment: Alignment.center,
+ ),
),
-
-
- Divider(),
- FlatButton(
- child: Container(
- width: cWidth,
- child: Column(
+ child: Column(
+ mainAxisAlignment: MainAxisAlignment.center,
+ children: [
+ Divider(),
+ Wrap(
+ //runAlignment: WrapAlignment.center,
+ alignment: WrapAlignment.center,
children: [
- Text(AppLocalizations.of(context).translate("Beginner"),
- textWidthBasis: TextWidthBasis.longestLine,
- style: TextStyle(color: Colors.blue,
- fontSize: 32, fontFamily: 'Arial',
- fontWeight: FontWeight.w900 )),
- Text(AppLocalizations.of(context).translate("I am beginner"),
- style: TextStyle(color: Colors.black,
- fontSize: 20, fontFamily: 'Arial',
- fontWeight: FontWeight.w100 ),),
- ],
- )
- ),
- padding: EdgeInsets.all(10.0),
- shape: getShape(changingViewModel, FitnessItem.beginner ),
- onPressed:() =>
- {
- setState((){
- selected = FitnessItem.beginner;
- changingViewModel.customer.setFitnessLevel(selected);
- print(selected);
- }),
-
- }
-
- ),
- Divider(),
- FlatButton(
- child: Container(
- width: cWidth,
- child: Column(
- children: [
- InkWell(
- child: Text(AppLocalizations.of(context).translate("Intermediate"),
- style: TextStyle(color: Colors.blue,
- fontSize: 32, fontFamily: 'Arial',
- fontWeight: FontWeight.w900 ),),
- highlightColor: Colors.white,
+ Text(
+ AppLocalizations.of(context)
+ .translate("Your Fitness State"),
+ textAlign: TextAlign.center,
+ style: TextStyle(
+ color: Colors.orange,
+ fontSize: 42,
+ fontFamily: 'Arial',
+ fontWeight: FontWeight.w900),
+ )
+ ]),
+ Divider(),
+ FlatButton(
+ child: Container(
+ width: cWidth,
+ child: Column(
+ children: [
+ Text(
+ AppLocalizations.of(context)
+ .translate("Beginner"),
+ textWidthBasis:
+ TextWidthBasis.longestLine,
+ style: TextStyle(
+ color: Colors.blue,
+ fontSize: 32,
+ fontFamily: 'Arial',
+ fontWeight: FontWeight.w900)),
+ Text(
+ AppLocalizations.of(context)
+ .translate("I am beginner"),
+ style: TextStyle(
+ color: Colors.black,
+ fontSize: 20,
+ fontFamily: 'Arial',
+ fontWeight: FontWeight.w100),
+ ),
+ ],
+ )),
+ padding: EdgeInsets.all(10.0),
+ shape: getShape(
+ customerRepository, FitnessItem.beginner),
+ onPressed: () => {
+ setState(() {
+ selected = FitnessItem.beginner;
+ changeBloc.add(CustomerFitnessChange(fitness: selected));
+ print(selected);
+ }),
+ }),
+ Divider(),
+ FlatButton(
+ child: Container(
+ width: cWidth,
+ child: Column(
+ children: [
+ InkWell(
+ child: Text(
+ AppLocalizations.of(context)
+ .translate("Intermediate"),
+ style: TextStyle(
+ color: Colors.blue,
+ fontSize: 32,
+ fontFamily: 'Arial',
+ fontWeight: FontWeight.w900),
+ ),
+ highlightColor: Colors.white,
+ ),
+ InkWell(
+ child: Text(
+ AppLocalizations.of(context)
+ .translate("I am intermediate"),
+ style: TextStyle(
+ color: Colors.black,
+ fontSize: 20,
+ fontFamily: 'Arial',
+ fontWeight: FontWeight.w100),
+ ),
+ highlightColor: Colors.white,
+ ),
+ ],
),
- InkWell(
- child: Text(AppLocalizations.of(context).translate("I am intermediate"),
- style: TextStyle(color: Colors.black,
- fontSize: 20, fontFamily: 'Arial',
- fontWeight: FontWeight.w100 ),),
- highlightColor: Colors.white,
+ ),
+ padding: EdgeInsets.all(10.0),
+ shape: getShape(
+ customerRepository, FitnessItem.intermediate),
+ onPressed: () => {
+ setState(() {
+ selected = FitnessItem.intermediate;
+ changeBloc.add(CustomerFitnessChange(fitness: selected));
+ print(selected);
+ }),
+ }),
+ Divider(),
+ FlatButton(
+ child: Container(
+ width: cWidth,
+ child: Column(
+ children: [
+ InkWell(
+ child: Text(
+ AppLocalizations.of(context)
+ .translate("Advanced"),
+ style: TextStyle(
+ color: Colors.blue,
+ fontSize: 32,
+ fontFamily: 'Arial',
+ fontWeight: FontWeight.w900),
+ ),
+ highlightColor: Colors.white,
+ ),
+ InkWell(
+ child: Text(
+ AppLocalizations.of(context)
+ .translate("I am advanced"),
+ style: TextStyle(
+ color: Colors.black,
+ fontSize: 20,
+ fontFamily: 'Arial',
+ fontWeight: FontWeight.w100),
+ ),
+ highlightColor: Colors.white,
+ ),
+ ],
),
- ],
- ),
- ),
- padding: EdgeInsets.all(10.0),
- shape: getShape(changingViewModel, FitnessItem.intermediate ),
-
- onPressed:() =>
- {
- setState((){
- selected = FitnessItem.intermediate;
- changingViewModel.customer.setFitnessLevel(selected);
- print(selected);
- }),
-
- }
- ),
- Divider(),
- FlatButton(
- child: Container(
- width: cWidth,
- child: Column(
- children: [
- InkWell(
- child: Text(AppLocalizations.of(context).translate("Advanced"),
- style: TextStyle(color: Colors.blue,
- fontSize: 32, fontFamily: 'Arial',
- fontWeight: FontWeight.w900 ),),
- highlightColor: Colors.white,
+ ),
+ padding: EdgeInsets.all(10.0),
+ shape: getShape(
+ customerRepository, FitnessItem.advanced),
+ onPressed: () => {
+ setState(() {
+ selected = FitnessItem.advanced;
+ changeBloc.add(CustomerFitnessChange(fitness: selected));
+ print(selected);
+ }),
+ }),
+ Divider(),
+ FlatButton(
+ child: Container(
+ width: cWidth,
+ child: Column(
+ children: [
+ InkWell(
+ child: Text(
+ AppLocalizations.of(context)
+ .translate("Professional"),
+ style: TextStyle(
+ color: Colors.blue,
+ fontSize: 32,
+ fontFamily: 'Arial',
+ fontWeight: FontWeight.w900),
+ ),
+ highlightColor: Colors.white,
+ ),
+ InkWell(
+ child: Text(
+ AppLocalizations.of(context)
+ .translate("I am professional"),
+ style: TextStyle(
+ color: Colors.black,
+ fontSize: 20,
+ fontFamily: 'Arial',
+ fontWeight: FontWeight.w100),
+ ),
+ highlightColor: Colors.white,
+ ),
+ ],
),
- InkWell(
- child: Text(AppLocalizations.of(context).translate("I am advanced"),
- style: TextStyle(color: Colors.black,
- fontSize: 20, fontFamily: 'Arial',
- fontWeight: FontWeight.w100 ),),
- highlightColor: Colors.white,
- ),
- ],
- ),
- ),
- padding: EdgeInsets.all(10.0),
- shape: getShape(changingViewModel, FitnessItem.advanced ),
- onPressed:() =>
- {
- setState((){
- selected = FitnessItem.advanced;
- changingViewModel.customer.setFitnessLevel(selected);
- print(selected);
- }),
-
- }
- ),
- Divider(),
- FlatButton(
- child: Container(
- width: cWidth,
- child: Column(
- children: [
- InkWell(
- child: Text(AppLocalizations.of(context).translate("Professional"),
- style: TextStyle(color: Colors.blue,
- fontSize: 32, fontFamily: 'Arial',
- fontWeight: FontWeight.w900 ),),
- highlightColor: Colors.white,
- ),
- InkWell(
- child: Text(AppLocalizations.of(context).translate("I am professional"),
- style: TextStyle(color: Colors.black,
- fontSize: 20, fontFamily: 'Arial',
- fontWeight: FontWeight.w100 ),),
- highlightColor: Colors.white,
- ),
- ],
- ),
- ),
- padding: EdgeInsets.all(10.0),
- shape: getShape(changingViewModel, FitnessItem.professional ),
- onPressed:() =>
- {
- setState((){
- selected = FitnessItem.professional;
- changingViewModel.customer.setFitnessLevel(selected);
- print(selected);
- }),
-
- }
- ),
- Divider(),
- RaisedButton(
-
- color: Colors.orange,
- textColor: Colors.white,
- child: InkWell(
- child: Text(AppLocalizations.of(context).translate("Next"))),
- onPressed: () => {
- changingViewModel.saveCustomer(),
- Navigator.of(context).pop(),
- Navigator.of(context).pushNamed("customerBodyTypePage", arguments: changingViewModel)
- },
- )
- ],
- ),
- ),
- )
- );
+ ),
+ padding: EdgeInsets.all(10.0),
+ shape: getShape(
+ customerRepository, FitnessItem.professional),
+ onPressed: () => {
+ setState(() {
+ selected = FitnessItem.professional;
+ changeBloc.add(CustomerFitnessChange(fitness: selected));
+ print(selected);
+ }),
+ }),
+ Divider(),
+ RaisedButton(
+ color: Colors.orange,
+ textColor: Colors.white,
+ child: InkWell(
+ child: Text(AppLocalizations.of(context)
+ .translate("Next"))),
+ onPressed: () => {
+ changeBloc.add(CustomerSave()),
+ Navigator.of(context).pop(),
+ Navigator.of(context).pushNamed(
+ "customerBodyTypePage",
+ arguments: customerRepository)
+ },
+ )
+ ],
+ ),
+ ),
+ );
+ })));
}
- dynamic getShape( CustomerChangingViewModel changingViewModel, String fitnessLevel ) {
- String selected = changingViewModel.customer.fitnessLevel;
- dynamic returnCode = ( selected == fitnessLevel ) ?
- RoundedRectangleBorder(
- side: BorderSide(width: 4, color: Colors.orange),
- )
- :
- RoundedRectangleBorder(
- side: BorderSide(width: 1, color: Colors.blue),
- );
+ dynamic getShape(CustomerRepository customerRepository, String fitnessLevel) {
+ String selected = customerRepository.fitnessLevel;
+ dynamic returnCode = (selected == fitnessLevel)
+ ? RoundedRectangleBorder(
+ side: BorderSide(width: 4, color: Colors.orange),
+ )
+ : RoundedRectangleBorder(
+ side: BorderSide(width: 1, color: Colors.blue),
+ );
//return
return returnCode;
}
-
-}
\ No newline at end of file
+}
diff --git a/lib/view/customer_goal_page.dart b/lib/view/customer_goal_page.dart
index 30320cb..18a8a01 100644
--- a/lib/view/customer_goal_page.dart
+++ b/lib/view/customer_goal_page.dart
@@ -1,41 +1,37 @@
+import 'package:aitrainer_app/bloc/customer_change/customer_change_bloc.dart';
import 'package:aitrainer_app/localization/app_localization.dart';
-import 'package:aitrainer_app/viewmodel/customer_changing_view_model.dart';
+import 'package:aitrainer_app/repository/customer_repository.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
+import 'package:flutter_form_bloc/flutter_form_bloc.dart';
-// ignore: must_be_immutable
-class CustomerGoalPage extends StatefulWidget{
- _CustomerGoalPageState _state;
-
- _CustomerGoalPageState createState() {
- _state = _CustomerGoalPageState();
- return _state;
- }
-}
-
-class GoalsItem{
+class GoalsItem {
static String muscle = "gain_muscle";
static String weight = "weight_loss";
}
-class _CustomerGoalPageState extends State {
- String selected;
+// ignore: must_be_immutable
+class CustomerGoalPage extends StatefulWidget {
- initState() {
- super.initState();
- }
+ @override
+ State createState() => _CustomerGoalPage();
+}
+
+
+class _CustomerGoalPage extends State {
+ String selected;
@override
Widget build(BuildContext context) {
- final double cWidth = MediaQuery.of(context).size.width*0.75;
- final CustomerChangingViewModel changingViewModel = ModalRoute.of(context).settings.arguments;
- selected = changingViewModel.customer.goal;
+ final double cWidth = MediaQuery.of(context).size.width * 0.75;
+ final CustomerRepository customerRepository =
+ ModalRoute.of(context).settings.arguments;
+
return Scaffold(
appBar: AppBar(
title: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
-
Image.asset(
'asset/image/WT_long_logo.png',
fit: BoxFit.cover,
@@ -44,116 +40,138 @@ class _CustomerGoalPageState extends State {
],
),
backgroundColor: Colors.transparent,
- ),
- body: Container(
- decoration: BoxDecoration(
- image: DecorationImage(
- image: AssetImage('asset/image/WT_light_background.png'),
- fit: BoxFit.cover,
-
- alignment: Alignment.center,
- ),
+ ),
+ body: Container(
+ decoration: BoxDecoration(
+ image: DecorationImage(
+ image: AssetImage('asset/image/WT_light_background.png'),
+ fit: BoxFit.cover,
+ alignment: Alignment.center,
),
- height: double.infinity,
- width: double.infinity,
- child: SingleChildScrollView(
- child: Center(
- child: Column(
- children: [
- Divider(),
- InkWell(
- child: Text(AppLocalizations.of(context).translate("Set Your Goals"),
- style: TextStyle(color: Colors.orange,
- fontSize: 50, fontFamily: 'Arial',
- fontWeight: FontWeight.w900 ),),
- highlightColor: Colors.white,
- ),
-
- Stack(
- alignment: Alignment.bottomLeft,
- overflow: Overflow.visible,
- children: [
- FlatButton(
- child: Image.asset("asset/image/WT_gain_muscle.png", height: 180,),
- padding: EdgeInsets.all(0.0),
- shape: getShape(changingViewModel, GoalsItem.muscle ),
- onPressed:() =>
- {
- print("gain muscle"),
- setState((){
- selected = GoalsItem.muscle;
- changingViewModel.customer.setGoal(GoalsItem.muscle);
- }),
-
- }
- ),
- InkWell(
- child: Text(AppLocalizations.of(context).translate("Gain Muscle"),
- style: TextStyle(color: Colors.white,
- fontSize: 32, fontFamily: 'Arial',
- fontWeight: FontWeight.w900 ),),
- highlightColor: Colors.white,
- )
- ]
- ),
- Divider(),
- Stack(
- alignment: Alignment.bottomLeft,
- overflow: Overflow.visible,
- children: [
- FlatButton(
- child: Image.asset("asset/image/WT_weight_loss.png", height: 180,),
- padding: EdgeInsets.all(0.0),
- shape: getShape(changingViewModel, GoalsItem.weight ),
- onPressed:() =>
- {
- print("weight_loss"),
- setState((){
- selected = GoalsItem.weight;
- changingViewModel.customer.setGoal(GoalsItem.weight);
- }),
-
- }
- ),
- InkWell(
- child: Text(AppLocalizations.of(context).translate("Loose Weight"),
- style: TextStyle(color: Colors.white,
- fontSize: 32, fontFamily: 'Arial',
- fontWeight: FontWeight.w900 ),),
- highlightColor: Colors.white,
- )
- ]
- ),
- Divider(),
- RaisedButton(
-
- color: Colors.orange,
- textColor: Colors.white,
- child: InkWell(
- child: Text(AppLocalizations.of(context).translate("Next"))),
- onPressed: () => {
- changingViewModel.saveCustomer(),
- Navigator.of(context).pop(),
- Navigator.of(context).pushNamed("customerFitnessPage", arguments: changingViewModel)
- },
- )
- ],
- ),
- )
- )
),
- );
+ height: double.infinity,
+ width: double.infinity,
+ child: BlocProvider(
+ create: (context) =>
+ CustomerChangeBloc(customerRepository: customerRepository),
+ child: Builder(builder: (context) {
+ CustomerChangeBloc changeBloc =
+ BlocProvider.of(context);
+
+
+ return SingleChildScrollView(
+ child: Center(
+ child: Column(
+ children: [
+ Divider(),
+ InkWell(
+ child: Text(
+ AppLocalizations.of(context)
+ .translate("Set Your Goals"),
+ style: TextStyle(
+ color: Colors.orange,
+ fontSize: 50,
+ fontFamily: 'Arial',
+ fontWeight: FontWeight.w900),
+ ),
+ highlightColor: Colors.white,
+ ),
+ Stack(
+ alignment: Alignment.bottomLeft,
+ overflow: Overflow.visible,
+ children: [
+ FlatButton(
+ child: Image.asset(
+ "asset/image/WT_gain_muscle.png",
+ height: 180,
+ ),
+ padding: EdgeInsets.all(0.0),
+ shape: getShape(changeBloc, GoalsItem.muscle),
+ onPressed: () => {
+ print("gain muscle"),
+ setState((){
+ selected = GoalsItem.muscle;
+ changeBloc.add(CustomerGoalChange(goal: GoalsItem.muscle));
+ }),
+
+ }),
+ InkWell(
+ child: Text(
+ AppLocalizations.of(context)
+ .translate("Gain Muscle"),
+ style: TextStyle(
+ color: Colors.white,
+ fontSize: 32,
+ fontFamily: 'Arial',
+ fontWeight: FontWeight.w900),
+ ),
+ highlightColor: Colors.white,
+ )
+ ]),
+ Divider(),
+ Stack(
+ alignment: Alignment.bottomLeft,
+ overflow: Overflow.visible,
+ children: [
+ FlatButton(
+ child: Image.asset(
+ "asset/image/WT_weight_loss.png",
+ height: 180,
+ ),
+ padding: EdgeInsets.all(0.0),
+ shape: getShape(changeBloc, GoalsItem.weight),
+ onPressed: () => {
+ print("weight_loss"),
+ setState((){
+ selected = GoalsItem.muscle;
+ changeBloc.add(CustomerGoalChange(goal: GoalsItem.weight));
+ }),
+
+ }),
+ InkWell(
+ child: Text(
+ AppLocalizations.of(context)
+ .translate("Loose Weight"),
+ style: TextStyle(
+ color: Colors.white,
+ fontSize: 32,
+ fontFamily: 'Arial',
+ fontWeight: FontWeight.w900),
+ ),
+ highlightColor: Colors.white,
+ )
+ ]),
+ Divider(),
+ RaisedButton(
+ color: Colors.orange,
+ textColor: Colors.white,
+ child: InkWell(
+ child: Text(
+ AppLocalizations.of(context).translate("Next"))),
+ onPressed: () => {
+ //changingViewModel.saveCustomer(),
+ changeBloc.add(CustomerSave()),
+ Navigator.of(context).pop(),
+ Navigator.of(context).pushNamed("customerFitnessPage",
+ arguments: changeBloc.customerRepository)
+ },
+ )
+ ],
+ ),
+ ));
+ }),
+ ),
+ ));
}
- dynamic getShape( CustomerChangingViewModel changingViewModel, String goal ) {
- String selectedGoal = changingViewModel.customer.goal;
- dynamic returnCode = ( selectedGoal == goal ) ?
- RoundedRectangleBorder(
- side: BorderSide(width: 4, color: Colors.red),
- )
- : null;
+ dynamic getShape(CustomerChangeBloc customerBloc, String goal) {
+ String selectedGoal = customerBloc.customerRepository.goal;
+ dynamic returnCode = (selectedGoal == goal)
+ ? RoundedRectangleBorder(
+ side: BorderSide(width: 4, color: Colors.red),
+ )
+ : null;
//return
return returnCode;
}
-
-}
\ No newline at end of file
+}
diff --git a/lib/view/customer_list_page.dart b/lib/view/customer_list_page.dart
deleted file mode 100644
index fe8eba0..0000000
--- a/lib/view/customer_list_page.dart
+++ /dev/null
@@ -1,93 +0,0 @@
-import 'package:aitrainer_app/viewmodel/customer_changing_view_model.dart';
-import 'package:aitrainer_app/viewmodel/customer_view_model.dart';
-import 'package:aitrainer_app/widgets/nav_drawer.dart';
-import 'package:flutter/cupertino.dart';
-import 'package:flutter/material.dart';
-import 'package:aitrainer_app/widgets/customer_list_widget.dart';
-
-class CustomerListPage extends StatefulWidget{
- _CustomerListPageState createState() => _CustomerListPageState();
-}
-
-class _CustomerListPageState extends State {
- //final TextEditingController _controller = TextEditingController();
- Future> _customers;
- final _customerViewModel = CustomerChangingViewModel(null);
-
- @override
- void initState() {
- super.initState();
- _customers = _customerViewModel.getCustomers();
- }
-
- @override
- Widget build(BuildContext context) {
-
- //final customerViewModel = CustomerChangingViewModel(null);
-
- return Scaffold(
- drawer: NavDrawer(),
- appBar: AppBar(
- title: Text("Real customers")
- ),
- body: Center(
- child: FutureBuilder>(
- future: _customers,
- builder: (context, snapshot) {
- if (snapshot.hasData) {
- return CustomerListWidget(customers: _customerViewModel.customerList);
- } else if (snapshot.hasError) {
- return Text("${snapshot.error}");
- }
-
- // By default, show a loading spinner.
- return CircularProgressIndicator();
- },
- ),
- ),
- /* body: Container(
- padding: EdgeInsets.all(10),
- width: MediaQuery.of(context).size.width,
- height: MediaQuery.of(context).size.height,
- child: Column(children: [
- Container(
- padding: EdgeInsets.only(left: 10),
- decoration: BoxDecoration(
- color: Colors.grey,
- borderRadius: BorderRadius.circular(10)
- ),
- child: TextField(
- controller: _controller,
- onSubmitted: (value) {
- if(value.isNotEmpty) {
- customerViewModel.getCustomers();
- _controller.clear();
- }
- },
- style: TextStyle(color: Colors.white),
- decoration: InputDecoration(
- hintText: "Search",
- hintStyle: TextStyle(color: Colors.white),
- border: InputBorder.none
- ),
-
- ),
- ),
- Expanded(
- child: CustomerListWidget(customers: customerViewModel.customers)),
- ]),
-
- ), */
- floatingActionButton: FloatingActionButton(
- onPressed: () => Navigator.pushNamed(
- context,
- 'customerNewPage',
- ),
- child: Icon(Icons.add,),
- mini: true,
- )
-
- );
- }
-
-}
\ No newline at end of file
diff --git a/lib/view/customer_modify_page.dart b/lib/view/customer_modify_page.dart
index d2c274a..e7d0990 100644
--- a/lib/view/customer_modify_page.dart
+++ b/lib/view/customer_modify_page.dart
@@ -1,278 +1,302 @@
+import 'package:aitrainer_app/bloc/account/account_bloc.dart';
+import 'package:aitrainer_app/bloc/customer_change_form_bloc.dart';
import 'package:aitrainer_app/localization/app_localization.dart';
-import 'package:aitrainer_app/viewmodel/customer_changing_view_model.dart';
import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/services.dart';
-import 'package:provider/provider.dart';
+import 'package:flutter_bloc/flutter_bloc.dart';
+import 'package:flutter_form_bloc/flutter_form_bloc.dart';
+
+import '../library_keys.dart';
+
+
// ignore: must_be_immutable
-class CustomerModifyPage extends StatefulWidget{
- _CustomerModifyPageState _state;
-
- _CustomerModifyPageState createState() {
- _state = _CustomerModifyPageState();
- return _state;
- }
-}
-
-class GenderItem {
- GenderItem(this.dbValue,this.name);
- final String dbValue;
- String name;
-}
-
-class _CustomerModifyPageState extends State {
+class CustomerModifyPage extends StatelessWidget{
final _formKey = GlobalKey();
- GenderItem selectedGender;
- List genders;
- @override
- void initState() {
- super.initState();
- genders = [
- GenderItem("m", "Man"),
- GenderItem("w", "Woman"),
- ];
- selectedGender = genders[0];
-
- }
@override
Widget build(BuildContext context) {
- //final CustomerViewModel model = CustomerViewModel();
- //model.customer = Auth().userLoggedIn;
- //final CustomerChangingViewModel customerChangeModel =
- // CustomerChangingViewModel(model);
- CustomerChangingViewModel customerChangingViewModel = Provider.of(context, listen: false);
- customerChangingViewModel.customer.customer.sex = selectedGender.dbValue;
-
+ // ignore: close_sinks
+ final accountBloc = BlocProvider.of(context);
// we cannot initialize the translations in the initState
- genders.forEach((GenderItem element) {
- if ( element.dbValue == "m") {
+/* genders.forEach((GenderItem element) {
+ if (element.dbValue == "m") {
element.name = AppLocalizations.of(context).translate("Man");
}
- if ( element.dbValue == "w") {
+ if (element.dbValue == "w") {
element.name = AppLocalizations.of(context).translate("Woman");
}
});
+*/
+ return BlocProvider(
+ create: (context) =>
+ CustomerChangeFormBloc(customerRepository: accountBloc.customerRepository),
+ child: Builder(builder: (context) {
+ // ignore: close_sinks
+ final customerBloc = BlocProvider.of(context);
- return Scaffold(
- resizeToAvoidBottomInset: true,
- appBar: AppBar(
- title: Row(
- mainAxisAlignment: MainAxisAlignment.spaceBetween,
- children: [
- Text("Profil"),
- Image.asset(
- 'asset/image/WT_long_logo.png',
- fit: BoxFit.cover,
- height: 65.0,
- ),
- ],
- ),
- //title: Text(AppLocalizations.of(context).translate('Settings')),
- backgroundColor: Colors.transparent,
- ),
- body: Container(
- decoration: BoxDecoration(
- image: DecorationImage(
- image: AssetImage('asset/image/WT_light_background.png'),
- fit: BoxFit.cover,
- alignment: Alignment.center,
+ return Scaffold(
+ resizeToAvoidBottomInset: true,
+ appBar: AppBar(
+ title: Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ Text("Profil"),
+ Image.asset(
+ 'asset/image/WT_long_logo.png',
+ fit: BoxFit.cover,
+ height: 65.0,
+ ),
+ ],
),
+ //title: Text(AppLocalizations.of(context).translate('Settings')),
+ backgroundColor: Colors.transparent,
),
- child: Form(
- key: _formKey,
- child: SingleChildScrollView(
- scrollDirection: Axis.vertical,
- padding: EdgeInsets.only(top: 40, left: 25, right: 45, bottom:100),
+ body: Container(
+ decoration: BoxDecoration(
+ image: DecorationImage(
+ image: AssetImage('asset/image/WT_light_background.png'),
+ fit: BoxFit.cover,
+ alignment: Alignment.center,
+ ),
+ ),
+ child: Form(
+ key: _formKey,
+ child: SingleChildScrollView(
+ scrollDirection: Axis.vertical,
+ padding: EdgeInsets.only(
+ top: 40, left: 25, right: 45, bottom: 100),
- child: Container(
- alignment: Alignment.center,
+ child: Container(
+ alignment: Alignment.center,
- child: Column(
- children: [
- Row(
- mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ child: Column(
children: [
+ Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
- Expanded(
- child: TextFormField(
- style: TextStyle(fontSize: 12),
- decoration: InputDecoration(
- fillColor: Colors.white24,
- filled: true,
- labelText: AppLocalizations.of(context).translate('Email'),
- ),
- initialValue: customerChangingViewModel.customer.customer.email,
- onFieldSubmitted: (input) => customerChangingViewModel.customer.setEmail(input)
- )
- )
- ],
- ),
- Divider(),
- Row(
- mainAxisAlignment: MainAxisAlignment.spaceBetween,
- children: [
+ Expanded(
+ child:
+ TextFieldBlocBuilder(
+ key: LibraryKeys.loginEmailField,
+ style: TextStyle(fontSize: 12),
+ textFieldBloc: customerBloc.emailField,
+ decoration: InputDecoration(
+ fillColor: Colors.white24,
+ filled: true,
+ labelText: AppLocalizations.of(context)
+ .translate('Email'),
+ ),
+ ),
- Expanded(
- child: TextFormField(
- style: TextStyle(fontSize: 12),
- obscureText: true,
- decoration: InputDecoration(
- fillColor: Colors.white24,
- filled: true,
- labelText: AppLocalizations.of(context).translate('Password (Leave empty if you don\'t want to change)' ),
+ /* TextFormField(
+ style: TextStyle(fontSize: 12),
+ decoration: InputDecoration(
+ fillColor: Colors.white24,
+ filled: true,
+ labelText: AppLocalizations.of(context)
+ .translate('Email'),
+ ), */
+ // initialValue: customerChangingViewModel.customer
+ // .customer.email,
+ // onFieldSubmitted: (input) =>
+ // customerChangingViewModel.customer.setEmail(
+ // input)
+ )
+ ],
+ ),
+
+ Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+
+ Expanded(
+ child:
+ TextFieldBlocBuilder(
+ style: TextStyle(fontSize: 12),
+ textFieldBloc: customerBloc.passwordField,
+ suffixButton: SuffixButton.obscureText,
+ decoration: InputDecoration(
+ fillColor: Colors.white24,
+ filled: true,
+ labelText: AppLocalizations.of(context)
+ .translate('Password (Leave empty if no change)'),
+ ),
),
- initialValue: customerChangingViewModel.customer.customer.password,
- onFieldSubmitted: (input) => customerChangingViewModel.customer.setPassword(input)
+ /*TextFormField(
+ style: TextStyle(fontSize: 12),
+ obscureText: true,
+ decoration: InputDecoration(
+ fillColor: Colors.white24,
+ filled: true,
+ labelText: AppLocalizations.of(context)
+ .translate(
+ 'Password (Leave empty if you don\'t want to change)'),
+ ),
+ //initialValue: customerChangingViewModel.customer.customer.password,
+ // onFieldSubmitted: (input) => customerChangingViewModel.customer.setPassword(input)
+ )*/
)
- )
- ],
- ),
- Divider(),
- Row(
- mainAxisAlignment: MainAxisAlignment.spaceBetween,
- children: [
+ ],
+ ),
- Expanded(
- child: TextFormField(
- style: TextStyle(fontSize: 12),
- decoration: InputDecoration(
- fillColor: Colors.white24,
- filled: true,
- labelText: AppLocalizations.of(context).translate('Name'),
+ Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+
+ Expanded(
+ child: TextFieldBlocBuilder(
+ style: TextStyle(fontSize: 12),
+ textFieldBloc: customerBloc.nameField,
+ decoration: InputDecoration(
+ fillColor: Colors.white24,
+ filled: true,
+ labelText: AppLocalizations.of(context)
+ .translate('Name'),
+ ),
),
- initialValue: customerChangingViewModel.customer.customer.name,
- onFieldSubmitted: (input) => customerChangingViewModel.customer.setName(input)
)
- )
- ],
- ),
- Divider(),
- Row(
- mainAxisAlignment: MainAxisAlignment.spaceBetween,
- children: [
+ ],
+ ),
- Expanded(
- child: TextFormField(
- style: TextStyle(fontSize: 12),
- decoration: InputDecoration(
- fillColor: Colors.white24,
- filled: true,
+ Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
- labelText: AppLocalizations.of(context).translate('First Name'),
+ Expanded(
+ child: TextFieldBlocBuilder(
+ style: TextStyle(fontSize: 12),
+ textFieldBloc: customerBloc.firstNameField,
+ decoration: InputDecoration(
+ fillColor: Colors.white24,
+ filled: true,
+ labelText: AppLocalizations.of(context)
+ .translate('First Name'),
+ ),
),
- keyboardType: TextInputType.emailAddress,
- initialValue: customerChangingViewModel.customer.customer.firstname,
- onFieldSubmitted: (input) => customerChangingViewModel.customer.setFirstName(input)
)
- )
- ],
- ),
- Divider(),
- Row(
- mainAxisAlignment: MainAxisAlignment.spaceBetween,
- children: [
+ ],
+ ),
- Expanded(
- child: TextFormField(
- style: TextStyle(fontSize: 12),
- decoration: InputDecoration(
- fillColor: Colors.white24,
- filled: true,
- labelText: AppLocalizations.of(context).translate('Birth Year'),
- ),
- keyboardType: TextInputType.number,
- inputFormatters: [
- WhitelistingTextInputFormatter.digitsOnly
+ Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+
+ Expanded(
+ child: TextFieldBlocBuilder(
+ style: TextStyle(fontSize: 12),
+ textFieldBloc: customerBloc.birthYearField,
+ inputFormatters: [
+ FilteringTextInputFormatter(RegExp(r"[\d]"), allow: true)
],
- initialValue: customerChangingViewModel.customer.customer.birthYear.toString(),
- onFieldSubmitted: (input) => customerChangingViewModel.customer.setBirthYear(int.parse(input))
- )
- )
- ],
- ),
- Divider(),
- Row(
- mainAxisAlignment: MainAxisAlignment.spaceBetween,
- children: [
-
- Expanded(
- child: TextFormField(
- style: TextStyle(fontSize: 12),
- decoration: InputDecoration(
- fillColor: Colors.white24,
- filled: true,
- labelText: AppLocalizations.of(context).translate('Weight'),
+ decoration: InputDecoration(
+ fillColor: Colors.white24,
+ filled: true,
+ labelText: AppLocalizations.of(context)
+ .translate('Birth Year'),
+ ),
),
- inputFormatters: [
- WhitelistingTextInputFormatter.digitsOnly
- ],
- initialValue: customerChangingViewModel.customer.customer.weight.toString(),
- keyboardType: TextInputType.number,
- onFieldSubmitted: (input) => customerChangingViewModel.customer.setWeight(int.parse(input)),
)
- )
- ],
- ),
- Divider(),
- Row(
- mainAxisAlignment: MainAxisAlignment.spaceBetween,
- children: [
+ ],
+ ),
+ Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
- Expanded(
- child: DropdownButtonHideUnderline(
+ Expanded(
+ child: TextFieldBlocBuilder(
+ style: TextStyle(fontSize: 12),
+ textFieldBloc: customerBloc.weightField,
+ inputFormatters: [
+ FilteringTextInputFormatter(RegExp(r"[\d]"), allow: true)
+ ],
+ decoration: InputDecoration(
+ fillColor: Colors.white24,
+ filled: true,
+ labelText: AppLocalizations.of(context)
+ .translate('Weight'),
+ ),
+ ),
+ )
+ ],
+ ),
+ Divider(),
+ Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+
+ Expanded(
+ child: DropdownFieldBlocBuilder(
+ selectFieldBloc: customerBloc.genderField,
+ itemBuilder: (context, item) => item,
+ decoration: InputDecoration(
+ labelText: AppLocalizations.of(context).translate(
+ 'Select a gender'),
+ )
+ ),
+ )
+ /* child: DropdownButtonHideUnderline(
child: DropdownButton(
- hint: Text(AppLocalizations.of(context).translate('Select a gender')),
- style: TextStyle(fontSize: 12, color: Colors.black),
+ hint: Text(
+ AppLocalizations.of(context).translate(
+ 'Select a gender')),
+ style: TextStyle(
+ fontSize: 12, color: Colors.black),
focusColor: Colors.white24,
- value: selectedGender,
- items: genders.map((GenderItem gender){
+ // value: selectedGender,
+ items: genders.map((GenderItem gender) {
return DropdownMenuItem(
value: gender,
child: Text(gender.name)
);
}).toList(),
- onChanged:(GenderItem gender) => {
- setState(() {
- selectedGender = gender;
- customerChangingViewModel.customer.setSex(gender.dbValue);
+ onChanged: (GenderItem gender) => {
+ // setState(() {
+ // selectedGender = gender;
+ // customerChangingViewModel.customer.setSex(gender.dbValue);
- print ("Gender " + gender.name);
- })
- //model.customer.sex =
- },
+ print ("Gender " + gender.name);
+ //})
+ //model.customer.sex =
+ },
+ )
+ ) */
+ ],
+ ),
+ Row(
+ mainAxisAlignment: MainAxisAlignment.end,
+ children: [
+
+ Expanded(
+ child: RaisedButton(
+
+ color: Colors.orange,
+ textColor: Colors.white,
+ child: InkWell(
+ child: Text(
+ AppLocalizations.of(context).translate(
+ "Next"))),
+ onPressed: () =>
+ {
+ customerBloc.add(SubmitFormBloc()),
+ Navigator.of(context).pushNamed("customerGoalPage", arguments: customerBloc.customerRepository)
+ },
)
)
- )
+ ],
+ ),
],
),
- Row(
- mainAxisAlignment: MainAxisAlignment.end,
- children: [
-
- Expanded(
- child: RaisedButton(
-
- color: Colors.orange,
- textColor: Colors.white,
- child: InkWell(
- child: Text(AppLocalizations.of(context).translate("Next"))),
- onPressed: () => {
- customerChangingViewModel.saveCustomer(),
- Navigator.of(context).pushNamed("customerGoalPage", arguments: customerChangingViewModel)
- },
- )
- )
- ],
- ),
- ],
+ ),
),
- ),
- ),
- )
- )
+ )
+ )
+ );
+ })
);
}
+
}
\ No newline at end of file
diff --git a/lib/view/exercise_new_page.dart b/lib/view/exercise_new_page.dart
index dd6c7c4..9cb47d9 100644
--- a/lib/view/exercise_new_page.dart
+++ b/lib/view/exercise_new_page.dart
@@ -1,153 +1,156 @@
-import 'package:aitrainer_app/localization/app_language.dart';
+import 'package:aitrainer_app/bloc/exercise_form_bloc.dart';
import 'package:aitrainer_app/localization/app_localization.dart';
-import 'package:aitrainer_app/viewmodel/exercise_changing_view_model.dart';
+import 'package:aitrainer_app/model/auth.dart';
+import 'package:aitrainer_app/model/exercise_type.dart';
+import 'package:aitrainer_app/repository/exercise_repository.dart';
import 'package:flutter/services.dart';
-import 'package:intl/intl.dart';
+import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
-import 'package:provider/provider.dart';
-//import 'package:datetime_picker_formfield/datetime_picker_formfield.dart';
+import 'package:flutter_form_bloc/flutter_form_bloc.dart';
class ExerciseNewPage extends StatefulWidget{
_ExerciseNewPageState createState() => _ExerciseNewPageState();
}
-class _ExerciseNewPageState extends State {
- final List excluded = [43,44];
- final _formKey = GlobalKey();
+class _ExerciseNewPageState extends State {
@override
Widget build(BuildContext context) {
+ final ExerciseType exerciseType = ModalRoute.of(context).settings.arguments;
- return Consumer(
- builder: (context, model, child ) {
- String exerciseName = "";
- String customerName = "";
- if ( model != null ) {
- if ( model.exerciseViewModel == null ) {
- model.createNewModel();
- }
- model.exerciseViewModel.createNew();
- customerName = model != null && model.customer != null
- ? model.customer.name + " " +
- model.customer.firstname
- : "Please select a customer";
+ return BlocProvider(
+ create: (context) => ExerciseFormBloc(exerciseRepository: ExerciseRepository()),
+ child: Builder(builder: (context) {
+ // ignore: close_sinks
+ final exerciseBloc = BlocProvider.of(context);
- exerciseName = model != null &&
- model.exerciseType != null
- ? model.exerciseType.name
- : "Please select an exercise";
- }
+ exerciseBloc.exerciseRepository.setExerciseType(exerciseType);
+ String exerciseName = exerciseBloc.exerciseRepository.exerciseType.name;
- AppLanguage appLanguage = AppLanguage();
- var date = DateTime.now();
- String dateName = DateFormat(DateFormat.YEAR_MONTH_DAY, appLanguage.appLocal.toString()).format(date.toUtc()) +
- " " +DateFormat(DateFormat.HOUR_MINUTE, appLanguage.appLocal.toString()).format(date.toUtc());
-
- return Form(
- key: _formKey,
+ return Form(
autovalidate: true,
child: Scaffold(
- resizeToAvoidBottomInset: false,
+ resizeToAvoidBottomInset: true,
appBar: AppBar(
- leading: IconButton(
- icon: Icon(Icons.arrow_back, color: Colors.deepOrange),
- onPressed: () => {
- Navigator.of(context).pop()
- },
+ backgroundColor: Colors.transparent,
+ title: Row(
+ mainAxisAlignment: MainAxisAlignment.end,
+ children: [
+ 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(),
),
- title: Text(AppLocalizations.of(context).translate(exerciseName) + " " +
- AppLocalizations.of(context).translate('Save Exercise'),
- style: TextStyle(fontWeight: FontWeight.bold, fontSize: 18, color: Colors.deepOrange)),
- backgroundColor: Colors.white70,
),
body: Container(
- decoration: BoxDecoration(
+ width: MediaQuery.of(context).size.width,
+ height: MediaQuery.of(context).size.height,
+ decoration: BoxDecoration(
image: DecorationImage(
- image: AssetImage('asset/image/WT_login.png'),
- fit: BoxFit.cover,
- //height: double.infinity,
- //width: double.infinity,
- alignment: Alignment.center,
+ image: AssetImage('asset/image/WT_light_background.png'),
+ fit: BoxFit.fill,
+ alignment: Alignment.center,
),
),
child: Container(
- padding: const EdgeInsets.only (top: 65, left:25, right: 100),
- child: Column(
+ padding: const EdgeInsets.only (top: 25, left:25, right: 25),
+ child: SingleChildScrollView(
+ scrollDirection: Axis.vertical,
+ child: Column(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
- columnQuantityUnit(model),
- columnQuantity(model),
+ Divider(color: Colors.transparent,),
+ Divider(color: Colors.transparent,),
+ Divider(color: Colors.transparent,),
- Column(
- children: [
- Row(
- mainAxisAlignment: MainAxisAlignment.center,
- children: [
- new InkWell(
- child: new Text(dateName,
- style: TextStyle( fontSize: 16,color: Colors.blue)),
- ),
- ButtonTheme(
- minWidth: 30.0,
- height: 30.0,
- child: FlatButton(
+ Text(AppLocalizations.of(context).translate(exerciseName) + " " +
+ AppLocalizations.of(context).translate('Save Exercise'),
+ style: TextStyle(fontWeight: FontWeight.bold, fontSize: 18, color: Colors.deepOrange)),
+ Divider(color: Colors.transparent,),
+ Divider(color: Colors.transparent,),
+ Divider(color: Colors.transparent,),
+ columnQuantityUnit(exerciseBloc),
+ Divider(color: Colors.transparent,),
+ Divider(color: Colors.transparent,),
+ Divider(color: Colors.transparent,),
- padding: EdgeInsets.only(bottom: 0),
- color: Colors.transparent,
- splashColor: Colors.black26,
- child: Row(
- children: [
+ columnQuantity(exerciseBloc),
+ Divider(),
- Icon(Icons.arrow_forward_ios, color: Colors.orange,)
- ]),
- onPressed:() { print("date change");},
-
- )),
- ],
- ),
-
- new InkWell(
- child: new Text(AppLocalizations.of(context).translate('Exercise date and time'),
- style: TextStyle( fontSize: 16)),
- ),
-
- ]),
RaisedButton(
textColor: Colors.white,
color: Colors.deepOrange,
focusColor: Colors.white,
onPressed: () =>
{
- if (_formKey.currentState.validate()) {
- //model = ExerciseChangingViewModel(model.exerciseViewModel),
-
- if ( ! excluded.contains(model.exerciseType.exerciseTypeId) ) {
- model.addExercise(),
- },
- Navigator.pop(context),
- }
+ confirmationDialog( exerciseBloc ),
},
- child: Text("Save", style: TextStyle(fontSize: 16),)
+ child: Text(AppLocalizations.of(context).translate("Save"), style: TextStyle(fontSize: 16),)
),
+ Divider(color: Colors.transparent,),
+ Divider(color: Colors.transparent,),
+ Divider(color: Colors.transparent,),
]),
+ )
)
),
),
- );
- });
+ );
+ })
+ );
}
- Column columnQuantityUnit( ExerciseChangingViewModel model) {
+ Column columnQuantityUnit( ExerciseFormBloc bloc ) {
Column column = Column();
- if ( model.exerciseType != null && model.exerciseType.unitQuantity == "1") {
+ if ( bloc.exerciseRepository.exerciseType != null &&
+ bloc.exerciseRepository.exerciseType.unitQuantity == "1") {
column = Column(
children: [
- TextFormField(
+ TextFieldBlocBuilder(
+ textFieldBloc: bloc.unitQuantityField,
+ textAlign: TextAlign.center,
+ style: TextStyle(fontSize: 30,
+ color: Colors.lightBlue,
+ fontWeight: FontWeight.bold),
+ inputFormatters: [
+ FilteringTextInputFormatter(RegExp(r"[\d.]"), allow: true)
+ ],
+ onChanged: (input) => {
+ print ("UnitQuantity value $input"),
+ bloc.exerciseRepository.setUnitQuantity(
+ double.parse(input))
+ },
+ decoration: InputDecoration(
+ fillColor: Colors.white,
+ filled: false,
+ hintStyle: TextStyle(fontSize: 16, color: Colors.black54, fontWeight: FontWeight.w100),
+ hintText: AppLocalizations.of(context).translate("The number of the exercise done with"),
+ labelStyle: TextStyle(fontSize: 16, color: Colors.lightBlue),
+ labelText: AppLocalizations.of(context).translate(
+ bloc.exerciseRepository.exerciseType.unitQuantityUnit),
+ ),
+ ),
+ /*TextFormField(
+ decoration: InputDecoration(
+ fillColor: Colors.white,
+ filled: false,
+ hintStyle: TextStyle(fontSize: 16, color: Colors.black54, fontWeight: FontWeight.w100),
+ hintText: AppLocalizations.of(context).translate("The number of the exercise done with"),
+ labelStyle: TextStyle(fontSize: 16, color: Colors.lightBlue),
+ labelText: AppLocalizations.of(context).translate(
+ bloc.exerciseRepository.exerciseType.unitQuantityUnit),
+ ),
autovalidate: true,
textAlign: TextAlign.center,
- initialValue: "0",
+ initialValue: "",
style: TextStyle(fontSize: 30,
color: Colors.lightBlue,
fontWeight: FontWeight.bold),
@@ -155,18 +158,19 @@ class _ExerciseNewPageState extends State {
return validateNumberInput(input);
},
inputFormatters: [
- WhitelistingTextInputFormatter(RegExp(r"[\d.]"))
+ FilteringTextInputFormatter(RegExp(r"[\d.]"))
+ //WhitelistingTextInputFormatter(RegExp(r"[\d.]"))
],
onChanged: (input) => {
print ("UnitQuantity value $input"),
- model.exerciseViewModel.setUnitQuantity(
+ bloc.exerciseRepository.setUnitQuantity(
double.parse(input))
},
- ),
+ ), */
new InkWell(
child: new Text(AppLocalizations.of(context).translate(
- model.exerciseType.unitQuantityUnit),
+ bloc.exerciseRepository.exerciseType.unitQuantityUnit),
style: TextStyle(fontSize: 16)),
),
@@ -175,16 +179,48 @@ class _ExerciseNewPageState extends State {
return column;
}
- Column columnQuantity( ExerciseChangingViewModel model) {
- Column column = Column();
-
- column = Column(
+ Column columnQuantity( ExerciseFormBloc bloc ) {
+ Column column = Column(
children: [
- TextFormField(
+ TextFieldBlocBuilder(
+ textFieldBloc: bloc.quantityField,
+ textAlign: TextAlign.center,
+ style: TextStyle(fontSize: 50,
+ color: Colors.deepOrange,
+ fontWeight: FontWeight.bold),
+ inputFormatters: [
+ FilteringTextInputFormatter(RegExp(r"[\d.]"), allow: true)
+ ],
+ onChanged: (input) =>
+ {
+ print ("Quantity value $input"),
+ bloc.exerciseRepository.setQuantity(double.parse(input)),
+ bloc.exerciseRepository.setUnit(bloc.exerciseRepository.exerciseType.unit)
+ },
+ decoration: InputDecoration(
+ fillColor: Colors.white,
+ filled: false,
+ hintStyle: TextStyle(fontSize: 16, color: Colors.black54, fontWeight: FontWeight.w100),
+ hintText: AppLocalizations.of(context).translate("The number of the exercise"),
+ labelStyle: TextStyle(fontSize: 16, color: Colors.deepOrange),
+ labelText: AppLocalizations.of(context).translate(
+ bloc.exerciseRepository.exerciseType.unit),
+ ),
+ ),
+ /* TextFormField(
+ decoration: InputDecoration(
+ fillColor: Colors.white,
+ filled: false,
+ hintText: AppLocalizations.of(context).translate("The number of the exercise"),
+ hintStyle: TextStyle(fontSize: 16, color: Colors.black54, fontWeight: FontWeight.w100),
+ labelStyle: TextStyle(fontSize: 16, color: Colors.deepOrange),
+ labelText: AppLocalizations.of(context).translate(
+ bloc.exerciseRepository.exerciseType.unit),
+ ),
autovalidate: true,
textAlign: TextAlign.center,
- initialValue: "0",
- style: TextStyle(fontSize: 60,
+ initialValue: "",
+ style: TextStyle(fontSize: 50,
color: Colors.deepOrange,
fontWeight: FontWeight.bold),
validator: (input) {
@@ -195,17 +231,12 @@ class _ExerciseNewPageState extends State {
],
onChanged: (input) =>
{
- print ("Quantity value $input"),
- model.exerciseViewModel.setQuantity(
- double.parse(input)),
- model.exerciseViewModel.setUnit(model.exerciseType.unit)
+ print ("Quantity value $input"),
+ bloc.exerciseRepository.setQuantity(double.parse(input)),
+ bloc.exerciseRepository.setUnit(bloc.exerciseRepository.exerciseType.unit)
}
- ),
- new InkWell(
- child: new Text(AppLocalizations.of(context).translate(model.exerciseType.unit),
- style: TextStyle(fontSize: 16)),
- ),
+ ),*/
]);
@@ -238,4 +269,65 @@ class _ExerciseNewPageState extends State {
return null;
}
+
+ void confirmationDialog( ExerciseFormBloc bloc ) {
+
+ print("exercise validated " + bloc.exerciseRepository.exercise.quantity.toString());
+ if ( bloc.exerciseRepository.exercise.quantity == null) {
+ return;
+ }
+
+ String quantity = bloc.exerciseRepository.exercise.quantity % 1 == 0?
+ bloc.exerciseRepository.exercise.quantity.round().toString() :
+ bloc.exerciseRepository.exercise.quantity.toString();
+
+ String unitQuantity = bloc.exerciseRepository.exercise.unitQuantity % 1 == 0?
+ bloc.exerciseRepository.exercise.unitQuantity.round().toString() :
+ bloc.exerciseRepository.exercise.unitQuantity.toString();
+
+
+ showCupertinoDialog(
+ useRootNavigator: true,
+ context: context,
+ barrierDismissible: false,
+ builder:(_) => CupertinoAlertDialog(
+ title: Text(AppLocalizations.of(context).translate("Do you save this exercise with these parameters?")),
+ content: Column(
+
+ children: [
+ Divider(),
+ Text(AppLocalizations.of(context).translate("Exercise") + ": " +
+ AppLocalizations.of(context).translate(bloc.exerciseRepository.exerciseType.name),
+ style: (TextStyle(color: Colors.blue)),),
+ Text(quantity + " " +
+ AppLocalizations.of(context).translate(bloc.exerciseRepository.exerciseType.unit),
+ style: (TextStyle(color: Colors.deepOrange)),),
+ Text(bloc.exerciseRepository.exerciseType.unitQuantity == "1" ?
+ AppLocalizations.of(context).translate("with") + " "
+ + unitQuantity + " "
+ + AppLocalizations.of(context).translate(bloc.exerciseRepository.exerciseType.unitQuantityUnit) :
+ "",
+ style: (TextStyle(color: Colors.deepOrange)),
+ ),
+
+ ]),
+ actions: [
+ FlatButton(
+ child: Text(AppLocalizations.of(context).translate("No")),
+ onPressed: () => Navigator.pop(context),
+ ),
+ FlatButton(
+ child: Text(AppLocalizations.of(context).translate("Yes")),
+ onPressed: () => {
+ bloc.exerciseRepository.setCustomer(Auth().userLoggedIn),
+ bloc.exerciseRepository.addExercise(),
+
+ Navigator.pop(context),
+ Navigator.pop(context),
+ },
+ )
+ ],
+ )
+ );
+ }
}
diff --git a/lib/view/exercise_type_list_page.dart b/lib/view/exercise_type_list_page.dart
deleted file mode 100644
index ce19ebb..0000000
--- a/lib/view/exercise_type_list_page.dart
+++ /dev/null
@@ -1,59 +0,0 @@
-import 'package:aitrainer_app/viewmodel/exercise_type_changing_view_model.dart';
-import 'package:aitrainer_app/viewmodel/exercise_type_view_model.dart';
-import 'package:aitrainer_app/widgets/exercise_type_list_widget.dart';
-import 'package:flutter/material.dart';
-import 'package:flutter/cupertino.dart';
-import 'package:aitrainer_app/widgets/nav_drawer.dart';
-
-class ExerciseTypeListPage extends StatefulWidget{
- _ExerciseTypeListPageState createState() => _ExerciseTypeListPageState();
-}
-
-class _ExerciseTypeListPageState extends State {
- Future> _exerciseTypes;
- final _exerciseTypeViewModel = ExerciseTypeChangingViewModel(null);
-
- // Push the page and remove everything else
- navigateToPage(BuildContext context, String page) {
- Navigator.of(context).pushNamedAndRemoveUntil(page, (Route route) => false);
- }
-
- @override
- void initState() {
- super.initState();
- _exerciseTypes = _exerciseTypeViewModel.getExerciseTypes();
- }
-
- @override
- Widget build(BuildContext context) {
- return Scaffold(
- drawer: NavDrawer(),
- appBar: AppBar(
- title: Text('Exercises'),
- ),
- body: Center(
- child: FutureBuilder>(
- future: _exerciseTypes,
- builder: (context, snapshot) {
- if (snapshot.hasData) {
- return ExerciseTypeListWidget(exerciseTypes: _exerciseTypeViewModel.exerciseTypeList);
- } else if (snapshot.hasError) {
- return Text("${snapshot.error}");
- }
-
- // By default, show a loading spinner.
- return CircularProgressIndicator();
- },
- ),
- ),
- floatingActionButton: FloatingActionButton(
- onPressed: () => Navigator.pushNamed(
- context,
- 'exerciseTypeNewPage',
- ),
- child: Icon(Icons.add,),
- mini: true,
- )
- );
- }
-}
\ No newline at end of file
diff --git a/lib/view/exercise_type_modify_page.dart b/lib/view/exercise_type_modify_page.dart
deleted file mode 100644
index 2ba415a..0000000
--- a/lib/view/exercise_type_modify_page.dart
+++ /dev/null
@@ -1,67 +0,0 @@
-import 'package:aitrainer_app/viewmodel/exercise_type_changing_view_model.dart';
-import 'package:aitrainer_app/viewmodel/exercise_type_view_model.dart';
-import 'package:flutter/material.dart';
-import 'package:flutter/cupertino.dart';
-import 'package:aitrainer_app/widgets/nav_drawer.dart';
-
-// ignore: must_be_immutable
-class ExerciseTypeModifyPage extends StatefulWidget{
- ExerciseTypeViewModel exerciseTypeViewModel;
- ExerciseTypeModifyPage({this.exerciseTypeViewModel});
- _ExerciseTypeModifyPageState createState() => _ExerciseTypeModifyPageState();
-}
-
-class _ExerciseTypeModifyPageState extends State {
- final _formKey = GlobalKey();
-
- @override
- Widget build(BuildContext context) {
- final ExerciseTypeViewModel exerciseType = ModalRoute.of(context).settings.arguments;
- ExerciseTypeChangingViewModel changeModel;
- return Scaffold(
- drawer: NavDrawer(),
- appBar: AppBar(
- title: Text('Modify "' + exerciseType.name + '"' ),
- ),
- body: Center(
- child: Form(
- key:_formKey,
- child: Column(
- children: [
- TextFormField(
- initialValue: exerciseType.name,
- decoration: InputDecoration(
- border: OutlineInputBorder(),
- labelText: 'Exercise',
- ),
- validator: (input) => input.length == 0 ? "Please type the name of the exercise" : null,
- onChanged: (input) => exerciseType.setName(input),
- ) ,
- TextFormField(
- initialValue: exerciseType.description,
- minLines: 4,
- maxLines: 10,
- decoration: InputDecoration(
- border: OutlineInputBorder(),
- labelText: 'Description',
- ),
- onChanged: (input) => exerciseType.setDescription(input),
- )
- ],
- ),
- ),
- ),
- floatingActionButton: FloatingActionButton(
- onPressed: () => {
- if (_formKey.currentState.validate()) {
- changeModel = ExerciseTypeChangingViewModel(exerciseType),
- changeModel.saveExerciseType(),
- Navigator.pop(context),
- }
- },
- child: Icon(Icons.save,),
- mini: true,
- )
- );
- }
-}
diff --git a/lib/view/exercise_type_new_page.dart b/lib/view/exercise_type_new_page.dart
deleted file mode 100644
index c568428..0000000
--- a/lib/view/exercise_type_new_page.dart
+++ /dev/null
@@ -1,64 +0,0 @@
-import 'package:aitrainer_app/viewmodel/exercise_type_changing_view_model.dart';
-import 'package:aitrainer_app/viewmodel/exercise_type_view_model.dart';
-import 'package:flutter/material.dart';
-import 'package:flutter/cupertino.dart';
-import 'package:aitrainer_app/widgets/nav_drawer.dart';
-
-class ExerciseTypeNewPage extends StatefulWidget{
- _ExerciseTypeNewPageState createState() => _ExerciseTypeNewPageState();
-}
-
-class _ExerciseTypeNewPageState extends State {
- final ExerciseTypeViewModel exerciseType = ExerciseTypeViewModel();
- final _formKey = GlobalKey();
-
- @override
- Widget build(BuildContext context) {
- ExerciseTypeChangingViewModel model;
- exerciseType.createNew();
- return Scaffold(
- drawer: NavDrawer(),
- appBar: AppBar(
- title: Text('New exercise'),
- ),
- body: Center(
- child: Form(
- key: _formKey,
- child: Column(
- children: [
- TextFormField(
- decoration: InputDecoration(
- border: OutlineInputBorder(),
- labelText: 'Exercise',
- ),
- validator: (input) => input.length == 0 ? "Please type the name of the exercise" : null,
- onChanged: (input) => exerciseType.setName(input),
- ) ,
- TextFormField(
- minLines: 4,
- maxLines: 10,
- decoration: InputDecoration(
- border: OutlineInputBorder(),
- labelText: 'Description',
- ),
- onChanged: (input) => exerciseType.setDescription(input),
- )
- ],
- ),
- ),
- ),
- floatingActionButton: FloatingActionButton(
- onPressed: () => {
- if (_formKey.currentState.validate()) {
- model = ExerciseTypeChangingViewModel(exerciseType),
- model.addExerciseType(),
- model.addNewExercise(exerciseType),
- Navigator.pop(context),
- }
- },
- child: Icon(Icons.save,),
- mini: true,
- )
- );
- }
-}
\ No newline at end of file
diff --git a/lib/view/login.dart b/lib/view/login.dart
index 0136261..88e4372 100644
--- a/lib/view/login.dart
+++ b/lib/view/login.dart
@@ -1,162 +1,201 @@
+import 'package:aitrainer_app/bloc/login_form_bloc.dart';
+import 'package:aitrainer_app/bloc/account/account_bloc.dart';
import 'package:aitrainer_app/localization/app_localization.dart';
-import 'package:aitrainer_app/model/auth.dart';
-import 'package:aitrainer_app/view/account.dart';
-import 'package:aitrainer_app/viewmodel/customer_changing_view_model.dart';
-import 'package:aitrainer_app/viewmodel/user_changing_view_model.dart';
-import 'package:aitrainer_app/viewmodel/user_view_model.dart';
+import 'package:aitrainer_app/repository/user_repository.dart';
+import 'package:aitrainer_app/util/common.dart';
+import 'package:aitrainer_app/widgets/splash.dart';
import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
-import 'package:provider/provider.dart';
+import 'package:flutter_bloc/flutter_bloc.dart';
+import 'package:flutter_facebook_login/flutter_facebook_login.dart';
+import 'package:flutter_form_bloc/flutter_form_bloc.dart';
+import '../library_keys.dart';
-class LoginPage extends StatefulWidget{
- _LoginPageState createState() => _LoginPageState();
+class LoginPage extends StatelessWidget {
+ @override
+ Widget build(BuildContext context) {
+ return LoginWidget();
+ }
}
-class _LoginPageState extends State {
+class LoginWidget extends StatefulWidget {
+ LoginWidget();
+
+ @override
+ State createState() => _LoginWidget();
+}
+
+class _LoginWidget extends State {
final GlobalKey _scaffoldKey = new GlobalKey();
- final UserViewModel user = UserViewModel();
- final bool _obscureText = true;
final _formKey = GlobalKey();
@override
Widget build(BuildContext context) {
- UserChangingViewModel model = UserChangingViewModel(user);
- CustomerChangingViewModel customerChangingViewModel = Provider.of(context, listen: false);
- user.createNew();
- Future customer;
- final State stateAccount = ModalRoute.of(context).settings.arguments;
-
- return Scaffold(
- key: _scaffoldKey,
- body: Container(
- decoration: BoxDecoration(
- image: DecorationImage(
- image: AssetImage('asset/image/WT_login.png'),
- fit: BoxFit.cover,
- //height: double.infinity,
- //width: double.infinity,
- alignment: Alignment.center,
- ),
- ),
- child: Form(
- key: _formKey,
+ final accountBloc = BlocProvider.of(context);
+ return BlocProvider(
+ create: (context) => LoginFormBloc(
+ userRepository: UserRepository(),
+ accountBloc: accountBloc
+ ),
+ child: Builder(builder: (context) {
+ final loginBloc = BlocProvider.of(context);
+ return Scaffold(
+ key: _scaffoldKey,
+ body: FormBlocListener(
+ onSubmitting: (context, state) {
+ LoadingDialog.show(context);
+ },
+ onSuccess: (context, state) {
+ LoadingDialog.hide(context);
+ Navigator.of(context).pushNamed('home');
+ },
+ onFailure: (context, state) {
+ LoadingDialog.hide(context);
+ showInSnackBar(state.failureResponse);
+ },
child: Container(
- padding: const EdgeInsets.only (left: 25, right: 100),
- child: Column(
- mainAxisAlignment: MainAxisAlignment.spaceAround,
- children: [
- Spacer(flex: 4),
- Row(
- mainAxisAlignment: MainAxisAlignment.start,
- children: [
- new InkWell(
- child: new Text(
- AppLocalizations.of(context).translate(
- 'Login'),
- style: TextStyle(fontWeight: FontWeight.bold,
- fontSize: 24)),
- ),
- ],
- ),
-
- TextFormField(
- decoration: InputDecoration(
- fillColor: Colors.white,
- filled: true,
- labelText: 'Email',
- ),
- validator: (String input) {
- RegExp exp = new RegExp(r"[\w._]+\@[\w._]+.[a-z]+",
- caseSensitive: false,
- multiLine: false,);
- String ret = exp.hasMatch(input) == true ?
- null :
- AppLocalizations.of(context).translate(
- 'Please type an email address');
- return ret;
- },
- onChanged: (input) => user.setEmail(input),
- ),
- Spacer(flex: 1),
- new TextFormField(
- decoration: const InputDecoration(
- filled: true,
- labelText: "Password",
- fillColor: Colors.white,
- focusColor: Colors.white,
- ),
- validator: (val) => val.length < 6
- ? AppLocalizations.of(context).translate(
- 'Password too short')
- : null,
- obscureText: _obscureText,
- onChanged: (input) => user.setPassword(input),
- ),
- Spacer(flex: 1),
- Row(
- mainAxisAlignment: MainAxisAlignment.end,
- children: [ new FlatButton(
- child: Image.asset('asset/image/WT_OK.png',
- width: 100,
- height: 100
- ),
- onPressed: () =>
- {
- if (_formKey.currentState.validate()) {
- model = UserChangingViewModel(user),
- model.getUser().then((_) =>
- {
- if ( stateAccount != null ) {
- stateAccount.setState(() {
- print("update account");
- }),
- },
- customerChangingViewModel.customer.setCustomer(Auth().userLoggedIn),
- Navigator.pop(context),
- }).catchError(( error, stackTrace )=> showInSnackBar(error)
- ),
- }
- }),
- ]),
- Spacer(flex: 2),
- Row(
- mainAxisAlignment: MainAxisAlignment.spaceAround,
- children: [
- new InkWell(
- child: new Text(
- AppLocalizations.of(context).translate(
- 'SignUp')),
- onTap: () =>
- Navigator.of(context).pushNamed(
- 'registration'),
- ),
- Spacer(flex: 1),
- new InkWell(
- child: new Text(
- AppLocalizations.of(context).translate(
- 'Privacy')),
- onTap: () =>
- Navigator.of(context).pushNamed('gdpr'),
- ),
- Spacer(flex: 2),
- ]),
- Spacer(flex: 2),
- ])
+ decoration: BoxDecoration(
+ image: DecorationImage(
+ image: AssetImage('asset/image/WT_login.png'),
+ fit: BoxFit.cover,
+ //height: double.infinity,
+ //width: double.infinity,
+ alignment: Alignment.center,
+ ),
+ ),
+ child: buildLoginForm(loginBloc, accountBloc),
),
),
- )
+ );
+ }));
+ }
+
+ Widget buildLoginForm(LoginFormBloc formBloc, AccountBloc accountBloc) {
+ final cWidth = Common.mediaSizeWidth(context);
+
+ return Form(
+ key: _formKey,
+ child: Container(
+ padding: const EdgeInsets.only(left: 25, right: 100),
+ child:
+ ListView(shrinkWrap: false, padding: EdgeInsets.only(top: 120.0),
+ children: [
+ FlatButton(
+ child: new Image.asset(
+ 'asset/image/login_fb.png',
+ width: cWidth * .85,
+ ),
+ onPressed: () => {
+ _fbLogin(),
+ print("Login with FB"),
+ },
+ ),
+ Text(AppLocalizations.of(context).translate("OR")),
+ Divider(),
+ Row(
+ mainAxisAlignment: MainAxisAlignment.start,
+ children: [
+ new InkWell(
+ child: new Text(
+ AppLocalizations.of(context).translate('Login'),
+ style: TextStyle(
+ fontWeight: FontWeight.bold, fontSize: 24)),
+ ),
+ ],
+ ),
+ Divider(),
+ TextFieldBlocBuilder(
+ key: LibraryKeys.loginEmailField,
+ textFieldBloc: formBloc.emailField,
+ decoration: InputDecoration(
+ fillColor: Colors.white,
+ filled: true,
+ labelText: 'Email',
+ ),
+ ),
+ Divider(
+ color: Colors.transparent,
+ ),
+ TextFieldBlocBuilder(
+ key: LibraryKeys.loginPasswordField,
+ textFieldBloc: formBloc.passwordField,
+ decoration: InputDecoration(
+ fillColor: Colors.white,
+ filled: true,
+ labelText: 'Password',
+ ),
+ suffixButton: SuffixButton.obscureText,
+ ),
+ Divider(
+ color: Colors.transparent,
+ ),
+ Row(
+ mainAxisAlignment: MainAxisAlignment.end,
+ children: [
+ new FlatButton(
+ key: LibraryKeys.loginOKButton,
+ child: Image.asset('asset/image/WT_OK.png',
+ width: 100, height: 100),
+ onPressed: () => {
+ formBloc.add(SubmitFormBloc())
+ }),
+ ]),
+ Divider(
+ color: Colors.transparent,
+ ),
+ Row(
+ mainAxisAlignment: MainAxisAlignment.spaceAround,
+ children: [
+ new InkWell(
+ child: new Text(
+ AppLocalizations.of(context).translate('SignUp')),
+ onTap: () =>
+ Navigator.of(context).pushNamed('registration'),
+ ),
+ Spacer(flex: 1),
+ new InkWell(
+ child: new Text(
+ AppLocalizations.of(context).translate('Privacy')),
+ onTap: () => Navigator.of(context).pushNamed('gdpr'),
+ ),
+ Spacer(flex: 2),
+ ]),
+ ])),
);
}
+
void showInSnackBar(String error) {
- _scaffoldKey.currentState.showSnackBar(
- SnackBar(
- backgroundColor: Colors.orange,
- content: Text(
- AppLocalizations.of(context).translate("Customer does not exist or the password is wrong") + " " + error,
- style: TextStyle(color: Colors.white))
- )
- );
+ _scaffoldKey.currentState.showSnackBar(SnackBar(
+ backgroundColor: Colors.orange,
+ content: Text(error, style: TextStyle(color: Colors.white))));
}
-}
\ No newline at end of file
+
+ Future _fbLogin() async {
+ final FacebookLogin facebookSignIn = new FacebookLogin();
+ final FacebookLoginResult result = await facebookSignIn.logIn(['email']);
+
+ switch (result.status) {
+ case FacebookLoginStatus.loggedIn:
+ final FacebookAccessToken accessToken = result.accessToken;
+ showInSnackBar('''
+ Logged in!
+
+ Token: ${accessToken.token}
+ User id: ${accessToken.userId}
+ Expires: ${accessToken.expires}
+ Permissions: ${accessToken.permissions}
+ Declined permissions: ${accessToken.declinedPermissions}
+ ''');
+ break;
+ case FacebookLoginStatus.cancelledByUser:
+ showInSnackBar('Login cancelled by the user.');
+ break;
+ case FacebookLoginStatus.error:
+ showInSnackBar('Something went wrong with the login process.\n'
+ 'Here\'s the error Facebook gave us: ${result.errorMessage}');
+ break;
+ }
+ }
+}
diff --git a/lib/view/menu_page.dart b/lib/view/menu_page.dart
index c2f8a4c..f376d82 100644
--- a/lib/view/menu_page.dart
+++ b/lib/view/menu_page.dart
@@ -1,161 +1,115 @@
+import 'package:aitrainer_app/bloc/menu/menu_bloc.dart';
import 'package:aitrainer_app/localization/app_localization.dart';
-import 'package:aitrainer_app/model/auth.dart';
-import 'package:aitrainer_app/model/exercise_type.dart';
-import 'package:aitrainer_app/model/workout_tree.dart';
-import 'package:aitrainer_app/util/common.dart';
-import 'package:aitrainer_app/util/menu_tests.dart';
-import 'package:aitrainer_app/viewmodel/exercise_changing_view_model.dart';
import 'package:aitrainer_app/widgets/bottom_nav.dart';
+import 'package:aitrainer_app/widgets/menu_page_widget.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
-import 'dart:collection';
-import 'package:provider/provider.dart';
+import 'package:flutter/scheduler.dart';
+import 'package:flutter_bloc/flutter_bloc.dart';
+
// ignore: must_be_immutable
-class MenuPage extends StatefulWidget {
- _MenuPageState _state;
+class MenuPage extends StatelessWidget {
static const routeName = '/menu_page';
int parent;
+ MenuBloc menuBloc;
MenuPage({this.parent});
- @override
- _MenuPageState createState() {
- _state = new _MenuPageState();
- return _state;
- }
-
-}
-
-class _MenuPageState extends State {
- final BottomNavigator bottomNav = BottomNavigator();
-
@override
Widget build(BuildContext context) {
- final MenuTests menu = MenuTests(context);
+ menuBloc = BlocProvider.of(context);
return Scaffold(
- appBar: AppBar(
- backgroundColor: Colors.transparent,
- title: Row(
- mainAxisAlignment: MainAxisAlignment.spaceBetween,
- children: [
- Text(AppLocalizations.of(context).translate("Tests")),
- Image.asset(
- 'asset/image/WT_long_logo.png',
- fit: BoxFit.cover,
- height: 65.0,
- ),
- ],
- ),
- leading: IconButton(
- icon: Icon(Icons.arrow_back, color: Colors.white),
- onPressed: () => {
- this.setState(() {
- widget.parent = 0;
- },
- )},
- ),
- ),
-
- body: Container(
- decoration: BoxDecoration(
- image: DecorationImage(
- image: AssetImage('asset/image/WT_menu_dark.png'),
- fit: BoxFit.fill,
- alignment: Alignment.center,
- ),
+ appBar: AppBar(
+ backgroundColor: Colors.transparent,
+ title: Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ Text(AppLocalizations.of(context).translate("Tests")),
+ Image.asset(
+ 'asset/image/WT_long_logo.png',
+ fit: BoxFit.cover,
+ height: 65.0,
),
- child: CustomScrollView(
- scrollDirection: Axis.vertical,
- slivers: [
- buildMenuColumn(widget.parent, context, menu)
- ]
- )
+ ],
),
+ leading: IconButton(
+ icon: Icon(Icons.arrow_back, color: Colors.white),
+ onPressed: () =>
+ {
+ menuBloc.add(MenuTreeUp(parent: 0))
+ },
+ ),
+ ),
+
+ body: Container(
+ decoration: BoxDecoration(
+ image: DecorationImage(
+ image: AssetImage('asset/image/WT_menu_dark.png'),
+ fit: BoxFit.fill,
+ alignment: Alignment.center,
+ ),
+ ),
+ child: BlocConsumer(
+ listener: (context, state) {
+ if (state is MenuError) {
+ Scaffold.of(context).showSnackBar(SnackBar(
+ backgroundColor: Colors.orange,
+ content: Text("error", style: TextStyle(color: Colors.white))));
+ } else if ( state is MenuLoading ) {
+ return MenuPageWidget();
+ }
+ },
+ // ignore: missing_return
+ builder: (context, state) {
+ if ( state is MenuInitial ) {
+ return LoadingMenuDialog();
+ } else if (state is MenuReady ) {
+ return MenuPageWidget();
+ } else if ( state is MenuLoading ) {
+ return LoadingMenuDialog();
+ }
+ }
+ )
+ ),
+ bottomNavigationBar: BottomNavigator(bottomNavIndex: 0)
);
}
-
- SliverList buildMenuColumn(int parent, BuildContext context, MenuTests menu) {
- LinkedHashMap tree = menu.getMenuItems();
- List _columnChildren = List();
- ExerciseType exerciseType;
- ExerciseChangingViewModel model = Provider.of(context, listen: false);
-
- tree.forEach((treeName, value) {
- WorkoutTree workoutTree = value as WorkoutTree;
-
- if ( workoutTree.parent == parent ) {
- _columnChildren.add(
- Container(
- padding: EdgeInsets.only(top: 16.0),
- child: Center(
- child: Stack(
- alignment: Alignment.bottomLeft,
- overflow: Overflow.visible,
- children: [
- FlatButton(
- child: _getButtonImage(workoutTree),
- padding: EdgeInsets.all(0.0),
- onPressed:() =>
- {
- print("Hi!, Menu clicked " + workoutTree.id.toString()),
- if ( workoutTree.child == false ) {
- this.setState(() {
- widget.parent = workoutTree.id;
- },
- ),
- } else {
- exerciseType = Common.getExerciseType(workoutTree.exerciseTypeId),
- model.setExerciseType(exerciseType),
- model.setCustomer(Auth().userLoggedIn),
- if ( Auth().userLoggedIn == null ) {
- Scaffold.of(context)
- . showSnackBar(
- SnackBar(
- backgroundColor: Colors.orange,
- content: Text(
- AppLocalizations.of(context).translate('Please log in'),
- style: TextStyle(color: Colors.white))
- ))
- } else {
- Navigator.of(context).pushNamed('exerciseNewPage'),
- }
- }
-
- }
- ),
- InkWell(
- child: Text(workoutTree.name, style: TextStyle(color: workoutTree.color, fontSize: workoutTree.fontSize, fontFamily: 'Arial', fontWeight: FontWeight.w900 ),),
- highlightColor: workoutTree.color,
- )]))));
-
- }
- });
- //_columnChildren.add(Spacer(flex: 3));
- SliverList sliverList =
- SliverList(
- delegate: SliverChildListDelegate(
- _columnChildren
- )
- );
-
- return sliverList;
- }
-
- dynamic _getButtonImage(WorkoutTree workoutTree) {
- dynamic image;
- if ( workoutTree.imageName.startsWith("http") ) {
- image = FadeInImage.assetNetwork(
- image: workoutTree.imageName,
- placeholder: 'asset/image/dots.gif',
- //imageScale: 0.1,
- height: 180,
- placeholderScale: 0.1,
- );
- } else {
- image = Image.asset(workoutTree.imageName, height: 180,);
- }
- return image;
- }
-
}
+
+class LoadingMenuDialog extends StatefulWidget {
+
+ LoadingMenuDialog({Key key}) : super(key: key);
+
+ @override
+ State createState() => _LoadingMenuDialog();
+}
+
+class _LoadingMenuDialog extends State {
+ @override
+ void initState() {
+ super.initState();
+
+ /// We require the initializers to run after the loading screen is rendered
+ SchedulerBinding.instance.addPostFrameCallback((_) {
+ BlocProvider.of(context).add(MenuCreate());
+ });
+ }
+ @override
+ Widget build(BuildContext context) {
+ return WillPopScope(
+ onWillPop: () async => false,
+ child: Center(
+ child: Card(
+ child: Container(
+ width: 80,
+ height: 80,
+ padding: EdgeInsets.all(12.0),
+ child: CircularProgressIndicator(),
+ color: Colors.transparent,
+ ),
+ ),
+ ),
+ );
+ }
+}
\ No newline at end of file
diff --git a/lib/view/registration.dart b/lib/view/registration.dart
index 70572e8..946ba4f 100644
--- a/lib/view/registration.dart
+++ b/lib/view/registration.dart
@@ -1,142 +1,216 @@
-
+import 'package:aitrainer_app/bloc/account/account_bloc.dart';
+import 'package:aitrainer_app/bloc/registration_form_bloc.dart';
import 'package:aitrainer_app/localization/app_localization.dart';
-import 'package:aitrainer_app/model/auth.dart';
-import 'package:aitrainer_app/viewmodel/customer_changing_view_model.dart';
-import 'package:aitrainer_app/viewmodel/user_changing_view_model.dart';
-import 'package:aitrainer_app/viewmodel/user_view_model.dart';
+import 'package:aitrainer_app/util/common.dart';
+import 'package:aitrainer_app/repository/customer_repository.dart';
+import 'package:aitrainer_app/repository/user_repository.dart';
+import 'package:aitrainer_app/widgets/splash.dart';
import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
-import 'package:provider/provider.dart';
+import 'package:flutter_bloc/flutter_bloc.dart';
+import 'package:flutter_facebook_login/flutter_facebook_login.dart';
+import 'package:flutter_form_bloc/flutter_form_bloc.dart';
-class RegistrationPage extends StatefulWidget{
- _RegistrationPageState createState() => _RegistrationPageState();
+import '../library_keys.dart';
+
+class RegistrationPage extends StatelessWidget {
+ final UserRepository userRepository = UserRepository();
+ final CustomerRepository customerRepository = CustomerRepository();
+
+ @override
+ Widget build(BuildContext context) {
+ return RegistrationWidget(
+ userRepository: userRepository, customerRepository: customerRepository);
+ }
}
-class _RegistrationPageState extends State {
- final GlobalKey _scaffoldKey = new GlobalKey();
- final UserViewModel user = UserViewModel();
- bool _obscureText = true;
+class RegistrationWidget extends StatefulWidget {
+ final UserRepository userRepository;
+ final CustomerRepository customerRepository;
+ RegistrationWidget({this.userRepository, this.customerRepository});
+
+ @override
+ State createState() => _RegistrationWidget();
+}
+
+class _RegistrationWidget extends State {
+ final GlobalKey _scaffoldKey = new GlobalKey();
final _formKey = GlobalKey();
@override
Widget build(BuildContext context) {
- UserChangingViewModel model = UserChangingViewModel(user);
- CustomerChangingViewModel customerChangingViewModel = Provider.of(context, listen: false);
- user.createNew();
+ final cWidth = Common.mediaSizeWidth(context);
+ // ignore: close_sinks
+ final accountBloc = BlocProvider.of(context);
+ return BlocProvider(
+ create: (context) => RegistrationFormBloc(
+ userRepository: UserRepository(),
+ accountBloc: accountBloc),
+ child: Builder(builder: (context) {
+ // ignore: close_sinks
+ final registrationBloc = BlocProvider.of(context);
- return Scaffold(
- key: _scaffoldKey,
- body: Container(
- decoration: BoxDecoration(
- image: DecorationImage(
- image: AssetImage('asset/image/WT_login.png'),
- fit: BoxFit.cover,
- //height: double.infinity,
- //width: double.infinity,
- alignment: Alignment.center,
- ),
- ),
- child: Form(
- key: _formKey,
- child: Container(
- padding: const EdgeInsets.only (left:25, right: 100),
- child: Column(
- mainAxisAlignment: MainAxisAlignment.spaceAround,
- children: [
- Spacer(flex:4),
- Row(
- mainAxisAlignment: MainAxisAlignment.start,
- children: [
- new InkWell(
- child: new Text(AppLocalizations.of(context).translate('SignUp'),
- style: TextStyle(fontWeight: FontWeight.bold, fontSize: 24)),
- ),
- ],
- ),
+ return Scaffold(
+ key: _scaffoldKey,
+ body: FormBlocListener(
+ onSubmitting: (context, state) {
+ LoadingDialog.show(context);
+ },
+ onSuccess: (context, state) {
+ LoadingDialog.hide(context);
+ Navigator.of(context).pushNamed('customerModifyPage');
+ },
+ onFailure: (context, state) {
+ LoadingDialog.hide(context);
+ showInSnackBar(state.failureResponse);
+ },
+ child: Container(
+ decoration: BoxDecoration(
+ image: DecorationImage(
+ image: AssetImage('asset/image/WT_login.png'),
+ fit: BoxFit.cover,
+ //height: double.infinity,
+ //width: double.infinity,
+ alignment: Alignment.center,
+ ),
+ ),
+ child: Form(
+ key: _formKey,
+ child: Container(
+ padding: const EdgeInsets.only(left: 25, right: 100),
+ child: ListView(
+ shrinkWrap: false,
+ padding: EdgeInsets.only(top: 120.0),
+ //mainAxisAlignment: MainAxisAlignment.spaceAround,
+ children: [
+ //Spacer(flex:4),
- TextFormField(
- decoration: InputDecoration(
- fillColor: Colors.white,
- filled:true,
- labelText: 'Email',
- ),
- validator: (String input) {
- RegExp exp = new RegExp(r"[\w._]+\@[\w._]+.[a-z]+",
- caseSensitive: false,
- multiLine: false,);
- String ret = exp.hasMatch(input) == true ?
- null:
- AppLocalizations.of(context).translate('Please type an email address');
- return ret;
- },
- onChanged: (input) => user.setEmail(input),
- ),
- Spacer(flex:1),
- new TextFormField(
- decoration: const InputDecoration(
- filled:true,
- labelText: "Password",
- fillColor: Colors.white,
- focusColor: Colors.white,
- ),
- validator: (val) => val.length < 6 ? AppLocalizations.of(context).translate('Password too short') : null,
- obscureText: _obscureText,
- onChanged: (input) => user.setPassword(input),
- ),
- Spacer(flex:1),
- Row(
- mainAxisAlignment: MainAxisAlignment.end,
- children: [ new FlatButton(
- child: Image.asset('asset/image/WT_OK.png',
- width: 100,
- height:100
+ FlatButton(
+ child: new Image.asset(
+ 'asset/image/login_fb.png',
+ width: cWidth * .85,
+ ),
+ onPressed: () => {
+ _fbLogin(),
+ print("Login with FB"),
+ },
),
- onPressed:() => {
- if (_formKey.currentState.validate()) {
- model = UserChangingViewModel(user),
- model.addUser().then((_) =>
- {
- Navigator.of(context).pushNamed("customerModifyPage",),
- customerChangingViewModel.customer.setCustomer(Auth().userLoggedIn),
- }).catchError(( error, stackTrace )=> showInSnackBar()
+ Text(AppLocalizations.of(context).translate("OR")),
+ Divider(),
+ Row(
+ mainAxisAlignment: MainAxisAlignment.start,
+ children: [
+ new InkWell(
+ child: new Text(
+ AppLocalizations.of(context)
+ .translate('SignUp'),
+ style: TextStyle(
+ fontWeight: FontWeight.bold,
+ fontSize: 24)),
),
-
- }
- }),
- ]),
- Spacer(flex:2),
- Row(
- mainAxisAlignment: MainAxisAlignment.spaceAround,
- children: [
- new InkWell(
- child: new Text(AppLocalizations.of(context).translate('Login')),
- onTap: () => Navigator.of(context).pushNamed('login'),
- ),
- Spacer(flex:1),
- new InkWell(
- child: new Text(AppLocalizations.of(context).translate('Privacy')),
- onTap: () => Navigator.of(context).pushNamed('gdpr'),
- ),
- Spacer(flex:2),
- ]),
- Spacer(flex:2),
- ])
- ),
- ),
- ),
-
- );
+ ],
+ ),
+ Divider(),
+ TextFieldBlocBuilder(
+ key: LibraryKeys.loginEmailField,
+ textFieldBloc: registrationBloc.emailField,
+ decoration: InputDecoration(
+ fillColor: Colors.white,
+ filled: true,
+ labelText: 'Email',
+ ),
+ ),
+ Divider(
+ color: Colors.transparent,
+ ),
+ TextFieldBlocBuilder(
+ key: LibraryKeys.loginPasswordField,
+ textFieldBloc: registrationBloc.passwordField,
+ decoration: InputDecoration(
+ fillColor: Colors.white,
+ filled: true,
+ labelText: 'Password',
+ ),
+ suffixButton: SuffixButton.obscureText,
+ ),
+ Divider(
+ color: Colors.transparent,
+ ),
+ Row(
+ mainAxisAlignment: MainAxisAlignment.end,
+ children: [
+ new FlatButton(
+ child: Image.asset(
+ 'asset/image/WT_OK.png',
+ width: 100,
+ height: 100),
+ onPressed: () => {
+ registrationBloc.add(SubmitFormBloc())
+ }),
+ ]),
+ Row(
+ mainAxisAlignment:
+ MainAxisAlignment.spaceAround,
+ children: [
+ new InkWell(
+ child: new Text(AppLocalizations.of(context)
+ .translate('Login')),
+ onTap: () => Navigator.of(context)
+ .pushNamed('login'),
+ ),
+ Spacer(flex: 1),
+ new InkWell(
+ child: new Text(AppLocalizations.of(context)
+ .translate('Privacy')),
+ onTap: () =>
+ Navigator.of(context).pushNamed('gdpr'),
+ ),
+ Spacer(flex: 2),
+ ]),
+ //Spacer(flex:2),
+ ])),
+ ),
+ ),
+ ),
+ );
+ }));
}
- void showInSnackBar() {
- _scaffoldKey.currentState.showSnackBar(
- SnackBar(
- backgroundColor: Colors.orange,
- content: Text(
- AppLocalizations.of(context).translate("Customer exists"),
- style: TextStyle(color: Colors.white))
- )
- );
+ void showInSnackBar(String error) {
+ _scaffoldKey.currentState.showSnackBar(SnackBar(
+ backgroundColor: Colors.orange,
+ content: Text(
+ AppLocalizations.of(context)
+ .translate("There is an error: during registration:") +
+ " " +
+ error,
+ style: TextStyle(color: Colors.white))));
}
-}
\ No newline at end of file
+
+ Future _fbLogin() async {
+ final FacebookLogin facebookSignIn = new FacebookLogin();
+ final FacebookLoginResult result = await facebookSignIn.logIn(['email']);
+
+ switch (result.status) {
+ case FacebookLoginStatus.loggedIn:
+ final FacebookAccessToken accessToken = result.accessToken;
+ showInSnackBar('''
+ Logged in!
+ Token: ${accessToken.token}
+ User id: ${accessToken.userId}
+ Expires: ${accessToken.expires}
+ Permissions: ${accessToken.permissions}
+ Declined permissions: ${accessToken.declinedPermissions}
+ ''');
+ break;
+ case FacebookLoginStatus.cancelledByUser:
+ showInSnackBar('Login cancelled by the user.');
+ break;
+ case FacebookLoginStatus.error:
+ showInSnackBar('Something went wrong with the login process.\n'
+ 'Here\'s the error Facebook gave us: ${result.errorMessage}');
+ break;
+ }
+ }
+}
diff --git a/lib/view/settings.dart b/lib/view/settings.dart
index 27f4adf..cb4e1ff 100644
--- a/lib/view/settings.dart
+++ b/lib/view/settings.dart
@@ -1,30 +1,21 @@
+import 'package:aitrainer_app/bloc/settings/settings_bloc.dart';
import 'package:aitrainer_app/localization/app_language.dart';
import 'package:aitrainer_app/localization/app_localization.dart';
import 'package:aitrainer_app/widgets/bottom_nav.dart';
+import 'package:aitrainer_app/widgets/splash.dart';
import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
+import 'package:flutter_bloc/flutter_bloc.dart';
-class SettingsPage extends StatefulWidget{
- _SettingsPageState _state;
-
- _SettingsPageState createState() {
- _state = new _SettingsPageState();
- return _state;
- }
-}
-
-class _SettingsPageState extends State {
- final AppLanguage appLanguage = AppLanguage();
- Locale _locale;
-
- final _formKey = GlobalKey();
+class SettingsPage extends StatelessWidget{
@override
Widget build(BuildContext context) {
- BottomNavigator bottomNav = BottomNavigator();
- _locale = appLanguage.appLocal;
+ // ignore: close_sinks
+ SettingsBloc settingsBloc = BlocProvider.of(context);
+ settingsBloc.context = context;
return Scaffold(
appBar: AppBar(
title: Row(
@@ -50,54 +41,60 @@ class _SettingsPageState extends State {
),
),
child: Form(
- key: _formKey,
- child:
- ListView(
+ child: BlocConsumer(
+ listener: (context, state) {
+ if ( state is SettingsError ) {
+
+ }
+ },
+ // ignore: missing_return
+ builder: (context, state) {
+ if ( state is SettingsLoading ) {
+ return LoadingDialog();
+ } else if ( state is SettingsReady || state is SettingsInitial) {
+ return ListView(
padding: EdgeInsets.only(top: 150),
children: [
ListTile(
leading: Icon(Icons.language),
- subtitle: Text(AppLocalizations.of(context).translate("Change App Language")),
+ subtitle: Text(
+ AppLocalizations.of(context).translate(
+ "Change App Language")),
title: DropdownButton(
- value: _locale == Locale('en') ? AppLocalizations.of(context).translate("English") : AppLocalizations.of(context).translate("Hungarian"),
- items: [AppLocalizations.of(context).translate("English"), AppLocalizations.of(context).translate("Hungarian")]
- .map>((String value) {
+
+ value: state.props[0] == Locale('en')
+ ? AppLocalizations.of(context).translate(
+ "English")
+ : AppLocalizations.of(context).translate(
+ "Hungarian"),
+ items: [AppLocalizations.of(context).translate(
+ "English"), AppLocalizations.of(context)
+ .translate("Hungarian")
+ ]
+ .map>((String value) {
return DropdownMenuItem(
value: value,
child: Text(value),
);
}).toList(),
- onChanged:(String lang) => _changeLanguage(lang),
+ onChanged: (String lang) =>
+ settingsBloc.add(
+ SettingsChangeLanguage(language: lang)
+ ),
)
),
- ]
-
+ ]
+ );
+ } else {
+ return Container();
+ }
+ }
),
),
),
- bottomNavigationBar: bottomNav.buildBottomNavigator(context, widget._state)
+ bottomNavigationBar: BottomNavigator(bottomNavIndex: 3)
);
}
-
- _changeLanguage( String lang ) {
-
- setState(() {
- switch ( lang ) {
- case "English":
- case "Angol":
- _locale = Locale('en');
- break;
- case "Hungarian":
- case "Magyar":
- _locale = Locale('hu');
- break;
- }
- appLanguage.changeLanguage(_locale);
- AppLocalizations.of(context).setLocale(_locale);
- AppLocalizations.of(context).load();
-
- });
- }
}
\ No newline at end of file
diff --git a/lib/viewmodel/customer_changing_view_model.dart b/lib/viewmodel/customer_changing_view_model.dart
deleted file mode 100644
index b0d7e0c..0000000
--- a/lib/viewmodel/customer_changing_view_model.dart
+++ /dev/null
@@ -1,37 +0,0 @@
-import 'package:aitrainer_app/service/customer_service.dart';
-import 'package:flutter/cupertino.dart';
-import 'package:aitrainer_app/model/customer.dart';
-
-import 'customer_view_model.dart';
-
-class CustomerChangingViewModel extends ChangeNotifier {
- CustomerViewModel customer = CustomerViewModel();
- List customerList = List();
-
- CustomerChangingViewModel(customer) {
- this.customer = customer;
- }
-
- Future addCustomer() async {
- this.customer = customer;
- final Customer modelCustomer = customer.getCustomer();
- await CustomerApi().addCustomer(modelCustomer);
- }
-
- Future saveCustomer() async {
- //this.customer = customer;
- final Customer modelCustomer = customer.getCustomer();
- await CustomerApi().saveCustomer(modelCustomer);
- }
-
- Future> getCustomers() async {
- final results = await CustomerApi().getRealCustomers("");
- this.customerList = results.map((item) => CustomerViewModel(customer: item)).toList();
- notifyListeners();
- return this.customerList;
- }
-
- addNewCustomerToList(CustomerViewModel customerViewModel) {
- customerList.add(customerViewModel);
- }
-}
\ No newline at end of file
diff --git a/lib/viewmodel/customer_view_model.dart b/lib/viewmodel/customer_view_model.dart
deleted file mode 100644
index 4e8546c..0000000
--- a/lib/viewmodel/customer_view_model.dart
+++ /dev/null
@@ -1,88 +0,0 @@
-import 'package:aitrainer_app/model/customer.dart';
-
-class CustomerViewModel {
- Customer customer;
- bool visibleDetails = false;
-
- CustomerViewModel({this.customer});
-
- String get name {
- return this.customer.name;
- }
-
- String get firstName {
- return this.customer.firstname;
- }
-
- String get sex {
- return this.customer.sex == "m" ? "Man" : "Woman";
- }
-
- int get birthYear {
- return this.customer.birthYear;
- }
-
- String get goal {
- return this.customer.goal;
- }
-
- String get fitnessLevel {
- return this.customer.fitnessLevel;
- }
-
- String get bodyType {
- return this.customer.bodyType;
- }
-
- setName(String name) {
- this.customer.name = name;
- }
- setFirstName(String firstName) {
- this.customer.firstname = firstName;
- }
-
- setPassword( String password ) {
- this.customer.password = password;
- }
-
- setEmail(String email) {
- this.customer.email = email;
- }
-
-
- setSex(String sex) {
- this.customer.sex = sex;
- }
-
- setWeight( int weight) {
- this.customer.weight = weight;
- }
-
- setBirthYear( int birthYear ) {
- this.customer.birthYear = birthYear;
- }
-
- setFitnessLevel( String level ) {
- this.customer.fitnessLevel = level;
- }
-
- setGoal( String goal ) {
- this.customer.goal = goal;
- }
-
- setBodyType(String bodyType) {
- this.customer.bodyType = bodyType;
- }
-
- createNew() {
- this.customer = Customer();
- }
-
- Customer getCustomer() {
- return this.customer;
- }
-
- void setCustomer ( Customer customer ) {
- this.customer = customer;
- }
-}
diff --git a/lib/viewmodel/exercise_changing_view_model.dart b/lib/viewmodel/exercise_changing_view_model.dart
deleted file mode 100644
index 0b3df88..0000000
--- a/lib/viewmodel/exercise_changing_view_model.dart
+++ /dev/null
@@ -1,56 +0,0 @@
-import 'package:aitrainer_app/model/customer.dart';
-import 'package:aitrainer_app/model/exercise.dart';
-import 'package:aitrainer_app/model/exercise_type.dart';
-import 'package:aitrainer_app/service/exercise_service.dart';
-import 'package:flutter/cupertino.dart';
-
-import 'exercise_view_model.dart';
-
-class ExerciseChangingViewModel with ChangeNotifier {
- Customer customer;
- ExerciseType exerciseType;
- List exerciseList = List();
-
- ExerciseViewModel exerciseViewModel = ExerciseViewModel();
-
- ExerciseChangingViewModel(exerciseViewModel) {
- this.exerciseViewModel = exerciseViewModel;
- }
-
- int quantity;
-
- setCustomer(Customer customer) {
- this.customer = customer;
- notifyListeners();
- }
-
- setExerciseType( ExerciseType exerciseType) {
- this.exerciseType = exerciseType;
- notifyListeners();
- }
-
- setQuantity(int quantity) {
- this.quantity = quantity;
- }
-
- addExercise() async {
-// this.exerciseViewModel = exerciseViewModel;
- final Exercise modelExercise = exerciseViewModel.getExercise();
- modelExercise.customerId = this.customer.customerId;
- modelExercise.exerciseTypeId = this.exerciseType.exerciseTypeId;
- await ExerciseApi().addExercise(modelExercise);
- }
-
- createNewModel() {
- exerciseViewModel = ExerciseViewModel();
- exerciseViewModel.createNew();
- }
-
- Future> getExercisesByCustomer( int customerId ) async {
- final results = await ExerciseApi().getExercisesByCustomer(customerId);
- this.exerciseList = results.map((item) => ExerciseViewModel(exercise: item)).toList();
- notifyListeners();
- return this.exerciseList;
- }
-
-}
\ No newline at end of file
diff --git a/lib/viewmodel/exercise_type_changing_view_model.dart b/lib/viewmodel/exercise_type_changing_view_model.dart
deleted file mode 100644
index 3c53aca..0000000
--- a/lib/viewmodel/exercise_type_changing_view_model.dart
+++ /dev/null
@@ -1,36 +0,0 @@
-import 'package:aitrainer_app/model/exercise_type.dart';
-import 'package:aitrainer_app/viewmodel/exercise_type_view_model.dart';
-import 'package:flutter/cupertino.dart';
-import 'package:aitrainer_app/service/exercisetype_service.dart';
-
-class ExerciseTypeChangingViewModel extends ChangeNotifier {
- ExerciseTypeViewModel exerciseType = ExerciseTypeViewModel();
- List exerciseTypeList = List();
-
- ExerciseTypeChangingViewModel(exerciseType) {
- this.exerciseType = exerciseType;
- }
-
- Future addExerciseType() async {
- this.exerciseType = exerciseType;
- final ExerciseType modelExerciseType = exerciseType.getExerciseType();
- await ExerciseTypeApi().addExerciseType(modelExerciseType);
- }
-
- Future saveExerciseType() async {
- this.exerciseType = exerciseType;
- final ExerciseType modelExerciseType = exerciseType.getExerciseType();
- await ExerciseTypeApi().saveExerciseType(modelExerciseType);
- }
-
- Future> getExerciseTypes() async {
- final results = await ExerciseTypeApi().getExerciseTypes("");
- this.exerciseTypeList = results.map((item) => ExerciseTypeViewModel( exerciseType: item) ).toList();
- notifyListeners();
- return this.exerciseTypeList;
- }
-
- addNewExercise(ExerciseTypeViewModel exerciseTypeViewModel) {
- exerciseTypeList.add(exerciseTypeViewModel);
- }
-}
\ No newline at end of file
diff --git a/lib/viewmodel/exercise_type_view_model.dart b/lib/viewmodel/exercise_type_view_model.dart
deleted file mode 100644
index f666366..0000000
--- a/lib/viewmodel/exercise_type_view_model.dart
+++ /dev/null
@@ -1,36 +0,0 @@
-import 'package:aitrainer_app/model/exercise_type.dart';
-
-class ExerciseTypeViewModel {
- ExerciseType exerciseType;
- bool visible = false;
-
- ExerciseTypeViewModel( {this.exerciseType} );
-
- String get name {
- return this.exerciseType.name;
- }
-
- setName(String name) {
- this.exerciseType.name = name;
- }
-
- String get description {
- return this.exerciseType.description;
- }
-
- setDescription(String description) {
- this.exerciseType.description = description;
- }
-
- int get exerciseTypeId {
- return this.exerciseType.exerciseTypeId;
- }
-
- ExerciseType getExerciseType() {
- return this.exerciseType;
- }
-
- createNew() {
- this.exerciseType = ExerciseType();
- }
-}
\ No newline at end of file
diff --git a/lib/viewmodel/exercise_view_model.dart b/lib/viewmodel/exercise_view_model.dart
deleted file mode 100644
index 35fb91d..0000000
--- a/lib/viewmodel/exercise_view_model.dart
+++ /dev/null
@@ -1,31 +0,0 @@
-import 'package:aitrainer_app/model/exercise.dart';
-
-class ExerciseViewModel {
- Exercise exercise;
- ExerciseViewModel({this.exercise});
-
- createNew() {
- this.exercise = Exercise();
- exercise.dateAdd = DateTime.now();
- }
-
- setQuantity(double quantity) {
- this.exercise.quantity = quantity;
- }
-
- setUnitQuantity(double unitQuantity) {
- this.exercise.unitQuantity = unitQuantity;
- }
-
- setUnit( String unit) {
- this.exercise.unit = unit;
- }
-
- setDatetimeExercise(DateTime datetimeExercise) {
- this.exercise.dateAdd = datetimeExercise;
- }
-
- Exercise getExercise() {
- return this.exercise;
- }
-}
\ No newline at end of file
diff --git a/lib/viewmodel/user_changing_view_model.dart b/lib/viewmodel/user_changing_view_model.dart
deleted file mode 100644
index bfc4b9d..0000000
--- a/lib/viewmodel/user_changing_view_model.dart
+++ /dev/null
@@ -1,22 +0,0 @@
-import 'package:aitrainer_app/model/user.dart';
-import 'package:aitrainer_app/service/customer_service.dart';
-import 'package:aitrainer_app/viewmodel/user_view_model.dart';
-import 'package:flutter/cupertino.dart';
-
-class UserChangingViewModel extends ChangeNotifier {
- UserViewModel userViewModel = UserViewModel();
-
- UserChangingViewModel(userViewModel) {
- this.userViewModel = userViewModel;
- }
-
- Future addUser() async {
- final User modelUser = userViewModel.getUser();
- await CustomerApi().addUser(modelUser);
- }
-
- Future getUser() async {
- final User modelUser = userViewModel.getUser();
- await CustomerApi().getUser(modelUser);
- }
-}
\ No newline at end of file
diff --git a/lib/viewmodel/user_view_model.dart b/lib/viewmodel/user_view_model.dart
deleted file mode 100644
index 20586d3..0000000
--- a/lib/viewmodel/user_view_model.dart
+++ /dev/null
@@ -1,23 +0,0 @@
-import 'package:aitrainer_app/model/user.dart';
-
-class UserViewModel {
- User user;
-
- UserViewModel({this.user});
-
- setEmail(String email) {
- this.user.email = email;
- }
-
- setPassword(String password) {
- this.user.password = password;
- }
-
- User getUser() {
- return this.user;
- }
-
- createNew() {
- this.user = User();
- }
-}
diff --git a/lib/widgets/bottom_nav.dart b/lib/widgets/bottom_nav.dart
index 31099fd..bf0c86a 100644
--- a/lib/widgets/bottom_nav.dart
+++ b/lib/widgets/bottom_nav.dart
@@ -1,15 +1,35 @@
import 'package:aitrainer_app/localization/app_localization.dart';
import 'package:flutter/material.dart';
-class BottomNavigator {
- BottomNavigationBar buildBottomNavigator(BuildContext context, State state) {
+class BottomNavigator extends StatefulWidget {
+ int bottomNavIndex = 0;
+ BottomNavigator({this.bottomNavIndex}) {
+ this.bottomNavIndex = bottomNavIndex;
+ }
+
+ @override
+ _NawDrawerWidget createState() => _NawDrawerWidget();
+}
+
+class _NawDrawerWidget extends State {
+
+
+ @override
+ void initState() {
+ super.initState();
+ }
+
+ @override
+ Widget build(BuildContext context) {
+
return BottomNavigationBar(
- currentIndex: 0, // this will be set when a new tab is tapped
- backgroundColor: Colors.black12,
+ currentIndex: widget.bottomNavIndex, // this will be set when a new tab is tapped
+ backgroundColor: Colors.transparent,
selectedItemColor: Colors.yellow,
unselectedItemColor: Colors.lightGreen,
- type: BottomNavigationBarType.shifting,
+ //type: BottomNavigationBarType.shifting,
showSelectedLabels: true,
+ showUnselectedLabels: true,
items: [
BottomNavigationBarItem(
backgroundColor: Colors.black12,
@@ -18,23 +38,29 @@ class BottomNavigator {
title: new Text(AppLocalizations.of(context).translate("Home")),
),
BottomNavigationBarItem(
- icon: new Icon(Icons.event, color: Colors.lightGreen),
+ backgroundColor: Colors.black12,
+ icon: new Icon(Icons.confirmation_number, color: Colors.lightGreen),
activeIcon: new Icon(Icons.event, color: Colors.yellow,),
title: new Text(AppLocalizations.of(context).translate("Events")),
),
+
BottomNavigationBarItem(
+ backgroundColor: Colors.black12,
icon: Icon(Icons.person, color: Colors.lightGreen,),
activeIcon: new Icon(Icons.person, color: Colors.yellow,),
title: Text(AppLocalizations.of(context).translate("Account"))
),
BottomNavigationBarItem(
+ backgroundColor: Colors.black12,
icon: Icon(Icons.settings, color: Colors.lightGreen),
activeIcon: new Icon(Icons.settings, color: Colors.yellow,),
title: Text(AppLocalizations.of(context).translate("Settings"))
)
],
onTap:(index) {
- // ignore: invalid_use_of_protected_member
+ setState(() {
+ widget.bottomNavIndex = index;
+ });
switch (index) {
case 0:
Navigator.of(context).pop();
@@ -59,4 +85,6 @@ class BottomNavigator {
}
);
}
+
+
}
\ No newline at end of file
diff --git a/lib/widgets/customer_list_widget.dart b/lib/widgets/customer_list_widget.dart
deleted file mode 100644
index 332783b..0000000
--- a/lib/widgets/customer_list_widget.dart
+++ /dev/null
@@ -1,67 +0,0 @@
-import 'package:aitrainer_app/viewmodel/exercise_changing_view_model.dart';
-import 'package:flutter/cupertino.dart';
-import 'package:flutter/material.dart';
-import 'package:aitrainer_app/viewmodel/customer_view_model.dart';
-import 'package:provider/provider.dart';
-
-class CustomerListWidget extends StatefulWidget {
- static const routeName = '/customer_list';
- final List customers;
-
- CustomerListWidget({this.customers});
-
- @override
- _CustomerListWidget createState() => _CustomerListWidget();
-
-}
-
-class _CustomerListWidget extends State {
-
-
- @override
- Widget build(BuildContext context) {
- return ListView.builder(
- itemCount: widget.customers.length,
- itemBuilder: (context, index) {
-
- final customer = widget.customers[index];
-
- return ListTile(
- contentPadding: EdgeInsets.all(10),
- leading:Icon(Icons.accessibility),
- title: Text(customer.name + " " + customer.firstName),
- subtitle:
- Container(
- child: Visibility(
- visible: customer.visibleDetails,
- child: Row(
- children: [
- Text(customer.birthYear.toString() + " years, " + customer.sex),
- new RaisedButton(
- child: new Text('Modify'),
- color: Color.fromRGBO(244, 122, 22, 0.9),
- onPressed: () => {
-
- },
- ),
- new RaisedButton(
- child: new Text('Select'),
- color: Colors.blueGrey,
- onPressed: () => {
- Provider.of(context, listen: false).setCustomer(customer.customer),
- Navigator.pop(context)
- },
- ),
- ],
- ),
- ),
- ),
- onTap: () { setState( () {
- customer.visibleDetails = customer.visibleDetails ? false : true;
- });
- },
- );
- },
- );
- }
-}
\ No newline at end of file
diff --git a/lib/widgets/datetime_picker.dart b/lib/widgets/datetime_picker.dart
deleted file mode 100644
index 2f5b5d6..0000000
--- a/lib/widgets/datetime_picker.dart
+++ /dev/null
@@ -1,65 +0,0 @@
-import 'package:flutter_datetime_picker/flutter_datetime_picker.dart';
-
-class CustomPicker extends CommonPickerModel {
- String digits(int value, int length) {
- return '$value'.padLeft(length, "0");
- }
-
- CustomPicker({DateTime currentTime, LocaleType locale}) : super(locale: locale) {
- this.currentTime = currentTime ?? DateTime.now();
- this.setLeftIndex(this.currentTime.hour);
- this.setMiddleIndex(this.currentTime.minute);
- this.setRightIndex(this.currentTime.second);
- }
-
- @override
- String leftStringAtIndex(int index) {
- if (index >= 0 && index < 24) {
- return this.digits(index, 2);
- } else {
- return null;
- }
- }
-
- @override
- String middleStringAtIndex(int index) {
- if (index >= 0 && index < 60) {
- return this.digits(index, 2);
- } else {
- return null;
- }
- }
-
- @override
- String rightStringAtIndex(int index) {
- if (index >= 0 && index < 60) {
- return this.digits(index, 2);
- } else {
- return null;
- }
- }
-
- @override
- String leftDivider() {
- return "|";
- }
-
- @override
- String rightDivider() {
- return "|";
- }
-
- @override
- List layoutProportions() {
- return [1, 2, 1];
- }
-
- @override
- DateTime finalTime() {
- return currentTime.isUtc
- ? DateTime.utc(currentTime.year, currentTime.month, currentTime.day,
- this.currentLeftIndex(), this.currentMiddleIndex(), this.currentRightIndex())
- : DateTime(currentTime.year, currentTime.month, currentTime.day, this.currentLeftIndex(),
- this.currentMiddleIndex(), this.currentRightIndex());
- }
-}
\ No newline at end of file
diff --git a/lib/widgets/exercise_type_list_widget.dart b/lib/widgets/exercise_type_list_widget.dart
deleted file mode 100644
index 9e3cb3d..0000000
--- a/lib/widgets/exercise_type_list_widget.dart
+++ /dev/null
@@ -1,75 +0,0 @@
-import 'package:aitrainer_app/viewmodel/exercise_changing_view_model.dart';
-import 'package:aitrainer_app/viewmodel/exercise_type_view_model.dart';
-import 'package:flutter/cupertino.dart';
-import 'package:flutter/material.dart';
-import 'package:provider/provider.dart';
-
-class ExerciseTypeListWidget extends StatefulWidget {
- final List exerciseTypes;
- ExerciseTypeListWidget({this.exerciseTypes});
-
- @override
- _ExerciseTypeListWidgetState createState() => _ExerciseTypeListWidgetState();
-}
-
-class _ExerciseTypeListWidgetState extends State {
- //static const routeName = '/exercise_type_list';
- bool visible = false;
-
- // Push the page and remove everything else
- navigateToPage(BuildContext context, String page) {
- Navigator.of(context).pushNamedAndRemoveUntil(page, (Route route) => false);
- }
-
- @override
- Widget build(BuildContext context) {
-
- return ListView.builder(
- itemCount: widget.exerciseTypes.length,
- itemBuilder: (context, index) {
-
- final exerciseType = widget.exerciseTypes[index];
-
- return ListTile(
- contentPadding: EdgeInsets.all(10),
- leading: Icon(Icons.directions_run),
- title: Text(exerciseType.name),
- subtitle:
- Container(
- child: Visibility(
- visible: exerciseType.visible,
- child: Column(
- children: [
- Text(exerciseType.description),
- new RaisedButton(
- child: new Text('Modify'),
- color: Color.fromRGBO(244, 122, 22, 0.9),
- onPressed: () => {
- Navigator.pushNamed(
- context,
- 'exerciseTypeModifyPage',
- arguments: exerciseType
- )
- },
- ),
- new RaisedButton(
- child: new Text('Select'),
- color: Colors.blueGrey,
- onPressed: () => {
- Navigator.pop(context),
- Provider.of(context, listen: false).setExerciseType(exerciseType.exerciseType),
- },
- ),
- ],
- ),
- ),
- ),
- onTap: () { setState( () {
- exerciseType.visible = true;
- });
- },
- );
- },
- );
- }
-}
diff --git a/lib/widgets/home.dart b/lib/widgets/home.dart
index 35fe2ed..6112843 100644
--- a/lib/widgets/home.dart
+++ b/lib/widgets/home.dart
@@ -1,12 +1,17 @@
+import 'package:aitrainer_app/bloc/session/session_bloc.dart';
+import 'package:aitrainer_app/bloc/settings/settings_bloc.dart';
import 'package:aitrainer_app/localization/app_language.dart';
-import 'package:aitrainer_app/localization/app_localization.dart';
+import 'package:aitrainer_app/model/auth.dart';
+import 'package:aitrainer_app/view/login.dart';
import 'package:aitrainer_app/view/menu_page.dart';
-import 'package:aitrainer_app/widgets/bottom_nav.dart';
+import 'package:aitrainer_app/view/registration.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
+import 'package:flutter/scheduler.dart';
import 'package:flutter/widgets.dart';
-import 'bottom_nav.dart';
-import 'nav_drawer.dart';
+import 'package:flutter_bloc/flutter_bloc.dart';
+import 'loading.dart';
+
class AitrainerHome extends StatefulWidget {
_HomePageState _state;
@@ -15,10 +20,6 @@ class AitrainerHome extends StatefulWidget {
_state = new _HomePageState();
return _state;
}
-
- void callback() {
- _state.setLangNoContext();
- }
}
class _HomePageState extends State {
@@ -28,30 +29,61 @@ class _HomePageState extends State