Created ProgressEditorWidget and rewritten ProgressCreationScreen with it

Signed-off-by: Andreas Fahrecker <AndreasFahrecker@gmail.com>
This commit is contained in:
Andreas Fahrecker 2021-02-11 18:35:47 +01:00
parent 763cf9d627
commit 1abfd0c1f5
3 changed files with 153 additions and 109 deletions

View File

@ -11,13 +11,7 @@ class TimeProgress {
final DateTime endTime;
TimeProgress(this.name, this.startTime, this.endTime, {String id})
: id = id ?? Uuid().generateV4() {
if (this.name == null || this.name == "")
throw new TimeProgressInvalidNameException(this.name);
if (!this.startTime.isBefore(this.endTime))
throw new TimeProgressStartTimeIsNotBeforeEndTimeException(
startTime, endTime);
}
: id = id ?? Uuid().generateV4();
factory TimeProgress.initialDefault() {
int thisYear = DateTime.now().year;
@ -81,6 +75,11 @@ class TimeProgress {
}
TimeProgressEntity toEntity() {
if (!TimeProgress.isNameValid(name))
throw new TimeProgressInvalidNameException(name);
if (!TimeProgress.areTimesValid(startTime, endTime))
throw new TimeProgressStartTimeIsNotBeforeEndTimeException(
startTime, endTime);
return TimeProgressEntity(id, name, startTime, endTime);
}
@ -92,4 +91,17 @@ class TimeProgress {
id: entity.id ?? Uuid().generateV4(),
);
}
static bool isValid(TimeProgress tp) {
return TimeProgress.isNameValid(tp.name) &&
TimeProgress.areTimesValid(tp.startTime, tp.endTime);
}
static bool isNameValid(String name) {
return name != null && name != "" && name.length > 3 && name.length < 20;
}
static bool areTimesValid(DateTime startTime, DateTime endTime) {
return startTime.isBefore(endTime);
}
}

View File

@ -6,6 +6,7 @@ import 'package:time_progress_tracker/models/app_exceptions.dart';
import 'package:time_progress_tracker/models/app_state.dart';
import 'package:time_progress_tracker/models/time_progress.dart';
import 'package:time_progress_tracker/widgets/date_picker_btn.dart';
import 'package:time_progress_tracker/widgets/progress_editor_widget.dart';
class ProgressCreationScreen extends StatefulWidget {
static const routeName = "/progress-creation";
@ -18,115 +19,26 @@ class ProgressCreationScreen extends StatefulWidget {
}
class _ProgressCreationScreenState extends State<ProgressCreationScreen> {
final TextEditingController _nameController = TextEditingController();
DateTime pickedStartTime = DateTime.now();
DateTime pickedEndTime = DateTime(
DateTime.now().year + 1, DateTime.now().month, DateTime.now().day);
TimeProgress timeProgressToCreate =
TimeProgress("", DateTime.now(), DateTime(DateTime.now().year + 1));
bool _validName = true;
bool _validDates = true;
void _createTimeProgress(BuildContext context) {
try {
TimeProgress tpToCreate =
TimeProgress(_nameController.text, pickedStartTime, pickedEndTime);
StoreProvider.of<AppState>(context)
.dispatch(AddTimeProgressAction(tpToCreate));
Navigator.pop(context);
} on TimeProgressInvalidNameException catch (e) {
setState(() {
_validName = false;
});
} on TimeProgressStartTimeIsNotBeforeEndTimeException catch (e) {
setState(() {
_validDates = false;
});
}
}
@override
void dispose() {
_nameController.dispose();
super.dispose();
void onTimeProgressChanged(TimeProgress newTimeProgress) {
setState(() {
timeProgressToCreate = newTimeProgress;
});
}
@override
Widget build(BuildContext context) {
ThemeData appTheme = Theme.of(context);
return Scaffold(
appBar: AppBar(
title: Text(ProgressCreationScreen.title),
),
body: Container(
padding: EdgeInsets.all(8),
child: Column(
children: <Widget>[
Expanded(
flex: 1,
child: TextField(
controller: _nameController,
decoration: InputDecoration(
border: OutlineInputBorder(),
labelText: "Progress Name",
errorText: _validName
? null
: "The Name of the Time Progress has to be set.",
),
),
),
Expanded(
flex: 1,
child: Row(
children: <Widget>[
Expanded(
flex: 5,
child: DatePickerBtn(
leadingString: "Start Date:",
pickedDate: pickedStartTime,
onDatePicked: (DateTime startTime) {
if (startTime != null) {
setState(() {
pickedStartTime = startTime;
});
}
},
),
),
Spacer(
flex: 1,
),
Expanded(
flex: 5,
child: DatePickerBtn(
leadingString: "EndDate:",
pickedDate: pickedEndTime,
onDatePicked: (DateTime endTime) {
if (endTime != null) {
setState(() {
pickedEndTime = endTime;
});
}
},
),
),
],
),
),
_validDates
? Spacer(
flex: 1,
)
: Expanded(
child: Center(
child: Text(
"Your Picked Dates are invalid. The Start Date has to be before the end Date."),
),
),
Spacer(
flex: 4,
)
],
padding: EdgeInsets.all(12),
child: ProgressEditorWidget(
timeProgress: timeProgressToCreate,
onTimeProgressChanged: onTimeProgressChanged,
),
),
floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat,
@ -136,9 +48,13 @@ class _ProgressCreationScreenState extends State<ProgressCreationScreen> {
child: FloatingActionButton(
heroTag: "createTimeProgressBTN",
child: Icon(Icons.save),
onPressed: () {
_createTimeProgress(context);
},
onPressed: TimeProgress.isValid(timeProgressToCreate)
? () {
StoreProvider.of<AppState>(context).dispatch(
AddTimeProgressAction(timeProgressToCreate));
Navigator.pop(context);
}
: null,
),
),
Expanded(

View File

@ -0,0 +1,116 @@
import 'package:flutter/material.dart';
import 'package:time_progress_tracker/models/time_progress.dart';
import 'package:time_progress_tracker/widgets/date_picker_btn.dart';
class ProgressEditorWidget extends StatefulWidget {
final TimeProgress timeProgress;
final Function(TimeProgress) onTimeProgressChanged;
ProgressEditorWidget({
@required this.timeProgress,
@required this.onTimeProgressChanged,
});
@override
State<StatefulWidget> createState() {
return _ProgressEditorWidgetState();
}
}
class _ProgressEditorWidgetState extends State<ProgressEditorWidget> {
bool _validName = true, _validDate = true;
void _onNameChanged(String newName) {
if (!TimeProgress.isNameValid(newName))
setState(() {
_validName = false;
});
widget.onTimeProgressChanged(widget.timeProgress.copyWith(name: newName));
setState(() {
_validName = true;
});
}
void _onStartDateChanged(DateTime newStartDate) {
if (!TimeProgress.areTimesValid(newStartDate, widget.timeProgress.endTime))
setState(() {
_validDate = false;
});
widget.onTimeProgressChanged(
widget.timeProgress.copyWith(startTime: newStartDate));
setState(() {
_validDate = true;
});
}
void _onEndDateChanged(DateTime newEndDate) {
if (!TimeProgress.areTimesValid(widget.timeProgress.startTime, newEndDate))
setState(() {
_validDate = false;
});
widget.onTimeProgressChanged(
widget.timeProgress.copyWith(endTime: newEndDate));
}
@override
Widget build(BuildContext context) {
List<Widget> columnChildren = [
Expanded(
child: TextField(
onChanged: _onNameChanged,
decoration: InputDecoration(
border: OutlineInputBorder(),
labelText: "Progress Name",
errorText:
_validName ? null : "The Name of the Progress can't be empty.",
),
),
),
Expanded(
child: Row(
children: [
Expanded(
child: Padding(
padding: EdgeInsets.only(right: 5),
child: DatePickerBtn(
leadingString: "Start Date:",
pickedDate: widget.timeProgress.startTime,
onDatePicked: _onStartDateChanged,
),
),
),
Expanded(
child: Padding(
padding: EdgeInsets.only(left: 5),
child: DatePickerBtn(
leadingString: "End Date:",
pickedDate: widget.timeProgress.endTime,
onDatePicked: _onEndDateChanged,
),
),
),
],
),
)
];
if (!_validDate)
columnChildren.add(
Expanded(
child: Center(
child: Text(
"Invalid Dates. The Start Date has to be before the End Date"),
),
),
);
return Container(
child: Column(
children: columnChildren,
),
);
}
}