WT 1.1.22 reengineering: Training Plan execution, registration
This commit is contained in:
@@ -12,6 +12,7 @@ import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:aitrainer_app/widgets/bottom_nav.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:firebase_in_app_messaging/firebase_in_app_messaging.dart';
|
||||
|
||||
// ignore: must_be_immutable
|
||||
class AccountPage extends StatelessWidget with Trans {
|
||||
@@ -151,6 +152,7 @@ class AccountPage extends StatelessWidget with Trans {
|
||||
),
|
||||
devices(context, accountBloc),
|
||||
loginOut(context, accountBloc),
|
||||
//messaging(),
|
||||
//getMyTrainees(context, accountBloc),
|
||||
]);
|
||||
}
|
||||
@@ -180,6 +182,25 @@ class AccountPage extends StatelessWidget with Trans {
|
||||
return element;
|
||||
}
|
||||
|
||||
ListTile messaging() {
|
||||
FirebaseInAppMessaging fiam = FirebaseInAppMessaging();
|
||||
ListTile element = ListTile(
|
||||
leading: Icon(Icons.message),
|
||||
title: TextButton(
|
||||
style: TextButton.styleFrom(
|
||||
backgroundColor: Colors.white38,
|
||||
onSurface: Colors.grey,
|
||||
),
|
||||
child: Row(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [
|
||||
Text(t("Trigger message"), style: TextStyle(color: Colors.purple)),
|
||||
]),
|
||||
onPressed: () => fiam.triggerEvent("mydevelopment"),
|
||||
),
|
||||
);
|
||||
|
||||
return element;
|
||||
}
|
||||
|
||||
ListTile loginOut(BuildContext context, AccountBloc accountBloc) {
|
||||
ListTile element = ListTile();
|
||||
|
||||
|
||||
+160
-184
@@ -1,6 +1,7 @@
|
||||
import 'dart:collection';
|
||||
|
||||
import 'package:aitrainer_app/bloc/customer_change/customer_change_bloc.dart';
|
||||
import 'package:aitrainer_app/library/custom_icon_icons.dart';
|
||||
import 'package:aitrainer_app/model/cache.dart';
|
||||
import 'package:aitrainer_app/model/sport.dart';
|
||||
import 'package:aitrainer_app/util/app_localization.dart';
|
||||
@@ -14,6 +15,7 @@ import 'package:flutter/material.dart';
|
||||
import 'package:flutter/rendering.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
import 'package:modal_progress_hud_nsn/modal_progress_hud_nsn.dart';
|
||||
|
||||
import '../bloc/customer_change/customer_change_bloc.dart';
|
||||
import '../library/dropdown_search/dropdown_search.dart';
|
||||
@@ -31,11 +33,13 @@ class CustomerFitnessPage extends StatefulWidget {
|
||||
class _CustomerFitnessPageState extends State<CustomerFitnessPage> with Trans {
|
||||
String? selected;
|
||||
bool fulldata = false;
|
||||
late CustomerChangeBloc changeBloc;
|
||||
late double cWidth;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
setContext(context);
|
||||
final double cWidth = MediaQuery.of(context).size.width * 0.75;
|
||||
cWidth = MediaQuery.of(context).size.width * 0.75;
|
||||
CustomerRepository customerRepository;
|
||||
dynamic args = ModalRoute.of(context)!.settings.arguments;
|
||||
if (args is HashMap && args['personal_data'] != null) {
|
||||
@@ -49,186 +53,122 @@ class _CustomerFitnessPageState extends State<CustomerFitnessPage> with Trans {
|
||||
back: true,
|
||||
);
|
||||
if (!fulldata) {
|
||||
_bar = AppBarProgress(max: 50, min: 26);
|
||||
_bar = AppBarProgress(max: 30, min: 15);
|
||||
}
|
||||
final double h = 27;
|
||||
return Scaffold(
|
||||
appBar: _bar,
|
||||
body: BlocProvider(
|
||||
appBar: _bar,
|
||||
body: Container(
|
||||
decoration: BoxDecoration(
|
||||
image: DecorationImage(
|
||||
image: AssetImage('asset/image/WT_plainblack_background.jpg'),
|
||||
fit: BoxFit.cover,
|
||||
alignment: Alignment.center,
|
||||
),
|
||||
),
|
||||
height: double.infinity,
|
||||
width: double.infinity,
|
||||
child: BlocProvider(
|
||||
create: (context) => CustomerChangeBloc(customerRepository: customerRepository),
|
||||
child: Builder(builder: (context) {
|
||||
// ignore: close_sinks
|
||||
CustomerChangeBloc changeBloc = BlocProvider.of<CustomerChangeBloc>(context);
|
||||
selected = changeBloc.selectedFitnessItem;
|
||||
if (selected == null) {
|
||||
selected = FitnessState.beginner;
|
||||
}
|
||||
return SingleChildScrollView(
|
||||
scrollDirection: Axis.vertical,
|
||||
child: Container(
|
||||
padding: EdgeInsets.only(bottom: 200),
|
||||
decoration: BoxDecoration(
|
||||
image: DecorationImage(
|
||||
image: AssetImage('asset/image/WT_light_background.jpg'),
|
||||
fit: BoxFit.cover,
|
||||
alignment: Alignment.center,
|
||||
),
|
||||
),
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Divider(),
|
||||
Wrap(
|
||||
//runAlignment: WrapAlignment.center,
|
||||
alignment: WrapAlignment.center,
|
||||
children: [
|
||||
Text(
|
||||
t("Your Fitness State"),
|
||||
textAlign: TextAlign.center,
|
||||
style: GoogleFonts.archivoBlack(
|
||||
color: Colors.orange,
|
||||
fontSize: 30,
|
||||
fontWeight: FontWeight.w900,
|
||||
),
|
||||
)
|
||||
]),
|
||||
Divider(),
|
||||
TextButton(
|
||||
style: TextButton.styleFrom(
|
||||
padding: EdgeInsets.all(10.0),
|
||||
shape: getShape(changeBloc, FitnessState.beginner),
|
||||
),
|
||||
child: Container(
|
||||
width: cWidth,
|
||||
child: Column(
|
||||
children: [
|
||||
Text(t("Beginner"),
|
||||
textWidthBasis: TextWidthBasis.longestLine,
|
||||
style: TextStyle(color: Colors.blue, fontSize: 32, fontFamily: 'Arial', fontWeight: FontWeight.w900)),
|
||||
Text(
|
||||
t("I am beginner"),
|
||||
style: TextStyle(color: Colors.black, fontSize: 20, fontFamily: 'Arial', fontWeight: FontWeight.w100),
|
||||
),
|
||||
],
|
||||
)),
|
||||
onPressed: () => {
|
||||
setState(() {
|
||||
selected = FitnessState.beginner;
|
||||
changeBloc.add(CustomerFitnessChange(fitness: selected!));
|
||||
}),
|
||||
}),
|
||||
Divider(),
|
||||
TextButton(
|
||||
style: TextButton.styleFrom(
|
||||
padding: EdgeInsets.all(10.0),
|
||||
shape: getShape(changeBloc, FitnessState.intermediate),
|
||||
),
|
||||
child: Container(
|
||||
width: cWidth,
|
||||
child: Column(
|
||||
children: [
|
||||
InkWell(
|
||||
child: Text(
|
||||
t("Intermediate"),
|
||||
style: TextStyle(color: Colors.blue, fontSize: 32, fontFamily: 'Arial', fontWeight: FontWeight.w900),
|
||||
),
|
||||
highlightColor: Colors.white,
|
||||
),
|
||||
InkWell(
|
||||
child: Text(
|
||||
t("I am intermediate"),
|
||||
style: TextStyle(color: Colors.black, fontSize: 20, fontFamily: 'Arial', fontWeight: FontWeight.w100),
|
||||
),
|
||||
highlightColor: Colors.white,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
onPressed: () => {
|
||||
setState(() {
|
||||
selected = FitnessState.intermediate;
|
||||
changeBloc.add(CustomerFitnessChange(fitness: selected!));
|
||||
print(selected);
|
||||
}),
|
||||
}),
|
||||
Divider(),
|
||||
TextButton(
|
||||
style: TextButton.styleFrom(
|
||||
padding: EdgeInsets.all(10.0),
|
||||
shape: getShape(changeBloc, FitnessState.advanced),
|
||||
),
|
||||
child: Container(
|
||||
width: cWidth,
|
||||
child: Column(
|
||||
children: [
|
||||
InkWell(
|
||||
child: Text(
|
||||
t("Advanced"),
|
||||
style: TextStyle(color: Colors.blue, fontSize: 32, fontFamily: 'Arial', fontWeight: FontWeight.w900),
|
||||
),
|
||||
highlightColor: Colors.white,
|
||||
),
|
||||
InkWell(
|
||||
child: Text(
|
||||
t("I am advanced"),
|
||||
style: TextStyle(color: Colors.black, fontSize: 20, fontFamily: 'Arial', fontWeight: FontWeight.w100),
|
||||
),
|
||||
highlightColor: Colors.white,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
onPressed: () => {
|
||||
setState(() {
|
||||
selected = FitnessState.advanced;
|
||||
changeBloc.add(CustomerFitnessChange(fitness: selected!));
|
||||
print(selected);
|
||||
}),
|
||||
}),
|
||||
Divider(),
|
||||
TextButton(
|
||||
style: TextButton.styleFrom(
|
||||
padding: EdgeInsets.all(10.0),
|
||||
shape: getShape(changeBloc, FitnessState.professional),
|
||||
),
|
||||
child: Container(
|
||||
width: cWidth,
|
||||
child: Column(
|
||||
children: [
|
||||
InkWell(
|
||||
child: Text(
|
||||
AppLocalizations.of(context)!.translate("Professional"),
|
||||
style: TextStyle(color: Colors.blue, fontSize: 32, fontFamily: 'Arial', fontWeight: FontWeight.w900),
|
||||
),
|
||||
highlightColor: Colors.white,
|
||||
),
|
||||
InkWell(
|
||||
child: Text(
|
||||
AppLocalizations.of(context)!.translate("I am professional"),
|
||||
style: TextStyle(color: Colors.black, fontSize: 20, fontFamily: 'Arial', fontWeight: FontWeight.w100),
|
||||
),
|
||||
highlightColor: Colors.white,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
onPressed: () => {
|
||||
setState(() {
|
||||
selected = FitnessState.professional;
|
||||
changeBloc.add(CustomerFitnessChange(fitness: selected!));
|
||||
print(selected);
|
||||
}),
|
||||
}),
|
||||
Divider(),
|
||||
Text(
|
||||
t("Your Primary Sport") + ":",
|
||||
textAlign: TextAlign.center,
|
||||
style: GoogleFonts.archivoBlack(
|
||||
color: Colors.orange,
|
||||
fontSize: 20,
|
||||
),
|
||||
child: BlocConsumer<CustomerChangeBloc, CustomerChangeState>(
|
||||
listener: (context, state) {
|
||||
if (state is CustomerSaveError) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(backgroundColor: Colors.orange, content: Text(state.message, style: TextStyle(color: Colors.white))));
|
||||
} else if (state is CustomerSaveSuccess) {
|
||||
Navigator.of(context).pop();
|
||||
Navigator.of(context).pushNamed("customerSexPage", arguments: changeBloc.customerRepository);
|
||||
}
|
||||
},
|
||||
builder: (context, state) {
|
||||
changeBloc = BlocProvider.of<CustomerChangeBloc>(context);
|
||||
return ModalProgressHUD(
|
||||
child: getPage(),
|
||||
inAsyncCall: state is CustomerChangeLoading,
|
||||
opacity: 0.5,
|
||||
color: Colors.black54,
|
||||
progressIndicator: CircularProgressIndicator(),
|
||||
);
|
||||
},
|
||||
),
|
||||
)),
|
||||
floatingActionButton: FloatingActionButton.extended(
|
||||
onPressed: () => {
|
||||
if (!fulldata)
|
||||
{
|
||||
changeBloc.add(CustomerSaveFitness()),
|
||||
}
|
||||
else
|
||||
{
|
||||
changeBloc.add(CustomerSave()),
|
||||
}
|
||||
},
|
||||
backgroundColor: Color(0xffb4f500),
|
||||
icon: Icon(
|
||||
CustomIcon.save,
|
||||
color: Colors.black,
|
||||
size: 26,
|
||||
),
|
||||
label: Text(
|
||||
fulldata ? t("Save") : t("Next"),
|
||||
style: GoogleFonts.inter(fontWeight: FontWeight.bold, fontSize: 18, color: Colors.black),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget getPage() {
|
||||
final double h = 27;
|
||||
return SingleChildScrollView(
|
||||
scrollDirection: Axis.vertical,
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
SizedBox(
|
||||
height: h,
|
||||
),
|
||||
Wrap(alignment: WrapAlignment.center, children: [
|
||||
Text(
|
||||
t("Your Fitness State"),
|
||||
textAlign: TextAlign.center,
|
||||
style: GoogleFonts.archivoBlack(
|
||||
color: Colors.white,
|
||||
fontSize: 30,
|
||||
fontWeight: FontWeight.w900,
|
||||
),
|
||||
)
|
||||
]),
|
||||
SizedBox(
|
||||
height: h,
|
||||
),
|
||||
|
||||
getButton("Beginner", "I am beginner", FitnessState.beginner),
|
||||
SizedBox(
|
||||
height: h,
|
||||
),
|
||||
getButton("Intermediate", "I am intermediate", FitnessState.intermediate),
|
||||
|
||||
SizedBox(
|
||||
height: h,
|
||||
),
|
||||
getButton("Advanced", "I am advanced", FitnessState.advanced),
|
||||
|
||||
SizedBox(
|
||||
height: h,
|
||||
),
|
||||
getButton("Professional", "I am professional", FitnessState.professional),
|
||||
|
||||
/* Divider(),
|
||||
Text(
|
||||
t("Your Primary Sport") + ":",
|
||||
textAlign: TextAlign.center,
|
||||
style: GoogleFonts.archivoBlack(
|
||||
color: Colors.orange,
|
||||
fontSize: 20,
|
||||
),
|
||||
getSport(changeBloc),
|
||||
Divider(),
|
||||
), */
|
||||
//getSport(changeBloc),
|
||||
/* Divider(),
|
||||
ElevatedButton(
|
||||
style: ElevatedButton.styleFrom(
|
||||
onPrimary: Colors.white,
|
||||
@@ -240,22 +180,58 @@ class _CustomerFitnessPageState extends State<CustomerFitnessPage> with Trans {
|
||||
Navigator.of(context).pop(),
|
||||
if (!fulldata) {Navigator.of(context).pushNamed("customerBodyTypePage", arguments: customerRepository)}
|
||||
},
|
||||
)
|
||||
],
|
||||
),
|
||||
) */
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
TextButton getButton(String title, String desc, String state) {
|
||||
return TextButton(
|
||||
style: TextButton.styleFrom(
|
||||
padding: EdgeInsets.all(10.0),
|
||||
shape: getShape(changeBloc, state),
|
||||
),
|
||||
child: Container(
|
||||
width: cWidth,
|
||||
child: Column(
|
||||
children: [
|
||||
InkWell(
|
||||
child: Text(
|
||||
AppLocalizations.of(context)!.translate(title),
|
||||
style: TextStyle(color: Colors.white, fontSize: 32, fontFamily: 'Arial', fontWeight: FontWeight.w900),
|
||||
),
|
||||
);
|
||||
})));
|
||||
highlightColor: Colors.white,
|
||||
),
|
||||
InkWell(
|
||||
child: Text(
|
||||
AppLocalizations.of(context)!.translate(desc),
|
||||
style: TextStyle(color: Colors.white, fontSize: 20, fontFamily: 'Arial', fontWeight: FontWeight.w100),
|
||||
),
|
||||
highlightColor: Colors.white,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
onPressed: () => {
|
||||
changeBloc.add(CustomerFitnessChange(fitness: state)),
|
||||
});
|
||||
}
|
||||
|
||||
dynamic getShape(CustomerChangeBloc changeBloc, String fitnessLevel) {
|
||||
String? selected = changeBloc.selectedFitnessItem;
|
||||
|
||||
dynamic returnCode = (selected == fitnessLevel)
|
||||
? RoundedRectangleBorder(
|
||||
side: BorderSide(width: 4, color: Colors.orange),
|
||||
side: BorderSide(
|
||||
width: 4,
|
||||
color: Color(0xffb4f500),
|
||||
),
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
)
|
||||
: RoundedRectangleBorder(
|
||||
side: BorderSide(width: 1, color: Colors.blue),
|
||||
side: BorderSide(width: 4, color: Colors.white24),
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
);
|
||||
//return
|
||||
return returnCode;
|
||||
|
||||
@@ -10,6 +10,7 @@ import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
import 'package:modal_progress_hud_nsn/modal_progress_hud_nsn.dart';
|
||||
|
||||
enum Goals { gain_muscle, weight_loss, endurance, muscle_endurance, flexibility, gain_strength, explosiveness, shape_forming }
|
||||
|
||||
@@ -69,18 +70,21 @@ class _CustomerGoalPage extends State<CustomerGoalPage> with Trans {
|
||||
|
||||
CustomerRepository customerRepository;
|
||||
dynamic args = ModalRoute.of(context)!.settings.arguments;
|
||||
if (args is HashMap && args['personal_data'] != null) {
|
||||
fulldata = args['personal_data'];
|
||||
customerRepository = args['bloc'];
|
||||
if (args != null) {
|
||||
if (args is HashMap && args['personal_data'] != null) {
|
||||
fulldata = args['personal_data'];
|
||||
customerRepository = args['bloc'];
|
||||
} else {
|
||||
customerRepository = ModalRoute.of(context)!.settings.arguments as CustomerRepository;
|
||||
}
|
||||
} else {
|
||||
customerRepository = ModalRoute.of(context)!.settings.arguments as CustomerRepository;
|
||||
customerRepository = CustomerRepository();
|
||||
}
|
||||
|
||||
PreferredSizeWidget _bar = AppBarMin(
|
||||
back: true,
|
||||
back: false,
|
||||
);
|
||||
if (!fulldata) {
|
||||
_bar = AppBarProgress(max: 50, min: 26);
|
||||
_bar = AppBarProgress(max: 14, min: 0);
|
||||
}
|
||||
|
||||
return Scaffold(
|
||||
@@ -88,7 +92,7 @@ class _CustomerGoalPage extends State<CustomerGoalPage> with Trans {
|
||||
body: Container(
|
||||
decoration: BoxDecoration(
|
||||
image: DecorationImage(
|
||||
image: AssetImage('asset/image/WT_light_background.jpg'),
|
||||
image: AssetImage('asset/image/WT_plainblack_background.jpg'),
|
||||
fit: BoxFit.cover,
|
||||
alignment: Alignment.center,
|
||||
),
|
||||
@@ -97,75 +101,120 @@ class _CustomerGoalPage extends State<CustomerGoalPage> with Trans {
|
||||
width: double.infinity,
|
||||
child: BlocProvider(
|
||||
create: (context) => CustomerChangeBloc(customerRepository: customerRepository),
|
||||
child: Builder(builder: (context) {
|
||||
changeBloc = BlocProvider.of<CustomerChangeBloc>(context);
|
||||
|
||||
return SingleChildScrollView(
|
||||
child: Center(
|
||||
child: Column(
|
||||
children: [
|
||||
Divider(),
|
||||
Wrap(alignment: WrapAlignment.center, children: [
|
||||
Text(
|
||||
t("Set Your Primary Goal"),
|
||||
maxLines: 2,
|
||||
textAlign: TextAlign.center,
|
||||
style: GoogleFonts.archivoBlack(
|
||||
color: Colors.orange,
|
||||
fontSize: 30,
|
||||
shadows: <Shadow>[
|
||||
Shadow(
|
||||
offset: Offset(2.0, 2.0),
|
||||
blurRadius: 3.0,
|
||||
color: Colors.black87,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
]),
|
||||
Divider(),
|
||||
getItem(changeBloc, Goals.gain_muscle),
|
||||
Divider(),
|
||||
getItem(changeBloc, Goals.weight_loss),
|
||||
Divider(),
|
||||
getItem(changeBloc, Goals.shape_forming),
|
||||
Divider(),
|
||||
getItem(changeBloc, Goals.endurance),
|
||||
Divider(),
|
||||
getItem(changeBloc, Goals.gain_strength),
|
||||
Divider(),
|
||||
getItem(changeBloc, Goals.muscle_endurance),
|
||||
Divider(),
|
||||
getItem(changeBloc, Goals.flexibility),
|
||||
Divider(),
|
||||
getItem(changeBloc, Goals.explosiveness),
|
||||
Divider(),
|
||||
],
|
||||
),
|
||||
));
|
||||
}),
|
||||
child: BlocConsumer<CustomerChangeBloc, CustomerChangeState>(
|
||||
listener: (context, state) {
|
||||
if (state is CustomerSaveError) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(backgroundColor: Colors.orange, content: Text(state.message, style: TextStyle(color: Colors.white))));
|
||||
} else if (state is CustomerSaveSuccess) {
|
||||
Navigator.of(context).pushNamed("customerFitnessPage", arguments: changeBloc.customerRepository);
|
||||
}
|
||||
},
|
||||
builder: (context, state) {
|
||||
changeBloc = BlocProvider.of<CustomerChangeBloc>(context);
|
||||
return ModalProgressHUD(
|
||||
child: getPage(),
|
||||
inAsyncCall: state is CustomerChangeLoading,
|
||||
opacity: 0.5,
|
||||
color: Colors.black54,
|
||||
progressIndicator: CircularProgressIndicator(),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
floatingActionButton: FloatingActionButton.extended(
|
||||
onPressed: () => {
|
||||
//changingViewModel.saveCustomer(),
|
||||
changeBloc.add(CustomerSave()),
|
||||
Navigator.of(context).pop(),
|
||||
if (!fulldata) {Navigator.of(context).pushNamed("customerFitnessPage", arguments: changeBloc.customerRepository)}
|
||||
print("Fulldata: $fulldata bloc $changeBloc"),
|
||||
if (!fulldata)
|
||||
{
|
||||
print("Savegoal"),
|
||||
changeBloc.add(CustomerSaveGoal()),
|
||||
}
|
||||
else
|
||||
{
|
||||
changeBloc.add(CustomerSave()),
|
||||
}
|
||||
},
|
||||
backgroundColor: Colors.orange[800],
|
||||
backgroundColor: Color(0xffb4f500),
|
||||
icon: Icon(
|
||||
CustomIcon.save,
|
||||
size: 20,
|
||||
color: Colors.black,
|
||||
size: 26,
|
||||
),
|
||||
label: Text(
|
||||
fulldata ? t("Save") : t("Next"),
|
||||
style: GoogleFonts.inter(fontWeight: FontWeight.bold, fontSize: 12),
|
||||
style: GoogleFonts.inter(fontWeight: FontWeight.bold, fontSize: 18, color: Colors.black),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget getPage() {
|
||||
final double h = 27;
|
||||
return SingleChildScrollView(
|
||||
child: Center(
|
||||
child: Column(
|
||||
children: [
|
||||
Divider(),
|
||||
Wrap(alignment: WrapAlignment.center, children: [
|
||||
Text(
|
||||
t("Set Your Primary Goal"),
|
||||
maxLines: 2,
|
||||
textAlign: TextAlign.center,
|
||||
style: GoogleFonts.archivoBlack(
|
||||
color: Colors.white,
|
||||
fontSize: 30,
|
||||
shadows: <Shadow>[
|
||||
Shadow(
|
||||
offset: Offset(2.0, 2.0),
|
||||
blurRadius: 3.0,
|
||||
color: Colors.black87,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
]),
|
||||
SizedBox(
|
||||
height: h,
|
||||
),
|
||||
getItem(changeBloc, Goals.gain_muscle),
|
||||
SizedBox(
|
||||
height: h,
|
||||
),
|
||||
getItem(changeBloc, Goals.weight_loss),
|
||||
SizedBox(
|
||||
height: h,
|
||||
),
|
||||
getItem(changeBloc, Goals.shape_forming),
|
||||
SizedBox(
|
||||
height: h,
|
||||
),
|
||||
getItem(changeBloc, Goals.endurance),
|
||||
SizedBox(
|
||||
height: h,
|
||||
),
|
||||
getItem(changeBloc, Goals.gain_strength),
|
||||
SizedBox(
|
||||
height: h,
|
||||
),
|
||||
getItem(changeBloc, Goals.muscle_endurance),
|
||||
SizedBox(
|
||||
height: h,
|
||||
),
|
||||
getItem(changeBloc, Goals.flexibility),
|
||||
SizedBox(
|
||||
height: h,
|
||||
),
|
||||
getItem(changeBloc, Goals.explosiveness),
|
||||
SizedBox(
|
||||
height: h,
|
||||
),
|
||||
],
|
||||
),
|
||||
));
|
||||
}
|
||||
|
||||
Widget getItem(CustomerChangeBloc changeBloc, Goals goal) {
|
||||
return Stack(alignment: Alignment.bottomLeft, children: [
|
||||
TextButton(
|
||||
@@ -188,7 +237,7 @@ class _CustomerGoalPage extends State<CustomerGoalPage> with Trans {
|
||||
child: Text(
|
||||
t(goal.description(goal)),
|
||||
style: GoogleFonts.archivoBlack(
|
||||
color: Colors.yellow[300],
|
||||
color: Colors.white,
|
||||
fontSize: 28,
|
||||
shadows: <Shadow>[
|
||||
Shadow(
|
||||
@@ -204,13 +253,18 @@ class _CustomerGoalPage extends State<CustomerGoalPage> with Trans {
|
||||
}
|
||||
|
||||
dynamic getShape(CustomerChangeBloc customerBloc, String goal) {
|
||||
if (customerBloc.customerRepository.goal == null) return null;
|
||||
dynamic baseCode = RoundedRectangleBorder(
|
||||
side: BorderSide(width: 2, color: Colors.white24),
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
);
|
||||
if (customerBloc.customerRepository.goal == null) return baseCode;
|
||||
String selectedGoal = customerBloc.customerRepository.goal!;
|
||||
dynamic returnCode = (selectedGoal == goal)
|
||||
? RoundedRectangleBorder(
|
||||
side: BorderSide(width: 4, color: Colors.red),
|
||||
side: BorderSide(width: 6, color: Color(0xffb4f500)),
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
)
|
||||
: null;
|
||||
: baseCode;
|
||||
//return
|
||||
return returnCode;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,178 @@
|
||||
import 'package:aitrainer_app/bloc/customer_change/customer_change_bloc.dart';
|
||||
import 'package:aitrainer_app/library/custom_icon_icons.dart';
|
||||
|
||||
import 'package:aitrainer_app/repository/customer_repository.dart';
|
||||
import 'package:aitrainer_app/util/trans.dart';
|
||||
import 'package:aitrainer_app/widgets/app_bar_min.dart';
|
||||
import 'package:aitrainer_app/widgets/app_bar_progress.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/rendering.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
|
||||
import 'package:syncfusion_flutter_gauges/gauges.dart';
|
||||
|
||||
import '../bloc/customer_change/customer_change_bloc.dart';
|
||||
|
||||
// ignore: must_be_immutable
|
||||
class CustomerHeightPage extends StatefulWidget {
|
||||
late _CustomerHeightPageState _state;
|
||||
|
||||
_CustomerHeightPageState createState() {
|
||||
_state = _CustomerHeightPageState();
|
||||
return _state;
|
||||
}
|
||||
}
|
||||
|
||||
class _CustomerHeightPageState extends State<CustomerHeightPage> with Trans {
|
||||
String? selected;
|
||||
bool fulldata = false;
|
||||
late CustomerChangeBloc changeBloc;
|
||||
late double cWidth;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
setContext(context);
|
||||
|
||||
final CustomerRepository customerRepository = ModalRoute.of(context)!.settings.arguments as CustomerRepository;
|
||||
|
||||
PreferredSizeWidget _bar = AppBarMin(
|
||||
back: true,
|
||||
);
|
||||
if (!fulldata) {
|
||||
_bar = AppBarProgress(max: 75, min: 60);
|
||||
}
|
||||
|
||||
return Scaffold(
|
||||
appBar: _bar,
|
||||
body: Container(
|
||||
decoration: BoxDecoration(
|
||||
image: DecorationImage(
|
||||
image: AssetImage('asset/image/WT_plainblack_background.jpg'),
|
||||
fit: BoxFit.cover,
|
||||
alignment: Alignment.center,
|
||||
),
|
||||
),
|
||||
height: double.infinity,
|
||||
width: double.infinity,
|
||||
child: BlocProvider(
|
||||
create: (context) => CustomerChangeBloc(customerRepository: customerRepository),
|
||||
child: BlocConsumer<CustomerChangeBloc, CustomerChangeState>(
|
||||
listener: (context, state) {
|
||||
if (state is CustomerSaveError) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(backgroundColor: Colors.orange, content: Text(state.message, style: TextStyle(color: Colors.white))));
|
||||
} else if (state is CustomerSaveSuccess) {
|
||||
Navigator.of(context).pop();
|
||||
Navigator.of(context).pushNamed("registration", arguments: changeBloc.customerRepository);
|
||||
}
|
||||
},
|
||||
builder: (context, state) {
|
||||
changeBloc = BlocProvider.of<CustomerChangeBloc>(context);
|
||||
return getPage();
|
||||
},
|
||||
),
|
||||
)),
|
||||
floatingActionButton: FloatingActionButton.extended(
|
||||
onPressed: () => changeBloc.add(CustomerSaveHeight()),
|
||||
backgroundColor: Color(0xffb4f500),
|
||||
icon: Icon(
|
||||
CustomIcon.save,
|
||||
color: Colors.black,
|
||||
size: 26,
|
||||
),
|
||||
label: Text(
|
||||
fulldata ? t("Save") : t("Finish"),
|
||||
style: GoogleFonts.inter(fontWeight: FontWeight.bold, fontSize: 18, color: Colors.black),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget getPage() {
|
||||
final double h = 27;
|
||||
cWidth = MediaQuery.of(context).size.width * 0.75;
|
||||
return SingleChildScrollView(
|
||||
scrollDirection: Axis.vertical,
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
SizedBox(
|
||||
height: h,
|
||||
),
|
||||
Wrap(alignment: WrapAlignment.center, children: [
|
||||
Text(
|
||||
t("What is your height?"),
|
||||
textAlign: TextAlign.center,
|
||||
maxLines: 2,
|
||||
style: GoogleFonts.archivoBlack(
|
||||
color: Colors.white,
|
||||
fontSize: 30,
|
||||
fontWeight: FontWeight.w900,
|
||||
),
|
||||
)
|
||||
]),
|
||||
SizedBox(
|
||||
height: h,
|
||||
),
|
||||
getButton(),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget getButton() {
|
||||
double mediaWidth = MediaQuery.of(context).size.width * .4;
|
||||
double mediaHeight = MediaQuery.of(context).size.height * .4;
|
||||
return Row(children: [
|
||||
changeBloc.customerRepository.customer!.sex == "m"
|
||||
? Image.asset(
|
||||
"asset/image/test_picto_m.png",
|
||||
height: mediaHeight,
|
||||
width: mediaWidth,
|
||||
)
|
||||
: Image.asset(
|
||||
"asset/image/test_picto_w.png",
|
||||
height: mediaHeight,
|
||||
width: mediaWidth,
|
||||
),
|
||||
SfLinearGauge(
|
||||
minimum: 140,
|
||||
maximum: 220,
|
||||
markerPointers: [
|
||||
LinearWidgetPointer(
|
||||
value: changeBloc.height,
|
||||
offset: 55,
|
||||
position: LinearElementPosition.inside,
|
||||
markerAlignment: LinearMarkerAlignment.center,
|
||||
child: Container(
|
||||
height: 25,
|
||||
width: 55,
|
||||
color: Colors.transparent,
|
||||
child: Text(changeBloc.height.toString(),
|
||||
style: GoogleFonts.inter(
|
||||
fontSize: 20,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Color(0xffb4f500),
|
||||
)),
|
||||
),
|
||||
),
|
||||
LinearShapePointer(
|
||||
height: 25,
|
||||
width: 55,
|
||||
color: Color(0xffb4f500),
|
||||
value: changeBloc.height,
|
||||
onValueChanged: (value) => {
|
||||
changeBloc.add(CustomerHeightChange(height: value.toInt())),
|
||||
},
|
||||
),
|
||||
],
|
||||
orientation: LinearGaugeOrientation.vertical,
|
||||
majorTickStyle: LinearTickStyle(length: 20, color: Colors.white),
|
||||
axisLabelStyle: TextStyle(fontSize: 12.0, color: Colors.white),
|
||||
axisTrackStyle:
|
||||
LinearAxisTrackStyle(color: Colors.cyan, edgeStyle: LinearEdgeStyle.bothFlat, thickness: 1.0, borderColor: Colors.white))
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,185 @@
|
||||
import 'package:aitrainer_app/bloc/customer_change/customer_change_bloc.dart';
|
||||
import 'package:aitrainer_app/library/custom_icon_icons.dart';
|
||||
|
||||
import 'package:aitrainer_app/util/app_localization.dart';
|
||||
import 'package:aitrainer_app/repository/customer_repository.dart';
|
||||
import 'package:aitrainer_app/util/trans.dart';
|
||||
import 'package:aitrainer_app/widgets/app_bar_min.dart';
|
||||
import 'package:aitrainer_app/widgets/app_bar_progress.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/rendering.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
import 'package:modal_progress_hud_nsn/modal_progress_hud_nsn.dart';
|
||||
|
||||
import '../bloc/customer_change/customer_change_bloc.dart';
|
||||
|
||||
// ignore: must_be_immutable
|
||||
class CustomerSexPage extends StatefulWidget {
|
||||
late _CustomerSexPageState _state;
|
||||
|
||||
_CustomerSexPageState createState() {
|
||||
_state = _CustomerSexPageState();
|
||||
return _state;
|
||||
}
|
||||
}
|
||||
|
||||
class _CustomerSexPageState extends State<CustomerSexPage> with Trans {
|
||||
String? selected;
|
||||
bool fulldata = false;
|
||||
late CustomerChangeBloc changeBloc;
|
||||
late double cWidth;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
setContext(context);
|
||||
|
||||
final CustomerRepository customerRepository = ModalRoute.of(context)!.settings.arguments as CustomerRepository;
|
||||
|
||||
PreferredSizeWidget _bar = AppBarMin(
|
||||
back: true,
|
||||
);
|
||||
if (!fulldata) {
|
||||
_bar = AppBarProgress(max: 45, min: 30);
|
||||
}
|
||||
|
||||
return Scaffold(
|
||||
appBar: _bar,
|
||||
body: Container(
|
||||
decoration: BoxDecoration(
|
||||
image: DecorationImage(
|
||||
image: AssetImage('asset/image/WT_plainblack_background.jpg'),
|
||||
fit: BoxFit.cover,
|
||||
alignment: Alignment.center,
|
||||
),
|
||||
),
|
||||
height: double.infinity,
|
||||
width: double.infinity,
|
||||
child: BlocProvider(
|
||||
create: (context) => CustomerChangeBloc(customerRepository: customerRepository),
|
||||
child: BlocConsumer<CustomerChangeBloc, CustomerChangeState>(
|
||||
listener: (context, state) {
|
||||
if (state is CustomerSaveError) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(backgroundColor: Colors.orange, content: Text(state.message, style: TextStyle(color: Colors.white))));
|
||||
} else if (state is CustomerSaveSuccess) {
|
||||
Navigator.of(context).pop();
|
||||
Navigator.of(context).pushNamed("customerWeightPage", arguments: changeBloc.customerRepository);
|
||||
}
|
||||
},
|
||||
builder: (context, state) {
|
||||
changeBloc = BlocProvider.of<CustomerChangeBloc>(context);
|
||||
return ModalProgressHUD(
|
||||
child: getPage(),
|
||||
inAsyncCall: state is CustomerChangeLoading,
|
||||
opacity: 0.5,
|
||||
color: Colors.black54,
|
||||
progressIndicator: CircularProgressIndicator(),
|
||||
);
|
||||
},
|
||||
),
|
||||
)),
|
||||
floatingActionButton: FloatingActionButton.extended(
|
||||
onPressed: () => {
|
||||
changeBloc.add(CustomerSaveSex()),
|
||||
},
|
||||
backgroundColor: Color(0xffb4f500),
|
||||
icon: Icon(
|
||||
CustomIcon.save,
|
||||
color: Colors.black,
|
||||
size: 26,
|
||||
),
|
||||
label: Text(
|
||||
fulldata ? t("Save") : t("Next"),
|
||||
style: GoogleFonts.inter(fontWeight: FontWeight.bold, fontSize: 18, color: Colors.black),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget getPage() {
|
||||
final double h = 27;
|
||||
cWidth = MediaQuery.of(context).size.width * 0.75;
|
||||
return SingleChildScrollView(
|
||||
scrollDirection: Axis.vertical,
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
SizedBox(
|
||||
height: h,
|
||||
),
|
||||
Wrap(alignment: WrapAlignment.center, children: [
|
||||
Text(
|
||||
t("What is your biological sex?"),
|
||||
textAlign: TextAlign.center,
|
||||
maxLines: 2,
|
||||
style: GoogleFonts.archivoBlack(
|
||||
color: Colors.white,
|
||||
fontSize: 30,
|
||||
fontWeight: FontWeight.w900,
|
||||
),
|
||||
)
|
||||
]),
|
||||
SizedBox(
|
||||
height: h,
|
||||
),
|
||||
getButton("Man", "", "m"),
|
||||
SizedBox(
|
||||
height: h,
|
||||
),
|
||||
getButton("Woman", "", "w"),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
TextButton getButton(String title, String desc, String state) {
|
||||
return TextButton(
|
||||
style: TextButton.styleFrom(
|
||||
padding: EdgeInsets.all(10.0),
|
||||
shape: getShape(changeBloc, state),
|
||||
),
|
||||
child: Container(
|
||||
width: cWidth,
|
||||
child: Column(
|
||||
children: [
|
||||
InkWell(
|
||||
child: ListTile(
|
||||
leading: Icon(
|
||||
state == "m" ? Icons.male_outlined : Icons.female,
|
||||
color: Color(0xffb4f500),
|
||||
size: 60,
|
||||
),
|
||||
title: Text(
|
||||
AppLocalizations.of(context)!.translate(title),
|
||||
style: TextStyle(color: Colors.white, fontSize: 32, fontFamily: 'Arial', fontWeight: FontWeight.w900),
|
||||
),
|
||||
)),
|
||||
],
|
||||
),
|
||||
),
|
||||
onPressed: () => {
|
||||
print("Sex $state"),
|
||||
changeBloc.add(CustomerGenderChange(gender: state == "m" ? 0 : 1)),
|
||||
});
|
||||
}
|
||||
|
||||
dynamic getShape(CustomerChangeBloc changeBloc, String sex) {
|
||||
String? selected = changeBloc.customerRepository.customer!.sex;
|
||||
dynamic returnCode = (selected == sex)
|
||||
? RoundedRectangleBorder(
|
||||
side: BorderSide(
|
||||
width: 4,
|
||||
color: Color(0xffb4f500),
|
||||
),
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
)
|
||||
: RoundedRectangleBorder(
|
||||
side: BorderSide(width: 4, color: Colors.white24),
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
);
|
||||
|
||||
return returnCode;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,147 @@
|
||||
import 'package:aitrainer_app/bloc/customer_change/customer_change_bloc.dart';
|
||||
import 'package:aitrainer_app/library/custom_icon_icons.dart';
|
||||
|
||||
import 'package:aitrainer_app/util/app_localization.dart';
|
||||
import 'package:aitrainer_app/repository/customer_repository.dart';
|
||||
import 'package:aitrainer_app/util/trans.dart';
|
||||
import 'package:aitrainer_app/widgets/app_bar_min.dart';
|
||||
import 'package:aitrainer_app/widgets/app_bar_progress.dart';
|
||||
import 'package:aitrainer_app/widgets/number_picker.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/rendering.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
import 'package:modal_progress_hud_nsn/modal_progress_hud_nsn.dart';
|
||||
|
||||
import '../bloc/customer_change/customer_change_bloc.dart';
|
||||
|
||||
// ignore: must_be_immutable
|
||||
class CustomerWeightPage extends StatefulWidget {
|
||||
late _CustomerWeightPageState _state;
|
||||
|
||||
_CustomerWeightPageState createState() {
|
||||
_state = _CustomerWeightPageState();
|
||||
return _state;
|
||||
}
|
||||
}
|
||||
|
||||
class _CustomerWeightPageState extends State<CustomerWeightPage> with Trans {
|
||||
String? selected;
|
||||
bool fulldata = false;
|
||||
late CustomerChangeBloc changeBloc;
|
||||
late double cWidth;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
setContext(context);
|
||||
|
||||
final CustomerRepository customerRepository = ModalRoute.of(context)!.settings.arguments as CustomerRepository;
|
||||
|
||||
PreferredSizeWidget _bar = AppBarMin(
|
||||
back: true,
|
||||
);
|
||||
if (!fulldata) {
|
||||
_bar = AppBarProgress(max: 60, min: 45);
|
||||
}
|
||||
|
||||
return Scaffold(
|
||||
appBar: _bar,
|
||||
body: Container(
|
||||
decoration: BoxDecoration(
|
||||
image: DecorationImage(
|
||||
image: AssetImage('asset/image/WT_plainblack_background.jpg'),
|
||||
fit: BoxFit.cover,
|
||||
alignment: Alignment.center,
|
||||
),
|
||||
),
|
||||
height: double.infinity,
|
||||
width: double.infinity,
|
||||
child: BlocProvider(
|
||||
create: (context) => CustomerChangeBloc(customerRepository: customerRepository),
|
||||
child: BlocConsumer<CustomerChangeBloc, CustomerChangeState>(
|
||||
listener: (context, state) {
|
||||
if (state is CustomerSaveError) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(backgroundColor: Colors.orange, content: Text(state.message, style: TextStyle(color: Colors.white))));
|
||||
} else if (state is CustomerSaveSuccess) {
|
||||
Navigator.of(context).pop();
|
||||
Navigator.of(context).pushNamed("customerHeightPage", arguments: changeBloc.customerRepository);
|
||||
}
|
||||
},
|
||||
builder: (context, state) {
|
||||
changeBloc = BlocProvider.of<CustomerChangeBloc>(context);
|
||||
return ModalProgressHUD(
|
||||
child: getPage(),
|
||||
inAsyncCall: state is CustomerChangeLoading,
|
||||
opacity: 0.5,
|
||||
color: Colors.black54,
|
||||
progressIndicator: CircularProgressIndicator(),
|
||||
);
|
||||
},
|
||||
),
|
||||
)),
|
||||
floatingActionButton: FloatingActionButton.extended(
|
||||
onPressed: () => {
|
||||
changeBloc.add(CustomerSaveWeight()),
|
||||
},
|
||||
backgroundColor: Color(0xffb4f500),
|
||||
icon: Icon(
|
||||
CustomIcon.save,
|
||||
color: Colors.black,
|
||||
size: 26,
|
||||
),
|
||||
label: Text(
|
||||
fulldata ? t("Save") : t("Next"),
|
||||
style: GoogleFonts.inter(fontWeight: FontWeight.bold, fontSize: 18, color: Colors.black),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget getPage() {
|
||||
final double h = 27;
|
||||
cWidth = MediaQuery.of(context).size.width * 0.75;
|
||||
return SingleChildScrollView(
|
||||
scrollDirection: Axis.vertical,
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
SizedBox(
|
||||
height: h,
|
||||
),
|
||||
Wrap(alignment: WrapAlignment.center, children: [
|
||||
Text(
|
||||
t("What is your weight?"),
|
||||
textAlign: TextAlign.center,
|
||||
maxLines: 2,
|
||||
style: GoogleFonts.archivoBlack(
|
||||
color: Colors.white,
|
||||
fontSize: 30,
|
||||
fontWeight: FontWeight.w900,
|
||||
),
|
||||
)
|
||||
]),
|
||||
SizedBox(
|
||||
height: h,
|
||||
),
|
||||
getButton(),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget getButton() {
|
||||
return NumberPickerWidget(
|
||||
minValue: 40,
|
||||
maxValue: 150,
|
||||
fontSize: 30,
|
||||
diameterRatio: 1.1,
|
||||
itemExtent: 40,
|
||||
fontWeight: FontWeight.w700,
|
||||
initalValue: changeBloc.weight.toInt(),
|
||||
unit: t("kg"),
|
||||
color: Color(0xffb4f500),
|
||||
onChange: (value) => changeBloc.add(CustomerWeightChange(weight: value)));
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,10 @@
|
||||
import 'package:aitrainer_app/util/app_localization.dart';
|
||||
import 'package:aitrainer_app/library/button_animations.dart';
|
||||
import 'package:aitrainer_app/util/trans.dart';
|
||||
import 'package:aitrainer_app/widgets/app_bar_min.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_fadein/flutter_fadein.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
import 'package:percent_indicator/circular_percent_indicator.dart';
|
||||
|
||||
// ignore: must_be_immutable
|
||||
class CustomerWelcomePage extends StatefulWidget {
|
||||
@@ -12,11 +16,14 @@ class CustomerWelcomePage extends StatefulWidget {
|
||||
}
|
||||
}
|
||||
|
||||
class _CustomerWelcomePageState extends State<CustomerWelcomePage> {
|
||||
class _CustomerWelcomePageState extends State<CustomerWelcomePage> with Trans {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
setContext(context);
|
||||
return Scaffold(
|
||||
appBar: AppBarMin(),
|
||||
appBar: AppBarMin(
|
||||
back: true,
|
||||
),
|
||||
body: Container(
|
||||
decoration: BoxDecoration(
|
||||
image: DecorationImage(
|
||||
@@ -30,17 +37,64 @@ class _CustomerWelcomePageState extends State<CustomerWelcomePage> {
|
||||
child: Center(
|
||||
child: Column(
|
||||
children: [
|
||||
Divider(
|
||||
color: Colors.transparent,
|
||||
SizedBox(
|
||||
height: 200,
|
||||
),
|
||||
ElevatedButton(
|
||||
style: ElevatedButton.styleFrom(
|
||||
primary: Colors.orange,
|
||||
onSurface: Colors.white,
|
||||
CircularPercentIndicator(
|
||||
radius: 250.0,
|
||||
animation: true,
|
||||
animationDuration: 4800,
|
||||
lineWidth: 20.0,
|
||||
percent: 0.98,
|
||||
curve: Curves.bounceInOut,
|
||||
backgroundWidth: 4,
|
||||
center: Text(
|
||||
t("Training Plan Generation"),
|
||||
textAlign: TextAlign.center,
|
||||
style: GoogleFonts.archivoBlack(
|
||||
fontWeight: FontWeight.bold,
|
||||
fontSize: 28.0,
|
||||
color: Colors.white,
|
||||
shadows: <Shadow>[
|
||||
Shadow(
|
||||
offset: Offset(5.0, 5.0),
|
||||
blurRadius: 12.0,
|
||||
color: Colors.black54,
|
||||
),
|
||||
Shadow(
|
||||
offset: Offset(-3.0, 3.0),
|
||||
blurRadius: 12.0,
|
||||
color: Colors.black54,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
child: InkWell(child: Text(AppLocalizations.of(context)!.translate("Next"))),
|
||||
onPressed: () => {Navigator.of(context).pop(), Navigator.of(context).pushNamed("home")},
|
||||
)
|
||||
circularStrokeCap: CircularStrokeCap.round,
|
||||
progressColor: Color(0xffb4f500),
|
||||
backgroundColor: Colors.black,
|
||||
),
|
||||
SizedBox(
|
||||
height: 90,
|
||||
),
|
||||
FadeIn(
|
||||
child: Container(
|
||||
width: 160,
|
||||
height: 80,
|
||||
child: GestureDetector(
|
||||
onTap: () => Navigator.of(context).popAndPushNamed("home"),
|
||||
child: Stack(
|
||||
alignment: Alignment.center,
|
||||
children: [
|
||||
Image.asset('asset/icon/gomb_orange_a.png', width: 140, height: 80),
|
||||
Text(
|
||||
t("Next"),
|
||||
style: GoogleFonts.archivoBlack(fontSize: 20, color: Colors.white),
|
||||
),
|
||||
],
|
||||
),
|
||||
)),
|
||||
duration: Duration(seconds: 6),
|
||||
),
|
||||
],
|
||||
),
|
||||
))),
|
||||
|
||||
@@ -502,7 +502,7 @@ class EvaluationPage extends StatelessWidget with Trans {
|
||||
Divider(color: Colors.transparent),
|
||||
getSuggestionWidget(resultBloc, "Gain Strength", "asset/image/pict_weight_volumen_tonna.png", "3x4-8", 0.95, "3-5"),
|
||||
Divider(color: Colors.transparent),
|
||||
getSuggestionWidget(resultBloc, "Endurance", "asset/image/pict_reps_volumen_db.png", "4x25-35", 0.50, "3"),
|
||||
getSuggestionWidget(resultBloc, "Muscle Endurance", "asset/image/pict_reps_volumen_db.png", "4x25-35", 0.50, "3"),
|
||||
],
|
||||
),
|
||||
);
|
||||
|
||||
+103
-22
@@ -2,6 +2,7 @@ import 'dart:io';
|
||||
|
||||
import 'package:aitrainer_app/bloc/account/account_bloc.dart';
|
||||
import 'package:aitrainer_app/bloc/login/login_bloc.dart';
|
||||
import 'package:aitrainer_app/repository/training_plan_repository.dart';
|
||||
import 'package:aitrainer_app/repository/user_repository.dart';
|
||||
import 'package:aitrainer_app/util/trans.dart';
|
||||
import 'package:aitrainer_app/widgets/app_bar_min.dart';
|
||||
@@ -33,17 +34,18 @@ class RegistrationPage extends StatelessWidget with Trans {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(backgroundColor: Colors.orange, content: Text(t(state.message), style: TextStyle(color: Colors.white))));
|
||||
} else if (state is LoginSuccess) {
|
||||
TrainingPlanRepository trainingPlanRepository = TrainingPlanRepository();
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (BuildContext context) {
|
||||
return DialogCommon(
|
||||
title: t("Successful Registration"),
|
||||
descriptions: t("Now we would like to know you better to lift the experience of the app."),
|
||||
description2: t("Please go through the pages, it will take couple of minutes!"),
|
||||
descriptions: t("Based on your initial data, we will generate the personalized training plan for you."),
|
||||
text: "OK",
|
||||
onTap: () => {Navigator.of(context).pushNamed('customerModifyPage')},
|
||||
onTap: () => {Navigator.of(context).pushNamed('customerWelcomePage')},
|
||||
onCancel: () => {
|
||||
Navigator.of(context).pushNamed("home"),
|
||||
trainingPlanRepository.generateTrainingPlan(),
|
||||
Navigator.of(context).pushNamed("customerWelcomePage"),
|
||||
},
|
||||
);
|
||||
});
|
||||
@@ -83,7 +85,7 @@ class RegistrationPage extends StatelessWidget with Trans {
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
image: DecorationImage(
|
||||
image: AssetImage('asset/image/WT_login.jpg'),
|
||||
image: AssetImage('asset/image/WT_menu_dark.jpg'),
|
||||
fit: BoxFit.cover,
|
||||
alignment: Alignment.center,
|
||||
),
|
||||
@@ -99,17 +101,32 @@ class RegistrationPage extends StatelessWidget with Trans {
|
||||
child: Container(
|
||||
padding: const EdgeInsets.only(left: 20, right: 20),
|
||||
child: ListView(shrinkWrap: false, padding: EdgeInsets.only(top: 10.0), children: <Widget>[
|
||||
GestureDetector(
|
||||
onTap: () => loginBloc.add(LoginSkip()),
|
||||
child: Text(
|
||||
t("I Execute My First Test Now"),
|
||||
textAlign: TextAlign.right,
|
||||
style: GoogleFonts.inter(color: loginBloc.testColor, decoration: TextDecoration.underline, fontWeight: FontWeight.bold),
|
||||
)),
|
||||
SizedBox(
|
||||
height: 120,
|
||||
height: 100,
|
||||
),
|
||||
ListTile(
|
||||
title: Text(
|
||||
t("SignUp"),
|
||||
style: GoogleFonts.inter(
|
||||
color: Colors.white,
|
||||
fontWeight: FontWeight.w500,
|
||||
shadows: <Shadow>[
|
||||
Shadow(
|
||||
offset: Offset(3.0, 3.0),
|
||||
blurRadius: 6.0,
|
||||
color: Colors.black54,
|
||||
),
|
||||
Shadow(
|
||||
offset: Offset(-3.0, 3.0),
|
||||
blurRadius: 6.0,
|
||||
color: Colors.black54,
|
||||
),
|
||||
],
|
||||
),
|
||||
)),
|
||||
SizedBox(
|
||||
height: 20,
|
||||
),
|
||||
ListTile(title: Text(t("SignUp"), style: GoogleFonts.inter())),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
@@ -140,7 +157,6 @@ class RegistrationPage extends StatelessWidget with Trans {
|
||||
: Offstage(),
|
||||
],
|
||||
),
|
||||
//ListTile(title: Text(t("OR"), style: GoogleFonts.inter())),
|
||||
Divider(
|
||||
color: Colors.transparent,
|
||||
),
|
||||
@@ -149,6 +165,10 @@ class RegistrationPage extends StatelessWidget with Trans {
|
||||
decoration: InputDecoration(
|
||||
contentPadding: EdgeInsets.only(left: 15, top: 15, bottom: 15),
|
||||
labelText: t('Email'),
|
||||
labelStyle: TextStyle(
|
||||
fontSize: 14,
|
||||
color: Color(0xffb4f500),
|
||||
),
|
||||
fillColor: Colors.white24,
|
||||
filled: true,
|
||||
border: OutlineInputBorder(
|
||||
@@ -165,7 +185,7 @@ class RegistrationPage extends StatelessWidget with Trans {
|
||||
},
|
||||
onChanged: (value) => loginBloc.add(LoginEmailChange(email: value)),
|
||||
keyboardType: TextInputType.emailAddress,
|
||||
style: new TextStyle(fontSize: 16, color: Colors.indigo),
|
||||
style: new TextStyle(fontSize: 16, color: Colors.white),
|
||||
),
|
||||
Divider(
|
||||
color: Colors.transparent,
|
||||
@@ -174,7 +194,10 @@ class RegistrationPage extends StatelessWidget with Trans {
|
||||
key: LibraryKeys.loginPasswordField,
|
||||
obscureText: loginBloc.obscure,
|
||||
decoration: InputDecoration(
|
||||
labelStyle: TextStyle(fontSize: 14),
|
||||
labelStyle: TextStyle(
|
||||
fontSize: 14,
|
||||
color: Color(0xffb4f500),
|
||||
),
|
||||
contentPadding: EdgeInsets.only(left: 15, top: 15, bottom: 15),
|
||||
suffixIcon: IconButton(
|
||||
onPressed: () => {loginBloc.add(LoginPasswordChangeObscure())},
|
||||
@@ -197,7 +220,7 @@ class RegistrationPage extends StatelessWidget with Trans {
|
||||
},
|
||||
onChanged: (value) => loginBloc.add(LoginPasswordChange(password: value)),
|
||||
keyboardType: TextInputType.visiblePassword,
|
||||
style: new TextStyle(fontSize: 16, color: Colors.indigo),
|
||||
style: new TextStyle(fontSize: 16, color: Colors.white),
|
||||
),
|
||||
Divider(
|
||||
color: Colors.transparent,
|
||||
@@ -214,7 +237,22 @@ class RegistrationPage extends StatelessWidget with Trans {
|
||||
),
|
||||
title: Text(
|
||||
t("With the registration I accept the data policy and the terms of use."),
|
||||
style: GoogleFonts.inter(color: Colors.indigo),
|
||||
style: GoogleFonts.inter(
|
||||
color: Colors.white,
|
||||
fontWeight: FontWeight.w500,
|
||||
shadows: <Shadow>[
|
||||
Shadow(
|
||||
offset: Offset(3.0, 3.0),
|
||||
blurRadius: 6.0,
|
||||
color: Colors.black54,
|
||||
),
|
||||
Shadow(
|
||||
offset: Offset(-3.0, 3.0),
|
||||
blurRadius: 6.0,
|
||||
color: Colors.black54,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
Row(mainAxisAlignment: MainAxisAlignment.start, children: <Widget>[
|
||||
@@ -242,7 +280,23 @@ class RegistrationPage extends StatelessWidget with Trans {
|
||||
InkWell(
|
||||
child: Text(
|
||||
t('Login'),
|
||||
style: GoogleFonts.inter(decoration: TextDecoration.underline),
|
||||
style: GoogleFonts.inter(
|
||||
decoration: TextDecoration.underline,
|
||||
color: Colors.white,
|
||||
fontWeight: FontWeight.w500,
|
||||
shadows: <Shadow>[
|
||||
Shadow(
|
||||
offset: Offset(3.0, 3.0),
|
||||
blurRadius: 6.0,
|
||||
color: Colors.black54,
|
||||
),
|
||||
Shadow(
|
||||
offset: Offset(-3.0, 3.0),
|
||||
blurRadius: 6.0,
|
||||
color: Colors.black54,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
onTap: () => Navigator.of(context).pushNamed('login'),
|
||||
),
|
||||
@@ -250,7 +304,23 @@ class RegistrationPage extends StatelessWidget with Trans {
|
||||
InkWell(
|
||||
child: Text(
|
||||
t('Terms Of Use'),
|
||||
style: GoogleFonts.inter(decoration: TextDecoration.underline),
|
||||
style: GoogleFonts.inter(
|
||||
decoration: TextDecoration.underline,
|
||||
color: Colors.white,
|
||||
fontWeight: FontWeight.w500,
|
||||
shadows: <Shadow>[
|
||||
Shadow(
|
||||
offset: Offset(3.0, 3.0),
|
||||
blurRadius: 6.0,
|
||||
color: Colors.black54,
|
||||
),
|
||||
Shadow(
|
||||
offset: Offset(-3.0, 3.0),
|
||||
blurRadius: 6.0,
|
||||
color: Colors.black54,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
onTap: () => {
|
||||
showDialog(
|
||||
@@ -263,7 +333,18 @@ class RegistrationPage extends StatelessWidget with Trans {
|
||||
InkWell(
|
||||
child: Text(
|
||||
t('Privacy'),
|
||||
style: GoogleFonts.inter(decoration: TextDecoration.underline),
|
||||
style: GoogleFonts.inter(
|
||||
decoration: TextDecoration.underline,
|
||||
color: Colors.white,
|
||||
fontWeight: FontWeight.w500,
|
||||
shadows: <Shadow>[
|
||||
Shadow(
|
||||
offset: Offset(2.0, 2.0),
|
||||
blurRadius: 10.0,
|
||||
color: Colors.black87,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
onTap: () => {
|
||||
showDialog(
|
||||
|
||||
+28
-3
@@ -1,3 +1,5 @@
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:aitrainer_app/bloc/menu/menu_bloc.dart';
|
||||
import 'package:aitrainer_app/bloc/settings/settings_bloc.dart';
|
||||
import 'package:aitrainer_app/bloc/tutorial/tutorial_bloc.dart';
|
||||
@@ -17,7 +19,8 @@ import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
import 'package:modal_progress_hud_nsn/modal_progress_hud_nsn.dart';
|
||||
import 'package:toggle_switch/toggle_switch.dart';
|
||||
import 'package:url_launcher/url_launcher.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'dart:async';
|
||||
|
||||
// ignore: must_be_immutable
|
||||
class SettingsPage extends StatelessWidget with Trans {
|
||||
@@ -81,7 +84,7 @@ class SettingsPage extends StatelessWidget with Trans {
|
||||
Track().track(TrackingEvent.settings_lang, eventValue: lang)
|
||||
})),
|
||||
getServer(settingsBloc),
|
||||
getTuturialBasic(settingsBloc),
|
||||
//getTuturialBasic(settingsBloc),
|
||||
getTermsOfUse(),
|
||||
getPrivacy(),
|
||||
getFaq(),
|
||||
@@ -96,7 +99,7 @@ class SettingsPage extends StatelessWidget with Trans {
|
||||
title: Container(),
|
||||
);
|
||||
}
|
||||
print("Live: ${Cache().liveServer}");
|
||||
|
||||
return ListTile(
|
||||
leading: Icon(Icons.data_usage_sharp),
|
||||
subtitle: Text("For Test purpuses select Test-Server. After that please restart the the App"),
|
||||
@@ -260,4 +263,26 @@ class SettingsPage extends StatelessWidget with Trans {
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> _printAndCopy(String cmd) async {
|
||||
print(cmd);
|
||||
|
||||
await Clipboard.setData(ClipboardData(text: cmd));
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
const SnackBar(content: Text('Copied to Clipboard')),
|
||||
);
|
||||
}
|
||||
|
||||
void link1() {
|
||||
String? cmd;
|
||||
String cmdSuffix;
|
||||
if (Platform.isIOS) {
|
||||
cmd = '/usr/bin/xcrun simctl openurl booted';
|
||||
} else if (Platform.isAndroid) {
|
||||
cmd = '\$ANDROID_HOME/platform-tools/adb shell \'am start'
|
||||
' -a android.intent.action.VIEW'
|
||||
' -c android.intent.category.BROWSABLE -d';
|
||||
cmdSuffix = "'";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -128,7 +128,10 @@ class TrainingPlanActivatePage extends StatelessWidget with Trans {
|
||||
child: Text(
|
||||
parentTitle,
|
||||
maxLines: 2,
|
||||
style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
|
||||
style: TextStyle(
|
||||
fontSize: 20,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
)),
|
||||
],
|
||||
),
|
||||
|
||||
@@ -0,0 +1,649 @@
|
||||
import 'dart:collection';
|
||||
|
||||
import 'package:aitrainer_app/bloc/training_plan/training_plan_bloc.dart';
|
||||
import 'package:aitrainer_app/library/custom_icon_icons.dart';
|
||||
import 'package:aitrainer_app/model/customer_training_plan_details.dart';
|
||||
import 'package:aitrainer_app/model/exercise_plan_detail.dart';
|
||||
import 'package:aitrainer_app/util/app_localization.dart';
|
||||
import 'package:aitrainer_app/util/trans.dart';
|
||||
import 'package:aitrainer_app/widgets/app_bar.dart';
|
||||
import 'package:aitrainer_app/widgets/dialog_common.dart';
|
||||
import 'package:aitrainer_app/widgets/dialog_html.dart';
|
||||
import 'package:aitrainer_app/widgets/menu_image.dart';
|
||||
import 'package:badges/badges.dart';
|
||||
import 'package:extended_tabs/extended_tabs.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
import 'package:modal_progress_hud_nsn/modal_progress_hud_nsn.dart';
|
||||
|
||||
class TrainingPlanExecute extends StatefulWidget {
|
||||
const TrainingPlanExecute({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
_TrainingPlanExecuteState createState() => _TrainingPlanExecuteState();
|
||||
}
|
||||
|
||||
class _TrainingPlanExecuteState extends State<TrainingPlanExecute> with Trans {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final TrainingPlanBloc bloc = BlocProvider.of<TrainingPlanBloc>(context);
|
||||
bloc.activateDays();
|
||||
|
||||
setContext(context);
|
||||
return Scaffold(
|
||||
appBar: AppBarNav(depth: 0),
|
||||
body: Container(
|
||||
padding: EdgeInsets.all(0),
|
||||
decoration: BoxDecoration(
|
||||
image: DecorationImage(
|
||||
image: AssetImage('asset/image/WT_black_background.jpg'),
|
||||
fit: BoxFit.cover,
|
||||
alignment: Alignment.center,
|
||||
),
|
||||
),
|
||||
child: BlocConsumer<TrainingPlanBloc, TrainingPlanState>(listener: (context, state) {
|
||||
if (state is TrainingPlanError) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(backgroundColor: Colors.orange, content: Text(state.message, style: TextStyle(color: Colors.white))));
|
||||
} else if (state is TrainingPlanDayFinished) {
|
||||
bloc.celebrating = false;
|
||||
final HashMap args = HashMap();
|
||||
args["bloc"] = bloc;
|
||||
args["day"] = bloc.dayNames[bloc.activeDayIndex];
|
||||
Navigator.of(context).pushNamed('myTrainingEvaluation', arguments: args);
|
||||
} else if (state is TrainingPlanDayReadyToRestart) {
|
||||
if (!bloc.celebrating) {
|
||||
showCupertinoDialog(
|
||||
useRootNavigator: true,
|
||||
context: context,
|
||||
builder: (_) => CupertinoAlertDialog(
|
||||
title: Text(t("The training is finished")),
|
||||
content: Column(children: [Divider(), Text(t("Do you want to restart, or select a new Training Plan?"))]),
|
||||
actions: [
|
||||
TextButton(
|
||||
child: Text(t("New Training Plan"), textAlign: TextAlign.center),
|
||||
onPressed: () => {
|
||||
Navigator.pop(context),
|
||||
Navigator.of(context).popAndPushNamed('myTrainingPlans'),
|
||||
bloc.restarting = false,
|
||||
}),
|
||||
TextButton(
|
||||
child: Text(t("Restart")),
|
||||
onPressed: () {
|
||||
bloc.restart();
|
||||
Navigator.pop(context);
|
||||
Navigator.of(context).popAndPushNamed('home');
|
||||
},
|
||||
)
|
||||
],
|
||||
));
|
||||
}
|
||||
}
|
||||
}, builder: (context, state) {
|
||||
return ModalProgressHUD(
|
||||
child: ExerciseTabs(bloc: bloc),
|
||||
inAsyncCall: state is TrainingPlanLoading,
|
||||
opacity: 0.5,
|
||||
color: Colors.black54,
|
||||
progressIndicator: CircularProgressIndicator(),
|
||||
);
|
||||
}),
|
||||
),
|
||||
floatingActionButton: FloatingActionButton.extended(
|
||||
onPressed: () {
|
||||
final HashMap args = HashMap();
|
||||
args["bloc"] = bloc;
|
||||
args["day"] = bloc.dayNames[bloc.activeDayIndex];
|
||||
bloc.getNext() != null
|
||||
? _ExerciseListState.executeExercise(bloc, bloc.getNext()!, context)
|
||||
: Navigator.of(context).pushNamed('myTrainingEvaluation', arguments: args);
|
||||
},
|
||||
backgroundColor: Colors.orange[600], //Color(0xffb4f500),
|
||||
icon: Icon(
|
||||
CustomIcon.weight_hanging,
|
||||
color: Colors.black,
|
||||
),
|
||||
label: Text(
|
||||
t("Next Exercise"),
|
||||
style: GoogleFonts.inter(color: Colors.black, fontWeight: FontWeight.bold, fontSize: 16),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class ExerciseTabs extends StatefulWidget {
|
||||
final TrainingPlanBloc bloc;
|
||||
ExerciseTabs({required this.bloc});
|
||||
@override
|
||||
_ExerciseTabs createState() => _ExerciseTabs();
|
||||
}
|
||||
|
||||
class _ExerciseTabs extends State<ExerciseTabs> with TickerProviderStateMixin {
|
||||
late TabController tabController;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
tabController = TabController(length: widget.bloc.dayNames.length, vsync: this);
|
||||
tabController.animateTo(widget.bloc.activeDayIndex, duration: Duration(milliseconds: 300));
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
tabController.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return getTabs(widget.bloc);
|
||||
}
|
||||
|
||||
Widget getTabs(TrainingPlanBloc bloc) {
|
||||
return Column(children: [
|
||||
Text(
|
||||
bloc.getMyPlan()!.name!,
|
||||
style: GoogleFonts.archivoBlack(
|
||||
fontSize: 14,
|
||||
color: Colors.white,
|
||||
shadows: <Shadow>[
|
||||
Shadow(
|
||||
offset: Offset(2.0, 2.0),
|
||||
blurRadius: 6.0,
|
||||
color: Colors.black87,
|
||||
),
|
||||
Shadow(
|
||||
offset: Offset(2.0, 2.0),
|
||||
blurRadius: 6.0,
|
||||
color: Colors.black87,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
ExtendedTabBar(
|
||||
indicator: BoxDecoration(
|
||||
color: Colors.black87,
|
||||
border: Border(
|
||||
bottom: BorderSide(width: 4.0, color: Color(0xffb4f500)),
|
||||
// top: BorderSide(width: 4.0, color: Colors.blue),
|
||||
)),
|
||||
labelPadding: EdgeInsets.only(left: 0, right: 0),
|
||||
tabs: getTabNames(),
|
||||
controller: tabController,
|
||||
onTap: (index) => bloc.activeDayIndex = index,
|
||||
),
|
||||
Expanded(
|
||||
child: ExtendedTabBarView(
|
||||
children: getExerciseLists(),
|
||||
controller: tabController,
|
||||
|
||||
/// if link is true and current tabbarview over scroll,
|
||||
/// it will check and scroll ancestor or child tabbarView.
|
||||
link: true,
|
||||
|
||||
/// cache page count
|
||||
/// default is 0.
|
||||
/// if cacheExtent is 1, it has two pages in cache
|
||||
/// null is infinity, it will cache all pages
|
||||
cacheExtent: 0,
|
||||
)),
|
||||
]);
|
||||
}
|
||||
|
||||
List<Tab> getTabNames() {
|
||||
List<Tab> tabs = [];
|
||||
final int tabCount = widget.bloc.dayNames.length;
|
||||
double cWidth = MediaQuery.of(context).size.width;
|
||||
widget.bloc.dayNames.forEach((element) {
|
||||
final Widget widget = Container(
|
||||
//height: 40,
|
||||
padding: EdgeInsets.only(top: 3, left: 10, right: 10, bottom: 3),
|
||||
width: (cWidth / tabCount),
|
||||
color: Colors.white10,
|
||||
child: RichText(
|
||||
textScaleFactor: 0.8,
|
||||
text: TextSpan(
|
||||
style: GoogleFonts.inter(
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Colors.white,
|
||||
),
|
||||
children: [
|
||||
TextSpan(
|
||||
text: AppLocalizations.of(context)!.translate("Training Day") + ": \n",
|
||||
style: GoogleFonts.inter(
|
||||
fontSize: 14,
|
||||
color: Colors.white,
|
||||
shadows: <Shadow>[
|
||||
Shadow(
|
||||
offset: Offset(5.0, 5.0),
|
||||
blurRadius: 12.0,
|
||||
color: Colors.black54,
|
||||
),
|
||||
Shadow(
|
||||
offset: Offset(-3.0, 3.0),
|
||||
blurRadius: 12.0,
|
||||
color: Colors.black54,
|
||||
),
|
||||
],
|
||||
)),
|
||||
TextSpan(
|
||||
text: element,
|
||||
style: GoogleFonts.inter(
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Color(0xffb4f500),
|
||||
shadows: <Shadow>[
|
||||
Shadow(
|
||||
offset: Offset(5.0, 5.0),
|
||||
blurRadius: 12.0,
|
||||
color: Colors.black54,
|
||||
),
|
||||
Shadow(
|
||||
offset: Offset(-3.0, 3.0),
|
||||
blurRadius: 12.0,
|
||||
color: Colors.black54,
|
||||
),
|
||||
],
|
||||
)),
|
||||
])));
|
||||
|
||||
tabs.add(Tab(child: widget));
|
||||
});
|
||||
return tabs;
|
||||
}
|
||||
|
||||
List<Widget> getExerciseLists() {
|
||||
List<Widget> list = [];
|
||||
widget.bloc.dayNames.forEach((element) {
|
||||
list.add(ExerciseList(bloc: widget.bloc, dayName: element));
|
||||
});
|
||||
return list;
|
||||
}
|
||||
}
|
||||
|
||||
class ExerciseList extends StatefulWidget {
|
||||
final TrainingPlanBloc bloc;
|
||||
final String dayName;
|
||||
ExerciseList({required this.bloc, required this.dayName});
|
||||
|
||||
@override
|
||||
_ExerciseListState createState() => _ExerciseListState();
|
||||
}
|
||||
|
||||
class _ExerciseListState extends State<ExerciseList> with Trans {
|
||||
final scrollController = ScrollController();
|
||||
double offset = 5;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
WidgetsBinding.instance!.addPostFrameCallback((_) {
|
||||
animate();
|
||||
});
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
void didUpdateWidget(ExerciseList page) {
|
||||
super.didUpdateWidget(page);
|
||||
WidgetsBinding.instance!.addPostFrameCallback((_) {
|
||||
animate();
|
||||
});
|
||||
}
|
||||
|
||||
void animate() {
|
||||
offset = widget.bloc.getOffset();
|
||||
if (scrollController.hasClients) {
|
||||
scrollController.animateTo(offset, duration: Duration(milliseconds: 300), curve: Curves.easeIn);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
scrollController.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
static void executeExercise(TrainingPlanBloc bloc, CustomerTrainingPlanDetails detail, BuildContext context) {
|
||||
CustomerTrainingPlanDetails? next = bloc.getNext();
|
||||
|
||||
if (next != null) {
|
||||
String title = "";
|
||||
String description = "";
|
||||
String description2 = "";
|
||||
if (next.exerciseTypeId != detail.exerciseTypeId) {
|
||||
title = AppLocalizations.of(context)!.translate("Stop!");
|
||||
description = AppLocalizations.of(context)!.translate("Please continue with the next exercise in the queue:") +
|
||||
next.exerciseType!.nameTranslation;
|
||||
} else {
|
||||
final HashMap args = HashMap();
|
||||
args['exerciseType'] = next.exerciseType;
|
||||
args['customerTrainingPlanDetails'] = detail;
|
||||
Navigator.of(context).pushNamed('myTrainingPlanExercise', arguments: args);
|
||||
return;
|
||||
}
|
||||
|
||||
showDialog(
|
||||
context: context,
|
||||
barrierDismissible: false,
|
||||
builder: (BuildContext context) {
|
||||
return DialogCommon(
|
||||
title: title,
|
||||
descriptions: description,
|
||||
description2: description2,
|
||||
text: "OK",
|
||||
onTap: () => {Navigator.of(context).pop()},
|
||||
onCancel: () => {Navigator.of(context).pop()},
|
||||
);
|
||||
});
|
||||
} else {
|
||||
Navigator.of(context).pushNamed('home');
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
setContext(context);
|
||||
return CustomScrollView(controller: scrollController, slivers: [
|
||||
SliverList(delegate: SliverChildListDelegate(getTiles(widget.bloc))),
|
||||
]);
|
||||
}
|
||||
|
||||
List<Widget> getTiles(TrainingPlanBloc bloc) {
|
||||
List<Widget> tiles = [];
|
||||
|
||||
tiles.addAll(getExerciseTiles(bloc, context));
|
||||
|
||||
return tiles;
|
||||
}
|
||||
|
||||
List<Widget> getExerciseTiles(TrainingPlanBloc bloc, BuildContext context) {
|
||||
List<Widget> tiles = [];
|
||||
CustomerTrainingPlanDetails? prev;
|
||||
if (bloc.getMyPlan() != null &&
|
||||
bloc.getMyPlan()!.details.isNotEmpty &&
|
||||
bloc.getMyPlan()!.days[widget.dayName] != null &&
|
||||
bloc.getMyPlan()!.days[widget.dayName]!.isNotEmpty) {
|
||||
bloc.getMyPlan()!.days[widget.dayName]!.forEach((element) {
|
||||
if (prev != null && prev!.exerciseTypeId != element.exerciseTypeId) {
|
||||
tiles.add(GestureDetector(
|
||||
onTap: () =>
|
||||
bloc.getNext() != null ? executeExercise(bloc, bloc.getNext()!, context) : Navigator.of(context).pushNamed('home'),
|
||||
child: ExerciseTile(bloc: bloc, detail: element)));
|
||||
}
|
||||
prev = element;
|
||||
});
|
||||
}
|
||||
|
||||
return tiles;
|
||||
}
|
||||
}
|
||||
|
||||
// ignore: must_be_immutable
|
||||
class ExerciseTile extends StatelessWidget with Trans {
|
||||
final TrainingPlanBloc bloc;
|
||||
final CustomerTrainingPlanDetails detail;
|
||||
|
||||
ExerciseTile({required this.bloc, required this.detail});
|
||||
|
||||
Widget getExerciseQuantities(CustomerTrainingPlanDetails detail, int step, bool noFilter) {
|
||||
bool skipped = detail.state == ExercisePlanDetailState.skipped;
|
||||
String quantities = "";
|
||||
String set = "";
|
||||
List<TextSpan> spans = [];
|
||||
if (detail.exerciseType!.name == "Warming Up") {
|
||||
quantities = t("Min. 10 minutes");
|
||||
spans.add(
|
||||
TextSpan(text: quantities),
|
||||
);
|
||||
} else if (detail.exerciseType!.name == "Stretching") {
|
||||
quantities = t("Recommended");
|
||||
spans.add(
|
||||
TextSpan(text: quantities),
|
||||
);
|
||||
} else {
|
||||
set = detail.set! > 1 ? "${detail.set} " + t("set") : "";
|
||||
List<CustomerTrainingPlanDetails> details = bloc.getAllDetailsSameExercise(detail);
|
||||
int index = 0;
|
||||
bool isWeight = true;
|
||||
|
||||
if (set.length > 0) {
|
||||
spans.add(
|
||||
TextSpan(
|
||||
text: step.toString() + " ",
|
||||
style: GoogleFonts.archivoBlack(
|
||||
color: Colors.orange[600],
|
||||
)),
|
||||
);
|
||||
spans.add(
|
||||
TextSpan(text: "/ " + set),
|
||||
);
|
||||
}
|
||||
|
||||
details.forEach((element) {
|
||||
quantities = "";
|
||||
String delimiter = ",";
|
||||
if (index == 0) {
|
||||
delimiter = "";
|
||||
}
|
||||
if (element.repeats == -1) {
|
||||
quantities += delimiter + " MAX ";
|
||||
} else {
|
||||
quantities += delimiter + " ${element.repeats}";
|
||||
}
|
||||
if (element.exerciseType!.unitQuantityUnit != null) {
|
||||
quantities += "x";
|
||||
if (element.weight == -1 || element.weight == -2 || element.weight == -3) {
|
||||
quantities += "? kg";
|
||||
} else {
|
||||
num weight = element.weight! % element.weight!.round() == 0 ? element.weight!.round() : element.weight!;
|
||||
quantities += "$weight kg";
|
||||
}
|
||||
} else {
|
||||
isWeight = false;
|
||||
}
|
||||
if (step == index && noFilter) {
|
||||
spans.add(
|
||||
TextSpan(
|
||||
text: quantities,
|
||||
style: GoogleFonts.archivoBlack(
|
||||
color: Colors.orange[600],
|
||||
),
|
||||
),
|
||||
);
|
||||
} else {
|
||||
spans.add(
|
||||
TextSpan(text: quantities),
|
||||
);
|
||||
}
|
||||
index++;
|
||||
});
|
||||
if (isWeight) {
|
||||
quantities += " kg";
|
||||
}
|
||||
}
|
||||
|
||||
return RichText(
|
||||
text: TextSpan(
|
||||
style: GoogleFonts.archivoBlack(
|
||||
fontSize: 20,
|
||||
color: skipped ? Colors.grey : Colors.white,
|
||||
shadows: <Shadow>[
|
||||
Shadow(
|
||||
offset: Offset(2.0, 2.0),
|
||||
blurRadius: 6.0,
|
||||
color: Colors.black87,
|
||||
),
|
||||
Shadow(
|
||||
offset: Offset(2.0, 2.0),
|
||||
blurRadius: 6.0,
|
||||
color: Colors.black87,
|
||||
),
|
||||
],
|
||||
),
|
||||
children: spans),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
setContext(context);
|
||||
|
||||
final CustomerTrainingPlanDetails? next = bloc.getNext();
|
||||
final bool noFilter = next != null && next.exerciseTypeId == detail.exerciseTypeId;
|
||||
final bool done = detail.state == ExercisePlanDetailState.finished;
|
||||
final int step = bloc.getStep(detail); //detail.exercises.length;
|
||||
final bool buddyWarning = detail.exerciseType == null ? false : detail.exerciseType!.buddyWarning;
|
||||
|
||||
return Container(
|
||||
child: Stack(alignment: Alignment.bottomLeft, children: [
|
||||
Badge(
|
||||
elevation: 0,
|
||||
padding: EdgeInsets.all(0),
|
||||
position: BadgePosition.topEnd(top: 5, end: 5),
|
||||
animationDuration: Duration(milliseconds: 1500),
|
||||
animationType: BadgeAnimationType.fade,
|
||||
badgeColor: Colors.transparent,
|
||||
showBadge: noFilter || done,
|
||||
badgeContent: IconButton(
|
||||
iconSize: 40,
|
||||
onPressed: () => !done ? skip() : {},
|
||||
icon: Icon(
|
||||
done ? CustomIcon.ok_circled : Icons.cancel,
|
||||
color: done ? Colors.green[600] : Colors.red[600],
|
||||
)),
|
||||
child: Badge(
|
||||
elevation: 0,
|
||||
padding: EdgeInsets.all(0),
|
||||
position: BadgePosition.topStart(top: 5, start: 5),
|
||||
animationDuration: Duration(milliseconds: 500),
|
||||
animationType: BadgeAnimationType.slide,
|
||||
badgeColor: Colors.transparent,
|
||||
showBadge: true,
|
||||
badgeContent: IconButton(
|
||||
iconSize: 36,
|
||||
onPressed: () => showDialog(
|
||||
context: context,
|
||||
builder: (BuildContext context) {
|
||||
return DialogHTML(
|
||||
title: detail.exerciseType!.nameTranslation,
|
||||
htmlData: '<p>' + detail.exerciseType!.descriptionTranslation + '</p>');
|
||||
}),
|
||||
icon: Icon(
|
||||
Icons.info_outline,
|
||||
color: Colors.yellow[200],
|
||||
)),
|
||||
child: Badge(
|
||||
elevation: 0,
|
||||
padding: EdgeInsets.all(0),
|
||||
position: BadgePosition.topEnd(top: 65, end: 1),
|
||||
animationDuration: Duration(milliseconds: 500),
|
||||
animationType: BadgeAnimationType.fade,
|
||||
badgeColor: Colors.transparent,
|
||||
showBadge: buddyWarning,
|
||||
badgeContent: IconButton(
|
||||
iconSize: 50,
|
||||
onPressed: () => showDialog(
|
||||
context: context,
|
||||
builder: (BuildContext context) {
|
||||
return DialogCommon(
|
||||
warning: true,
|
||||
text: "Warning",
|
||||
descriptions: t("Attention!"),
|
||||
description2: t("The safe and exact execution of this exercise you need a training buddy or a trainer"),
|
||||
description3: t("Execution at your own risk!"),
|
||||
onTap: () => Navigator.of(context).pop(),
|
||||
onCancel: () => Navigator.of(context).pop(),
|
||||
title: t('Training Buddy'),
|
||||
);
|
||||
}),
|
||||
icon: Icon(
|
||||
CustomIcon.exclamation_circle,
|
||||
color: Colors.red[800],
|
||||
)),
|
||||
child: Column(children: [
|
||||
MenuImage(
|
||||
imageName: bloc.getActualImageName(detail.exerciseType!.exerciseTypeId),
|
||||
workoutTreeId: bloc.getActualWorkoutTreeId(detail.exerciseType!.exerciseTypeId)!,
|
||||
radius: 0,
|
||||
filter: !noFilter,
|
||||
),
|
||||
Container(
|
||||
padding: EdgeInsets.only(left: 20, top: 10, bottom: 0),
|
||||
decoration: BoxDecoration(
|
||||
image: DecorationImage(
|
||||
image: AssetImage('asset/image/WT_zold.jpg'),
|
||||
fit: BoxFit.cover,
|
||||
alignment: Alignment.center,
|
||||
),
|
||||
),
|
||||
foregroundDecoration: !noFilter
|
||||
? BoxDecoration(
|
||||
color: Colors.black38,
|
||||
backgroundBlendMode: BlendMode.darken,
|
||||
)
|
||||
: null,
|
||||
height: 80,
|
||||
width: double.infinity,
|
||||
child: getExerciseQuantities(detail, step, noFilter),
|
||||
)
|
||||
])))),
|
||||
Container(
|
||||
padding: EdgeInsets.only(left: 15, bottom: 80, right: 15),
|
||||
width: double.infinity,
|
||||
color: Colors.transparent,
|
||||
child: Text(
|
||||
detail.exerciseType!.nameTranslation,
|
||||
maxLines: 3,
|
||||
style: GoogleFonts.archivoBlack(
|
||||
color: noFilter ? Colors.white : Colors.grey,
|
||||
fontSize: 36,
|
||||
height: 1.1,
|
||||
shadows: <Shadow>[
|
||||
Shadow(
|
||||
offset: Offset(16.0, 16.0),
|
||||
blurRadius: 16.0,
|
||||
color: Colors.black54,
|
||||
),
|
||||
Shadow(
|
||||
offset: Offset(16.0, 16.0),
|
||||
blurRadius: 16.0,
|
||||
color: Colors.black54,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
]),
|
||||
);
|
||||
}
|
||||
|
||||
void skip() {
|
||||
showCupertinoDialog(
|
||||
useRootNavigator: true,
|
||||
context: context,
|
||||
builder: (_) => CupertinoAlertDialog(
|
||||
title: Text(t("You want to skip really this exercise?")),
|
||||
content: Column(children: [
|
||||
Divider(),
|
||||
]),
|
||||
actions: [
|
||||
TextButton(
|
||||
child: Text(t("No")),
|
||||
onPressed: () => {
|
||||
Navigator.pop(context),
|
||||
}),
|
||||
TextButton(
|
||||
child: Text(t("Yes")),
|
||||
onPressed: () {
|
||||
Navigator.pop(context);
|
||||
bloc.add(TrainingPlanSkipExercise(detail: detail));
|
||||
},
|
||||
)
|
||||
],
|
||||
));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user