summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAldrik Ramaekers <aldrik@amftech.nl>2022-08-17 11:09:46 +0200
committerAldrik Ramaekers <aldrik@amftech.nl>2022-08-17 11:09:46 +0200
commit9649d80a2b0a0c46a8ae68606d3e0cfe6f49faee (patch)
treebf4f9598e526f8a6991a5045c42a18e07fac29e1
parent72aa769bc32bb920bd255e68d6ad508e8543a398 (diff)
v0.1
-rw-r--r--README13
-rw-r--r--TODO0
-rw-r--r--lib/main.dart6
-rw-r--r--lib/pages/add_shift_page.dart156
-rw-r--r--lib/pages/agenda_page.dart243
-rw-r--r--lib/pages/logbook_page.dart1
-rw-r--r--lib/services/local_shift_provider_service.dart (renamed from lib/services/program_provider_service.dart)4
-rw-r--r--lib/services/mock_shift_provider_service.dart (renamed from lib/services/mock_program_provider_service.dart)0
-rw-r--r--lib/shift.dart82
-rw-r--r--lib/widgets/agenda_week.dart7
10 files changed, 250 insertions, 262 deletions
diff --git a/README b/README
new file mode 100644
index 0000000..b8d7ea5
--- /dev/null
+++ b/README
@@ -0,0 +1,13 @@
+# Nog te doen
+- Laat geld zien op gesloten shifts
+- gebruiker uurloon laten aanpassen
+- gebruiker begintijd laten aanpassen per shift
+
+# Features
+- Aanmelden van werktijden
+- Begin en eindtijd invullen per shift
+- Begin en eindtijd live bijhouden
+- Maandelijks overzicht van gewerkte uren en inkomen
+- data wordt lokaal opgeslagen
+- gemakkelijk meerdere shifts tegelijk aanmelden
+- schatting over aantal ingeplande uren en inkomen
diff --git a/TODO b/TODO
deleted file mode 100644
index e69de29..0000000
--- a/TODO
+++ /dev/null
diff --git a/lib/main.dart b/lib/main.dart
index 5690a5f..d5c1f21 100644
--- a/lib/main.dart
+++ b/lib/main.dart
@@ -1,8 +1,8 @@
import 'package:event_bus/event_bus.dart';
import 'package:flutter/material.dart';
import 'package:training_planner/services/ishift_provider_service.dart';
-import 'package:training_planner/services/mock_program_provider_service.dart';
-import 'package:training_planner/services/program_provider_service.dart';
+import 'package:training_planner/services/mock_shift_provider_service.dart';
+import 'package:training_planner/services/local_shift_provider_service.dart';
import 'pages/home_page.dart';
import 'package:local_auth/local_auth.dart';
@@ -10,7 +10,7 @@ void main() {
runApp(const MyApp());
}
-IProgramProviderService shiftProvider = ShiftProviderService();
+IProgramProviderService shiftProvider = LocalShiftProviderService();
final LocalAuthentication auth = LocalAuthentication();
EventBus eventBus = EventBus();
diff --git a/lib/pages/add_shift_page.dart b/lib/pages/add_shift_page.dart
deleted file mode 100644
index 21bdbf0..0000000
--- a/lib/pages/add_shift_page.dart
+++ /dev/null
@@ -1,156 +0,0 @@
-import 'package:flutter/material.dart';
-import 'package:training_planner/pages/agenda_page.dart';
-import 'package:training_planner/pages/home_page.dart';
-import 'package:training_planner/shift.dart';
-import 'package:training_planner/main.dart';
-import 'package:training_planner/style/style.dart';
-
-class AddShiftPage extends StatefulWidget {
- final int pageNr;
- final int pageIndex;
- final DateTime mondayOfWeek;
- final Function updateParent;
-
- @override
- _AddShiftPageState createState() => _AddShiftPageState();
-
- const AddShiftPage({
- Key? key,
- required this.pageNr,
- required this.pageIndex,
- required this.mondayOfWeek,
- required this.updateParent,
- }) : super(key: key);
-}
-
-class _AddShiftPageState extends State<AddShiftPage> {
- @override
- initState() {
- super.initState();
- }
-
- String dropdownValue = 'Maandag';
- List<bool> isSelected = [false, true, false];
-
- Future<void> addShift() async {
- DateTime startDate = widget.mondayOfWeek;
- switch (dropdownValue) {
- case 'Maandag':
- startDate = startDate.add(Duration(days: 0));
- break;
- case 'Dinsdag':
- startDate = startDate.add(Duration(days: 1));
- break;
- case 'Woensdag':
- startDate = startDate.add(Duration(days: 2));
- break;
- case 'Donderdag':
- startDate = startDate.add(Duration(days: 3));
- break;
- case 'Vrijdag':
- startDate = startDate.add(Duration(days: 4));
- break;
- case 'Zaterdag':
- startDate = startDate.add(Duration(days: 5));
- break;
- case 'Zondag':
- startDate = startDate.add(Duration(days: 6));
- break;
- }
-
- ShiftType type = ShiftType.Dagrit;
- if (isSelected[1]) type = ShiftType.Avondrit;
- if (isSelected[2]) type = ShiftType.Terugscannen;
-
- switch (type) {
- case ShiftType.Dagrit:
- startDate = startDate.add(Duration(hours: 10));
- break;
- case ShiftType.Avondrit:
- startDate = startDate.add(Duration(
- hours: startDate.weekday == 6 ? 15 : 17,
- minutes: startDate.weekday == 6 ? 30 : 0));
- break;
- case ShiftType.Terugscannen:
- startDate = startDate.add(
- Duration(hours: startDate.weekday == 6 ? 13 : 14, minutes: 30));
- break;
- }
-
- await shiftProvider.addShift(Shift(start: startDate, type: type));
- widget.updateParent();
- Navigator.pop(context);
- }
-
- @override
- Widget build(BuildContext context) {
- return Scaffold(
- appBar: AppBar(
- title: Text('Toevoegen aan planning #' + widget.pageNr.toString()),
- backgroundColor: Style.background,
- foregroundColor: Style.titleColor,
- ),
- body: Center(
- child: Column(
- children: [
- Padding(padding: const EdgeInsets.all(20)),
- Container(
- width: 200,
- child: DropdownButton<String>(
- value: dropdownValue,
- icon: const Icon(Icons.arrow_downward),
- elevation: 16,
- style: const TextStyle(color: Colors.black),
- underline: Container(
- height: 2,
- color: Colors.black,
- ),
- onChanged: (String? newValue) {
- setState(() {
- dropdownValue = newValue!;
- });
- },
- items: <String>[
- 'Maandag',
- 'Dinsdag',
- 'Woensdag',
- 'Donderdag',
- 'Vrijdag',
- 'Zaterdag',
- 'Zondag'
- ].map<DropdownMenuItem<String>>((String value) {
- return DropdownMenuItem<String>(
- value: value,
- child: Text(value),
- );
- }).toList(),
- ),
- ),
- Padding(padding: const EdgeInsets.all(20)),
- ToggleButtons(
- children: <Widget>[
- Padding(
- padding: const EdgeInsets.all(15), child: Text('Dagrit')),
- Padding(
- padding: const EdgeInsets.all(15), child: Text('Avondrit')),
- Padding(
- padding: const EdgeInsets.all(15),
- child: Text('Terugscan')),
- ],
- onPressed: (int index) {
- setState(() {
- isSelected[index] = !isSelected[index];
- });
- },
- isSelected: isSelected,
- ),
- Padding(
- padding: const EdgeInsets.all(20),
- ),
- TextButton(
- onPressed: () async => {await addShift()},
- child: Text('Toevoegen')),
- ],
- )));
- }
-}
diff --git a/lib/pages/agenda_page.dart b/lib/pages/agenda_page.dart
index f052434..eca39fe 100644
--- a/lib/pages/agenda_page.dart
+++ b/lib/pages/agenda_page.dart
@@ -2,12 +2,10 @@ import 'package:carousel_slider/carousel_slider.dart';
import 'package:flutter/material.dart';
import 'package:in_date_utils/in_date_utils.dart' as DateUtilities;
import 'package:training_planner/main.dart';
-import 'package:training_planner/pages/add_shift_page.dart';
+import 'package:training_planner/pages/home_page.dart';
import 'package:training_planner/shift.dart';
import 'package:training_planner/style/style.dart';
-import 'package:training_planner/utils/date.dart';
import 'package:training_planner/widgets/agenda_week.dart';
-import 'package:flutter_local_notifications/flutter_local_notifications.dart';
class AgendaPage extends StatefulWidget {
final int agendaWeekNr;
@@ -19,95 +17,216 @@ class AgendaPage extends StatefulWidget {
}
class _AgendaPageState extends State<AgendaPage> {
- int weekToStartAt = 0;
- List<int> weekNrs = [];
- List<DateTime> dateTimes = [];
int currentSelectedPageIndex = 0;
- int currentSelectedPageNr = 0;
- DateTime currentSelectedWeek = DateTime.now();
@override
initState() {
super.initState();
-
- weekToStartAt = widget.agendaWeekNr;
- getWeeks();
- currentSelectedPageIndex = weekToStartAt;
- currentSelectedPageNr = weekNrs[weekToStartAt];
- currentSelectedWeek = dateTimes[weekToStartAt];
+ currentSelectedPageIndex = getStartPageIndex();
}
- List<AgendaWeek> getWeeks() {
- List<AgendaWeek> result = [];
- List<int> weekNrs = [];
- DateTime startDate =
- DateUtilities.DateUtils.firstDayOfWeek(DateTime(2020, 1, 1));
- DateTime today = DateTime.now();
- DateTime firstDayOfCurrentWeek =
- DateUtilities.DateUtils.firstDayOfWeek(today);
- int difference = today.difference(startDate).inDays;
-
- int totalWeeks = (difference / 7.0).ceil() + 4;
-
- for (int i = 0; i < totalWeeks; i++) {
- DateTime mondayOfWeek = startDate.add(Duration(days: 7 * i));
- int weekNr = DateUtilities.DateUtils.getWeekNumber(mondayOfWeek);
-
- bool isCurrentWeek = false;
- if (mondayOfWeek == firstDayOfCurrentWeek) {
- if (weekToStartAt == 0) weekToStartAt = i;
- isCurrentWeek = true;
+ Future<void> addShiftsFromDialog() async {
+ DateTime startDate = getWeek(currentSelectedPageIndex).mondayOfWeek;
+ String dropdownValue = 'Maandag';
+
+ for (int i = 0; i < 7; i++) {
+ DateTime dayOfWeek = startDate;
+ if (!dayIsSelected[i]) continue;
+
+ switch (i) {
+ case 0:
+ dayOfWeek = startDate.add(Duration(days: 0));
+ break;
+ case 1:
+ dayOfWeek = startDate.add(Duration(days: 1));
+ break;
+ case 2:
+ dayOfWeek = startDate.add(Duration(days: 2));
+ break;
+ case 3:
+ dayOfWeek = startDate.add(Duration(days: 3));
+ break;
+ case 4:
+ dayOfWeek = startDate.add(Duration(days: 4));
+ break;
+ case 5:
+ dayOfWeek = startDate.add(Duration(days: 5));
+ break;
+ case 6:
+ dayOfWeek = startDate.add(Duration(days: 6));
+ break;
}
- result.add(
- AgendaWeek(
- weekNr: weekNr,
- mondayOfWeek: mondayOfWeek,
- isCurrentWeek: isCurrentWeek,
- ),
- );
- weekNrs.add(weekNr);
- dateTimes.add(mondayOfWeek);
+ ShiftType type = ShiftType.Dagrit;
+ if (shiftsSelected[1]) type = ShiftType.Avondrit;
+ if (shiftsSelected[2]) type = ShiftType.Terugscannen;
+
+ switch (type) {
+ case ShiftType.Dagrit:
+ dayOfWeek = dayOfWeek.add(Duration(hours: 10));
+ break;
+ case ShiftType.Avondrit:
+ dayOfWeek = dayOfWeek.add(Duration(
+ hours: dayOfWeek.weekday == 6 ? 15 : 17,
+ minutes: dayOfWeek.weekday == 6 ? 30 : 0));
+ break;
+ case ShiftType.Terugscannen:
+ dayOfWeek = dayOfWeek.add(
+ Duration(hours: dayOfWeek.weekday == 6 ? 13 : 14, minutes: 30));
+ break;
+ }
+
+ await shiftProvider.addShift(Shift(start: dayOfWeek, type: type));
+ }
+ }
+
+ List<bool> dayIsSelected = [false, false, false, false, false, false, false];
+ List<bool> shiftsSelected = [false, true, false];
+
+ Future<void> showAddShiftDialog() async {
+ dayIsSelected = [false, false, false, false, false, false, false];
+ shiftsSelected = [false, true, false];
+
+ // set up the buttons
+ Widget cancelButton = FlatButton(
+ child: Text("Terug"),
+ onPressed: () {
+ Navigator.pop(context);
+ },
+ );
+ Widget continueButton = FlatButton(
+ child: Text("Ok"),
+ onPressed: () async {
+ await addShiftsFromDialog();
+ setState(() {});
+ Navigator.pop(context);
+ },
+ );
+
+ // show the dialog
+ await showDialog(
+ context: context,
+ builder: (BuildContext context) {
+ return StatefulBuilder(builder: (context, setState) {
+ return AlertDialog(
+ title: Text("Wanneer wil je werken?"),
+ content: Row(children: [
+ ToggleButtons(
+ direction: Axis.vertical,
+ children: <Widget>[
+ Padding(padding: const EdgeInsets.all(15), child: Text('Ma')),
+ Padding(padding: const EdgeInsets.all(15), child: Text('Di')),
+ Padding(padding: const EdgeInsets.all(15), child: Text('Wo')),
+ Padding(padding: const EdgeInsets.all(15), child: Text('Do')),
+ Padding(padding: const EdgeInsets.all(15), child: Text('Vr')),
+ Padding(padding: const EdgeInsets.all(15), child: Text('Za')),
+ Padding(padding: const EdgeInsets.all(15), child: Text('Zo')),
+ ],
+ onPressed: (int index) {
+ setState(() {
+ dayIsSelected[index] = !dayIsSelected[index];
+ });
+ },
+ isSelected: dayIsSelected,
+ ),
+ Padding(padding: const EdgeInsets.all(20)),
+ ToggleButtons(
+ direction: Axis.vertical,
+ children: <Widget>[
+ Padding(
+ padding: const EdgeInsets.all(15), child: Text('Dagrit')),
+ Padding(
+ padding: const EdgeInsets.all(15),
+ child: Text('Avondrit')),
+ Padding(
+ padding: const EdgeInsets.all(15),
+ child: Text('Terugscan')),
+ ],
+ onPressed: (int index) {
+ setState(() {
+ shiftsSelected = [false, false, false];
+ shiftsSelected[index] = true;
+ });
+ },
+ isSelected: shiftsSelected,
+ ),
+ ]),
+ actions: [
+ cancelButton,
+ continueButton,
+ ],
+ );
+ });
+ },
+ );
+ }
+
+ DateTime getStartWeek() {
+ return DateTime(2000, 1, 1);
+ }
+
+ int getStartPageIndex() {
+ if (widget.agendaWeekNr != 0) return widget.agendaWeekNr;
+ Duration diff = DateTime.now().difference(getStartWeek());
+ int index = diff.inDays ~/ 7;
+
+ if (getWeek(index).mondayOfWeek !=
+ DateUtilities.DateUtils.firstDayOfWeek(DateTime.now())) {
+ return index + 1;
}
- this.weekNrs = weekNrs;
+ return index;
+ }
- return result;
+ int getMaxNumberOfWeeksToDisplay() {
+ DateTime start = getStartWeek();
+ DateTime end = DateTime.now().add(Duration(days: 365));
+
+ return end.difference(start).inDays ~/ 7;
+ }
+
+ AgendaWeek getWeek(int index) {
+ DateTime weekday = getStartWeek().add(Duration(days: index * 7));
+ DateTime mondayOfWeek = DateUtilities.DateUtils.firstDayOfWeek(weekday);
+ DateTime mondayOfCurrentWeek =
+ DateUtilities.DateUtils.firstDayOfWeek(DateTime.now());
+
+ return AgendaWeek(
+ weekNr: DateUtilities.DateUtils.getWeekNumber(mondayOfWeek),
+ mondayOfWeek: mondayOfWeek,
+ isCurrentWeek:
+ DateUtilities.DateUtils.isSameDay(mondayOfWeek, mondayOfCurrentWeek),
+ );
}
@override
Widget build(BuildContext context) {
- List<AgendaWeek> weeks = getWeeks();
-
return Scaffold(
body: Padding(
padding: const EdgeInsets.all(0),
- child: CarouselSlider(
+ child: CarouselSlider.builder(
options: CarouselOptions(
onPageChanged: (index, _) {
currentSelectedPageIndex = index;
- currentSelectedPageNr = weekNrs[index];
- currentSelectedWeek = dateTimes[index];
},
height: MediaQuery.of(context).size.height - 163,
viewportFraction: 1.0,
enlargeCenterPage: false,
enableInfiniteScroll: false,
- initialPage: weekToStartAt, // Week nr
+ initialPage: getStartPageIndex(), // Week nr
),
- items: weeks,
+ itemCount: getMaxNumberOfWeeksToDisplay(),
+ itemBuilder: (context, index, realIndex) => getWeek(index),
),
),
floatingActionButton: FloatingActionButton(
- onPressed: () {
- Navigator.push(
- context,
- MaterialPageRoute(
- builder: (context) => AddShiftPage(
- pageNr: currentSelectedPageNr,
- pageIndex: currentSelectedPageIndex,
- mondayOfWeek: currentSelectedWeek,
- updateParent: weeks[currentSelectedPageIndex].updateFunc!)),
- );
+ onPressed: () async {
+ await showAddShiftDialog();
+ Navigator.pushReplacement(
+ context,
+ MaterialPageRoute(
+ builder: (BuildContext context) => HomePage(
+ agendaWeekNr: currentSelectedPageIndex,
+ )));
},
backgroundColor: Style.titleColor,
child: const Icon(Icons.add),
diff --git a/lib/pages/logbook_page.dart b/lib/pages/logbook_page.dart
index bd9bde2..0e81f49 100644
--- a/lib/pages/logbook_page.dart
+++ b/lib/pages/logbook_page.dart
@@ -2,7 +2,6 @@ import 'package:carousel_slider/carousel_slider.dart';
import 'package:flutter/material.dart';
import 'package:in_date_utils/in_date_utils.dart' as DateUtilities;
import 'package:training_planner/main.dart';
-import 'package:training_planner/pages/add_shift_page.dart';
import 'package:training_planner/shift.dart';
import 'package:training_planner/style/style.dart';
import 'package:training_planner/utils/date.dart';
diff --git a/lib/services/program_provider_service.dart b/lib/services/local_shift_provider_service.dart
index 1512096..263d747 100644
--- a/lib/services/program_provider_service.dart
+++ b/lib/services/local_shift_provider_service.dart
@@ -7,8 +7,8 @@ import 'package:uuid/uuid.dart';
import 'package:in_date_utils/in_date_utils.dart' as DateUtilities;
import 'package:path_provider/path_provider.dart';
-class ShiftProviderService extends IProgramProviderService {
- ShiftProviderService() {
+class LocalShiftProviderService extends IProgramProviderService {
+ LocalShiftProviderService() {
writeShiftsFromFile([]);
}
diff --git a/lib/services/mock_program_provider_service.dart b/lib/services/mock_shift_provider_service.dart
index 8f8db3e..8f8db3e 100644
--- a/lib/services/mock_program_provider_service.dart
+++ b/lib/services/mock_shift_provider_service.dart
diff --git a/lib/shift.dart b/lib/shift.dart
index 143fe58..fd32cf7 100644
--- a/lib/shift.dart
+++ b/lib/shift.dart
@@ -8,6 +8,14 @@ enum ShiftType {
Terugscannen,
}
+enum ShiftStatus {
+ OldOpen,
+ Closed,
+ Open,
+ Active,
+ Invalid,
+}
+
class Shift {
DateTime start;
DateTime? end;
@@ -32,30 +40,26 @@ class Shift {
}
Widget getStatusIcon() {
- if (shiftIsOpenButBeforeToday()) {
- return Icon(Icons.pending);
- }
- if (getIsActive() && end == null) {
- return Padding(
- child: CircularProgressIndicator(
- strokeWidth: 1,
- color: Colors.white,
- ),
- padding:
- const EdgeInsets.only(top: 18, left: 10, right: 10, bottom: 18),
- );
+ ShiftStatus status = getShiftStatus();
+ switch (status) {
+ case ShiftStatus.Active:
+ return Padding(
+ child: CircularProgressIndicator(
+ strokeWidth: 1,
+ color: Colors.white,
+ ),
+ padding:
+ const EdgeInsets.only(top: 18, left: 10, right: 10, bottom: 18),
+ );
+ case ShiftStatus.OldOpen:
+ return Icon(Icons.pending);
+ case ShiftStatus.Open:
+ return canStart() ? Icon(Icons.today) : Icon(Icons.cabin);
+ case ShiftStatus.Closed:
+ return Icon(Icons.check);
+ case ShiftStatus.Invalid:
+ return Icon(Icons.public_off_outlined);
}
- if (canStart()) {
- return Icon(Icons.today);
- }
- if (!getIsActive() && end == null) {
- return Icon(Icons.cabin);
- }
- if (end != null) {
- return Icon(Icons.check);
- }
-
- return Icon(Icons.question_answer);
}
bool canStart() {
@@ -120,7 +124,8 @@ class Shift {
if (getIsActive()) {
Duration totalMinutes = expectedEndTime().difference(start);
Duration elapsed = DateTime.now().difference(start);
- int percentage = (elapsed.inMinutes ~/ totalMinutes.inMinutes);
+ int percentage =
+ ((elapsed.inMinutes / totalMinutes.inMinutes) * 100).toInt();
if (percentage < 0) percentage = 0;
if (percentage > 100) percentage = 100;
return percentage;
@@ -130,7 +135,6 @@ class Shift {
void setIsActive(bool active) {
isActive = active;
-
if (active) {
start = DateTime.now();
} else {
@@ -138,20 +142,36 @@ class Shift {
}
}
- Color getStatusColor() {
+ ShiftStatus getShiftStatus() {
if (shiftIsOpenButBeforeToday()) {
- return Colors.orange;
+ return ShiftStatus.OldOpen;
}
if (getIsActive() && end == null) {
- return Colors.grey;
+ return ShiftStatus.Active;
}
if (!getIsActive() && end == null) {
- return Colors.red;
+ return ShiftStatus.Open;
}
if (end != null) {
- return Colors.green;
+ return ShiftStatus.Closed;
}
- return Colors.pink;
+ return ShiftStatus.Invalid;
+ }
+
+ Color getStatusColor() {
+ ShiftStatus status = getShiftStatus();
+ switch (status) {
+ case ShiftStatus.Active:
+ return Colors.grey;
+ case ShiftStatus.OldOpen:
+ return Colors.orange;
+ case ShiftStatus.Open:
+ return Colors.red;
+ case ShiftStatus.Closed:
+ return Colors.green;
+ case ShiftStatus.Invalid:
+ return Colors.pink;
+ }
}
}
diff --git a/lib/widgets/agenda_week.dart b/lib/widgets/agenda_week.dart
index 754a46b..543e0ff 100644
--- a/lib/widgets/agenda_week.dart
+++ b/lib/widgets/agenda_week.dart
@@ -10,7 +10,6 @@ class AgendaWeek extends StatefulWidget {
final int weekNr;
final DateTime mondayOfWeek;
final bool isCurrentWeek;
- Function? updateFunc;
@override
_AgendaWeekState createState() => _AgendaWeekState();
@@ -59,7 +58,6 @@ class _AgendaWeekState extends State<AgendaWeek> {
void initState() {
super.initState();
updateItems();
- widget.updateFunc = updateItems;
}
@override
@@ -96,11 +94,6 @@ class _AgendaWeekState extends State<AgendaWeek> {
},
childCount: weekItems.length,
)),
-
- // Rest day
- //if (day == null)
- // createRestDayPage(list)
-
SliverPadding(padding: EdgeInsets.only(top: 20)),
],
),