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

master
Stefan Haslinger 2020-04-30 13:30:46 +02:00
parent 35f68ef691
commit 14a9eeb328
16 changed files with 501 additions and 374 deletions

BIN
assets/fonts/Ubuntu-R.ttf Normal file

Binary file not shown.

BIN
assets/fonts/Ubuntu-RI.ttf Normal file

Binary file not shown.

View File

@ -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;

View File

@ -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);

View File

@ -1,4 +1,5 @@
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,76 +96,62 @@ 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(
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(
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(
SizedBox(height: 10),
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),
MyButton.delete(
onPressed: () => deletePowerZoneSchema(
powerZoneSchema: widget.powerZoneSchema, ),
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),
),
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();

View File

@ -1,24 +1,72 @@
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,61 +77,94 @@ 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(
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>[
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),
),
MyButton.delete(onPressed: () => deletePowerZone(context)),
SizedBox(width: 5),
MyButton.cancel(onPressed: () => Navigator.of(context).pop()),
SizedBox(width: 5),
MyButton.save(onPressed: () => savePowerZone(context)),
],
),
),
],
),
);
}
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();
}
}

View File

@ -1,26 +1,19 @@
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,27 +41,19 @@ class AddWeightScreen extends StatelessWidget {
keyboardType: TextInputType.number,
onChanged: (value) => weight.db.value = double.parse(value),
),
Padding(
padding: EdgeInsets.all(15),
child: Row(
SizedBox(height: 20),
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),
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();
}
}

View File

@ -1,3 +1,4 @@
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()),
);

View File

@ -1,3 +1,4 @@
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,106 +56,104 @@ 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",
navigationButton(
color: MyColor.settings,
title: "Settings",
icon: MyIcon.settings,
nextWidget: AthleteSettingsWidget(athlete: widget.athlete),
),
navigationButton(
color: MyColor.navigate,
title: "Power /\nHeart Rate",
icon: MyIcon.power,
nextWidget: AthletePowerPerHeartRateWidget(athlete: widget.athlete),
),
detailTile(
title: "Speed / Heart Rate",
icon: MyIcon.speed,
nextWidget: AthleteSpeedPerHeartRateWidget(athlete: widget.athlete),
),
]),
TableRow(children: [
detailTile(
title: "Stride Ratio",
icon: MyIcon.strideRatio,
nextWidget: AthleteStrideRatioWidget(athlete: widget.athlete),
),
Card(
shape:
RoundedRectangleBorder(borderRadius: BorderRadius.circular(25)),
child: ListTile(
leading: MyIcon.settings,
title: Text("Recalculate Averages"),
onTap: () => recalculate(),
),
),
]),
TableRow(children: [
Card(
shape:
RoundedRectangleBorder(borderRadius: BorderRadius.circular(25)),
child: ListTile(
leading: MyIcon.downloadLocal,
title: Text("Import from Local Directory"),
onTap: () => importLocal(),
),
),
Card(
shape:
RoundedRectangleBorder(borderRadius: BorderRadius.circular(25)),
child: ListTile(
leading: MyIcon.delete,
title: Text("Delete Athlete"),
onTap: () => deleteUser(),
),
),
]),
TableRow(children: [
detailTile(
navigationButton(
color: MyColor.settings,
title: "Body Weight",
icon: MyIcon.weight,
nextWidget: AthleteBodyWeightWidget(athlete: widget.athlete),
),
detailTile(
title: "Power Zone Schemas",
navigationButton(
color: MyColor.navigate,
title: "Stride Ratio",
icon: MyIcon.strideRatio,
nextWidget: AthleteStrideRatioWidget(athlete: widget.athlete),
),
navigationButton(
color: MyColor.settings,
title: "Power Zone\nSchemas",
icon: MyIcon.power,
nextWidget: AthletePowerZoneSchemaWidget(athlete: widget.athlete),
),
])
]),
navigationButton(
color: MyColor.navigate,
title: "Speed /\nHeart Rate",
icon: MyIcon.speed,
nextWidget: AthleteSpeedPerHeartRateWidget(athlete: widget.athlete),
),
RaisedButton.icon(
color: MyColor.danger,
textColor: MyColor.white,
icon: MyIcon.delete,
label: Text("Delete Athlete"),
onPressed: () => deleteUser(),
),
],
),
);
}
detailTile({
navigationButton({
Widget nextWidget,
Widget icon,
String title,
Color color,
Color textColor,
}) {
return Card(
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(25)),
child: ListTile(
leading: icon,
title: Text(title),
onTap: () => Navigator.push(
return RaisedButton.icon(
color: color ?? MyColor.primary,
textColor: textColor ?? MyColor.black,
icon: icon,
label: Text(title),
onPressed: () => Navigator.push(
context,
MaterialPageRoute(
builder: (context) => ShowAthleteDetailScreen(
@ -164,7 +163,6 @@ class _ShowAthleteScreenState extends State<ShowAthleteScreen> {
),
),
),
),
);
}
@ -352,7 +350,7 @@ class _ShowAthleteScreenState extends State<ShowAthleteScreen> {
);
}
deleteAthleteAndPop() async{
deleteAthleteAndPop() async {
await widget.athlete.delete();
Navigator.of(context).popUntil((route) => route.isFirst);
}

View File

@ -6,6 +6,7 @@ class MyIcon {
// A
static final activities = Icon(Icons.view_list);
static final amount = Icon(Icons.playlist_add);
static final analyze = Icon(Icons.multiline_chart);
static final ascent = Icon(Icons.trending_up);
static final athlete = Icon(
Icons.face,

52
lib/utils/my_button.dart Normal file
View File

@ -0,0 +1,52 @@
import 'dart:ui';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'my_color.dart';
class MyButton extends RaisedButton {
MyButton.delete({Widget child, VoidCallback onPressed})
: super(
color: MyColor.delete,
textColor: Colors.white,
child: child ?? Text('Delete'),
onPressed: onPressed,
);
MyButton.cancel({Widget child, VoidCallback onPressed})
: super(
color: MyColor.cancel,
child: child ?? Text('Cancel'),
onPressed: onPressed,
);
MyButton.save({Widget child, VoidCallback onPressed})
: super(
color: MyColor.save,
child: child ?? Text('Save'),
onPressed: onPressed,
);
MyButton.add({Widget child, VoidCallback onPressed})
: super(
color: MyColor.add,
child: child ?? Text('Add'),
onPressed: onPressed,
);
MyButton.navigate({Widget child, VoidCallback onPressed})
: super(
color: MyColor.navigate,
child: child ?? Text('Navigate'),
onPressed: onPressed,
);
MyButton.detail({Widget child, VoidCallback onPressed})
: super(
color: MyColor.detail,
textColor: Colors.white,
child: child ?? Text('Detail'),
onPressed: onPressed,
);
}

View File

@ -1,49 +1,60 @@
import 'package:flutter/material.dart';
// import 'package:encrateia/utils/my_color.dart';
class MyColor {
static final blueJeans = Color(0xFF4A89DC);
static final blueJeansAccent = Color(0xFF5D9CEC);
static final aqua = Color(0xFF3BAFDA);
static final aquaAccent = Color(0xFF4FC1E9);
static final mint = Color(0xFF37BC9B);
static final mintAccent = Color(0xFF48CFAD);
static final grass = Color(0xFF8CC152);
static final grassAccent = Color(0xFFA0D468);
static final sunFlower = Color(0xFFF6BB42);
static final sunFlowerAccent = Color(0xFFFFCE54);
static final bitterSweet = Color(0xFFE9573F);
static final bitterSweetAccent = Color(0xFFFC6E51);
static final grapeFruit = Color(0xFFDA4453);
static final grapeFruitAccent = Color(0xFFED5565);
static final lavender = Color(0xFF967ADC);
static final lavenderAccent = Color(0xFFAC92EC);
static final pinkRose = Color(0xFFD770AD);
static final pinkRoseAccent = Color(0xFFEC87C0);
static final lightGray = Color(0xFFE6E9ED);
static final lightGrayAccent = Color(0xFFF5F7FA);
static final mediumGray = Color(0xFFAAB2BD);
static final mediumGrayAccent = Color(0xFFCCD1D9);
static final darkGray = Color(0xFF434A54);
static final darkGrayAccent = Color(0xFF656D78);
static final white = Colors.white;
static final black = Colors.black;
static Color blueJeans = Color(0xFF4A89DC);
static Color blueJeansAccent = Color(0xFF5D9CEC);
static Color aqua = Color(0xFF3BAFDA);
static Color aquaAccent = Color(0xFF4FC1E9);
static Color mint = Color(0xFF37BC9B);
static Color mintAccent = Color(0xFF48CFAD);
static Color grass = Color(0xFF8CC152);
static Color grassAccent = Color(0xFFA0D468);
static Color sunFlower = Color(0xFFF6BB42);
static Color sunFlowerAccent = Color(0xFFFFCE54);
static Color bitterSweet = Color(0xFFE9573F);
static Color bitterSweetAccent = Color(0xFFFC6E51);
static Color grapeFruit = Color(0xFFDA4453);
static Color grapeFruitAccent = Color(0xFFED5565);
static Color lavender = Color(0xFF967ADC);
static Color lavenderAccent = Color(0xFFAC92EC);
static Color pinkRose = Color(0xFFD770AD);
static Color pinkRoseAccent = Color(0xFFEC87C0);
static Color lightGray = Color(0xFFE6E9ED);
static Color lightGrayAccent = Color(0xFFF5F7FA);
static Color mediumGray = Color(0xFFAAB2BD);
static Color mediumGrayAccent = Color(0xFFCCD1D9);
static Color darkGray = Color(0xFF434A54);
static Color darkGrayAccent = Color(0xFF656D78);
static Color white = Colors.white;
static Color black = Colors.black;
static final normal = mediumGray;
static final normalAccent = mediumGrayAccent;
static final defaultColor = white;
static final defaultAccent = mediumGrayAccent;
static final primary = sunFlower;
static final primaryAccent = sunFlowerAccent;
static final success = grass;
static final successAccent = grassAccent;
static final info = mint;
static final infoAccent = mintAccent;
static final warning = sunFlower;
static final warningAccent = sunFlowerAccent;
static final danger = grapeFruit;
static final dangerAccent = grapeFruitAccent;
static final link = Color(0x11ffffff);
static final linkAccent = Color(0xAAffffff);
static Color ecstasy = Color(0xFFF9690E);
static Color gamboge = Color(0xFFFFB61E);
static Color brightGoldenYellow = Color(0xFFFFA400);
static Color normal = mediumGray;
static Color normalAccent = mediumGrayAccent;
static Color defaultColor = white;
static Color defaultAccent = mediumGrayAccent;
static Color primary = gamboge;
static Color primaryAccent = ecstasy;
static Color success = grass;
static Color successAccent = grassAccent;
static Color info = mint;
static Color infoAccent = mintAccent;
static Color warning = sunFlower;
static Color warningAccent = sunFlowerAccent;
static Color danger = grapeFruit;
static Color dangerAccent = grapeFruitAccent;
static Color link = Color(0x11ffffff);
static Color linkAccent = Color(0xAAffffff);
static Color detail = brightGoldenYellow;
static Color settings = lightGray;
static Color add = mint;
static Color save = success;
static Color cancel = warning;
static Color delete = danger;
static Color navigate = white;
}

View File

@ -2,6 +2,7 @@ import 'package:encrateia/utils/my_color.dart';
import 'package:flutter/material.dart';
class MyTheme {
static call() {
var redness = MyColor.primary.red;
var greenness = MyColor.primary.green;

View File

@ -1,6 +1,7 @@
import 'dart:convert';
import 'dart:io';
import 'package:encrateia/screens/add_weight_screen.dart';
import 'package:encrateia/utils/my_button.dart';
import 'package:flutter/material.dart';
import 'package:encrateia/models/athlete.dart';
import 'package:encrateia/models/weight.dart';
@ -37,20 +38,16 @@ class _AthleteBodyWeightWidgetState extends State<AthleteBodyWeightWidget> {
rows = (weights.length < 8) ? weights.length : 8;
return ListView(
children: <Widget>[
Center(
child: Text("\nWeightings ${offset + 1} - ${offset + rows} "
"of ${weights.length}"),
),
DataTable(
columnSpacing: 20,
headingRowHeight: kMinInteractiveDimension * 0.80,
dataRowHeight: kMinInteractiveDimension * 0.80,
columns: <DataColumn>[
DataColumn(label: Text("Date")),
DataColumn(
label: Text("Weight\nkg"),
label: Text("Weight in kg"),
numeric: true,
),
DataColumn(label: Text("")),
DataColumn(label: Text(""))
DataColumn(label: Text("Edit"))
],
rows: weights.sublist(offset, offset + rows).map((Weight weight) {
return DataRow(
@ -59,45 +56,45 @@ class _AthleteBodyWeightWidgetState extends State<AthleteBodyWeightWidget> {
DataCell(
Text(DateFormat("d MMM yyyy").format(weight.db.date))),
DataCell(Text(weight.db.value.toString())),
DataCell(
MyIcon.delete,
onTap: () => deleteWeight(weight: weight),
),
DataCell(
MyIcon.edit,
onTap: () => Navigator.push(
DataCell(MyIcon.edit, onTap: () async {
await Navigator.push(
context,
MaterialPageRoute(
builder: (context) => AddWeightScreen(
athlete: widget.athlete,
weight: weight,
builder: (context) => AddWeightScreen(weight: weight),
),
),
).then((_) => getData()()),
)
);
getData();
})
],
);
}).toList(),
),
Padding(
padding: EdgeInsets.all(10),
child: Text(
"${offset + 1} - ${offset + rows} "
"of ${weights.length} ",
textAlign: TextAlign.right,
),
),
Row(
children: <Widget>[
Spacer(),
RaisedButton(
color: Colors.green,
MyButton.add(
child: Text("New weighting"),
onPressed: () => Navigator.push(
onPressed: () async {
await Navigator.push(
context,
MaterialPageRoute(
builder: (context) => AddWeightScreen(
athlete: widget.athlete,
weight: Weight(),
weight: Weight(athlete: widget.athlete),
),
),
).then((_) => getData()()),
),
);
getData();
}),
Spacer(),
RaisedButton(
color: Colors.orange,
MyButton.navigate(
child: Text("<<"),
onPressed: (offset == 0)
? null
@ -106,8 +103,7 @@ class _AthleteBodyWeightWidgetState extends State<AthleteBodyWeightWidget> {
}),
),
Spacer(),
RaisedButton(
color: Colors.orange,
MyButton.navigate(
child: Text(">>"),
onPressed: (offset + rows == weights.length)
? null
@ -152,16 +148,17 @@ Or you can simply enter your current weight using the New Weighting button.
RaisedButton(
color: Colors.green,
child: Text("New weighting"),
onPressed: () => Navigator.push(
onPressed: () async {
await Navigator.push(
context,
MaterialPageRoute(
builder: (context) => AddWeightScreen(
athlete: widget.athlete,
weight: Weight(),
weight: Weight(athlete: widget.athlete),
),
),
).then((_) => getData()()),
),
);
getData();
}),
Spacer(),
],
)
@ -198,8 +195,7 @@ Or you can simply enter your current weight using the New Weighting button.
.transform(CsvToListConverter(eol: "\n"))
.toList();
for (List weighting in weightings) {
weight = Weight();
weight.db.athletesId = widget.athlete.db.id;
weight = Weight(athlete: widget.athlete);
weight.db.date = DateTime.utc(
int.parse(weighting[0].split("-")[0]),
int.parse(weighting[0].split("-")[1]),
@ -211,9 +207,4 @@ Or you can simply enter your current weight using the New Weighting button.
await getData();
}
}
deleteWeight({Weight weight}) async {
await weight.delete();
await getData();
}
}

View File

@ -1,4 +1,5 @@
import 'package:encrateia/screens/add_power_zone_schema_screen.dart';
import 'package:encrateia/utils/my_button.dart';
import 'package:flutter/material.dart';
import 'package:encrateia/models/athlete.dart';
import 'package:encrateia/models/power_zone_schema.dart';
@ -35,17 +36,23 @@ class _AthletePowerZoneSchemaWidgetState
return ListView(
children: <Widget>[
Center(
child: Text("\nPowerZoneSchemas ${offset + 1} - ${offset + rows} "
"of ${powerZoneSchemas.length}"),
child: Text(
"\nPowerZoneSchemas ${offset + 1} - ${offset + rows} "
"of ${powerZoneSchemas.length}",
style: Theme.of(context).textTheme.title,
),
),
DataTable(
dataRowHeight: kMinInteractiveDimension * 0.60,
columnSpacing: 1,
horizontalMargin: 12,
headingRowHeight: kMinInteractiveDimension * 0.80,
dataRowHeight: kMinInteractiveDimension * 0.80,
columnSpacing: 20,
columns: <DataColumn>[
DataColumn(label: Text("Date")),
DataColumn(label: Text("Name")),
DataColumn(label: Text("Base (W)")),
DataColumn(
label: Text("Base (W)"),
numeric: true,
),
DataColumn(label: Text("Edit")),
],
rows: powerZoneSchemas
@ -60,26 +67,30 @@ class _AthletePowerZoneSchemaWidgetState
DataCell(Text(powerZoneSchema.db.base.toString())),
DataCell(
MyIcon.edit,
onTap: () => Navigator.push(
onTap: () async {
await Navigator.push(
context,
MaterialPageRoute(
builder: (context) => AddPowerZoneSchemaScreen(
powerZoneSchema: powerZoneSchema,
),
),
).then((_) => getData()()),
);
getData();
},
)
],
);
}).toList(),
),
SizedBox(height: 20),
Row(
children: <Widget>[
Spacer(),
RaisedButton(
color: Colors.green,
MyButton.add(
child: Text("New schema"),
onPressed: () => Navigator.push(
onPressed: () async {
await Navigator.push(
context,
MaterialPageRoute(
builder: (context) => AddPowerZoneSchemaScreen(
@ -87,11 +98,11 @@ class _AthletePowerZoneSchemaWidgetState
PowerZoneSchema(athlete: widget.athlete),
),
),
).then((_) => getData()()),
),
);
getData();
}),
Spacer(),
RaisedButton(
color: Colors.orange,
MyButton.navigate(
child: Text("<<"),
onPressed: (offset == 0)
? null
@ -100,8 +111,7 @@ class _AthletePowerZoneSchemaWidgetState
}),
),
Spacer(),
RaisedButton(
color: Colors.orange,
MyButton.navigate(
child: Text(">>"),
onPressed: (offset + rows == powerZoneSchemas.length)
? null
@ -133,14 +143,18 @@ You could also create a schema from scratch.
RaisedButton(
color: Colors.green,
child: Text("New schema"),
onPressed: () => Navigator.push(
onPressed: () async {
await Navigator.push(
context,
MaterialPageRoute(
builder: (context) => AddPowerZoneSchemaScreen(
powerZoneSchema: PowerZoneSchema(athlete: widget.athlete),
powerZoneSchema:
PowerZoneSchema(athlete: widget.athlete),
),
),
).then((_) => getData()()),
);
getData();
},
),
RaisedButton(
// MyIcon.downloadLocal,

View File

@ -28,7 +28,6 @@ dependencies:
csv: ^4.0.3
datetime_picker_formfield: ^1.0.0
flutter_material_color_picker: ^1.0.5
dev_dependencies:
@ -39,6 +38,12 @@ dev_dependencies:
flutter:
uses-material-design: true
fonts:
- family: Ubuntu
fonts:
- asset: assets/fonts/Ubuntu-R.ttf
- asset: assets/fonts/Ubuntu-RI.ttf
style: italic
flutter_icons:
android: launcher_icon