diff --git a/assets/fonts/Ubuntu-R.ttf b/assets/fonts/Ubuntu-R.ttf new file mode 100644 index 0000000..d748728 Binary files /dev/null and b/assets/fonts/Ubuntu-R.ttf differ diff --git a/assets/fonts/Ubuntu-RI.ttf b/assets/fonts/Ubuntu-RI.ttf new file mode 100644 index 0000000..4f2d2bc Binary files /dev/null and b/assets/fonts/Ubuntu-RI.ttf differ diff --git a/lib/models/power_zone.dart b/lib/models/power_zone.dart index 665c63d..115a938 100644 --- a/lib/models/power_zone.dart +++ b/lib/models/power_zone.dart @@ -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; diff --git a/lib/models/weight.dart b/lib/models/weight.dart index 7e6b106..f701f43 100644 --- a/lib/models/weight.dart +++ b/lib/models/weight.dart @@ -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); diff --git a/lib/screens/add_power_zone_schema_screen.dart b/lib/screens/add_power_zone_schema_screen.dart index f8dc3ec..dddcae6 100644 --- a/lib/screens/add_power_zone_schema_screen.dart +++ b/lib/screens/add_power_zone_schema_screen.dart @@ -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 { title: Text('Add Power Zone Schema'), ), body: ListView( - padding: EdgeInsets.all(20), + padding: EdgeInsets.only(left: 20, right: 20), children: [ DateTimeField( decoration: InputDecoration( @@ -70,27 +71,17 @@ class _AddPowerZoneSchemaScreenState extends State { 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(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 { 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: [ - 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: [ - 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, ), + SizedBox(height: 10), + Row( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + MyButton.delete( + 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), - ), - 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 { setState(() {}); } - deletePowerZone({PowerZone powerZone}) async { - await powerZone.db.delete(); - await getData(); - } - deletePowerZoneSchema({PowerZoneSchema powerZoneSchema}) async { await powerZoneSchema.delete(); Navigator.of(context).pop(); diff --git a/lib/screens/add_power_zone_screen.dart b/lib/screens/add_power_zone_screen.dart index c170983..531f612 100644 --- a/lib/screens/add_power_zone_screen.dart +++ b/lib/screens/add_power_zone_screen.dart @@ -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 { + 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: [ 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: [ - 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: [ + 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(); } } diff --git a/lib/screens/add_weight_screen.dart b/lib/screens/add_weight_screen.dart index 5e0a726..74d9021 100644 --- a/lib/screens/add_weight_screen.dart +++ b/lib/screens/add_weight_screen.dart @@ -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,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: [ - 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: [ + 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(); + } } diff --git a/lib/screens/dashboard.dart b/lib/screens/dashboard.dart index e07b747..ce2039e 100644 --- a/lib/screens/dashboard.dart +++ b/lib/screens/dashboard.dart @@ -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 { 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 { ); } else { return ListView( - padding: EdgeInsets.all(40), + padding: EdgeInsets.all(20), children: [ for (Athlete athlete in athletes) ListTile( @@ -107,13 +110,17 @@ class _DashboardState extends State { subtitle: Row( mainAxisSize: MainAxisSize.min, children: [ - 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 { floatingActionButton() { if (athletes.length != 0) { return FloatingActionButton.extended( + backgroundColor: MyColor.add, label: const Text('Add Athlete'), onPressed: () => goToEditAthleteScreen(athlete: Athlete()), ); diff --git a/lib/screens/show_athlete_screen.dart b/lib/screens/show_athlete_screen.dart index 9763a53..5194943 100644 --- a/lib/screens/show_athlete_screen.dart +++ b/lib/screens/show_athlete_screen.dart @@ -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,113 +56,110 @@ class _ShowAthleteScreenState extends State { 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( - context, - MaterialPageRoute( - builder: (context) => ShowAthleteDetailScreen( - athlete: widget.athlete, - widget: nextWidget, - title: title, - ), + return RaisedButton.icon( + color: color ?? MyColor.primary, + textColor: textColor ?? MyColor.black, + icon: icon, + label: Text(title), + onPressed: () => Navigator.push( + context, + MaterialPageRoute( + builder: (context) => ShowAthleteDetailScreen( + athlete: widget.athlete, + widget: nextWidget, + title: title, ), ), ), @@ -352,7 +350,7 @@ class _ShowAthleteScreenState extends State { ); } - deleteAthleteAndPop() async{ + deleteAthleteAndPop() async { await widget.athlete.delete(); Navigator.of(context).popUntil((route) => route.isFirst); } diff --git a/lib/utils/icon_utils.dart b/lib/utils/icon_utils.dart index 2d358c1..b343d6d 100644 --- a/lib/utils/icon_utils.dart +++ b/lib/utils/icon_utils.dart @@ -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, diff --git a/lib/utils/my_button.dart b/lib/utils/my_button.dart new file mode 100644 index 0000000..d9bdf20 --- /dev/null +++ b/lib/utils/my_button.dart @@ -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, + ); +} diff --git a/lib/utils/my_color.dart b/lib/utils/my_color.dart index b7edb4e..34e228b 100644 --- a/lib/utils/my_color.dart +++ b/lib/utils/my_color.dart @@ -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; } diff --git a/lib/utils/my_theme.dart b/lib/utils/my_theme.dart index 4f71307..7d5ba93 100644 --- a/lib/utils/my_theme.dart +++ b/lib/utils/my_theme.dart @@ -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; diff --git a/lib/widgets/athlete_widgets/athlete_body_weight_widget.dart b/lib/widgets/athlete_widgets/athlete_body_weight_widget.dart index d362c15..822daac 100644 --- a/lib/widgets/athlete_widgets/athlete_body_weight_widget.dart +++ b/lib/widgets/athlete_widgets/athlete_body_weight_widget.dart @@ -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 { rows = (weights.length < 8) ? weights.length : 8; return ListView( children: [ - Center( - child: Text("\nWeightings ${offset + 1} - ${offset + rows} " - "of ${weights.length}"), - ), DataTable( - columnSpacing: 20, + headingRowHeight: kMinInteractiveDimension * 0.80, + dataRowHeight: kMinInteractiveDimension * 0.80, columns: [ 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 { 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: [ Spacer(), - RaisedButton( - color: Colors.green, - child: Text("New weighting"), - onPressed: () => Navigator.push( - context, - MaterialPageRoute( - builder: (context) => AddWeightScreen( - athlete: widget.athlete, - weight: Weight(), - ), - ), - ).then((_) => getData()()), - ), + MyButton.add( + child: Text("New weighting"), + onPressed: () async { + await Navigator.push( + context, + MaterialPageRoute( + builder: (context) => AddWeightScreen( + weight: Weight(athlete: widget.athlete), + ), + ), + ); + getData(); + }), Spacer(), - RaisedButton( - color: Colors.orange, + MyButton.navigate( child: Text("<<"), onPressed: (offset == 0) ? null @@ -106,8 +103,7 @@ class _AthleteBodyWeightWidgetState extends State { }), ), Spacer(), - RaisedButton( - color: Colors.orange, + MyButton.navigate( child: Text(">>"), onPressed: (offset + rows == weights.length) ? null @@ -150,18 +146,19 @@ Or you can simply enter your current weight using the New Weighting button. ), Spacer(), RaisedButton( - color: Colors.green, - child: Text("New weighting"), - onPressed: () => Navigator.push( - context, - MaterialPageRoute( - builder: (context) => AddWeightScreen( - athlete: widget.athlete, - weight: Weight(), - ), - ), - ).then((_) => getData()()), - ), + color: Colors.green, + child: Text("New weighting"), + onPressed: () async { + await Navigator.push( + context, + MaterialPageRoute( + builder: (context) => AddWeightScreen( + weight: Weight(athlete: widget.athlete), + ), + ), + ); + 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(); - } } diff --git a/lib/widgets/athlete_widgets/athlete_power_zone_schema_widget.dart b/lib/widgets/athlete_widgets/athlete_power_zone_schema_widget.dart index 349a3cc..dd85158 100644 --- a/lib/widgets/athlete_widgets/athlete_power_zone_schema_widget.dart +++ b/lib/widgets/athlete_widgets/athlete_power_zone_schema_widget.dart @@ -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: [ 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(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,38 +67,42 @@ class _AthletePowerZoneSchemaWidgetState DataCell(Text(powerZoneSchema.db.base.toString())), DataCell( MyIcon.edit, - onTap: () => Navigator.push( - context, - MaterialPageRoute( - builder: (context) => AddPowerZoneSchemaScreen( - powerZoneSchema: powerZoneSchema, + onTap: () async { + await Navigator.push( + context, + MaterialPageRoute( + builder: (context) => AddPowerZoneSchemaScreen( + powerZoneSchema: powerZoneSchema, + ), ), - ), - ).then((_) => getData()()), + ); + getData(); + }, ) ], ); }).toList(), ), + SizedBox(height: 20), Row( children: [ Spacer(), - RaisedButton( - color: Colors.green, - child: Text("New schema"), - onPressed: () => Navigator.push( - context, - MaterialPageRoute( - builder: (context) => AddPowerZoneSchemaScreen( - powerZoneSchema: - PowerZoneSchema(athlete: widget.athlete), - ), - ), - ).then((_) => getData()()), - ), + MyButton.add( + child: Text("New schema"), + onPressed: () async { + await Navigator.push( + context, + MaterialPageRoute( + builder: (context) => AddPowerZoneSchemaScreen( + powerZoneSchema: + PowerZoneSchema(athlete: widget.athlete), + ), + ), + ); + 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( - context, - MaterialPageRoute( - builder: (context) => AddPowerZoneSchemaScreen( - powerZoneSchema: PowerZoneSchema(athlete: widget.athlete), + onPressed: () async { + await Navigator.push( + context, + MaterialPageRoute( + builder: (context) => AddPowerZoneSchemaScreen( + powerZoneSchema: + PowerZoneSchema(athlete: widget.athlete), + ), ), - ), - ).then((_) => getData()()), + ); + getData(); + }, ), RaisedButton( // MyIcon.downloadLocal, diff --git a/pubspec.yaml b/pubspec.yaml index 35eff9d..c4dce07 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -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