Aitrainer_app 1.1.1
test menu, customer modification, exercise save images, localization
Before Width: | Height: | Size: 3.0 MiB After Width: | Height: | Size: 3.0 MiB |
BIN
asset/image/WT_OK.png
Normal file
After Width: | Height: | Size: 101 KiB |
BIN
asset/image/WT_gain_muscle.png
Normal file
After Width: | Height: | Size: 1.6 MiB |
BIN
asset/image/WT_light_background.png
Normal file
After Width: | Height: | Size: 2.3 MiB |
BIN
asset/image/WT_login.png
Normal file
After Width: | Height: | Size: 2.1 MiB |
BIN
asset/image/WT_long_logo.png
Normal file
After Width: | Height: | Size: 181 KiB |
BIN
asset/image/WT_menu.png
Normal file
After Width: | Height: | Size: 4.4 MiB |
BIN
asset/image/WT_menu_backround.png
Normal file
After Width: | Height: | Size: 2.9 MiB |
BIN
asset/image/WT_menu_dark.png
Normal file
After Width: | Height: | Size: 2.8 MiB |
BIN
asset/image/WT_menu_welcome.png
Normal file
After Width: | Height: | Size: 3.9 MiB |
BIN
asset/image/WT_weight_loss.png
Normal file
After Width: | Height: | Size: 1.4 MiB |
BIN
asset/image/dots.gif
Normal file
After Width: | Height: | Size: 119 KiB |
BIN
asset/menu/1.1.1.cooper.png
Normal file
After Width: | Height: | Size: 781 KiB |
BIN
asset/menu/1.1.aerob.png
Normal file
After Width: | Height: | Size: 1.6 MiB |
BIN
asset/menu/1.2.1.300m.png
Normal file
After Width: | Height: | Size: 1.2 MiB |
BIN
asset/menu/1.2.2.400m.png
Normal file
After Width: | Height: | Size: 1.6 MiB |
BIN
asset/menu/1.2.anaerob.png
Normal file
After Width: | Height: | Size: 1.1 MiB |
BIN
asset/menu/1.cardio.png
Normal file
After Width: | Height: | Size: 1.2 MiB |
BIN
asset/menu/2.1.1.pull-ups.png
Normal file
After Width: | Height: | Size: 1.5 MiB |
BIN
asset/menu/2.1.2.pushup.png
Normal file
After Width: | Height: | Size: 1.2 MiB |
BIN
asset/menu/2.1.3.sit-ups.png
Normal file
After Width: | Height: | Size: 1.1 MiB |
BIN
asset/menu/2.1.4.squats.png
Normal file
After Width: | Height: | Size: 1.4 MiB |
BIN
asset/menu/2.1.5.timedpushup.png
Normal file
After Width: | Height: | Size: 1.4 MiB |
BIN
asset/menu/2.1.6.core.png
Normal file
After Width: | Height: | Size: 1.4 MiB |
BIN
asset/menu/2.1.endurance.png
Normal file
After Width: | Height: | Size: 1.4 MiB |
BIN
asset/menu/2.2.1.1.chestpress.png
Normal file
After Width: | Height: | Size: 1.5 MiB |
BIN
asset/menu/2.2.1.1RM.png
Normal file
After Width: | Height: | Size: 1.3 MiB |
BIN
asset/menu/2.2.1.2.pullups.png
Normal file
After Width: | Height: | Size: 1.2 MiB |
BIN
asset/menu/2.2.1.3.biceps.png
Normal file
After Width: | Height: | Size: 1.2 MiB |
BIN
asset/menu/2.2.1.4.triceps.png
Normal file
After Width: | Height: | Size: 1.5 MiB |
BIN
asset/menu/2.2.1.5.shoulders.png
Normal file
After Width: | Height: | Size: 1.4 MiB |
BIN
asset/menu/2.strength.png
Normal file
After Width: | Height: | Size: 988 KiB |
BIN
asset/menu/3.1.BMI.png
Normal file
After Width: | Height: | Size: 1.8 MiB |
BIN
asset/menu/3.2.BMR.png
Normal file
After Width: | Height: | Size: 1.8 MiB |
BIN
asset/menu/3.3.sizes.png
Normal file
After Width: | Height: | Size: 1.4 MiB |
BIN
asset/menu/3.bcs1.png
Normal file
After Width: | Height: | Size: 1.1 MiB |
79
i18n/en.json
Normal file
79
i18n/hu.json
Normal file
@ -0,0 +1,79 @@
|
||||
{
|
||||
"Customers And Exercises": "Ügyfelek és gyakorlatok",
|
||||
"Home": "Főoldal",
|
||||
"Customers": "Ügyfelek",
|
||||
"Exercises": "Gyakorlatok",
|
||||
"TRAINING!": "EDZÉS!",
|
||||
"Login": "Bejelentkezés",
|
||||
"Logout": "Kijelentkezés",
|
||||
"Change Language": "Nyelv",
|
||||
"Password too short": "A jelszó min. 6 karakterből álljon",
|
||||
"Please type an email address": "Kérlek írj be egy email címet",
|
||||
"SignUp": "Regisztráció",
|
||||
"Privacy": "Adatkezelés",
|
||||
"Change App Language": "Nyelvválasztás",
|
||||
"English": "Angol",
|
||||
"Hungarian": "Magyar",
|
||||
"Events": "Események",
|
||||
"Account": "Fiók",
|
||||
"Settings": "Beállítások",
|
||||
"Profile": "Személyes adatok",
|
||||
"Selected Language": "Választott nyelv",
|
||||
"gdpr_text": "",
|
||||
|
||||
"Please select an exercise": "Válassz ki egy gyakorlatot",
|
||||
"Cardio": "Kardió",
|
||||
"400m": "400m",
|
||||
"300m": "300m",
|
||||
"Aerobic": "Aerob",
|
||||
"Anaerobic": "Anaerob",
|
||||
"Cooper": "Cooper teszt",
|
||||
"Strength": "Erő",
|
||||
"Endurance": "Erő állóképesség",
|
||||
"Pushups": "Fekvőtámasz",
|
||||
"Timed Pushups": "Fekvőtámasz időre",
|
||||
"Core": "Core (plank)",
|
||||
"Squats": "Guggolás",
|
||||
"Sit-ups": "Felülés",
|
||||
"1RM": "1RM - Maxerő",
|
||||
"Chest Press": "Fekvenyomás",
|
||||
"Pull Ups": "Húzódszkodás",
|
||||
"Biceps": "Bicepsz",
|
||||
"Triceps": "Tricepsz",
|
||||
"Shoulders": "Vállak",
|
||||
"Body Compositions": "Testformálás",
|
||||
"BMI": "Testtömegindex",
|
||||
"BMR": "Alapanyagcsere érték",
|
||||
"Sizes": "Méretek",
|
||||
"Save Exercise": "gyakorlat mentése",
|
||||
"Save": "Save",
|
||||
|
||||
"Name": "Név",
|
||||
"Exercise": "Gyakorlat",
|
||||
"Quantity": "Mennyiség",
|
||||
"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",
|
||||
|
||||
"repeat": "ismétlés",
|
||||
"meter": "meter",
|
||||
"percent": "százalék",
|
||||
"kg": "kg",
|
||||
"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)",
|
||||
"First Name": "Keresztnév",
|
||||
"Birth Year": "Születési év",
|
||||
"Weight": "Tömeg",
|
||||
"Gender": "Nemed",
|
||||
"Man": "Férfi",
|
||||
"Woman": "Nő",
|
||||
"Next": "Tovább",
|
||||
"Select a gender": "Válaszd ki a nemet",
|
||||
|
||||
"Goal Settings": "Cél"
|
||||
|
||||
}
|
@ -29,8 +29,6 @@
|
||||
<key>UISupportedInterfaceOrientations</key>
|
||||
<array>
|
||||
<string>UIInterfaceOrientationPortrait</string>
|
||||
<string>UIInterfaceOrientationLandscapeLeft</string>
|
||||
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||
</array>
|
||||
<key>UISupportedInterfaceOrientations~ipad</key>
|
||||
<array>
|
||||
|
55
lib/localization/app_language.dart
Normal file
@ -0,0 +1,55 @@
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
|
||||
class AppLanguage extends ChangeNotifier {
|
||||
static final AppLanguage _singleton = AppLanguage._internal();
|
||||
|
||||
Locale _appLocale = Locale('en');
|
||||
|
||||
factory AppLanguage() {
|
||||
return _singleton;
|
||||
}
|
||||
|
||||
AppLanguage._internal();
|
||||
|
||||
static Future<AppLanguage> getInstance() async {
|
||||
return _singleton;
|
||||
}
|
||||
|
||||
Locale get appLocal => _appLocale ?? Locale("en");
|
||||
|
||||
fetchLocale() async {
|
||||
var prefs = await SharedPreferences.getInstance();
|
||||
if (prefs.getString('language_code') == null) {
|
||||
_appLocale = Locale('en');
|
||||
}
|
||||
_appLocale = Locale(prefs.getString('language_code'));
|
||||
print(" ---- Fetched lang: " + _appLocale.toString());
|
||||
}
|
||||
|
||||
getLocale(SharedPreferences prefs) {
|
||||
if (prefs.getString('language_code') == null) {
|
||||
_appLocale = Locale('en');
|
||||
}
|
||||
_appLocale = Locale(prefs.getString('language_code'));
|
||||
}
|
||||
|
||||
|
||||
void changeLanguage(Locale type) async {
|
||||
var prefs = await SharedPreferences.getInstance();
|
||||
if (_appLocale == type) {
|
||||
return;
|
||||
}
|
||||
if (type == Locale("hu")) {
|
||||
_appLocale = Locale("hu");
|
||||
await prefs.setString('language_code', 'hu');
|
||||
await prefs.setString('countryCode', 'HU');
|
||||
} else {
|
||||
_appLocale = Locale("en");
|
||||
await prefs.setString('language_code', 'en');
|
||||
await prefs.setString('countryCode', 'US');
|
||||
}
|
||||
print(" ---- Stored lang: " + _appLocale.toString());
|
||||
notifyListeners();
|
||||
}
|
||||
}
|
70
lib/localization/app_localization.dart
Normal file
@ -0,0 +1,70 @@
|
||||
import 'dart:convert';
|
||||
import 'dart:ui';
|
||||
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
|
||||
class AppLocalizations {
|
||||
Locale locale;
|
||||
|
||||
AppLocalizations(this.locale);
|
||||
|
||||
// Helper method to keep the code in the widgets concise
|
||||
// Localizations are accessed using an InheritedWidget "of" syntax
|
||||
static AppLocalizations of(BuildContext context) {
|
||||
return Localizations.of<AppLocalizations>(context, AppLocalizations);
|
||||
}
|
||||
|
||||
// Static member to have a simple access to the delegate from the MaterialApp
|
||||
static const LocalizationsDelegate<AppLocalizations> delegate =
|
||||
_AppLocalizationsDelegate();
|
||||
|
||||
Map<String, String> _localizedStrings;
|
||||
|
||||
setLocale(Locale locale) {
|
||||
this.locale = locale;
|
||||
}
|
||||
|
||||
Future<bool> load() async {
|
||||
// Load the language JSON file from the "lang" folder
|
||||
String jsonString =
|
||||
await rootBundle.loadString('i18n/${locale.languageCode}.json');
|
||||
Map<String, dynamic> jsonMap = json.decode(jsonString);
|
||||
|
||||
_localizedStrings = jsonMap.map((key, value) {
|
||||
return MapEntry(key, value.toString());
|
||||
});
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// This method will be called from every widget which needs a localized text
|
||||
String translate(String key) {
|
||||
return _localizedStrings[key];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class _AppLocalizationsDelegate
|
||||
extends LocalizationsDelegate<AppLocalizations> {
|
||||
// This delegate instance will never change (it doesn't even have fields!)
|
||||
// It can provide a constant constructor.
|
||||
const _AppLocalizationsDelegate();
|
||||
|
||||
@override
|
||||
bool isSupported(Locale locale) {
|
||||
// Include all of your supported language codes here
|
||||
return ['en', 'hu'].contains(locale.languageCode);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<AppLocalizations> load(Locale locale) async {
|
||||
// AppLocalizations class is where the JSON loading actually runs
|
||||
AppLocalizations localizations = new AppLocalizations(locale);
|
||||
await localizations.load();
|
||||
return localizations;
|
||||
}
|
||||
|
||||
@override
|
||||
bool shouldReload(_AppLocalizationsDelegate old) => false;
|
||||
}
|
334
lib/main.dart
@ -1,33 +1,43 @@
|
||||
import 'package:aitrainer_app/model/auth.dart';
|
||||
import 'package:aitrainer_app/service/api.dart';
|
||||
import 'package:aitrainer_app/service/customer_service.dart';
|
||||
import 'package:aitrainer_app/view/account.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:aitrainer_app/widgets/nav_drawer.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:flutter_localizations/flutter_localizations.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
import 'package:aitrainer_app/localization/app_localization.dart';
|
||||
|
||||
void main() {
|
||||
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.
|
||||
providers: [
|
||||
ChangeNotifierProvider(create: (context) => ExerciseChangingViewModel(null)),
|
||||
],
|
||||
child: AitrainerApp(),
|
||||
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.
|
||||
providers: [
|
||||
ChangeNotifierProvider(create: (context) => ExerciseChangingViewModel(null)),
|
||||
ChangeNotifierProvider(create: (context) => CustomerChangingViewModel(null)),
|
||||
],
|
||||
|
||||
child: AitrainerApp(),
|
||||
),
|
||||
);
|
||||
}
|
||||
@ -36,308 +46,54 @@ class AitrainerApp extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
|
||||
return MaterialApp(
|
||||
localizationsDelegates: [
|
||||
// ... app-specific localization delegate[s] here
|
||||
GlobalMaterialLocalizations.delegate,
|
||||
AppLocalizations.delegate,
|
||||
GlobalWidgetsLocalizations.delegate,
|
||||
GlobalCupertinoLocalizations.delegate,
|
||||
],
|
||||
supportedLocales: [
|
||||
const Locale('en'), // English
|
||||
const Locale('hu'), // Hungarian
|
||||
const Locale('en', "US"), // English
|
||||
const Locale('hu', "HU"), // Hungarian
|
||||
// ... other locales the app supports
|
||||
],
|
||||
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(),
|
||||
'login': (context) => LoginPage(),
|
||||
'registration': (context) => RegistrationPage(),
|
||||
'gdpr': (context) => Gdpr(),
|
||||
'menu_page': (context) => MenuPage(),
|
||||
'account': (context) => AccountPage(),
|
||||
'settings': (context) => SettingsPage(),
|
||||
},
|
||||
initialRoute: 'home',
|
||||
title: 'Aitrainer Demo',
|
||||
initialRoute: 'loading',
|
||||
title: 'Aitrainer',
|
||||
theme: ThemeData(
|
||||
primarySwatch: Colors.green,
|
||||
),
|
||||
home: AitrainerHome(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class AitrainerHome extends StatefulWidget {
|
||||
static final String routeName = 'home';
|
||||
|
||||
|
||||
@override
|
||||
State<StatefulWidget> createState() {
|
||||
return new _HomePageState();
|
||||
}
|
||||
}
|
||||
|
||||
class _HomePageState extends State<AitrainerHome> {
|
||||
GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
|
||||
Future<SharedPreferences> _prefs = SharedPreferences.getInstance();
|
||||
Auth _auth = Auth();
|
||||
SharedPreferences _sharedPreferences;
|
||||
var _authToken;
|
||||
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_fetchSessionAndNavigate();
|
||||
}
|
||||
|
||||
_fetchSessionAndNavigate() async {
|
||||
_sharedPreferences = await _prefs;
|
||||
String authToken = Auth.getToken(_sharedPreferences);
|
||||
var customerId = _sharedPreferences.getInt(Auth.customerIdKey);
|
||||
|
||||
if ( _auth.firstLoad ) {
|
||||
_fetchToken(_sharedPreferences);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
Auth flow of the user, see auth.dart
|
||||
*/
|
||||
_fetchToken(SharedPreferences prefs) async {
|
||||
var responseJson = await APIClient.authenticateUser(
|
||||
Auth.username,
|
||||
Auth.password
|
||||
);
|
||||
|
||||
if(responseJson['error'] != null) {
|
||||
showSnackBar(_scaffoldKey, responseJson['error']);
|
||||
print("************** Here big error - no authentication");
|
||||
} else if (responseJson['token'] != null) {
|
||||
prefs.setString(Auth.authTokenKey, responseJson['token']);
|
||||
Auth auth = Auth();
|
||||
auth.authToken = responseJson['token'];
|
||||
if ( prefs.get(Auth.customerIdKey) == null ) {
|
||||
print("************** Registration");
|
||||
// registration
|
||||
Navigator.of(context).pushNamed('registration');
|
||||
prefs.setBool(Auth.isRegisteredKey, true);
|
||||
} else {
|
||||
DateTime now = DateTime.now();
|
||||
DateTime lastStoreDate = DateTime.parse( prefs.get(Auth.lastStoreDateKey) );
|
||||
DateTime minStoreDate = now.add(Duration(days: -10));
|
||||
|
||||
if ( lastStoreDate == null ||
|
||||
lastStoreDate.difference(minStoreDate) > Duration(days: 10) ||
|
||||
prefs.get(Auth.isLoggedInKey) == null ||
|
||||
prefs.get(Auth.isLoggedInKey) == false ) {
|
||||
print("************* Login");
|
||||
Navigator.of(context).pushNamed('login');
|
||||
|
||||
} else {
|
||||
print("************** Store SharedPreferences");
|
||||
// get API customer
|
||||
await CustomerApi().getCustomer( prefs.getInt(Auth.customerIdKey));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
setState(() {
|
||||
_auth.firstLoad = false;
|
||||
_authToken = auth.authToken;
|
||||
_sharedPreferences.setString(Auth.authTokenKey, _authToken);
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static showSnackBar(GlobalKey<ScaffoldState> scaffoldKey, String message) {
|
||||
scaffoldKey.currentState.showSnackBar(
|
||||
new SnackBar(
|
||||
content: new Text(message ?? 'You are offline'),
|
||||
brightness: Brightness.light,
|
||||
//primarySwatch: Colors.transparent,
|
||||
fontFamily: 'Arial',
|
||||
textTheme: TextTheme(
|
||||
bodyText1: TextStyle(fontSize: 14.0),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
key: _scaffoldKey,
|
||||
drawer: NavDrawer(),
|
||||
appBar: AppBar(
|
||||
title: Text('Home'),
|
||||
backgroundColor: Colors.transparent
|
||||
),
|
||||
body: Image.asset('asset/WT01_loading_layers.png',
|
||||
fit: BoxFit.fill,
|
||||
height: double.infinity,
|
||||
width: double.infinity,
|
||||
alignment: Alignment.center,
|
||||
),
|
||||
|
||||
home: LoadingScreenMain(),
|
||||
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
class CustomerScreen extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
drawer: NavDrawer(),
|
||||
appBar: AppBar(
|
||||
title: Text('Customers'),
|
||||
),
|
||||
body: Center(
|
||||
child: CustomerListPage(),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
/* class AitrainerApp extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return MaterialApp(
|
||||
title: "AITRAINER customers",
|
||||
home:
|
||||
ChangeNotifierProvider(
|
||||
create: (context) => CustomerListViewModel(),
|
||||
child: CustomerListPage(),
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
/*
|
||||
// #docregion MyApp
|
||||
class MyApp extends StatelessWidget {
|
||||
// #docregion build
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return MaterialApp(
|
||||
title: 'Startup Name Generator',
|
||||
theme: ThemeData( // Add the 3 lines from here...
|
||||
primaryColor: Colors.white,
|
||||
),
|
||||
home: RandomWords(),
|
||||
);
|
||||
}
|
||||
// #enddocregion build
|
||||
}
|
||||
// #enddocregion MyApp
|
||||
|
||||
// #docregion RWS-var
|
||||
class RandomWordsState extends State<RandomWords> {
|
||||
final _suggestions = <WordPair>[];
|
||||
final _biggerFont = const TextStyle(fontSize: 18.0);
|
||||
final Set<WordPair> _saved = Set<WordPair>();
|
||||
|
||||
// #enddocregion RWS-var
|
||||
|
||||
// #docregion _buildSuggestions
|
||||
Widget _buildSuggestions() {
|
||||
return ListView.builder(
|
||||
padding: const EdgeInsets.all(16.0),
|
||||
itemBuilder: /*1*/ (context, i) {
|
||||
if (i.isOdd) return Divider(); /*2*/
|
||||
|
||||
final index = i ~/ 2; /*3*/
|
||||
if (index >= _suggestions.length) {
|
||||
_suggestions.addAll(generateWordPairs().take(10)); /*4*/
|
||||
}
|
||||
return _buildRow(_suggestions[index]);
|
||||
});
|
||||
}
|
||||
// #enddocregion _buildSuggestions
|
||||
|
||||
// #docregion _buildRow
|
||||
Widget _buildRow(WordPair pair) {
|
||||
final bool alreadySaved = _saved.contains(pair);
|
||||
return ListTile(
|
||||
title: Text(
|
||||
pair.asPascalCase,
|
||||
style: _biggerFont,
|
||||
),
|
||||
trailing: Icon( // Add the lines from here...
|
||||
alreadySaved ? Icons.favorite : Icons.favorite_border,
|
||||
color: alreadySaved ? Colors.red : null,
|
||||
),
|
||||
onTap: () { // Add 9 lines from here...
|
||||
setState(() {
|
||||
if (alreadySaved) {
|
||||
_saved.remove(pair);
|
||||
} else {
|
||||
_saved.add(pair);
|
||||
}
|
||||
});
|
||||
},
|
||||
);
|
||||
}
|
||||
// #enddocregion _buildRow
|
||||
|
||||
// #docregion RWS-build
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: Text('Startup Name Generator'),
|
||||
actions: <Widget>[ // Add 3 lines from here...
|
||||
IconButton(icon: Icon(Icons.list), onPressed: _pushSaved),
|
||||
],
|
||||
),
|
||||
body: _buildSuggestions(),
|
||||
);
|
||||
}
|
||||
|
||||
void _pushSaved() {
|
||||
Navigator.of(context).push(
|
||||
MaterialPageRoute<void>( // Add 20 lines from here...
|
||||
builder: (BuildContext context) {
|
||||
final Iterable<ListTile> tiles = _saved.map(
|
||||
(WordPair pair) {
|
||||
return ListTile(
|
||||
title: Text(
|
||||
pair.asPascalCase,
|
||||
style: _biggerFont,
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
final List<Widget> divided = ListTile
|
||||
.divideTiles(
|
||||
context: context,
|
||||
tiles: tiles,
|
||||
).toList();
|
||||
return Scaffold( // Add 6 lines from here...
|
||||
appBar: AppBar(
|
||||
title: Text('Saved Suggestions'),
|
||||
),
|
||||
body: ListView(children: divided),
|
||||
);
|
||||
},
|
||||
|
||||
),
|
||||
|
||||
);
|
||||
}
|
||||
// #enddocregion RWS-build
|
||||
// #docregion RWS-var
|
||||
}
|
||||
// #enddocregion RWS-var
|
||||
|
||||
class RandomWords extends StatefulWidget {
|
||||
@override
|
||||
RandomWordsState createState() => new RandomWordsState();
|
||||
}
|
||||
|
||||
*/
|
||||
|
@ -1,5 +1,7 @@
|
||||
import 'package:aitrainer_app/model/customer.dart';
|
||||
import 'package:aitrainer_app/service/exercisetype_service.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
import 'package:aitrainer_app/model/exercise_type.dart';
|
||||
|
||||
enum SharePrefsChange {
|
||||
login,
|
||||
@ -40,6 +42,7 @@ class Auth {
|
||||
String authToken = "";
|
||||
Customer userLoggedIn;
|
||||
bool firstLoad = true;
|
||||
List<ExerciseType> _exerciseTypes;
|
||||
|
||||
factory Auth() {
|
||||
return _singleton;
|
||||
@ -79,6 +82,7 @@ class Auth {
|
||||
//firstLoad = true;
|
||||
Future<SharedPreferences> prefs = SharedPreferences.getInstance();
|
||||
setPreferences(prefs, SharePrefsChange.logout, 0);
|
||||
|
||||
}
|
||||
|
||||
setPreferences(Future<SharedPreferences> prefs,
|
||||
@ -93,13 +97,24 @@ class Auth {
|
||||
sharedPreferences.setInt(Auth.customerIdKey, customerId);
|
||||
sharedPreferences.setBool(Auth.isRegisteredKey, true);
|
||||
sharedPreferences.setBool(Auth.isLoggedInKey, true);
|
||||
await ExerciseTypeApi().getExerciseTypes("");
|
||||
} else if ( type == SharePrefsChange.login ) {
|
||||
|
||||
sharedPreferences.setInt(Auth.customerIdKey, customerId);
|
||||
sharedPreferences.setBool(Auth.isLoggedInKey, true);
|
||||
} else if ( type == SharePrefsChange.login ) {
|
||||
await ExerciseTypeApi().getExerciseTypes("");
|
||||
} else if ( type == SharePrefsChange.logout ) {
|
||||
sharedPreferences.setBool(Auth.isLoggedInKey, false);
|
||||
sharedPreferences.setInt(Auth.customerIdKey, 0);
|
||||
//sharedPreferences.setInt(Auth.customerIdKey, 0);
|
||||
sharedPreferences.setString(authTokenKey, "");
|
||||
}
|
||||
}
|
||||
|
||||
void setExerciseTypes( List<ExerciseType> exerciseTypes) {
|
||||
this._exerciseTypes = exerciseTypes;
|
||||
}
|
||||
|
||||
List<ExerciseType> getExerciseTypes() {
|
||||
return this._exerciseTypes;
|
||||
}
|
||||
}
|
@ -7,18 +7,46 @@ class Customer {
|
||||
String active;
|
||||
int customerId;
|
||||
String password;
|
||||
int birthYear;
|
||||
int weight;
|
||||
String goal;
|
||||
String fitnessLevel;
|
||||
String bodyType;
|
||||
int admin;
|
||||
int dataPolicyAllowed;
|
||||
|
||||
|
||||
Customer({this.customerId, this.name, this.firstName, this.email, this.sex, this.age, this.active, this.password});
|
||||
Customer({this.customerId,
|
||||
this.name,
|
||||
this.firstName,
|
||||
this.email,
|
||||
this.sex,
|
||||
this.age,
|
||||
this.active,
|
||||
this.password,
|
||||
this.birthYear,
|
||||
this.bodyType,
|
||||
this.fitnessLevel,
|
||||
this.goal,
|
||||
this.weight,
|
||||
this.admin,
|
||||
this.dataPolicyAllowed
|
||||
});
|
||||
|
||||
Customer.fromJson(Map json) {
|
||||
this.customerId = json['customer_id'];
|
||||
this.customerId = json['customerId'];
|
||||
this.name = json['name'];
|
||||
this.firstName = json['firstname'];
|
||||
this.email = json['email'];
|
||||
this.sex = json['sex'];
|
||||
this.age = json['age'];
|
||||
this.active = json['active'];
|
||||
this.birthYear = json['birthYear'];
|
||||
this.bodyType = json['bodyType'];
|
||||
this.fitnessLevel = json['fitnessLevel'];
|
||||
this.goal = json['goal'];
|
||||
this.weight = json['weight'];
|
||||
this.admin = json['admin'];
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() =>
|
||||
@ -30,5 +58,12 @@ class Customer {
|
||||
"sex": sex,
|
||||
"active": 'Y',
|
||||
"password": password,
|
||||
"birthYear": birthYear,
|
||||
"bodyType": bodyType,
|
||||
"fitnessLevel": fitnessLevel,
|
||||
"goal": goal,
|
||||
"weight": weight,
|
||||
"admin": admin,
|
||||
"dataPolicyAllowed": dataPolicyAllowed,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -4,18 +4,22 @@ class Exercise {
|
||||
int exerciseId;
|
||||
int exerciseTypeId;
|
||||
int customerId;
|
||||
int quantity;
|
||||
DateTime datetimeExercise;
|
||||
double quantity;
|
||||
String unit;
|
||||
double unitQuantity;
|
||||
DateTime dateAdd;
|
||||
|
||||
|
||||
|
||||
Exercise({this.exerciseTypeId, this.customerId, this.quantity, this.datetimeExercise});
|
||||
Exercise({this.exerciseTypeId, this.customerId, this.quantity, this.dateAdd});
|
||||
|
||||
Exercise.fromJson(Map json) {
|
||||
this.exerciseTypeId = json['exerciseTypeId'];
|
||||
this.customerId = json['customerId'];
|
||||
this.quantity = json['quantity'];
|
||||
this.datetimeExercise = json['datetimeExercise'];
|
||||
this.unit = json['unit'];
|
||||
this.unitQuantity = json['unitQuantity'];
|
||||
this.dateAdd = DateTime.parse( json['dateAdd'] );
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() =>
|
||||
@ -23,7 +27,8 @@ class Exercise {
|
||||
"exerciseTypeId": exerciseTypeId,
|
||||
"customerId": customerId,
|
||||
"quantity": quantity,
|
||||
|
||||
"datetimeExercise": DateFormat('yyyy-MM-dd HH:mm:ss').format(this.datetimeExercise),
|
||||
"unit": unit,
|
||||
"unitQuantity": unitQuantity,
|
||||
"dateAdd": DateFormat('yyyy-MM-dd HH:mm:ss').format(this.dateAdd),
|
||||
};
|
||||
}
|
@ -5,6 +5,9 @@ class ExerciseType {
|
||||
String name;
|
||||
String description;
|
||||
BinaryCodec video;
|
||||
String unit;
|
||||
String unitQuantity;
|
||||
String unitQuantityUnit;
|
||||
|
||||
ExerciseType({this.name, this.description});
|
||||
|
||||
@ -12,11 +15,17 @@ class ExerciseType {
|
||||
this.exerciseTypeId = json['exerciseTypeId'];
|
||||
this.name = json['name'];
|
||||
this.description = json['description'];
|
||||
this.unit = json['unit'];
|
||||
this.unitQuantity = json['unitQuantity'];
|
||||
this.unitQuantityUnit = json['unitQuantityUnit'];
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() =>
|
||||
{
|
||||
"name": name,
|
||||
"description": description,
|
||||
"unit": unit,
|
||||
"unitQuantity": unitQuantity,
|
||||
"unitQuantityUnit": unitQuantityUnit
|
||||
};
|
||||
}
|
16
lib/model/workout_tree.dart
Normal file
@ -0,0 +1,16 @@
|
||||
import 'dart:collection';
|
||||
import 'dart:ui';
|
||||
|
||||
class WorkoutTree {
|
||||
int id;
|
||||
int parent;
|
||||
String name; // is also the key
|
||||
String imageName;
|
||||
Color color;
|
||||
double fontSize;
|
||||
bool child;
|
||||
int exercise_type_id;
|
||||
|
||||
WorkoutTree(this.id, this.parent, this.name, this.imageName, this.color, this.fontSize, this.child, this.exercise_type_id);
|
||||
|
||||
}
|
@ -7,11 +7,18 @@ class APIClient extends ChangeNotifier {
|
||||
|
||||
Future<String> get(String endPoint, String param) async {
|
||||
final url = Auth.getBaseUrl() + endPoint + param;
|
||||
Auth auth = Auth();
|
||||
String authToken = Auth().getAuthToken();
|
||||
if ( authToken.length == 0 ) {
|
||||
var responseJson = await APIClient.authenticateUser(
|
||||
Auth.username,
|
||||
Auth.password
|
||||
);
|
||||
authToken = responseJson['token'];
|
||||
}
|
||||
final response = await http.get(url,
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'Authorization' : "Bearer " + auth.getAuthToken() }
|
||||
'Authorization' : "Bearer " + authToken }
|
||||
);
|
||||
notifyListeners();
|
||||
if(response.statusCode == 200) {
|
||||
@ -24,11 +31,18 @@ class APIClient extends ChangeNotifier {
|
||||
Future<String> post(String endPoint, String body) async {
|
||||
final url = Auth.getBaseUrl() + endPoint;
|
||||
print(" ------------ http/post endpoint $endPoint body $body - url: $url ");
|
||||
Auth auth = Auth();
|
||||
String authToken = Auth().getAuthToken();
|
||||
if ( authToken.length == 0 ) {
|
||||
var responseJson = await APIClient.authenticateUser(
|
||||
Auth.username,
|
||||
Auth.password
|
||||
);
|
||||
authToken = responseJson['token'];
|
||||
}
|
||||
final response = await http.post(url,
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'Authorization' : "Bearer " + auth.getAuthToken()
|
||||
'Authorization' : "Bearer " + authToken
|
||||
},
|
||||
body: body
|
||||
);
|
||||
@ -59,7 +73,8 @@ class APIClient extends ChangeNotifier {
|
||||
return responseJson;
|
||||
|
||||
} catch (exception) {
|
||||
return { "error" : "Network error, try again later"};
|
||||
return { "error" : "Network error, try again later "
|
||||
+ exception.toString()};
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -37,9 +37,8 @@ class CustomerApi {
|
||||
final String responseBody = await _client.post(
|
||||
"registration",
|
||||
body);
|
||||
Auth auth = Auth();
|
||||
Customer customer = Customer.fromJson(jsonDecode(responseBody));
|
||||
auth.afterRegistration(customer);
|
||||
Auth().afterRegistration(customer);
|
||||
|
||||
}
|
||||
|
||||
@ -49,9 +48,8 @@ class CustomerApi {
|
||||
final String responseBody = await _client.post(
|
||||
"login",
|
||||
body);
|
||||
Auth auth = Auth();
|
||||
Customer customer = Customer.fromJson(jsonDecode(responseBody));
|
||||
auth.afterRegistration(customer);
|
||||
Auth().afterRegistration(customer);
|
||||
}
|
||||
|
||||
Future<void> getCustomer(int customerId) async {
|
||||
@ -60,8 +58,7 @@ class CustomerApi {
|
||||
final String responseBody = await _client.get(
|
||||
"customers/"+customerId.toString(),
|
||||
body);
|
||||
Auth auth = Auth();
|
||||
Customer customer = Customer.fromJson(jsonDecode(responseBody));
|
||||
auth.afterRegistration(customer);
|
||||
Auth().afterRegistration(customer);
|
||||
}
|
||||
}
|
@ -30,4 +30,12 @@ class ExerciseApi {
|
||||
body);
|
||||
}
|
||||
|
||||
Future<List<Exercise>> getExercisesByCustomer(int customerId ) async {
|
||||
final body = await _client.get("exercises/customer/", customerId.toString() );
|
||||
final Iterable json = jsonDecode(body);
|
||||
final List<Exercise> exercises = json.map( (exercise) => Exercise.fromJson(exercise) ).toList();
|
||||
|
||||
return exercises;
|
||||
}
|
||||
|
||||
}
|
@ -1,4 +1,5 @@
|
||||
import 'dart:convert';
|
||||
import 'package:aitrainer_app/model/auth.dart';
|
||||
import 'package:aitrainer_app/model/exercise_type.dart';
|
||||
import 'package:aitrainer_app/service/api.dart';
|
||||
|
||||
@ -10,7 +11,7 @@ class ExerciseTypeApi {
|
||||
final body = await _client.get("exercise_type", param);
|
||||
final Iterable json = jsonDecode(body);
|
||||
final List<ExerciseType> exerciseTypes = json.map( (exerciseType) => ExerciseType.fromJson(exerciseType) ).toList();
|
||||
|
||||
Auth().setExerciseTypes(exerciseTypes);
|
||||
return exerciseTypes;
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,7 @@
|
||||
|
||||
import 'dart:collection';
|
||||
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:intl/intl.dart';
|
||||
|
||||
class Common {
|
||||
|
||||
@ -13,4 +15,29 @@ class Common {
|
||||
return rc;
|
||||
}
|
||||
|
||||
static ExerciseType getExerciseType( int exerciseTypeId ) {
|
||||
ExerciseType returnElement = null;
|
||||
List<ExerciseType> listExerciseType = Auth().getExerciseTypes();
|
||||
if ( listExerciseType != null ) {
|
||||
for ( var element in listExerciseType ) {
|
||||
if (exerciseTypeId == element.exerciseTypeId) {
|
||||
returnElement = element;
|
||||
break;
|
||||
}
|
||||
};
|
||||
}
|
||||
return returnElement;
|
||||
}
|
||||
|
||||
static String getDateLocale( DateTime datetime, bool timeDisplay ) {
|
||||
AppLanguage appLanguage = AppLanguage();
|
||||
var date = datetime;
|
||||
|
||||
String dateName = DateFormat(DateFormat.YEAR_MONTH_DAY, appLanguage.appLocal.toString()).format(date.toUtc());
|
||||
if ( timeDisplay ) {
|
||||
dateName += " " +DateFormat(DateFormat.HOUR_MINUTE, appLanguage.appLocal.toString()).format(date.toUtc());
|
||||
}
|
||||
|
||||
return dateName;
|
||||
}
|
||||
}
|
61
lib/util/loading_screen.dart
Normal file
@ -0,0 +1,61 @@
|
||||
import 'package:aitrainer_app/util/loading_screen_state.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/scheduler.dart';
|
||||
|
||||
|
||||
/// Loading Screen Widget that updates the screen once all inistializer methods
|
||||
/// are called
|
||||
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<dynamic> 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();
|
||||
}
|
||||
|
131
lib/util/loading_screen_state.dart
Normal file
@ -0,0 +1,131 @@
|
||||
import 'dart:core';
|
||||
import 'dart:async';
|
||||
import 'file:///D:/projects/aitrainer/src/aitrainer_app/lib/util/loading_screen.dart';
|
||||
import 'package:aitrainer_app/localization/app_language.dart';
|
||||
import 'package:aitrainer_app/localization/app_localization.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<LoadingScreen> {
|
||||
|
||||
/// 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: <Widget>[
|
||||
/// 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: <Widget>[
|
||||
new Expanded(
|
||||
flex: 3,
|
||||
child: new Container(
|
||||
child: new Column(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
new Padding(
|
||||
padding: const EdgeInsets.only(top: 30.0),
|
||||
),
|
||||
widget.title,
|
||||
],
|
||||
)),
|
||||
),
|
||||
Expanded(
|
||||
flex: 1,
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: <Widget>[
|
||||
/// Loader Animation Widget
|
||||
CircularProgressIndicator(
|
||||
valueColor: new AlwaysStoppedAnimation<Color>(
|
||||
widget.loaderColor),
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(top: 20.0),
|
||||
),
|
||||
Text(getMessage, style: widget.styleTextUnderTheLoader),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
93
lib/util/menu_tests.dart
Normal file
@ -0,0 +1,93 @@
|
||||
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, 48, false,0);
|
||||
this.tree['Aerobic']= WorkoutTree(2, 1, AppLocalizations.of(context).translate("Aerobic"),
|
||||
'asset/menu/1.1.aerob.png',
|
||||
Colors.white, 48, false,0);
|
||||
this.tree['Cooper']= WorkoutTree(21, 2, AppLocalizations.of(context).translate("Cooper"),
|
||||
'asset/menu/1.1.1.cooper.png',
|
||||
Colors.white, 48, true,30);
|
||||
this.tree['Anaerobic']= WorkoutTree(3, 1, AppLocalizations.of(context).translate("Anaerobic"),
|
||||
'asset/menu/1.2.anaerob.png',
|
||||
Colors.white, 48, false,0);
|
||||
this.tree['300m']= WorkoutTree(22, 3, "300m",
|
||||
'asset/menu/1.2.1.300m.png',
|
||||
Colors.white, 48, true,31);
|
||||
this.tree['400m']= WorkoutTree(24, 3, "400m",
|
||||
'asset/menu/1.2.2.400m.png',
|
||||
Colors.white, 48, true,32);
|
||||
|
||||
this.tree['Strength']= WorkoutTree(4, 0, AppLocalizations.of(context).translate("Strength"),
|
||||
'asset/menu/2.strength.png',
|
||||
Colors.white, 48, 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, 48, true,38);
|
||||
this.tree['Pushups']= WorkoutTree(7, 5, AppLocalizations.of(context).translate("Pushups"),
|
||||
'asset/menu/2.1.2.pushup.png',
|
||||
Colors.white, 48, true,33);
|
||||
this.tree['Situps']= WorkoutTree(10, 5, AppLocalizations.of(context).translate("Sit-ups"),
|
||||
'asset/menu/2.1.3.sit-ups.png',
|
||||
Colors.white, 48, true,36);
|
||||
this.tree['Squats']= WorkoutTree(11, 5, AppLocalizations.of(context).translate("Squats"),
|
||||
'asset/menu/2.1.4.squats.png',
|
||||
Colors.white, 48, 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, 48, true,45);
|
||||
|
||||
this.tree['1RM']= WorkoutTree(8, 4, AppLocalizations.of(context).translate("1RM"),
|
||||
'asset/menu/2.2.1.1RM.png',
|
||||
Colors.white, 48, false,0);
|
||||
this.tree['Chestpress']= WorkoutTree(13, 8, AppLocalizations.of(context).translate("Chest Press"),
|
||||
'asset/menu/2.2.1.1.chestpress.png',
|
||||
Colors.white, 48, true,37);
|
||||
this.tree['PullUps1rm']= WorkoutTree(14, 8, AppLocalizations.of(context).translate("Pull Ups"),
|
||||
'asset/menu/2.2.1.2.pullups.png',
|
||||
Colors.white, 48, true, 38);
|
||||
this.tree['Biceps']= WorkoutTree(15, 8, AppLocalizations.of(context).translate("Biceps"),
|
||||
'asset/menu/2.2.1.3.biceps.png',
|
||||
Colors.white, 48, true, 39);
|
||||
this.tree['Triceps']= WorkoutTree(16, 8, AppLocalizations.of(context).translate("Triceps"),
|
||||
'asset/menu/2.2.1.4.triceps.png',
|
||||
Colors.white, 48, true, 40);
|
||||
this.tree['Shoulders']= WorkoutTree(17, 8, AppLocalizations.of(context).translate("Shoulders"),
|
||||
'asset/menu/2.2.1.5.shoulders.png',
|
||||
Colors.white, 48, true, 41);
|
||||
|
||||
this.tree['BodyCompositions']= WorkoutTree(9, 0, AppLocalizations.of(context).translate("Body Compositions"),
|
||||
'asset/menu/3.bcs1.png',
|
||||
Colors.white, 40, 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,0);
|
||||
this.tree['Sizes']= WorkoutTree(20, 9, AppLocalizations.of(context).translate("Sizes"),
|
||||
'asset/menu/3.3.sizes.png',
|
||||
Colors.black, 48, true,0);
|
||||
|
||||
}
|
||||
|
||||
LinkedHashMap getMenuItems() {
|
||||
return this.tree;
|
||||
}
|
||||
|
||||
|
||||
}
|
32
lib/util/message_state.dart
Normal file
@ -0,0 +1,32 @@
|
||||
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<T extends StatefulWidget> extends State<T> {
|
||||
/// 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;
|
||||
}
|
74
lib/util/session.dart
Normal file
@ -0,0 +1,74 @@
|
||||
import 'package:aitrainer_app/localization/app_language.dart';
|
||||
import 'package:aitrainer_app/service/api.dart';
|
||||
import 'package:aitrainer_app/service/customer_service.dart';
|
||||
import 'package:aitrainer_app/service/exercisetype_service.dart';
|
||||
import 'package:aitrainer_app/viewmodel/exercise_type_changing_view_model.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
import 'package:aitrainer_app/model/auth.dart';
|
||||
|
||||
class Session {
|
||||
|
||||
Future<SharedPreferences> _prefs = SharedPreferences.getInstance();
|
||||
Auth _auth = Auth();
|
||||
SharedPreferences _sharedPreferences;
|
||||
final AppLanguage appLanguage = AppLanguage();
|
||||
|
||||
fetchSessionAndNavigate(Function callback ) async {
|
||||
_sharedPreferences = await _prefs;
|
||||
|
||||
|
||||
if ( _auth.firstLoad ) {
|
||||
_fetchToken(_sharedPreferences, callback);
|
||||
appLanguage.fetchLocale();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
Auth flow of the user, see auth.dart
|
||||
*/
|
||||
_fetchToken(SharedPreferences prefs, Function callback) async {
|
||||
|
||||
var responseJson = await APIClient.authenticateUser(
|
||||
Auth.username,
|
||||
Auth.password
|
||||
);
|
||||
print("--- Lang: " + appLanguage.appLocal.toString());
|
||||
if(responseJson['error'] != null) {
|
||||
print("************** Here big error - no authentication");
|
||||
} else if (responseJson['token'] != null) {
|
||||
prefs.setString(Auth.authTokenKey, responseJson['token']);
|
||||
Auth auth = Auth();
|
||||
auth.authToken = responseJson['token'];
|
||||
if (prefs.get(Auth.customerIdKey) == null) {
|
||||
print("************** Registration");
|
||||
// registration
|
||||
//Navigator.of(context).pushNamed('registration');
|
||||
prefs.setBool(Auth.isRegisteredKey, true);
|
||||
} else {
|
||||
DateTime now = DateTime.now();
|
||||
DateTime lastStoreDate = DateTime.parse(
|
||||
prefs.get(Auth.lastStoreDateKey));
|
||||
DateTime minStoreDate = now.add(Duration(days: -10));
|
||||
|
||||
if (lastStoreDate == null ||
|
||||
lastStoreDate.difference(minStoreDate) > Duration(days: 10) ||
|
||||
prefs.get(Auth.isLoggedInKey) == null ||
|
||||
prefs.get(Auth.isLoggedInKey) == false) {
|
||||
print("************* Login");
|
||||
//Navigator.of(context).pushNamed('login');
|
||||
|
||||
} else {
|
||||
print("************** Store SharedPreferences");
|
||||
// get API customer
|
||||
await CustomerApi().getCustomer(prefs.getInt(Auth.customerIdKey));
|
||||
}
|
||||
|
||||
await ExerciseTypeApi().getExerciseTypes("");
|
||||
print("--- Session finished, call callback ");
|
||||
callback();
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
248
lib/view/account.dart
Normal file
@ -0,0 +1,248 @@
|
||||
|
||||
import 'package:aitrainer_app/localization/app_language.dart';
|
||||
import 'package:aitrainer_app/localization/app_localization.dart';
|
||||
import 'package:aitrainer_app/model/auth.dart';
|
||||
import 'package:aitrainer_app/util/common.dart';
|
||||
import 'package:aitrainer_app/viewmodel/exercise_changing_view_model.dart';
|
||||
import 'package:aitrainer_app/viewmodel/exercise_view_model.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
import 'package:aitrainer_app/viewmodel/user_view_model.dart';
|
||||
import 'package:aitrainer_app/widgets/bottom_nav.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
|
||||
class AccountPage extends StatefulWidget{
|
||||
_AccountPagePageState _state;
|
||||
|
||||
_AccountPagePageState createState() {
|
||||
_state = new _AccountPagePageState();
|
||||
return _state;
|
||||
}
|
||||
}
|
||||
|
||||
class _AccountPagePageState extends State<AccountPage> {
|
||||
final UserViewModel user = UserViewModel();
|
||||
final AppLanguage appLanguage = AppLanguage();
|
||||
final Future<SharedPreferences> _prefs = SharedPreferences.getInstance();
|
||||
final BottomNavigator bottomNav = BottomNavigator();
|
||||
bool _loggedIn = Auth().userLoggedIn != null && Auth().userLoggedIn.email.length > 0;
|
||||
Future<List<ExerciseViewModel>> _exercises;
|
||||
ExerciseChangingViewModel model;
|
||||
|
||||
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
model = Provider.of<ExerciseChangingViewModel>(context, listen: false);
|
||||
if ( Auth().userLoggedIn != null ) {
|
||||
_exercises = model.getExercisesByCustomer(Auth().userLoggedIn.customerId);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: Text(AppLocalizations.of(context).translate('Account')),
|
||||
backgroundColor: Colors.transparent,
|
||||
),
|
||||
body: Container(
|
||||
foregroundDecoration: BoxDecoration(
|
||||
image: DecorationImage(
|
||||
image: AssetImage('asset/image/WT_long_logo.png'),
|
||||
//fit: BoxFit.scaleDown,
|
||||
scale: 1.2,
|
||||
alignment: Alignment.topRight,
|
||||
),
|
||||
),
|
||||
decoration: BoxDecoration(
|
||||
image: DecorationImage(
|
||||
image: AssetImage('asset/image/WT_light_background.png'),
|
||||
fit: BoxFit.cover,
|
||||
alignment: Alignment.center,
|
||||
),
|
||||
),
|
||||
child:
|
||||
ListView(
|
||||
padding: EdgeInsets.only(top: 135),
|
||||
children: <Widget>[
|
||||
ListTile(
|
||||
leading: Icon(Icons.perm_identity),
|
||||
subtitle: Text(
|
||||
AppLocalizations.of(context).translate("Profile")),
|
||||
title: FlatButton(
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(_loggedIn ? Auth().userLoggedIn.email + " " +
|
||||
Auth().userLoggedIn.name + " " +
|
||||
Auth().userLoggedIn.firstName : "",
|
||||
style: TextStyle(color: Colors.blue)),
|
||||
Icon(Icons.arrow_forward_ios),
|
||||
]),
|
||||
textColor: Colors.grey,
|
||||
color: Colors.white,
|
||||
onPressed: () {
|
||||
if (_loggedIn) {
|
||||
Navigator.of(context).pushNamed('customerModifyPage');
|
||||
print("Profile");
|
||||
}
|
||||
},
|
||||
),
|
||||
|
||||
),
|
||||
ListTile(
|
||||
leading: Icon(Icons.language),
|
||||
title: Text(appLanguage.appLocal == Locale('en') ?
|
||||
AppLocalizations.of(context).translate("English") :
|
||||
AppLocalizations.of(context).translate("Hungarian")),
|
||||
subtitle: Text(AppLocalizations.of(context).translate(
|
||||
"Selected Language")),
|
||||
),
|
||||
loginOut(),
|
||||
exercises( model ),
|
||||
]
|
||||
)
|
||||
),
|
||||
bottomNavigationBar: bottomNav.buildBottomNavigator(context, widget._state)
|
||||
);
|
||||
}
|
||||
|
||||
ListTile loginOut() {
|
||||
ListTile element = ListTile();
|
||||
|
||||
String text = "Logout";
|
||||
Color buttonColor = Colors.orange;
|
||||
|
||||
if ( ! _loggedIn ) {
|
||||
text = "Login";
|
||||
buttonColor = Colors.blue;
|
||||
}
|
||||
|
||||
element = ListTile(
|
||||
enabled: true,
|
||||
leading: Icon(Icons.input),
|
||||
title: FlatButton(
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(AppLocalizations.of(context).translate(text),
|
||||
style: TextStyle(
|
||||
color: buttonColor
|
||||
)),
|
||||
Icon(Icons.arrow_forward_ios),
|
||||
]),
|
||||
textColor: buttonColor,
|
||||
color: Colors.white,
|
||||
onPressed: () {
|
||||
setState(() {
|
||||
if ( ! _loggedIn) {
|
||||
print("Login");
|
||||
Navigator.of(context).pushNamed("login");
|
||||
} else {
|
||||
print("Logout");
|
||||
_loggedIn = false;
|
||||
Auth().logout();
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
},
|
||||
),
|
||||
);
|
||||
|
||||
return element;
|
||||
}
|
||||
|
||||
ListTile exercises( ExerciseChangingViewModel model ) {
|
||||
ListTile element = ListTile();
|
||||
if ( Auth().userLoggedIn == null ) {
|
||||
return element;
|
||||
}
|
||||
|
||||
element = ListTile(
|
||||
title: Text(AppLocalizations.of(context).translate("Exercises")),
|
||||
subtitle: Column(
|
||||
children: [
|
||||
FutureBuilder<List<ExerciseViewModel>>(
|
||||
future: _exercises,
|
||||
builder: (context, snapshot) {
|
||||
if (snapshot.hasData) {
|
||||
return getExercises( model );//CustomerListWidget(customers: _exerciseViewModel.exerciseList);
|
||||
} else if (snapshot.hasError) {
|
||||
return Text("${snapshot.error}");
|
||||
}
|
||||
|
||||
// By default, show a loading spinner.
|
||||
return CircularProgressIndicator();
|
||||
}
|
||||
),]
|
||||
));
|
||||
|
||||
return element;
|
||||
}
|
||||
|
||||
Widget getExercises( ExerciseChangingViewModel model ) {
|
||||
List<ExerciseViewModel> exercises = model.exerciseList;
|
||||
|
||||
Column element = Column();
|
||||
if (exercises.length > 0) {
|
||||
List<Column> rows = List();
|
||||
|
||||
exercises.forEach((exercise) {
|
||||
String exerciseName = AppLocalizations.of(context).translate(
|
||||
Common.getExerciseType(exercise.getExercise().exerciseTypeId).name);
|
||||
|
||||
String quantity = exercise.getExercise().quantity.toString() + " " +
|
||||
AppLocalizations.of(context).translate(exercise.getExercise().unit);
|
||||
|
||||
String unitQuantity = "";
|
||||
String unitQuantityUnit = "";
|
||||
String date = Common.getDateLocale(exercise.getExercise().dateAdd, false);
|
||||
if (exercise.getExercise().unitQuantity != null) {
|
||||
unitQuantity = exercise.getExercise().unitQuantity.toString();
|
||||
unitQuantityUnit = AppLocalizations.of(context).translate(
|
||||
Common.getExerciseType(exercise.getExercise().exerciseTypeId).unitQuantityUnit);
|
||||
}
|
||||
|
||||
TableRow row = TableRow(
|
||||
children: [
|
||||
Text(date),
|
||||
Text(exerciseName),
|
||||
Text(quantity),
|
||||
|
||||
Text(unitQuantity + " " + unitQuantityUnit),
|
||||
]
|
||||
);
|
||||
|
||||
Table table = Table(
|
||||
defaultColumnWidth: FractionColumnWidth(0.28),
|
||||
children: [row],
|
||||
);
|
||||
|
||||
Column col = Column(
|
||||
children: [
|
||||
table,
|
||||
Row(
|
||||
children: [
|
||||
Text(" "),
|
||||
]
|
||||
)
|
||||
],
|
||||
);
|
||||
rows.add(col);
|
||||
});
|
||||
|
||||
|
||||
element = Column(
|
||||
children: rows,
|
||||
);
|
||||
}
|
||||
|
||||
return element;
|
||||
|
||||
}
|
||||
}
|
81
lib/view/customer_bodytype_page.dart
Normal file
@ -0,0 +1,81 @@
|
||||
import 'package:aitrainer_app/localization/app_localization.dart';
|
||||
import 'package:aitrainer_app/viewmodel/customer_changing_view_model.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
// ignore: must_be_immutable
|
||||
class CustomerBodyTypePage extends StatefulWidget{
|
||||
_CustomerBodyTypePageState _state;
|
||||
|
||||
_CustomerBodyTypePageState createState() {
|
||||
_state = _CustomerBodyTypePageState();
|
||||
return _state;
|
||||
}
|
||||
}
|
||||
|
||||
class GenderItem {
|
||||
GenderItem(this.dbValue,this.name);
|
||||
final String dbValue;
|
||||
String name;
|
||||
}
|
||||
|
||||
class _CustomerBodyTypePageState extends State<CustomerBodyTypePage> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final CustomerChangingViewModel changingViewModel = ModalRoute.of(context).settings.arguments;
|
||||
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
children: <Widget>[
|
||||
|
||||
Image.asset(
|
||||
'asset/image/WT_long_logo.png',
|
||||
fit: BoxFit.cover,
|
||||
height: 65.0,
|
||||
),
|
||||
],
|
||||
),
|
||||
backgroundColor: Colors.transparent,
|
||||
),
|
||||
body: Container(
|
||||
decoration: BoxDecoration(
|
||||
image: DecorationImage(
|
||||
image: AssetImage('asset/image/WT_light_background.png'),
|
||||
fit: BoxFit.cover,
|
||||
alignment: Alignment.center,
|
||||
),
|
||||
),
|
||||
child: Center(
|
||||
child: Column(
|
||||
children: [
|
||||
Divider(),
|
||||
InkWell(
|
||||
child: Text("Your Body Type",
|
||||
style: TextStyle(color: Colors.orange,
|
||||
fontSize: 50, fontFamily: 'Arial',
|
||||
fontWeight: FontWeight.w900 ),),
|
||||
highlightColor: Colors.white,
|
||||
),
|
||||
|
||||
|
||||
RaisedButton(
|
||||
|
||||
color: Colors.orange,
|
||||
textColor: Colors.white,
|
||||
child: InkWell(
|
||||
child: Text(AppLocalizations.of(context).translate("Next"))),
|
||||
onPressed: () => {
|
||||
//changingViewModel.saveCustomer(),
|
||||
Navigator.of(context).pop(),
|
||||
Navigator.of(context).pushNamed("customerWelcomePage", arguments: changingViewModel)
|
||||
},
|
||||
)
|
||||
],
|
||||
),
|
||||
)
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
}
|
80
lib/view/customer_fitness_page.dart
Normal file
@ -0,0 +1,80 @@
|
||||
import 'package:aitrainer_app/localization/app_localization.dart';
|
||||
import 'package:aitrainer_app/viewmodel/customer_changing_view_model.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
// ignore: must_be_immutable
|
||||
class CustomerFitnessPage extends StatefulWidget{
|
||||
_CustomerFitnessPageState _state;
|
||||
|
||||
_CustomerFitnessPageState createState() {
|
||||
_state = _CustomerFitnessPageState();
|
||||
return _state;
|
||||
}
|
||||
}
|
||||
|
||||
class GenderItem {
|
||||
GenderItem(this.dbValue,this.name);
|
||||
final String dbValue;
|
||||
String name;
|
||||
}
|
||||
|
||||
class _CustomerFitnessPageState extends State<CustomerFitnessPage> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final CustomerChangingViewModel changingViewModel = ModalRoute.of(context).settings.arguments;
|
||||
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
children: <Widget>[
|
||||
|
||||
Image.asset(
|
||||
'asset/image/WT_long_logo.png',
|
||||
fit: BoxFit.cover,
|
||||
height: 65.0,
|
||||
),
|
||||
],
|
||||
),
|
||||
backgroundColor: Colors.transparent,
|
||||
),
|
||||
body: Container(
|
||||
decoration: BoxDecoration(
|
||||
image: DecorationImage(
|
||||
image: AssetImage('asset/image/WT_light_background.png'),
|
||||
fit: BoxFit.cover,
|
||||
alignment: Alignment.center,
|
||||
),
|
||||
),
|
||||
child: Center(
|
||||
child: Column(
|
||||
children: [
|
||||
Divider(),
|
||||
InkWell(
|
||||
child: Text("Your Fitness State",
|
||||
style: TextStyle(color: Colors.orange,
|
||||
fontSize: 50, fontFamily: 'Arial',
|
||||
fontWeight: FontWeight.w900 ),),
|
||||
highlightColor: Colors.white,
|
||||
),
|
||||
|
||||
RaisedButton(
|
||||
|
||||
color: Colors.orange,
|
||||
textColor: Colors.white,
|
||||
child: InkWell(
|
||||
child: Text(AppLocalizations.of(context).translate("Next"))),
|
||||
onPressed: () => {
|
||||
//changingViewModel.saveCustomer(),
|
||||
Navigator.of(context).pop(),
|
||||
Navigator.of(context).pushNamed("customerBodyTypePage", arguments: changingViewModel)
|
||||
},
|
||||
)
|
||||
],
|
||||
),
|
||||
)
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
}
|
124
lib/view/customer_goal_page.dart
Normal file
@ -0,0 +1,124 @@
|
||||
import 'package:aitrainer_app/localization/app_localization.dart';
|
||||
import 'package:aitrainer_app/viewmodel/customer_changing_view_model.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
// ignore: must_be_immutable
|
||||
class CustomerGoalPage extends StatefulWidget{
|
||||
_CustomerGoalPageState _state;
|
||||
|
||||
_CustomerGoalPageState createState() {
|
||||
_state = _CustomerGoalPageState();
|
||||
return _state;
|
||||
}
|
||||
}
|
||||
|
||||
class GenderItem {
|
||||
GenderItem(this.dbValue,this.name);
|
||||
final String dbValue;
|
||||
String name;
|
||||
}
|
||||
|
||||
class _CustomerGoalPageState extends State<CustomerGoalPage> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final CustomerChangingViewModel changingViewModel = ModalRoute.of(context).settings.arguments;
|
||||
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
children: <Widget>[
|
||||
|
||||
Image.asset(
|
||||
'asset/image/WT_long_logo.png',
|
||||
fit: BoxFit.cover,
|
||||
height: 65.0,
|
||||
),
|
||||
],
|
||||
),
|
||||
backgroundColor: Colors.transparent,
|
||||
),
|
||||
body: Container(
|
||||
decoration: BoxDecoration(
|
||||
image: DecorationImage(
|
||||
image: AssetImage('asset/image/WT_light_background.png'),
|
||||
fit: BoxFit.cover,
|
||||
alignment: Alignment.center,
|
||||
),
|
||||
),
|
||||
child: Center(
|
||||
child: Column(
|
||||
children: [
|
||||
Divider(),
|
||||
InkWell(
|
||||
child: Text("Set Your Goals",
|
||||
style: TextStyle(color: Colors.orange,
|
||||
fontSize: 50, fontFamily: 'Arial',
|
||||
fontWeight: FontWeight.w900 ),),
|
||||
highlightColor: Colors.white,
|
||||
),
|
||||
|
||||
Stack(
|
||||
alignment: Alignment.bottomLeft,
|
||||
overflow: Overflow.visible,
|
||||
children: [
|
||||
FlatButton(
|
||||
child: Image.asset("asset/image/WT_gain_muscle.png", height: 250,),
|
||||
padding: EdgeInsets.all(0.0),
|
||||
onPressed:() =>
|
||||
{
|
||||
print("gain muscle"),
|
||||
changingViewModel.customer.setGoal("gain_muscle"),
|
||||
}
|
||||
),
|
||||
InkWell(
|
||||
child: Text("Gain Muscle",
|
||||
style: TextStyle(color: Colors.white,
|
||||
fontSize: 36, fontFamily: 'Arial',
|
||||
fontWeight: FontWeight.w900 ),),
|
||||
highlightColor: Colors.white,
|
||||
)
|
||||
]
|
||||
),
|
||||
Stack(
|
||||
alignment: Alignment.bottomLeft,
|
||||
overflow: Overflow.visible,
|
||||
children: [
|
||||
FlatButton(
|
||||
child: Image.asset("asset/image/WT_weight_loss.png", height: 220,),
|
||||
padding: EdgeInsets.all(0.0),
|
||||
onPressed:() =>
|
||||
{
|
||||
print("weight_loss"),
|
||||
changingViewModel.customer.setGoal("weight_loss"),
|
||||
}
|
||||
),
|
||||
InkWell(
|
||||
child: Text("Loose Weight",
|
||||
style: TextStyle(color: Colors.white,
|
||||
fontSize: 36, fontFamily: 'Arial',
|
||||
fontWeight: FontWeight.w900 ),),
|
||||
highlightColor: Colors.white,
|
||||
)
|
||||
]
|
||||
),
|
||||
RaisedButton(
|
||||
|
||||
color: Colors.orange,
|
||||
textColor: Colors.white,
|
||||
child: InkWell(
|
||||
child: Text(AppLocalizations.of(context).translate("Next"))),
|
||||
onPressed: () => {
|
||||
//changingViewModel.saveCustomer(),
|
||||
Navigator.of(context).pop(),
|
||||
Navigator.of(context).pushNamed("customerFitnessPage", arguments: changingViewModel)
|
||||
},
|
||||
)
|
||||
],
|
||||
),
|
||||
)
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
}
|
@ -1,29 +1,277 @@
|
||||
import 'package:aitrainer_app/localization/app_localization.dart';
|
||||
import 'package:aitrainer_app/model/auth.dart';
|
||||
import 'package:aitrainer_app/viewmodel/customer_changing_view_model.dart';
|
||||
import 'package:aitrainer_app/viewmodel/customer_view_model.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:aitrainer_app/widgets/nav_drawer.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
|
||||
class CustomerModifyPage extends StatefulWidget{
|
||||
_CustomerModifyPageState createState() => _CustomerModifyPageState();
|
||||
_CustomerModifyPageState _state;
|
||||
|
||||
_CustomerModifyPageState createState() {
|
||||
_state = _CustomerModifyPageState();
|
||||
return _state;
|
||||
}
|
||||
}
|
||||
|
||||
class _CustomerModifyPageState extends State {
|
||||
//final _formKey = GlobalKey<FormState>();
|
||||
class GenderItem {
|
||||
GenderItem(this.dbValue,this.name);
|
||||
final String dbValue;
|
||||
String name;
|
||||
}
|
||||
|
||||
class _CustomerModifyPageState extends State<CustomerModifyPage> {
|
||||
final _formKey = GlobalKey<FormState>();
|
||||
GenderItem selectedGender;
|
||||
List<GenderItem> genders;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
genders = [
|
||||
GenderItem("m", "Man"),
|
||||
GenderItem("w", "Woman"),
|
||||
];
|
||||
selectedGender = genders[0];
|
||||
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final CustomerViewModel model = CustomerViewModel();
|
||||
model.customer = Auth().userLoggedIn;
|
||||
final CustomerChangingViewModel customerChangeModel =
|
||||
CustomerChangingViewModel(model);
|
||||
customerChangeModel.customer.customer.sex = selectedGender.dbValue;
|
||||
|
||||
// we cannot initialize the translations in the initState
|
||||
genders.forEach((GenderItem element) {
|
||||
if ( element.dbValue == "m") {
|
||||
element.name = AppLocalizations.of(context).translate("Man");
|
||||
}
|
||||
if ( element.dbValue == "w") {
|
||||
element.name = AppLocalizations.of(context).translate("Woman");
|
||||
}
|
||||
});
|
||||
|
||||
return Scaffold(
|
||||
drawer: NavDrawer(),
|
||||
resizeToAvoidBottomInset: true,
|
||||
appBar: AppBar(
|
||||
title: Text('Modify customer'),
|
||||
title: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: <Widget>[
|
||||
Text("Profil"),
|
||||
Image.asset(
|
||||
'asset/image/WT_long_logo.png',
|
||||
fit: BoxFit.cover,
|
||||
height: 65.0,
|
||||
),
|
||||
],
|
||||
),
|
||||
//title: Text(AppLocalizations.of(context).translate('Settings')),
|
||||
backgroundColor: Colors.transparent,
|
||||
),
|
||||
body: Center(
|
||||
child: Text('Modify customer'),
|
||||
),
|
||||
floatingActionButton: FloatingActionButton(
|
||||
onPressed: () => {},
|
||||
child: Icon(Icons.save,),
|
||||
mini: true,
|
||||
body: Container(
|
||||
decoration: BoxDecoration(
|
||||
image: DecorationImage(
|
||||
image: AssetImage('asset/image/WT_light_background.png'),
|
||||
fit: BoxFit.cover,
|
||||
alignment: Alignment.center,
|
||||
),
|
||||
),
|
||||
child: Form(
|
||||
key: _formKey,
|
||||
child: SingleChildScrollView(
|
||||
scrollDirection: Axis.vertical,
|
||||
padding: EdgeInsets.only(top: 40, left: 25, right: 45, bottom:100),
|
||||
|
||||
child: Container(
|
||||
alignment: Alignment.center,
|
||||
|
||||
child: Column(
|
||||
children: [
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
|
||||
Expanded(
|
||||
child: TextFormField(
|
||||
style: TextStyle(fontSize: 12),
|
||||
decoration: InputDecoration(
|
||||
fillColor: Colors.white24,
|
||||
filled: true,
|
||||
labelText: AppLocalizations.of(context).translate('Email'),
|
||||
),
|
||||
initialValue: customerChangeModel.customer.customer.email,
|
||||
onFieldSubmitted: (input) => customerChangeModel.customer.setEmail(input)
|
||||
)
|
||||
)
|
||||
],
|
||||
),
|
||||
Divider(),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
|
||||
Expanded(
|
||||
child: TextFormField(
|
||||
style: TextStyle(fontSize: 12),
|
||||
obscureText: true,
|
||||
decoration: InputDecoration(
|
||||
fillColor: Colors.white24,
|
||||
filled: true,
|
||||
labelText: AppLocalizations.of(context).translate('Password (Leave empty if you don\'t want to change)' ),
|
||||
),
|
||||
initialValue: customerChangeModel.customer.customer.password,
|
||||
onFieldSubmitted: (input) => customerChangeModel.customer.setPassword(input)
|
||||
)
|
||||
)
|
||||
],
|
||||
),
|
||||
Divider(),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
|
||||
Expanded(
|
||||
child: TextFormField(
|
||||
style: TextStyle(fontSize: 12),
|
||||
decoration: InputDecoration(
|
||||
fillColor: Colors.white24,
|
||||
filled: true,
|
||||
labelText: AppLocalizations.of(context).translate('Name'),
|
||||
),
|
||||
initialValue: customerChangeModel.customer.customer.name,
|
||||
onFieldSubmitted: (input) => customerChangeModel.customer.setName(input)
|
||||
)
|
||||
)
|
||||
],
|
||||
),
|
||||
Divider(),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
|
||||
Expanded(
|
||||
child: TextFormField(
|
||||
style: TextStyle(fontSize: 12),
|
||||
decoration: InputDecoration(
|
||||
fillColor: Colors.white24,
|
||||
filled: true,
|
||||
|
||||
labelText: AppLocalizations.of(context).translate('First Name'),
|
||||
),
|
||||
keyboardType: TextInputType.emailAddress,
|
||||
initialValue: customerChangeModel.customer.customer.firstName,
|
||||
onFieldSubmitted: (input) => customerChangeModel.customer.setFirstName(input)
|
||||
)
|
||||
)
|
||||
],
|
||||
),
|
||||
Divider(),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
|
||||
Expanded(
|
||||
child: TextFormField(
|
||||
style: TextStyle(fontSize: 12),
|
||||
decoration: InputDecoration(
|
||||
fillColor: Colors.white24,
|
||||
filled: true,
|
||||
labelText: AppLocalizations.of(context).translate('Birth Year'),
|
||||
),
|
||||
keyboardType: TextInputType.number,
|
||||
inputFormatters: <TextInputFormatter>[
|
||||
WhitelistingTextInputFormatter.digitsOnly
|
||||
],
|
||||
initialValue: customerChangeModel.customer.customer.birthYear.toString(),
|
||||
onFieldSubmitted: (input) => customerChangeModel.customer.setBirthYear(int.parse(input))
|
||||
)
|
||||
)
|
||||
],
|
||||
),
|
||||
Divider(),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
|
||||
Expanded(
|
||||
child: TextFormField(
|
||||
style: TextStyle(fontSize: 12),
|
||||
decoration: InputDecoration(
|
||||
fillColor: Colors.white24,
|
||||
filled: true,
|
||||
labelText: AppLocalizations.of(context).translate('Weight'),
|
||||
),
|
||||
inputFormatters: <TextInputFormatter>[
|
||||
WhitelistingTextInputFormatter.digitsOnly
|
||||
],
|
||||
initialValue: customerChangeModel.customer.customer.weight.toString(),
|
||||
keyboardType: TextInputType.number,
|
||||
onFieldSubmitted: (input) => customerChangeModel.customer.setWeight(int.parse(input)),
|
||||
)
|
||||
)
|
||||
],
|
||||
),
|
||||
Divider(),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
|
||||
Expanded(
|
||||
child: DropdownButtonHideUnderline(
|
||||
child: DropdownButton<GenderItem>(
|
||||
hint: Text(AppLocalizations.of(context).translate('Select a gender')),
|
||||
style: TextStyle(fontSize: 12, color: Colors.black),
|
||||
focusColor: Colors.white24,
|
||||
value: selectedGender,
|
||||
items: genders.map((GenderItem gender){
|
||||
return DropdownMenuItem<GenderItem>(
|
||||
value: gender,
|
||||
child: Text(gender.name)
|
||||
);
|
||||
}).toList(),
|
||||
onChanged:(GenderItem gender) => {
|
||||
setState(() {
|
||||
selectedGender = gender;
|
||||
customerChangeModel.customer.setSex(gender.dbValue);
|
||||
|
||||
print ("Gender " + gender.name);
|
||||
})
|
||||
//model.customer.sex =
|
||||
},
|
||||
)
|
||||
)
|
||||
)
|
||||
],
|
||||
),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
children: [
|
||||
|
||||
Expanded(
|
||||
child: RaisedButton(
|
||||
|
||||
color: Colors.orange,
|
||||
textColor: Colors.white,
|
||||
child: InkWell(
|
||||
child: Text(AppLocalizations.of(context).translate("Next"))),
|
||||
onPressed: () => {
|
||||
customerChangeModel.saveCustomer(),
|
||||
Navigator.of(context).pushNamed("customerGoalPage", arguments: customerChangeModel)
|
||||
},
|
||||
)
|
||||
)
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
@ -68,7 +68,7 @@ class _CustomerNewPageState extends State {
|
||||
validator: (input) => (int.parse(input) < 99 && int.parse(input) > 0) ?
|
||||
null :
|
||||
"Please type the right age 0-99",
|
||||
onChanged: (input) => customer.setAge(int.parse(input)),
|
||||
onChanged: (input) => customer.setBirthYear(int.parse(input)),
|
||||
),
|
||||
RadioListTile(
|
||||
title: const Text('Man'),
|
||||
|
75
lib/view/customer_welcome_page.dart
Normal file
@ -0,0 +1,75 @@
|
||||
import 'package:aitrainer_app/localization/app_localization.dart';
|
||||
import 'package:aitrainer_app/viewmodel/customer_changing_view_model.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
// ignore: must_be_immutable
|
||||
class CustomerWelcomePage extends StatefulWidget{
|
||||
_CustomerWelcomePageState _state;
|
||||
|
||||
_CustomerWelcomePageState createState() {
|
||||
_state = _CustomerWelcomePageState();
|
||||
return _state;
|
||||
}
|
||||
}
|
||||
|
||||
class GenderItem {
|
||||
GenderItem(this.dbValue,this.name);
|
||||
final String dbValue;
|
||||
String name;
|
||||
}
|
||||
|
||||
class _CustomerWelcomePageState extends State<CustomerWelcomePage> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final CustomerChangingViewModel changingViewModel = ModalRoute.of(context).settings.arguments;
|
||||
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
children: <Widget>[
|
||||
|
||||
Image.asset(
|
||||
'asset/image/WT_long_logo.png',
|
||||
fit: BoxFit.cover,
|
||||
height: 65.0,
|
||||
),
|
||||
],
|
||||
),
|
||||
backgroundColor: Colors.transparent,
|
||||
),
|
||||
body: Container(
|
||||
decoration: BoxDecoration(
|
||||
image: DecorationImage(
|
||||
image: AssetImage('asset/image/WT_welcome.png'),
|
||||
fit: BoxFit.cover,
|
||||
alignment: Alignment.center,
|
||||
),
|
||||
),
|
||||
child: Center(
|
||||
child: Column(
|
||||
children: [
|
||||
Divider(),
|
||||
|
||||
|
||||
|
||||
RaisedButton(
|
||||
|
||||
color: Colors.orange,
|
||||
textColor: Colors.white,
|
||||
child: InkWell(
|
||||
child: Text(AppLocalizations.of(context).translate("Next"))),
|
||||
onPressed: () => {
|
||||
|
||||
Navigator.of(context).pop(),
|
||||
Navigator.of(context).pushNamed("home", arguments: changingViewModel)
|
||||
},
|
||||
)
|
||||
],
|
||||
),
|
||||
)
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
}
|
@ -1,108 +1,226 @@
|
||||
import 'package:aitrainer_app/localization/app_language.dart';
|
||||
import 'package:aitrainer_app/localization/app_localization.dart';
|
||||
import 'package:aitrainer_app/viewmodel/exercise_changing_view_model.dart';
|
||||
import 'package:aitrainer_app/widgets/nav_drawer.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:datetime_picker_formfield/datetime_picker_formfield.dart';
|
||||
//import 'package:datetime_picker_formfield/datetime_picker_formfield.dart';
|
||||
|
||||
class ExerciseNewPage extends StatefulWidget{
|
||||
_ExerciseNewPageState createState() => _ExerciseNewPageState();
|
||||
}
|
||||
|
||||
class _ExerciseNewPageState extends State {
|
||||
final List excluded = [43,44];
|
||||
final _formKey = GlobalKey<FormState>();
|
||||
final format = DateFormat("yyyy-MM-dd HH:mm");
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
ExerciseChangingViewModel model = Provider.of<ExerciseChangingViewModel>(context, listen: false);
|
||||
model.createNewModel();
|
||||
return Scaffold(
|
||||
drawer: NavDrawer(),
|
||||
appBar: AppBar(
|
||||
title: Text('New exercise'),
|
||||
),
|
||||
body: Center(
|
||||
child: Form(
|
||||
key: _formKey,
|
||||
child: Column(
|
||||
children: <Widget>[
|
||||
TextFormField(
|
||||
decoration: InputDecoration(
|
||||
border: OutlineInputBorder(),
|
||||
labelText: 'Name',
|
||||
),
|
||||
readOnly: true,
|
||||
initialValue: model != null && model.customer != null ? model.customer.name + " " + model.customer.firstName : "Please select a customer",
|
||||
),
|
||||
TextFormField(
|
||||
decoration: InputDecoration(
|
||||
border: OutlineInputBorder(),
|
||||
labelText: 'Exercise',
|
||||
),
|
||||
readOnly: true,
|
||||
initialValue: model != null && model.exerciseType != null ? model.exerciseType.name : "Please select an exercise",
|
||||
),
|
||||
TextFormField(
|
||||
decoration: InputDecoration(
|
||||
border: OutlineInputBorder(),
|
||||
labelText: 'Quantity',
|
||||
),
|
||||
validator: (input) => (int.parse(input) < 1000 && int.parse(input) > 0) ?
|
||||
null :
|
||||
"Please type the right quantity 0-1000",
|
||||
onChanged: (input) => model.exerciseViewModel.setQuantity(int.parse(input)),
|
||||
),
|
||||
|
||||
Text('Exercise date and time'),
|
||||
DateTimeField(
|
||||
format: format,
|
||||
initialValue: DateTime.now(),
|
||||
onShowPicker: (context, currentValue) async {
|
||||
final date = await showDatePicker(
|
||||
context: context,
|
||||
firstDate: DateTime(1900),
|
||||
initialDate: DateTime.now(),
|
||||
lastDate: DateTime(2100),
|
||||
builder: (context, child) => Localizations.override(
|
||||
context: context,
|
||||
locale: Locale('hu'),
|
||||
child: child,
|
||||
),
|
||||
);
|
||||
if (date != null) {
|
||||
final time = await showTimePicker(
|
||||
context: context,
|
||||
initialTime:
|
||||
TimeOfDay.fromDateTime(currentValue ?? DateTime.now()),
|
||||
builder: (context, child) => Localizations.override(
|
||||
context: context,
|
||||
locale: Locale('hu'),
|
||||
child: child,
|
||||
),
|
||||
);
|
||||
return DateTimeField.combine(date, time);
|
||||
} else {
|
||||
return currentValue;
|
||||
}
|
||||
},
|
||||
onChanged: (input) => model.exerciseViewModel.setDatetimeExercise(input),
|
||||
),
|
||||
]),
|
||||
)
|
||||
),
|
||||
floatingActionButton: FloatingActionButton(
|
||||
onPressed: () => {
|
||||
if (_formKey.currentState.validate()) {
|
||||
//model = ExerciseChangingViewModel(model.exerciseViewModel),
|
||||
model.addExercise(),
|
||||
Navigator.pop(context),
|
||||
return Consumer<ExerciseChangingViewModel>(
|
||||
builder: (context, model, child ) {
|
||||
String exerciseName = "";
|
||||
String customerName = "";
|
||||
if ( model != null ) {
|
||||
if ( model.exerciseViewModel == null ) {
|
||||
model.createNewModel();
|
||||
}
|
||||
},
|
||||
child: Icon(Icons.save,),
|
||||
mini: true,
|
||||
)
|
||||
);
|
||||
model.exerciseViewModel.createNew();
|
||||
customerName = model != null && model.customer != null
|
||||
? model.customer.name + " " +
|
||||
model.customer.firstName
|
||||
: "Please select a customer";
|
||||
|
||||
exerciseName = model != null &&
|
||||
model.exerciseType != null
|
||||
? model.exerciseType.name
|
||||
: "Please select an exercise";
|
||||
}
|
||||
|
||||
AppLanguage appLanguage = AppLanguage();
|
||||
var date = DateTime.now();
|
||||
String dateName = DateFormat(DateFormat.YEAR_MONTH_DAY, appLanguage.appLocal.toString()).format(date.toUtc()) +
|
||||
" " +DateFormat(DateFormat.HOUR_MINUTE, appLanguage.appLocal.toString()).format(date.toUtc());
|
||||
|
||||
return Form(
|
||||
key: _formKey,
|
||||
autovalidate: true,
|
||||
child: Scaffold(
|
||||
resizeToAvoidBottomInset: false,
|
||||
appBar: AppBar(
|
||||
leading: IconButton(
|
||||
icon: Icon(Icons.arrow_back, color: Colors.deepOrange),
|
||||
onPressed: () => {
|
||||
Navigator.of(context).pop()
|
||||
},
|
||||
),
|
||||
title: Text(AppLocalizations.of(context).translate(exerciseName) + " " +
|
||||
AppLocalizations.of(context).translate('Save Exercise'),
|
||||
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 18, color: Colors.deepOrange)),
|
||||
backgroundColor: Colors.white70,
|
||||
),
|
||||
body: Container(
|
||||
decoration: BoxDecoration(
|
||||
image: DecorationImage(
|
||||
image: AssetImage('asset/image/WT_login.png'),
|
||||
fit: BoxFit.cover,
|
||||
//height: double.infinity,
|
||||
//width: double.infinity,
|
||||
alignment: Alignment.center,
|
||||
),
|
||||
),
|
||||
child: Container(
|
||||
padding: const EdgeInsets.only (top: 65, left:25, right: 100),
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||||
children: <Widget>[
|
||||
columnQuantityUnit(model),
|
||||
columnQuantity(model),
|
||||
|
||||
Column(
|
||||
children: [
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
new InkWell(
|
||||
child: new Text(dateName,
|
||||
style: TextStyle( fontSize: 16,color: Colors.blue)),
|
||||
),
|
||||
ButtonTheme(
|
||||
minWidth: 30.0,
|
||||
height: 30.0,
|
||||
child: FlatButton(
|
||||
|
||||
padding: EdgeInsets.only(bottom: 0),
|
||||
color: Colors.transparent,
|
||||
splashColor: Colors.black26,
|
||||
child: Row(
|
||||
children: [
|
||||
|
||||
Icon(Icons.arrow_forward_ios, color: Colors.orange,)
|
||||
]),
|
||||
onPressed:() { print("date change");},
|
||||
|
||||
)),
|
||||
],
|
||||
),
|
||||
|
||||
new InkWell(
|
||||
child: new Text(AppLocalizations.of(context).translate('Exercise date and time'),
|
||||
style: TextStyle( fontSize: 16)),
|
||||
),
|
||||
|
||||
]),
|
||||
RaisedButton(
|
||||
textColor: Colors.white,
|
||||
color: Colors.deepOrange,
|
||||
focusColor: Colors.white,
|
||||
onPressed: () =>
|
||||
{
|
||||
if (_formKey.currentState.validate()) {
|
||||
//model = ExerciseChangingViewModel(model.exerciseViewModel),
|
||||
|
||||
if ( ! excluded.contains(model.exerciseType.exerciseTypeId) ) {
|
||||
model.addExercise(),
|
||||
},
|
||||
Navigator.pop(context),
|
||||
}
|
||||
},
|
||||
child: Text("Save", style: TextStyle(fontSize: 16),)
|
||||
),
|
||||
|
||||
]),
|
||||
)
|
||||
),
|
||||
),
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
Column columnQuantityUnit( ExerciseChangingViewModel model) {
|
||||
Column column = Column();
|
||||
if ( model.exerciseType != null && model.exerciseType.unitQuantity == "1") {
|
||||
column = Column(
|
||||
children: [
|
||||
TextFormField(
|
||||
autovalidate: true,
|
||||
textAlign: TextAlign.center,
|
||||
initialValue: "0",
|
||||
style: TextStyle(fontSize: 30,
|
||||
color: Colors.lightBlue,
|
||||
fontWeight: FontWeight.bold),
|
||||
validator: (input) {
|
||||
return validateNumberInput(input);
|
||||
},
|
||||
onFieldSubmitted: (input) => {
|
||||
print ("UnitQuantity value $input"),
|
||||
model.exerciseViewModel.setUnitQuantity(
|
||||
double.parse(input))
|
||||
},
|
||||
|
||||
),
|
||||
new InkWell(
|
||||
child: new Text(AppLocalizations.of(context).translate(
|
||||
model.exerciseType.unitQuantityUnit),
|
||||
style: TextStyle(fontSize: 16)),
|
||||
),
|
||||
|
||||
]);
|
||||
};
|
||||
return column;
|
||||
}
|
||||
|
||||
Column columnQuantity( ExerciseChangingViewModel model) {
|
||||
Column column = Column();
|
||||
|
||||
column = Column(
|
||||
children: [
|
||||
TextFormField(
|
||||
autovalidate: true,
|
||||
textAlign: TextAlign.center,
|
||||
initialValue: "0",
|
||||
style: TextStyle(fontSize: 60,
|
||||
color: Colors.deepOrange,
|
||||
fontWeight: FontWeight.bold),
|
||||
validator: (input) {
|
||||
return validateNumberInput(input);
|
||||
},
|
||||
onFieldSubmitted: (input) =>
|
||||
{
|
||||
print ("Quantity value $input"),
|
||||
model.exerciseViewModel.setQuantity(
|
||||
double.parse(input)),
|
||||
model.exerciseViewModel.setUnit(model.exerciseType.unit)
|
||||
|
||||
}
|
||||
),
|
||||
new InkWell(
|
||||
child: new Text(AppLocalizations.of(context).translate(model.exerciseType.unit),
|
||||
style: TextStyle(fontSize: 16)),
|
||||
),
|
||||
|
||||
]);
|
||||
|
||||
return column;
|
||||
}
|
||||
|
||||
String validateNumberInput( input ) {
|
||||
String error = AppLocalizations.of(context).translate("Please type the right quantity 0-10000");
|
||||
dynamic rc = ( input != null && input.length > 0);
|
||||
if ( ! rc ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
rc = double.tryParse(input);
|
||||
if ( rc == null ) {
|
||||
return error;
|
||||
}
|
||||
|
||||
if ( ! ( double.parse(input) < 10000 && double.parse(input) > 0) ) {
|
||||
return error;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
39
lib/view/gdpr.dart
Normal file
@ -0,0 +1,39 @@
|
||||
import 'package:aitrainer_app/localization/app_localization.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class Gdpr extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
body: Container(
|
||||
padding: const EdgeInsets.only (left:15, right: 15),
|
||||
child: ListView(
|
||||
children: <Widget>[
|
||||
new InkWell(
|
||||
child: new Text(
|
||||
AppLocalizations.of(context).translate('gdpr_text'),
|
||||
|
||||
),
|
||||
|
||||
customBorder: Border.all(color:Colors.teal, width:1),
|
||||
),
|
||||
Spacer(flex:2),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
children: [
|
||||
FlatButton(
|
||||
textColor: Colors.black,
|
||||
|
||||
onPressed: () { },
|
||||
|
||||
)
|
||||
],
|
||||
)
|
||||
],
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
}
|
@ -1,9 +1,12 @@
|
||||
|
||||
import 'package:aitrainer_app/localization/app_localization.dart';
|
||||
import 'package:aitrainer_app/model/auth.dart';
|
||||
import 'package:aitrainer_app/viewmodel/exercise_changing_view_model.dart';
|
||||
import 'package:aitrainer_app/viewmodel/user_changing_view_model.dart';
|
||||
import 'package:aitrainer_app/viewmodel/user_view_model.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:aitrainer_app/widgets/nav_drawer.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
|
||||
class LoginPage extends StatefulWidget{
|
||||
_LoginPageState createState() => _LoginPageState();
|
||||
@ -11,71 +14,126 @@ class LoginPage extends StatefulWidget{
|
||||
|
||||
class _LoginPageState extends State {
|
||||
final UserViewModel user = UserViewModel();
|
||||
bool _obscureText = true;
|
||||
|
||||
final bool _obscureText = true;
|
||||
final _formKey = GlobalKey<FormState>();
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
UserChangingViewModel model = UserChangingViewModel(user);
|
||||
ExerciseChangingViewModel exerciseModel = Provider.of<ExerciseChangingViewModel>(context, listen: false);
|
||||
user.createNew();
|
||||
return Scaffold(
|
||||
drawer: NavDrawer(),
|
||||
appBar: AppBar(
|
||||
title: Text('Login'),
|
||||
),
|
||||
body: Center(
|
||||
child: Form(
|
||||
key: _formKey,
|
||||
child: Column(
|
||||
children: <Widget>[
|
||||
TextFormField(
|
||||
decoration: InputDecoration(
|
||||
border: OutlineInputBorder(),
|
||||
labelText: 'Email',
|
||||
icon: const Padding(
|
||||
padding:const EdgeInsets.only(left: 20.0, top: 50.0),
|
||||
child: const Icon(Icons.people)
|
||||
)
|
||||
),
|
||||
validator: (String input) {
|
||||
RegExp exp = new RegExp(r"[\w._]+\@[\w._]+.[a-z]+",
|
||||
caseSensitive: false,
|
||||
multiLine: false,);
|
||||
String ret = exp.hasMatch(input) == true ?
|
||||
null:
|
||||
"Please type an email address";
|
||||
return ret;
|
||||
},
|
||||
onChanged: (input) => user.setEmail(input),
|
||||
),
|
||||
new TextFormField(
|
||||
decoration: const InputDecoration(
|
||||
labelText: 'Password',
|
||||
icon: const Padding(
|
||||
padding: const EdgeInsets.only(left: 20.0, top: 15.0),
|
||||
child: const Icon(Icons.lock))),
|
||||
validator: (val) => val.length < 6 ? 'Password too short.' : null,
|
||||
obscureText: _obscureText,
|
||||
onChanged: (input) => user.setPassword(input),
|
||||
),
|
||||
new InkWell(
|
||||
child: new Text('SignUp'),
|
||||
onTap: () => Navigator.of(context).pushNamed('registration'),
|
||||
),
|
||||
new FloatingActionButton(
|
||||
child: Icon(Icons.cloud_done,),
|
||||
onPressed:() => {
|
||||
if (_formKey.currentState.validate()) {
|
||||
model = UserChangingViewModel(user),
|
||||
model.getUser(),
|
||||
Navigator.pop(context),
|
||||
}
|
||||
})
|
||||
])
|
||||
),
|
||||
),
|
||||
|
||||
return Scaffold(
|
||||
body: Container(
|
||||
decoration: BoxDecoration(
|
||||
image: DecorationImage(
|
||||
image: AssetImage('asset/image/WT_login.png'),
|
||||
fit: BoxFit.cover,
|
||||
//height: double.infinity,
|
||||
//width: double.infinity,
|
||||
alignment: Alignment.center,
|
||||
),
|
||||
),
|
||||
child: Form(
|
||||
key: _formKey,
|
||||
child: Container(
|
||||
padding: const EdgeInsets.only (left: 25, right: 100),
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||||
children: <Widget>[
|
||||
Spacer(flex: 4),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
new InkWell(
|
||||
child: new Text(
|
||||
AppLocalizations.of(context).translate(
|
||||
'Login'),
|
||||
style: TextStyle(fontWeight: FontWeight.bold,
|
||||
fontSize: 24)),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
TextFormField(
|
||||
decoration: InputDecoration(
|
||||
fillColor: Colors.white,
|
||||
filled: true,
|
||||
labelText: 'Email',
|
||||
),
|
||||
validator: (String input) {
|
||||
RegExp exp = new RegExp(r"[\w._]+\@[\w._]+.[a-z]+",
|
||||
caseSensitive: false,
|
||||
multiLine: false,);
|
||||
String ret = exp.hasMatch(input) == true ?
|
||||
null :
|
||||
AppLocalizations.of(context).translate(
|
||||
'Please type an email address');
|
||||
return ret;
|
||||
},
|
||||
onChanged: (input) => user.setEmail(input),
|
||||
),
|
||||
Spacer(flex: 1),
|
||||
new TextFormField(
|
||||
decoration: const InputDecoration(
|
||||
filled: true,
|
||||
labelText: "Password",
|
||||
fillColor: Colors.white,
|
||||
focusColor: Colors.white,
|
||||
),
|
||||
validator: (val) => val.length < 6
|
||||
? AppLocalizations.of(context).translate(
|
||||
'Password too short')
|
||||
: null,
|
||||
obscureText: _obscureText,
|
||||
onChanged: (input) => user.setPassword(input),
|
||||
),
|
||||
Spacer(flex: 1),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
children: <Widget>[ new FlatButton(
|
||||
child: Image.asset('asset/image/WT_OK.png',
|
||||
width: 100,
|
||||
height: 100
|
||||
),
|
||||
onPressed: () =>
|
||||
{
|
||||
if (_formKey.currentState.validate()) {
|
||||
model = UserChangingViewModel(user),
|
||||
model.getUser(),
|
||||
exerciseModel.setCustomer(
|
||||
Auth().userLoggedIn),
|
||||
Navigator.pop(context),
|
||||
}
|
||||
}),
|
||||
]),
|
||||
Spacer(flex: 2),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||||
children: <Widget>[
|
||||
new InkWell(
|
||||
child: new Text(
|
||||
AppLocalizations.of(context).translate(
|
||||
'SignUp')),
|
||||
onTap: () =>
|
||||
Navigator.of(context).pushNamed(
|
||||
'registration'),
|
||||
),
|
||||
Spacer(flex: 1),
|
||||
new InkWell(
|
||||
child: new Text(
|
||||
AppLocalizations.of(context).translate(
|
||||
'Privacy')),
|
||||
onTap: () =>
|
||||
Navigator.of(context).pushNamed('gdpr'),
|
||||
),
|
||||
Spacer(flex: 2),
|
||||
]),
|
||||
Spacer(flex: 2),
|
||||
])
|
||||
),
|
||||
),
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
154
lib/view/menu_page.dart
Normal file
@ -0,0 +1,154 @@
|
||||
import 'package:aitrainer_app/model/auth.dart';
|
||||
import 'package:aitrainer_app/model/exercise_type.dart';
|
||||
import 'package:aitrainer_app/model/workout_tree.dart';
|
||||
import 'package:aitrainer_app/util/common.dart';
|
||||
import 'package:aitrainer_app/util/menu_tests.dart';
|
||||
import 'package:aitrainer_app/viewmodel/exercise_changing_view_model.dart';
|
||||
import 'package:aitrainer_app/widgets/bottom_nav.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'dart:collection';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
// ignore: must_be_immutable
|
||||
class MenuPage extends StatefulWidget {
|
||||
_MenuPageState _state;
|
||||
static const routeName = '/menu_page';
|
||||
int parent;
|
||||
|
||||
MenuPage({this.parent});
|
||||
|
||||
@override
|
||||
_MenuPageState createState() {
|
||||
_state = new _MenuPageState();
|
||||
return _state;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class _MenuPageState extends State<MenuPage> {
|
||||
final BottomNavigator bottomNav = BottomNavigator();
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final MenuTests menu = MenuTests(context);
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
backgroundColor: Colors.transparent,
|
||||
title: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
children: <Widget>[
|
||||
Image.asset(
|
||||
'asset/image/WT_long_logo.png',
|
||||
fit: BoxFit.cover,
|
||||
height: 65.0,
|
||||
),
|
||||
],
|
||||
),
|
||||
leading: IconButton(
|
||||
icon: Icon(Icons.arrow_back, color: Colors.black),
|
||||
onPressed: () => {
|
||||
this.setState(() {
|
||||
widget.parent = 0;
|
||||
},
|
||||
)},
|
||||
),
|
||||
),
|
||||
|
||||
body: Container(
|
||||
decoration: BoxDecoration(
|
||||
image: DecorationImage(
|
||||
image: AssetImage('asset/image/WT_menu_dark.png'),
|
||||
fit: BoxFit.fill,
|
||||
alignment: Alignment.center,
|
||||
),
|
||||
),
|
||||
|
||||
child: CustomScrollView(
|
||||
scrollDirection: Axis.vertical,
|
||||
slivers: <Widget>[
|
||||
buildMenuColumn(widget.parent, context, menu)
|
||||
]
|
||||
)
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
SliverList buildMenuColumn(int parent, BuildContext context, MenuTests menu) {
|
||||
LinkedHashMap tree = menu.getMenuItems();
|
||||
List<Widget> _columnChildren = List();
|
||||
ExerciseType exerciseType;
|
||||
ExerciseChangingViewModel model = Provider.of<ExerciseChangingViewModel>(context, listen: false);
|
||||
|
||||
tree.forEach((treeName, value) {
|
||||
WorkoutTree workoutTree = value as WorkoutTree;
|
||||
|
||||
if ( workoutTree.parent == parent ) {
|
||||
_columnChildren.add(
|
||||
Container(
|
||||
padding: EdgeInsets.only(top: 16.0),
|
||||
child: Center(
|
||||
child: Stack(
|
||||
alignment: Alignment.bottomLeft,
|
||||
overflow: Overflow.visible,
|
||||
children: [
|
||||
FlatButton(
|
||||
child: _getButtonImage(workoutTree),
|
||||
padding: EdgeInsets.all(0.0),
|
||||
onPressed:() =>
|
||||
{
|
||||
print("Hi!, Menu clicked " + workoutTree.id.toString()),
|
||||
if ( workoutTree.child == false ) {
|
||||
this.setState(() {
|
||||
widget.parent = workoutTree.id;
|
||||
},
|
||||
),
|
||||
} else {
|
||||
exerciseType = Common.getExerciseType(workoutTree.exercise_type_id),
|
||||
model.setExerciseType(exerciseType),
|
||||
model.setCustomer(Auth().userLoggedIn),
|
||||
if ( Auth().userLoggedIn == null ) {
|
||||
Scaffold.of(context)
|
||||
. showSnackBar(SnackBar(content: Text('Please log in')))
|
||||
} else {
|
||||
Navigator.of(context).pushNamed('exerciseNewPage'),
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
),
|
||||
InkWell(
|
||||
child: Text(workoutTree.name, style: TextStyle(color: workoutTree.color, fontSize: workoutTree.fontSize, fontFamily: 'Arial', fontWeight: FontWeight.w900 ),),
|
||||
highlightColor: workoutTree.color,
|
||||
)]))));
|
||||
|
||||
}
|
||||
});
|
||||
//_columnChildren.add(Spacer(flex: 3));
|
||||
SliverList sliverList =
|
||||
SliverList(
|
||||
delegate: SliverChildListDelegate(
|
||||
_columnChildren
|
||||
)
|
||||
);
|
||||
|
||||
return sliverList;
|
||||
}
|
||||
|
||||
dynamic _getButtonImage(WorkoutTree workoutTree) {
|
||||
dynamic image;
|
||||
if ( workoutTree.imageName.startsWith("http") ) {
|
||||
image = FadeInImage.assetNetwork(
|
||||
image: workoutTree.imageName,
|
||||
placeholder: 'asset/image/dots.gif',
|
||||
//imageScale: 0.1,
|
||||
height: 180,
|
||||
placeholderScale: 0.1,
|
||||
);
|
||||
} else {
|
||||
image = Image.asset(workoutTree.imageName, height: 180,);
|
||||
}
|
||||
return image;
|
||||
}
|
||||
|
||||
}
|
@ -1,4 +1,5 @@
|
||||
|
||||
import 'package:aitrainer_app/localization/app_localization.dart';
|
||||
import 'package:aitrainer_app/viewmodel/user_changing_view_model.dart';
|
||||
import 'package:aitrainer_app/viewmodel/user_view_model.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
@ -19,66 +20,102 @@ class _RegistrationPageState extends State {
|
||||
Widget build(BuildContext context) {
|
||||
UserChangingViewModel model = UserChangingViewModel(user);
|
||||
user.createNew();
|
||||
|
||||
return Scaffold(
|
||||
drawer: NavDrawer(),
|
||||
appBar: AppBar(
|
||||
title: Text('Registration'),
|
||||
|
||||
body: Container(
|
||||
decoration: BoxDecoration(
|
||||
image: DecorationImage(
|
||||
image: AssetImage('asset/image/WT_login.png'),
|
||||
fit: BoxFit.cover,
|
||||
//height: double.infinity,
|
||||
//width: double.infinity,
|
||||
alignment: Alignment.center,
|
||||
),
|
||||
),
|
||||
body: Center(
|
||||
child: Form(
|
||||
key: _formKey,
|
||||
child: Column(
|
||||
child: Form(
|
||||
key: _formKey,
|
||||
child: Container(
|
||||
padding: const EdgeInsets.only (left:25, right: 100),
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||||
children: <Widget>[
|
||||
Spacer(flex:4),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
new InkWell(
|
||||
child: new Text(AppLocalizations.of(context).translate('SignUp'),
|
||||
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 24)),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
TextFormField(
|
||||
decoration: InputDecoration(
|
||||
border: OutlineInputBorder(),
|
||||
fillColor: Colors.white,
|
||||
filled:true,
|
||||
labelText: 'Email',
|
||||
icon: const Padding(
|
||||
padding:const EdgeInsets.only(left: 20.0, top: 50.0),
|
||||
child: const Icon(Icons.people)
|
||||
)
|
||||
),
|
||||
/* validator: (String input) {
|
||||
RegExp exp = new RegExp(r"[\w._]+\@[\w._]+.[a-z]+",
|
||||
caseSensitive: false,
|
||||
multiLine: false,);
|
||||
String ret = exp.hasMatch(input) == true ?
|
||||
null:
|
||||
"Please type an email address";
|
||||
return ret;
|
||||
},*/
|
||||
validator: (String input) {
|
||||
RegExp exp = new RegExp(r"[\w._]+\@[\w._]+.[a-z]+",
|
||||
caseSensitive: false,
|
||||
multiLine: false,);
|
||||
String ret = exp.hasMatch(input) == true ?
|
||||
null:
|
||||
AppLocalizations.of(context).translate('Please type an email address');
|
||||
return ret;
|
||||
},
|
||||
onChanged: (input) => user.setEmail(input),
|
||||
),
|
||||
Spacer(flex:1),
|
||||
new TextFormField(
|
||||
decoration: const InputDecoration(
|
||||
labelText: 'Password',
|
||||
icon: const Padding(
|
||||
padding: const EdgeInsets.only(left: 20.0, top: 15.0),
|
||||
child: const Icon(Icons.lock))),
|
||||
/* validator: (String input) {
|
||||
String rc = input.length < 4 ? 'Password too short.' : null;
|
||||
return rc;
|
||||
}, */
|
||||
onChanged: (input) => user.setPassword(input),
|
||||
filled:true,
|
||||
labelText: "Password",
|
||||
fillColor: Colors.white,
|
||||
focusColor: Colors.white,
|
||||
),
|
||||
validator: (val) => val.length < 6 ? AppLocalizations.of(context).translate('Password too short') : null,
|
||||
obscureText: _obscureText,
|
||||
onChanged: (input) => user.setPassword(input),
|
||||
),
|
||||
new InkWell(
|
||||
child: new Text('I have an account'),
|
||||
onTap: () => Navigator.of(context).pushNamed('login'),
|
||||
),
|
||||
new FloatingActionButton(
|
||||
child: Icon(Icons.cloud_done,),
|
||||
onPressed:() => {
|
||||
if (_formKey.currentState.validate()) {
|
||||
model = UserChangingViewModel(user),
|
||||
model.addUser(),
|
||||
Navigator.pop(context),
|
||||
}
|
||||
}
|
||||
)
|
||||
])
|
||||
),
|
||||
Spacer(flex:1),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
children: <Widget>[ new FlatButton(
|
||||
child: Image.asset('asset/image/WT_OK.png',
|
||||
width: 100,
|
||||
height:100
|
||||
),
|
||||
onPressed:() => {
|
||||
if (_formKey.currentState.validate()) {
|
||||
model = UserChangingViewModel(user),
|
||||
model.addUser(),
|
||||
Navigator.of(context).pushNamed("customerModifyPage",)
|
||||
}
|
||||
}),
|
||||
]),
|
||||
Spacer(flex:2),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||||
children: <Widget>[
|
||||
new InkWell(
|
||||
child: new Text(AppLocalizations.of(context).translate('Login')),
|
||||
onTap: () => Navigator.of(context).pushNamed('login'),
|
||||
),
|
||||
Spacer(flex:1),
|
||||
new InkWell(
|
||||
child: new Text(AppLocalizations.of(context).translate('Privacy')),
|
||||
onTap: () => Navigator.of(context).pushNamed('gdpr'),
|
||||
),
|
||||
Spacer(flex:2),
|
||||
]),
|
||||
Spacer(flex:2),
|
||||
])
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
);
|
||||
}
|
||||
|
103
lib/view/settings.dart
Normal file
@ -0,0 +1,103 @@
|
||||
import 'package:aitrainer_app/localization/app_language.dart';
|
||||
import 'package:aitrainer_app/localization/app_localization.dart';
|
||||
import 'package:aitrainer_app/widgets/bottom_nav.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
|
||||
|
||||
|
||||
class SettingsPage extends StatefulWidget{
|
||||
_SettingsPageState _state;
|
||||
|
||||
_SettingsPageState createState() {
|
||||
_state = new _SettingsPageState();
|
||||
return _state;
|
||||
}
|
||||
}
|
||||
|
||||
class _SettingsPageState extends State<SettingsPage> {
|
||||
final AppLanguage appLanguage = AppLanguage();
|
||||
Locale _locale;
|
||||
|
||||
final _formKey = GlobalKey<FormState>();
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
BottomNavigator bottomNav = BottomNavigator();
|
||||
_locale = appLanguage.appLocal;
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: <Widget>[
|
||||
Text(AppLocalizations.of(context).translate('Settings')),
|
||||
Image.asset(
|
||||
'asset/image/WT_long_logo.png',
|
||||
fit: BoxFit.cover,
|
||||
height: 65.0,
|
||||
),
|
||||
],
|
||||
),
|
||||
//title: Text(AppLocalizations.of(context).translate('Settings')),
|
||||
backgroundColor: Colors.transparent,
|
||||
),
|
||||
body: Container(
|
||||
decoration: BoxDecoration(
|
||||
image: DecorationImage(
|
||||
image: AssetImage('asset/image/WT_light_background.png'),
|
||||
fit: BoxFit.cover,
|
||||
alignment: Alignment.center,
|
||||
),
|
||||
),
|
||||
child: Form(
|
||||
key: _formKey,
|
||||
child:
|
||||
ListView(
|
||||
padding: EdgeInsets.only(top: 150),
|
||||
children: <Widget>[
|
||||
ListTile(
|
||||
leading: Icon(Icons.language),
|
||||
subtitle: Text(AppLocalizations.of(context).translate("Change App Language")),
|
||||
title: DropdownButton(
|
||||
value: _locale == Locale('en') ? AppLocalizations.of(context).translate("English") : AppLocalizations.of(context).translate("Hungarian"),
|
||||
items: [AppLocalizations.of(context).translate("English"), AppLocalizations.of(context).translate("Hungarian")]
|
||||
.map<DropdownMenuItem<String>>((String value) {
|
||||
return DropdownMenuItem<String>(
|
||||
value: value,
|
||||
child: Text(value),
|
||||
);
|
||||
}).toList(),
|
||||
onChanged:(String lang) => _changeLanguage(lang),
|
||||
)
|
||||
|
||||
),
|
||||
]
|
||||
|
||||
),
|
||||
),
|
||||
),
|
||||
bottomNavigationBar: bottomNav.buildBottomNavigator(context, widget._state)
|
||||
|
||||
);
|
||||
}
|
||||
|
||||
_changeLanguage( String lang ) {
|
||||
|
||||
setState(() {
|
||||
switch ( lang ) {
|
||||
case "English":
|
||||
case "Angol":
|
||||
_locale = Locale('en');
|
||||
break;
|
||||
case "Hungarian":
|
||||
case "Magyar":
|
||||
_locale = Locale('hu');
|
||||
break;
|
||||
}
|
||||
appLanguage.changeLanguage(_locale);
|
||||
AppLocalizations.of(context).setLocale(_locale);
|
||||
AppLocalizations.of(context).load();
|
||||
|
||||
});
|
||||
}
|
||||
}
|
@ -19,7 +19,7 @@ class CustomerChangingViewModel extends ChangeNotifier {
|
||||
}
|
||||
|
||||
Future<void> saveCustomer() async {
|
||||
this.customer = customer;
|
||||
//this.customer = customer;
|
||||
final Customer modelCustomer = customer.getCustomer();
|
||||
await CustomerApi().saveCustomer(modelCustomer);
|
||||
}
|
||||
|
@ -18,8 +18,8 @@ class CustomerViewModel {
|
||||
return this.customer.sex == "m" ? "Man" : "Woman";
|
||||
}
|
||||
|
||||
int get age {
|
||||
return this.customer.age;
|
||||
int get birthYear {
|
||||
return this.birthYear;
|
||||
}
|
||||
|
||||
setName(String name) {
|
||||
@ -29,18 +29,39 @@ class CustomerViewModel {
|
||||
this.customer.firstName = firstName;
|
||||
}
|
||||
|
||||
setPassword( String password ) {
|
||||
this.customer.password = password;
|
||||
}
|
||||
|
||||
setEmail(String email) {
|
||||
this.customer.email = email;
|
||||
}
|
||||
|
||||
setAge(int age) {
|
||||
this.customer.age = age;
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
|
@ -9,6 +9,7 @@ import 'exercise_view_model.dart';
|
||||
class ExerciseChangingViewModel with ChangeNotifier {
|
||||
Customer customer;
|
||||
ExerciseType exerciseType;
|
||||
List<ExerciseViewModel> exerciseList = List<ExerciseViewModel>();
|
||||
|
||||
ExerciseViewModel exerciseViewModel = ExerciseViewModel();
|
||||
|
||||
@ -20,10 +21,12 @@ class ExerciseChangingViewModel with ChangeNotifier {
|
||||
|
||||
setCustomer(Customer customer) {
|
||||
this.customer = customer;
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
setExerciseType( ExerciseType exerciseType) {
|
||||
this.exerciseType = exerciseType;
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
setQuantity(int quantity) {
|
||||
@ -31,7 +34,7 @@ class ExerciseChangingViewModel with ChangeNotifier {
|
||||
}
|
||||
|
||||
addExercise() async {
|
||||
this.exerciseViewModel = exerciseViewModel;
|
||||
// this.exerciseViewModel = exerciseViewModel;
|
||||
final Exercise modelExercise = exerciseViewModel.getExercise();
|
||||
modelExercise.customerId = this.customer.customerId;
|
||||
modelExercise.exerciseTypeId = this.exerciseType.exerciseTypeId;
|
||||
@ -43,4 +46,11 @@ class ExerciseChangingViewModel with ChangeNotifier {
|
||||
exerciseViewModel.createNew();
|
||||
}
|
||||
|
||||
Future<List<ExerciseViewModel>> getExercisesByCustomer( int customerId ) async {
|
||||
final results = await ExerciseApi().getExercisesByCustomer(customerId);
|
||||
this.exerciseList = results.map((item) => ExerciseViewModel(exercise: item)).toList();
|
||||
notifyListeners();
|
||||
return this.exerciseList;
|
||||
}
|
||||
|
||||
}
|
@ -6,15 +6,23 @@ class ExerciseViewModel {
|
||||
|
||||
createNew() {
|
||||
this.exercise = Exercise();
|
||||
exercise.datetimeExercise = DateTime.now();
|
||||
exercise.dateAdd = DateTime.now();
|
||||
}
|
||||
|
||||
setQuantity(int quantity) {
|
||||
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.datetimeExercise = datetimeExercise;
|
||||
this.exercise.dateAdd = datetimeExercise;
|
||||
}
|
||||
|
||||
Exercise getExercise() {
|
||||
|
58
lib/widgets/bottom_nav.dart
Normal file
@ -0,0 +1,58 @@
|
||||
import 'package:aitrainer_app/localization/app_localization.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class BottomNavigator {
|
||||
BottomNavigationBar buildBottomNavigator(BuildContext context, State state) {
|
||||
return BottomNavigationBar(
|
||||
currentIndex: 0, // this will be set when a new tab is tapped
|
||||
backgroundColor: Colors.black12,
|
||||
selectedItemColor: Colors.yellow,
|
||||
unselectedItemColor: Colors.lightGreen,
|
||||
type: BottomNavigationBarType.shifting,
|
||||
showSelectedLabels: true,
|
||||
items: [
|
||||
BottomNavigationBarItem(
|
||||
backgroundColor: Colors.black12,
|
||||
icon: new Icon(Icons.home, color: Colors.lightGreen),
|
||||
activeIcon: new Icon(Icons.home, color: Colors.yellow,),
|
||||
title: new Text(AppLocalizations.of(context).translate("Home")),
|
||||
),
|
||||
BottomNavigationBarItem(
|
||||
icon: new Icon(Icons.event, color: Colors.lightGreen),
|
||||
activeIcon: new Icon(Icons.event, color: Colors.yellow,),
|
||||
title: new Text(AppLocalizations.of(context).translate("Events")),
|
||||
),
|
||||
BottomNavigationBarItem(
|
||||
icon: Icon(Icons.person, color: Colors.lightGreen,),
|
||||
activeIcon: new Icon(Icons.person, color: Colors.yellow,),
|
||||
title: Text(AppLocalizations.of(context).translate("Account"))
|
||||
),
|
||||
BottomNavigationBarItem(
|
||||
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
|
||||
switch (index) {
|
||||
case 0:
|
||||
Navigator.of(context).pop();
|
||||
Navigator.of(context).pushNamed('home');
|
||||
|
||||
break;
|
||||
case 2:
|
||||
Navigator.of(context).pop();
|
||||
Navigator.of(context).pushNamed('account');
|
||||
|
||||
break;
|
||||
case 3:
|
||||
Navigator.of(context).pop();
|
||||
Navigator.of(context).pushNamed('settings');
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
@ -36,7 +36,7 @@ class _CustomerListWidget extends State<CustomerListWidget> {
|
||||
visible: customer.visibleDetails,
|
||||
child: Row(
|
||||
children: <Widget>[
|
||||
Text(customer.age.toString() + " years, " + customer.sex),
|
||||
Text(customer.birthYear.toString() + " years, " + customer.sex),
|
||||
new RaisedButton(
|
||||
child: new Text('Modify'),
|
||||
color: Color.fromRGBO(244, 122, 22, 0.9),
|
||||
|
57
lib/widgets/home.dart
Normal file
@ -0,0 +1,57 @@
|
||||
import 'package:aitrainer_app/localization/app_language.dart';
|
||||
import 'package:aitrainer_app/localization/app_localization.dart';
|
||||
import 'package:aitrainer_app/view/menu_page.dart';
|
||||
import 'package:aitrainer_app/widgets/bottom_nav.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'bottom_nav.dart';
|
||||
import 'nav_drawer.dart';
|
||||
|
||||
class AitrainerHome extends StatefulWidget {
|
||||
_HomePageState _state;
|
||||
@override
|
||||
State<StatefulWidget> createState() {
|
||||
_state = new _HomePageState();
|
||||
return _state;
|
||||
}
|
||||
|
||||
void callback() {
|
||||
_state.setLangNoContext();
|
||||
}
|
||||
}
|
||||
|
||||
class _HomePageState extends State<AitrainerHome> {
|
||||
GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
|
||||
final AppLanguage appLanguage = AppLanguage();
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
MenuPage menu = MenuPage();
|
||||
BottomNavigator bottomNav = BottomNavigator();
|
||||
return Scaffold(
|
||||
key: _scaffoldKey,
|
||||
drawer: NavDrawer(),
|
||||
body:Container(
|
||||
child: MenuPage(parent: 0),
|
||||
),
|
||||
bottomNavigationBar: bottomNav.buildBottomNavigator(context, widget._state)
|
||||
);
|
||||
}
|
||||
|
||||
void setLangNoContext() {
|
||||
print("--- Callback ");
|
||||
setState(() {
|
||||
final AppLanguage appLanguage = AppLanguage();
|
||||
AppLocalizations.of(context).setLocale(appLanguage.appLocal);
|
||||
AppLocalizations.of(context).load();
|
||||
print("--- Lang for context reloaded");
|
||||
});
|
||||
}
|
||||
|
||||
}
|
55
lib/widgets/loading.dart
Normal file
@ -0,0 +1,55 @@
|
||||
import 'package:aitrainer_app/util/message_state.dart';
|
||||
import 'package:aitrainer_app/util/session.dart';
|
||||
import 'package:aitrainer_app/view/menu_page.dart';
|
||||
import 'package:aitrainer_app/widgets/bottom_nav.dart';
|
||||
import 'package:aitrainer_app/widgets/home.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'file:///D:/projects/aitrainer/src/aitrainer_app/lib/util/loading_screen.dart';
|
||||
|
||||
class LoadingScreenMain extends StatefulWidget {
|
||||
@override
|
||||
LoadingScreenMainState createState() => LoadingScreenMainState();
|
||||
}
|
||||
|
||||
class LoadingScreenMainState extends State<LoadingScreenMain> {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
Image _backgroundImage = Image.asset('asset/WT01_loading_layers.png',
|
||||
fit: BoxFit.cover,
|
||||
height: double.infinity,
|
||||
width: double.infinity,
|
||||
alignment: Alignment.center,
|
||||
);
|
||||
dynamic _timer = <dynamic>[TimeMessages.timer];
|
||||
return Scaffold(
|
||||
body: LoadingScreen(
|
||||
initializers: _timer,
|
||||
navigateToWidget: AitrainerHome(),
|
||||
loaderColor: Colors.yellow,
|
||||
image: _backgroundImage,
|
||||
backgroundColor: Colors.black,
|
||||
styleTextUnderTheLoader: TextStyle(
|
||||
fontSize: 14.0,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Colors.lightGreenAccent),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
class TimeMessages {
|
||||
static Future timer(MessageState state, Function callback) async {
|
||||
//while (true) {
|
||||
await Future.delayed(Duration(seconds: 4), () {
|
||||
state.setMessage = DateTime.now().toIso8601String();
|
||||
print("---- TimeMessages initializer");
|
||||
Session session = Session();
|
||||
session.fetchSessionAndNavigate(callback);
|
||||
});
|
||||
//}
|
||||
}
|
||||
}
|
@ -1,8 +1,25 @@
|
||||
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:flutter/material.dart';
|
||||
|
||||
class NavDrawer extends StatelessWidget {
|
||||
class NavDrawer extends StatefulWidget {
|
||||
|
||||
@override
|
||||
_NawDrawerWidget createState() => _NawDrawerWidget();
|
||||
}
|
||||
|
||||
class _NawDrawerWidget extends State<NavDrawer> {
|
||||
final Auth auth = Auth();
|
||||
final AppLanguage appLanguage = AppLanguage();
|
||||
Locale _locale;
|
||||
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Drawer(
|
||||
@ -11,49 +28,64 @@ class NavDrawer extends StatelessWidget {
|
||||
children: <Widget>[
|
||||
DrawerHeader(
|
||||
child: Text(
|
||||
'Customers And Exercises',
|
||||
AppLocalizations.of(context).translate('Customers And Exercises'),
|
||||
style: TextStyle(color: Colors.blue, fontSize: 25),
|
||||
),
|
||||
|
||||
),
|
||||
ListTile(
|
||||
leading: Icon(Icons.home),
|
||||
title: Text('Home'),
|
||||
title: Text( AppLocalizations.of(context).translate('Home')),
|
||||
onTap: () => Navigator.of(context).pushNamed('home'),
|
||||
),
|
||||
|
||||
ListTile(
|
||||
leading: Icon(Icons.people),
|
||||
title: Text('Customers'),
|
||||
//onTap: () => navigateToPage(context, 'customersPage'),
|
||||
title: Text( AppLocalizations.of(context).translate('Customers')),
|
||||
onTap: () => Navigator.of(context).pushNamed('customersPage'),
|
||||
),
|
||||
|
||||
ListTile(
|
||||
leading: Icon(Icons.directions_run),
|
||||
title: Text('Exercises'),
|
||||
onTap: () => Navigator.of(context).pushNamed('exerciseTypeListPage'),
|
||||
title: Text(AppLocalizations.of(context).translate('Exercises')),
|
||||
onTap: () =>
|
||||
Navigator.of(context).pushNamed('exerciseTypeListPage'),
|
||||
),
|
||||
ListTile(
|
||||
leading: Icon(Icons.arrow_upward),
|
||||
title: Text("TRAINING!"),
|
||||
title: Text(AppLocalizations.of(context).translate("TRAINING!")),
|
||||
onTap: () => Navigator.of(context).pushNamed('exerciseNewPage'),
|
||||
),
|
||||
ListTile(
|
||||
leading: Icon(Icons.perm_identity),
|
||||
title: Text('Login'),
|
||||
title: Text(AppLocalizations.of(context).translate('Login')),
|
||||
onTap: () => Navigator.of(context).pushNamed('login'),
|
||||
),
|
||||
ListTile(
|
||||
leading: Icon(Icons.cancel),
|
||||
title: Text("Logout"),
|
||||
onTap: () => {
|
||||
auth.logout(),
|
||||
Navigator.of(context).pushNamed('home'),
|
||||
}
|
||||
leading: Icon(Icons.cancel),
|
||||
title: Text(AppLocalizations.of(context).translate('Logout')),
|
||||
onTap: () =>
|
||||
{
|
||||
auth.logout(),
|
||||
Navigator.of(context).pushNamed('home'),
|
||||
}
|
||||
),
|
||||
ListTile(
|
||||
leading: Icon(Icons.hearing),
|
||||
title: Text(AppLocalizations.of(context).translate('Change Language')),
|
||||
onTap: () => _tapped(),
|
||||
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
void _tapped() => {
|
||||
/* _locale = Locale("hu"),
|
||||
appLanguage.changeLanguage(_locale),
|
||||
AppLocalizations.of(context).setLocale(_locale),
|
||||
AppLocalizations.of(context).load() */
|
||||
};
|
||||
|
||||
}
|
40
pubspec.yaml
@ -56,8 +56,44 @@ flutter:
|
||||
|
||||
# To add assets to your application, add an assets section, like this:
|
||||
assets:
|
||||
- asset/WT01_loading_layers.png
|
||||
# - images/a_dot_ham.jpeg
|
||||
- asset/image/WT_menu_welcome.png
|
||||
- asset/image/WT_menu_backround.png
|
||||
- asset/image/WT_menu.png
|
||||
- asset/image/WT_login.png
|
||||
- asset/image/WT_OK.png
|
||||
- asset/image/dots.gif
|
||||
- asset/image/WT_long_logo.png
|
||||
- asset/image/WT_light_background.png
|
||||
- asset/image/WT_menu_dark.png
|
||||
- asset/image/WT_gain_muscle.png
|
||||
- asset/image/WT_weight_loss.png
|
||||
- asset/image/WT_welcome.png
|
||||
- asset/menu/1.cardio.png
|
||||
- asset/menu/1.1.aerob.png
|
||||
- asset/menu/1.2.anaerob.png
|
||||
- asset/menu/1.1.1.cooper.png
|
||||
- asset/menu/1.2.1.300m.png
|
||||
- asset/menu/1.2.2.400m.png
|
||||
- asset/menu/2.strength.png
|
||||
- asset/menu/2.1.endurance.png
|
||||
- asset/menu/2.1.1.pull-ups.png
|
||||
- asset/menu/2.1.2.pushup.png
|
||||
- asset/menu/2.1.3.sit-ups.png
|
||||
- asset/menu/2.1.4.squats.png
|
||||
- asset/menu/2.1.5.timedpushup.png
|
||||
- asset/menu/2.1.6.core.png
|
||||
- asset/menu/2.2.1.1RM.png
|
||||
- asset/menu/2.2.1.1.chestpress.png
|
||||
- asset/menu/2.2.1.2.pullups.png
|
||||
- asset/menu/2.2.1.3.biceps.png
|
||||
- asset/menu/2.2.1.4.triceps.png
|
||||
- asset/menu/2.2.1.5.shoulders.png
|
||||
- asset/menu/3.bcs1.png
|
||||
- asset/menu/3.1.BMI.png
|
||||
- asset/menu/3.2.BMR.png
|
||||
- asset/menu/3.3.sizes.png
|
||||
- i18n/en.json
|
||||
- i18n/hu.json
|
||||
|
||||
# An image asset can refer to one or more resolution-specific "variants", see
|
||||
# https://flutter.dev/assets-and-images/#resolution-aware.
|
||||
|