Listview of custom timetable events

This commit is contained in:
Elias Müller 2024-03-10 14:48:09 +01:00
parent faf37ff19f
commit 9f467d079f
5 changed files with 166 additions and 26 deletions

1
devtools_options.yaml Normal file

@ -0,0 +1 @@
extensions:

@ -1,4 +1,6 @@
import 'dart:async';
import 'package:bottom_sheet/bottom_sheet.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
@ -135,6 +137,26 @@ class AppointmentDetails {
);
}
static Completer deleteCustomEvent(BuildContext context, CustomTimetableEvent appointment) {
Completer future = Completer();
ConfirmDialog(
title: "Termin löschen",
content: "Der ${appointment.rrule.isEmpty ? "Termin" : "Serientermin"} wird unwiederruflich gelöscht.",
confirmButton: "Löschen",
onConfirm: () {
RemoveCustomTimetableEvent(
RemoveCustomTimetableEventParams(
appointment.id
)
).run().then((value) {
Provider.of<TimetableProps>(context, listen: false).run(renew: true);
future.complete();
});
},
).asDialog(context);
return future;
}
static void _custom(BuildContext context, TimetableProps webuntisData, CustomTimetableEvent appointment) {
_bottomSheet(
context,
@ -169,21 +191,7 @@ class AppointmentDetails {
),
TextButton.icon(
onPressed: () {
ConfirmDialog(
title: "Termin löschen",
content: "Der ${appointment.rrule.isEmpty ? "Termin" : "Serientermin"} wird unwiederruflich gelöscht.",
confirmButton: "Löschen",
onConfirm: () {
RemoveCustomTimetableEvent(
RemoveCustomTimetableEventParams(
appointment.id
)
).run().then((value) {
Navigator.of(context).pop();
Provider.of<TimetableProps>(context, listen: false).run(renew: true);
});
},
).asDialog(context);
deleteCustomEvent(context, appointment).future.then((value) => Navigator.of(context).pop());
},
label: const Text("Löschen"),
icon: const Icon(Icons.delete_outline),
@ -214,7 +222,7 @@ class AppointmentDetails {
ListTile(
leading: const CenteredLeading(Icon(Icons.rule)),
title: const Text("RRule"),
subtitle: Text(appointment.rrule),
subtitle: Text(appointment.rrule.isEmpty ? "Keine" : appointment.rrule),
)
),
DebugTile(context).jsonData(appointment.toJson()),

@ -108,7 +108,7 @@ class _AddCustomTimetableEventDialogState extends State<CustomTimetableEventEdit
fromText: "Beginnend",
toText: "Endend",
strokeColor: Theme.of(context).colorScheme.secondary,
minDuration: const Duration(minutes: 45),
minDuration: const Duration(minutes: 15),
selectedColor: Theme.of(context).primaryColor,
ticks: 24,
);

@ -20,6 +20,7 @@ import 'arbitraryAppointment.dart';
import 'customTimetableEventEditDialog.dart';
import 'timeRegionComponent.dart';
import 'timetableEvents.dart';
import 'viewCustomTimetableEvents.dart';
class Timetable extends StatefulWidget {
const Timetable({super.key});
@ -28,6 +29,8 @@ class Timetable extends StatefulWidget {
State<Timetable> createState() => _TimetableState();
}
enum CalendarActions { addEvent, viewEvents }
class _TimetableState extends State<Timetable> {
CalendarController controller = CalendarController();
late Timer updateTimings;
@ -66,16 +69,45 @@ class _TimetableState extends State<Timetable> {
controller.displayDate = DateTime.now().add(const Duration(days: 2));
}
),
IconButton(
icon: const Icon(Icons.add_outlined),
onPressed: () {
showDialog(
context: context,
builder: (context) => const CustomTimetableEventEditDialog(),
barrierDismissible: false,
);
PopupMenuButton<CalendarActions>(
icon: const Icon(Icons.edit_calendar_outlined),
itemBuilder: (context) {
return CalendarActions.values.map(
(e) {
String title;
Icon icon;
switch(e) {
case CalendarActions.addEvent:
title = "Kalendereintrag hinzufügen";
icon = const Icon(Icons.add);
case CalendarActions.viewEvents:
default:
title = "Kalendereinträge anzeigen";
icon = const Icon(Icons.perm_contact_calendar_outlined);
}
return PopupMenuItem<CalendarActions>(
value: e,
child: ListTile(
title: Text(title),
leading: icon,
)
);
}
).toList();
},
),
onSelected: (value) {
switch(value) {
case CalendarActions.addEvent:
showDialog(
context: context,
builder: (context) => const CustomTimetableEventEditDialog(),
barrierDismissible: false,
);
case CalendarActions.viewEvents:
Navigator.of(context).push(MaterialPageRoute(builder: (context) => const ViewCustomTimetableEvents()));
}
},
)
],
),
body: Consumer<TimetableProps>(

@ -0,0 +1,99 @@
import 'package:flutter/material.dart';
import 'package:jiffy/jiffy.dart';
import 'package:provider/provider.dart';
import '../../../api/mhsl/customTimetableEvent/get/getCustomTimetableEventResponse.dart';
import '../../../model/timetable/timetableProps.dart';
import '../../../widget/centeredLeading.dart';
import '../../../widget/loadingSpinner.dart';
import '../../../widget/placeholderView.dart';
import 'appointmentDetails.dart';
import 'customTimetableEventEditDialog.dart';
class ViewCustomTimetableEvents extends StatefulWidget {
const ViewCustomTimetableEvents({super.key});
@override
State<ViewCustomTimetableEvents> createState() => _ViewCustomTimetableEventsState();
}
class _ViewCustomTimetableEventsState extends State<ViewCustomTimetableEvents> {
late Future<GetCustomTimetableEventResponse> events;
@override
void initState() {
super.initState();
}
_openCreateDialog() {
showDialog(
context: context,
builder: (context) => const CustomTimetableEventEditDialog(),
barrierDismissible: false,
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("Eigene Termine"),
actions: [
IconButton(
icon: const Icon(Icons.add),
onPressed: _openCreateDialog,
)
],
),
body: Consumer<TimetableProps>(builder: (context, value, child) {
if(value.primaryLoading()) return const LoadingSpinner();
var listView = ListView(
children: value.getCustomTimetableEventResponse.events.map((e) {
return ListTile(
title: Text(e.title),
subtitle: Text("${e.rrule.isNotEmpty ? "wiederholdend, " : ""}beginnend ${Jiffy.parseFromDateTime(e.startDate).fromNow()}"),
leading: CenteredLeading(Icon(e.rrule.isEmpty ? Icons.event_outlined : Icons.event_repeat_outlined)),
trailing: Row(
mainAxisSize: MainAxisSize.min,
children: [
IconButton(
icon: const Icon(Icons.edit_outlined),
onPressed: () {
showDialog(context: context, builder: (context) => CustomTimetableEventEditDialog(existingEvent: e));
},
),
IconButton(
icon: const Icon(Icons.delete_outline),
onPressed: () {
AppointmentDetails.deleteCustomEvent(context, e);
},
)
],
),
);
}).toList(),
);
var placeholder = PlaceholderView(
icon: Icons.calendar_today_outlined,
text: "Keine Einträge vorhanden",
button: TextButton(
onPressed: _openCreateDialog,
child: const Text("Termin erstellen"),
),
);
return RefreshIndicator(
onRefresh: () {
Provider.of<TimetableProps>(context, listen: false).run(renew: true);
return Future.delayed(const Duration(seconds: 3));
},
child: value.getCustomTimetableEventResponse.events.isEmpty
? placeholder
: listView
);
}),
);
}
}