Commit 14a9eeb3 authored by Administrator's avatar Administrator

Ubuntu font, color schema, theme data, power zone and power zone schema management

parent 35f68ef6
......@@ -16,8 +16,8 @@ class PowerZone extends ChangeNotifier {
db = DbPowerZone()
..powerZoneSchemataId = powerZoneSchema.db.id
..name = name ?? "my Zone"
..lowerLimit = lowerLimit ?? 0
..upperLimit = upperLimit ?? 0
..lowerLimit = lowerLimit ?? 70
..upperLimit = upperLimit ?? 100
..lowerPercentage = lowerPercentage ?? 0
..upperPercentage = upperPercentage ?? 0
..color = color ?? 0xFFFFc107;
......
......@@ -5,8 +5,11 @@ import 'package:encrateia/models/athlete.dart';
class Weight extends ChangeNotifier {
DbWeight db;
Weight() {
db = DbWeight();
Weight({@required Athlete athlete}) {
db = DbWeight()
..athletesId = athlete.db.id
..value = 70
..date = DateTime.now();
}
Weight.fromDb(this.db);
......
import 'package:encrateia/utils/icon_utils.dart';
import 'package:encrateia/utils/my_button.dart';
import 'package:flutter/material.dart';
import 'package:encrateia/models/power_zone_schema.dart';
import 'package:encrateia/models/power_zone.dart';
......@@ -38,7 +39,7 @@ class _AddPowerZoneSchemaScreenState extends State<AddPowerZoneSchemaScreen> {
title: Text('Add Power Zone Schema'),
),
body: ListView(
padding: EdgeInsets.all(20),
padding: EdgeInsets.only(left: 20, right: 20),
children: <Widget>[
DateTimeField(
decoration: InputDecoration(
......@@ -70,27 +71,17 @@ class _AddPowerZoneSchemaScreenState extends State<AddPowerZoneSchemaScreen> {
keyboardType: TextInputType.number,
onChanged: (value) => db.base = int.parse(value),
),
Divider(),
Text(
"Zones",
style: Theme.of(context).textTheme.title,
),
SizedBox(height: 10),
DataTable(
headingRowHeight: kMinInteractiveDimension * 0.80,
dataRowHeight: kMinInteractiveDimension * 0.75,
columnSpacing: 1,
horizontalMargin: 12,
columnSpacing: 20,
horizontalMargin: 10,
columns: <DataColumn>[
DataColumn(label: Text("Name")),
DataColumn(
label: Text("Limits (W)"),
numeric: true,
),
DataColumn(
label: Text("Color"),
numeric: true,
),
DataColumn(label: Text("")),
DataColumn(label: Text("")),
DataColumn(label: Text("Zone")),
DataColumn(label: Text("Limits (W)")),
DataColumn(label: Text("Color")),
DataColumn(label: Text("Edit")),
],
rows: powerZones.map((PowerZone powerZone) {
return DataRow(
......@@ -105,75 +96,61 @@ class _AddPowerZoneSchemaScreenState extends State<AddPowerZoneSchemaScreen> {
elevation: 0,
color: Color(powerZone.db.color),
)),
DataCell(
MyIcon.delete,
onTap: () => deletePowerZone(powerZone: powerZone),
),
DataCell(
MyIcon.edit,
onTap: () => Navigator.push(
context,
MaterialPageRoute(
builder: (context) => AddPowerZoneScreen(
powerZone: powerZone,
onTap: () async {
await Navigator.push(
context,
MaterialPageRoute(
builder: (context) => AddPowerZoneScreen(
powerZone: powerZone,
base: db.base,
),
),
),
).then((_) => getData()()),
);
getData();
},
)
],
);
}).toList(),
),
SizedBox(height: 10),
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
Spacer(),
RaisedButton(
color: Colors.green,
MyButton.add(
child: Text("Add power zone"),
onPressed: () => Navigator.push(
context,
MaterialPageRoute(
builder: (context) => AddPowerZoneScreen(
powerZone:
PowerZone(powerZoneSchema: widget.powerZoneSchema),
onPressed: () async {
await Navigator.push(
context,
MaterialPageRoute(
builder: (context) => AddPowerZoneScreen(
powerZone:
PowerZone(powerZoneSchema: widget.powerZoneSchema),
base: widget.powerZoneSchema.db.base,
),
),
),
).then((_) => getData()()),
);
getData();
},
),
Spacer(flex: 10),
],
),
Divider(),
Padding(
padding: EdgeInsets.all(15),
child: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
Spacer(flex: 10),
RaisedButton(
color: Theme.of(context).primaryColorDark,
textColor: Theme.of(context).primaryColorLight,
child: Text('Delete', textScaleFactor: 1.5),
onPressed: () => deletePowerZoneSchema(
powerZoneSchema: widget.powerZoneSchema, ),
),
Spacer(),
RaisedButton(
color: Theme.of(context).primaryColorDark,
textColor: Theme.of(context).primaryColorLight,
child: Text('Cancel', textScaleFactor: 1.5),
onPressed: () => Navigator.of(context).pop(),
),
Spacer(),
RaisedButton(
color: Theme.of(context).primaryColorDark,
textColor: Theme.of(context).primaryColorLight,
child: Text('Save', textScaleFactor: 1.5),
onPressed: () => savePowerZoneSchema(context),
SizedBox(height: 10),
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
MyButton.delete(
onPressed: () => deletePowerZoneSchema(
powerZoneSchema: widget.powerZoneSchema,
),
Spacer(),
],
),
),
SizedBox(width: 5),
MyButton.cancel(onPressed: () => Navigator.of(context).pop()),
SizedBox(width: 5),
MyButton.save(onPressed: () => savePowerZoneSchema(context)),
],
),
],
),
......@@ -190,11 +167,6 @@ class _AddPowerZoneSchemaScreenState extends State<AddPowerZoneSchemaScreen> {
setState(() {});
}
deletePowerZone({PowerZone powerZone}) async {
await powerZone.db.delete();
await getData();
}
deletePowerZoneSchema({PowerZoneSchema powerZoneSchema}) async {
await powerZoneSchema.delete();
Navigator.of(context).pop();
......
import 'package:encrateia/models/athlete.dart';
import 'package:encrateia/utils/my_button.dart';
import 'package:flutter/material.dart';
import 'package:encrateia/models/power_zone.dart';
import 'package:flutter_material_color_picker/flutter_material_color_picker.dart';
class AddPowerZoneScreen extends StatelessWidget {
final Athlete athlete;
class AddPowerZoneScreen extends StatefulWidget {
final PowerZone powerZone;
final int base;
const AddPowerZoneScreen({
Key key,
this.athlete,
this.powerZone,
this.base,
}) : super(key: key);
@override
_AddPowerZoneScreenState createState() => _AddPowerZoneScreenState();
}
class _AddPowerZoneScreenState extends State<AddPowerZoneScreen> {
ColorSwatch _tempMainColor;
void _openDialog(Widget content) {
showDialog(
context: context,
builder: (_) {
return AlertDialog(
contentPadding: const EdgeInsets.all(6.0),
title: Text("Select Color"),
content: content,
actions: [
MyButton.cancel(onPressed: Navigator.of(context).pop),
MyButton.save(
child: Text('Select'),
onPressed: () {
Navigator.of(context).pop();
MaterialColorPicker(
onColorChange: (color) =>
widget.powerZone.db.color = color.value,
selectedColor: Color(widget.powerZone.db.color));
},
),
],
);
},
);
}
void openColorPicker() async {
_openDialog(
MaterialColorPicker(
selectedColor: Color(widget.powerZone.db.color),
onColorChange: (color) => widget.powerZone.db.color = color.value,
onMainColorChange: (color) => setState(() => _tempMainColor = color),
onBack: () => print("Back button pressed"),
),
);
}
@override
Widget build(BuildContext context) {
powerZone.db
..powerZoneSchemataId = powerZone.db.id
..lowerLimit = 70
..upperLimit = 100
..color = 0xFFFFc107;
var lowerLimitController =
TextEditingController(text: widget.powerZone.db.lowerLimit.toString());
var upperLimitController =
TextEditingController(text: widget.powerZone.db.upperLimit.toString());
var lowerPercentageController = TextEditingController(
text: widget.powerZone.db.lowerPercentage.toString());
var upperPercentageController = TextEditingController(
text: widget.powerZone.db.upperPercentage.toString());
return Scaffold(
appBar: AppBar(
......@@ -29,53 +77,81 @@ class AddPowerZoneScreen extends StatelessWidget {
children: <Widget>[
TextFormField(
decoration: InputDecoration(labelText: "Name"),
initialValue: powerZone.db.name,
onChanged: (value) => powerZone.db.name = value,
initialValue: widget.powerZone.db.name,
onChanged: (value) => widget.powerZone.db.name = value,
),
TextFormField(
decoration: InputDecoration(labelText: "Lower Limit in W"),
initialValue: powerZone.db.lowerLimit.toString(),
controller: lowerLimitController,
keyboardType: TextInputType.number,
onChanged: (value) => powerZone.db.lowerLimit = int.parse(value),
onChanged: (value) {
widget.powerZone.db.lowerLimit = int.parse(value);
widget.powerZone.db.lowerPercentage =
(int.parse(value) * 100 / widget.base).round();
lowerPercentageController.text =
(int.parse(value) * 100 / widget.base).round().toString();
},
),
TextFormField(
decoration: InputDecoration(labelText: "Upper Limit in W"),
initialValue: powerZone.db.upperLimit.toString(),
controller: upperLimitController,
keyboardType: TextInputType.number,
onChanged: (value) => powerZone.db.upperLimit = int.parse(value),
onChanged: (value) {
widget.powerZone.db.upperLimit = int.parse(value);
widget.powerZone.db.upperPercentage =
(int.parse(value) * 100 / widget.base).round();
upperPercentageController.text =
(int.parse(value) * 100 / widget.base).round().toString();
},
),
TextFormField(
decoration: InputDecoration(labelText: "Lower Percentage in %"),
initialValue: powerZone.db.lowerPercentage.toString(),
controller: lowerPercentageController,
keyboardType: TextInputType.number,
onChanged: (value) => powerZone.db.lowerPercentage = int.parse(value),
onChanged: (value) {
widget.powerZone.db.lowerPercentage = int.parse(value);
widget.powerZone.db.lowerLimit =
(int.parse(value) * widget.base / 100).round();
lowerLimitController.text =
(int.parse(value) * widget.base / 100).round().toString();
},
),
TextFormField(
decoration: InputDecoration(labelText: "Upper Percentage in %"),
initialValue: powerZone.db.upperPercentage.toString(),
controller: upperPercentageController,
keyboardType: TextInputType.number,
onChanged: (value) => powerZone.db.upperPercentage = int.parse(value),
onChanged: (value) {
widget.powerZone.db.upperPercentage = int.parse(value);
widget.powerZone.db.upperLimit =
(int.parse(value) * widget.base / 100).round();
upperLimitController.text =
(int.parse(value) * widget.base / 100).round().toString();
},
),
Padding(
padding: EdgeInsets.all(15),
child: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
RaisedButton(
color: Theme.of(context).primaryColorDark,
textColor: Theme.of(context).primaryColorLight,
child: Text('Cancel', textScaleFactor: 1.5),
onPressed: () => Navigator.of(context).pop(),
),
Container(width: 20.0),
RaisedButton(
color: Theme.of(context).primaryColorDark,
textColor: Theme.of(context).primaryColorLight,
child: Text('Save', textScaleFactor: 1.5),
onPressed: () => savePowerZone(context),
),
],
SizedBox(height: 10),
Row(children: [
Text("Color"),
Spacer(),
CircleAvatar(
backgroundColor: Color(widget.powerZone.db.color),
radius: 20.0,
),
Spacer(),
MyButton.detail(
onPressed: openColorPicker,
child: Text('Edit'),
),
]),
SizedBox(height: 20),
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
MyButton.delete(onPressed: () => deletePowerZone(context)),
SizedBox(width: 5),
MyButton.cancel(onPressed: () => Navigator.of(context).pop()),
SizedBox(width: 5),
MyButton.save(onPressed: () => savePowerZone(context)),
],
),
],
),
......@@ -83,7 +159,12 @@ class AddPowerZoneScreen extends StatelessWidget {
}
savePowerZone(BuildContext context) async {
await powerZone.db.save();
await widget.powerZone.db.save();
Navigator.of(context).pop();
}
deletePowerZone(BuildContext context) async {
await widget.powerZone.db.delete();
Navigator.of(context).pop();
}
}
import 'package:encrateia/models/athlete.dart';
import 'package:encrateia/utils/my_button.dart';
import 'package:flutter/material.dart';
import 'package:encrateia/models/weight.dart';
import 'package:intl/intl.dart';
import 'package:datetime_picker_formfield/datetime_picker_formfield.dart';
class AddWeightScreen extends StatelessWidget {
final Athlete athlete;
final Weight weight;
const AddWeightScreen({
Key key,
this.athlete,
this.weight,
}) : super(key: key);
@override
Widget build(BuildContext context) {
weight.db
..athletesId = athlete.db.id
..value = 70
..date = DateTime.now();
return Scaffold(
appBar: AppBar(
title: Text('Add your Weight'),
......@@ -31,7 +24,7 @@ class AddWeightScreen extends StatelessWidget {
DateTimeField(
decoration: InputDecoration(labelText: "Date"),
format: DateFormat("yyyy-MM-dd"),
initialValue: DateTime.now(),
initialValue: weight.db.date,
onShowPicker: (context, currentValue) {
return showDatePicker(
context: context,
......@@ -48,26 +41,18 @@ class AddWeightScreen extends StatelessWidget {
keyboardType: TextInputType.number,
onChanged: (value) => weight.db.value = double.parse(value),
),
Padding(
padding: EdgeInsets.all(15),
child: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
RaisedButton(
color: Theme.of(context).primaryColorDark,
textColor: Theme.of(context).primaryColorLight,
child: Text('Cancel', textScaleFactor: 1.5),
onPressed: () => Navigator.of(context).pop(),
),
Container(width: 20.0),
RaisedButton(
color: Theme.of(context).primaryColorDark,
textColor: Theme.of(context).primaryColorLight,
child: Text('Save', textScaleFactor: 1.5),
onPressed: () => saveWeight(context),
),
],
),
SizedBox(height: 20),
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
MyButton.delete(
onPressed: () => deleteWeight(context),
),
SizedBox(width: 5),
MyButton.cancel(onPressed: () => Navigator.of(context).pop()),
SizedBox(width: 5),
MyButton.save(onPressed: () => saveWeight(context)),
],
),
],
),
......@@ -78,4 +63,9 @@ class AddWeightScreen extends StatelessWidget {
await weight.db.save();
Navigator.of(context).pop();
}
deleteWeight(BuildContext context) async {
await weight.delete();
Navigator.of(context).pop();
}
}
import 'package:encrateia/utils/my_color.dart';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'edit_athlete_screen.dart';
......@@ -39,22 +40,24 @@ class _DashboardState extends State<Dashboard> {
goToListActivitiesScreen({Athlete athlete}) async {
await athlete.readCredentials();
Navigator.push(
await Navigator.push(
context,
MaterialPageRoute(
builder: (context) => ShowAthleteScreen(athlete: athlete),
),
).then((_) => getAthletes());
);
getAthletes();
}
goToEditAthleteScreen({Athlete athlete}) async {
await athlete.readCredentials();
Navigator.push(
await Navigator.push(
context,
MaterialPageRoute(
builder: (context) => EditAthleteScreen(athlete: athlete),
),
).then((_) => getAthletes());
);
getAthletes();
}
dashboardBody() {
......@@ -97,7 +100,7 @@ class _DashboardState extends State<Dashboard> {
);
} else {
return ListView(
padding: EdgeInsets.all(40),
padding: EdgeInsets.all(20),
children: <Widget>[
for (Athlete athlete in athletes)
ListTile(
......@@ -107,13 +110,17 @@ class _DashboardState extends State<Dashboard> {
subtitle: Row(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
RaisedButton(
RaisedButton.icon(
icon: MyIcon.analyze,
color: MyColor.detail,
onPressed: () => goToListActivitiesScreen(athlete: athlete),
child: Text("Analyze"),
label: Text("Analyze"),
),
RaisedButton(
RaisedButton.icon(
icon: MyIcon.edit,
color: MyColor.settings,
onPressed: () => goToEditAthleteScreen(athlete: athlete),
child: MyIcon.edit,
label: Text("Edit"),
),
],
),
......@@ -166,6 +173,7 @@ class _DashboardState extends State<Dashboard> {
floatingActionButton() {
if (athletes.length != 0) {
return FloatingActionButton.extended(
backgroundColor: MyColor.add,
label: const Text('Add Athlete'),
onPressed: () => goToEditAthleteScreen(athlete: Athlete()),
);
......
import 'package:encrateia/utils/my_color.dart';
import 'package:encrateia/widgets/athlete_widgets/athlete_power_ratio_widget.dart';
import 'package:encrateia/widgets/athlete_widgets/athlete_power_zone_schema_widget.dart';
import 'package:flutter/material.dart';
......@@ -55,113 +56,110 @@ class _ShowAthleteScreenState extends State<ShowAthleteScreen> {
icon: MyIcon.stravaDownload,
),
),
body: Table(children: [
TableRow(children: [
detailTile(
body: GridView.count(
padding: EdgeInsets.all(5),
crossAxisCount: 2,
childAspectRatio: 3,
crossAxisSpacing: 3,
mainAxisSpacing: 3,
children: [
navigationButton(
color: MyColor.detail,
title: "Activities List",
icon: MyIcon.activities,
nextWidget: ActivitiesListWidget(athlete: widget.athlete),
),
detailTile(
title: "Settings",
icon: MyIcon.settings,
nextWidget: AthleteSettingsWidget(athlete: widget.athlete),
RaisedButton.icon(
color: MyColor.add,
icon: MyIcon.downloadLocal,
label: Text("Import .fit\nfrom Folder"),
onPressed: () => importLocal(),
),
]),
TableRow(children: [
detailTile(
navigationButton(
color: MyColor.navigate,
title: "Power",
icon: MyIcon.power,
nextWidget: AthletePowerWidget(athlete: widget.athlete),
),
detailTile(
RaisedButton.icon(
color: MyColor.add,
icon: MyIcon.settings,
label: Text("Recalculate\nAverages"),
onPressed: () => recalculate(),
),
navigationButton(
title: "Power Ratio",
color: MyColor.navigate,
icon: MyIcon.power,
nextWidget: AthletePowerRatioWidget(athlete: widget.athlete),
),
]),
TableRow(children: [
detailTile(
title: "Power / Heart Rate",