#26 Listview of custom timetable events
This commit is contained in:
parent
faf37ff19f
commit
9f467d079f
1
devtools_options.yaml
Normal file
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:bottom_sheet/bottom_sheet.dart';
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:flutter/material.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) {
|
static void _custom(BuildContext context, TimetableProps webuntisData, CustomTimetableEvent appointment) {
|
||||||
_bottomSheet(
|
_bottomSheet(
|
||||||
context,
|
context,
|
||||||
@ -169,21 +191,7 @@ class AppointmentDetails {
|
|||||||
),
|
),
|
||||||
TextButton.icon(
|
TextButton.icon(
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
ConfirmDialog(
|
deleteCustomEvent(context, appointment).future.then((value) => Navigator.of(context).pop());
|
||||||
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);
|
|
||||||
},
|
},
|
||||||
label: const Text("Löschen"),
|
label: const Text("Löschen"),
|
||||||
icon: const Icon(Icons.delete_outline),
|
icon: const Icon(Icons.delete_outline),
|
||||||
@ -214,7 +222,7 @@ class AppointmentDetails {
|
|||||||
ListTile(
|
ListTile(
|
||||||
leading: const CenteredLeading(Icon(Icons.rule)),
|
leading: const CenteredLeading(Icon(Icons.rule)),
|
||||||
title: const Text("RRule"),
|
title: const Text("RRule"),
|
||||||
subtitle: Text(appointment.rrule),
|
subtitle: Text(appointment.rrule.isEmpty ? "Keine" : appointment.rrule),
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
DebugTile(context).jsonData(appointment.toJson()),
|
DebugTile(context).jsonData(appointment.toJson()),
|
||||||
|
@ -108,7 +108,7 @@ class _AddCustomTimetableEventDialogState extends State<CustomTimetableEventEdit
|
|||||||
fromText: "Beginnend",
|
fromText: "Beginnend",
|
||||||
toText: "Endend",
|
toText: "Endend",
|
||||||
strokeColor: Theme.of(context).colorScheme.secondary,
|
strokeColor: Theme.of(context).colorScheme.secondary,
|
||||||
minDuration: const Duration(minutes: 45),
|
minDuration: const Duration(minutes: 15),
|
||||||
selectedColor: Theme.of(context).primaryColor,
|
selectedColor: Theme.of(context).primaryColor,
|
||||||
ticks: 24,
|
ticks: 24,
|
||||||
);
|
);
|
||||||
|
@ -20,6 +20,7 @@ import 'arbitraryAppointment.dart';
|
|||||||
import 'customTimetableEventEditDialog.dart';
|
import 'customTimetableEventEditDialog.dart';
|
||||||
import 'timeRegionComponent.dart';
|
import 'timeRegionComponent.dart';
|
||||||
import 'timetableEvents.dart';
|
import 'timetableEvents.dart';
|
||||||
|
import 'viewCustomTimetableEvents.dart';
|
||||||
|
|
||||||
class Timetable extends StatefulWidget {
|
class Timetable extends StatefulWidget {
|
||||||
const Timetable({super.key});
|
const Timetable({super.key});
|
||||||
@ -28,6 +29,8 @@ class Timetable extends StatefulWidget {
|
|||||||
State<Timetable> createState() => _TimetableState();
|
State<Timetable> createState() => _TimetableState();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum CalendarActions { addEvent, viewEvents }
|
||||||
|
|
||||||
class _TimetableState extends State<Timetable> {
|
class _TimetableState extends State<Timetable> {
|
||||||
CalendarController controller = CalendarController();
|
CalendarController controller = CalendarController();
|
||||||
late Timer updateTimings;
|
late Timer updateTimings;
|
||||||
@ -66,16 +69,45 @@ class _TimetableState extends State<Timetable> {
|
|||||||
controller.displayDate = DateTime.now().add(const Duration(days: 2));
|
controller.displayDate = DateTime.now().add(const Duration(days: 2));
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
IconButton(
|
PopupMenuButton<CalendarActions>(
|
||||||
icon: const Icon(Icons.add_outlined),
|
icon: const Icon(Icons.edit_calendar_outlined),
|
||||||
onPressed: () {
|
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(
|
showDialog(
|
||||||
context: context,
|
context: context,
|
||||||
builder: (context) => const CustomTimetableEventEditDialog(),
|
builder: (context) => const CustomTimetableEventEditDialog(),
|
||||||
barrierDismissible: false,
|
barrierDismissible: false,
|
||||||
);
|
);
|
||||||
|
case CalendarActions.viewEvents:
|
||||||
|
Navigator.of(context).push(MaterialPageRoute(builder: (context) => const ViewCustomTimetableEvents()));
|
||||||
|
}
|
||||||
},
|
},
|
||||||
),
|
)
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
body: Consumer<TimetableProps>(
|
body: Consumer<TimetableProps>(
|
||||||
|
99
lib/view/pages/timetable/viewCustomTimetableEvents.dart
Normal file
99
lib/view/pages/timetable/viewCustomTimetableEvents.dart
Normal file
@ -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
|
||||||
|
);
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user