Client/lib/view/pages/timetable/customTimetableEventEditDialog.dart

234 lines
9.0 KiB
Dart

import 'dart:developer';
import 'package:flutter/material.dart';
import 'package:jiffy/jiffy.dart';
import '../../../extensions/dateTime.dart';
import 'package:provider/provider.dart';
import 'package:rrule_generator/rrule_generator.dart';
import 'package:time_range_picker/time_range_picker.dart';
import '../../../api/mhsl/customTimetableEvent/add/addCustomTimetableEvent.dart';
import '../../../api/mhsl/customTimetableEvent/add/addCustomTimetableEventParams.dart';
import '../../../api/mhsl/customTimetableEvent/customTimetableEvent.dart';
import '../../../api/mhsl/customTimetableEvent/update/updateCustomTimetableEvent.dart';
import '../../../api/mhsl/customTimetableEvent/update/updateCustomTimetableEventParams.dart';
import '../../../model/accountData.dart';
import '../../../model/timetable/timetableProps.dart';
import '../../../widget/focusBehaviour.dart';
import '../../../widget/infoDialog.dart';
import 'customTimetableColors.dart';
class CustomTimetableEventEditDialog extends StatefulWidget {
final CustomTimetableEvent? existingEvent;
const CustomTimetableEventEditDialog({this.existingEvent, super.key});
@override
State<CustomTimetableEventEditDialog> createState() => _AddCustomTimetableEventDialogState();
}
class _AddCustomTimetableEventDialogState extends State<CustomTimetableEventEditDialog> {
late DateTime _date = widget.existingEvent?.startDate ?? DateTime.now();
late TimeOfDay _startTime = widget.existingEvent?.startDate.toTimeOfDay() ?? const TimeOfDay(hour: 08, minute: 00);
late TimeOfDay _endTime = widget.existingEvent?.endDate.toTimeOfDay() ?? const TimeOfDay(hour: 09, minute: 30);
late final TextEditingController _eventName = TextEditingController(text: widget.existingEvent?.title);
late final TextEditingController _eventDescription = TextEditingController(text: widget.existingEvent?.description);
late String _recurringRule = widget.existingEvent?.rrule ?? '';
late CustomTimetableColors _customTimetableColor = CustomTimetableColors.values.firstWhere(
(element) => element.name == widget.existingEvent?.color,
orElse: () => TimetableColors.defaultColor
);
late bool isEditingExisting = widget.existingEvent != null;
bool validate() {
if(_eventName.text.isEmpty) return false;
return true;
}
void fetchTimetable() {
Provider.of<TimetableProps>(context, listen: false).run(renew: true);
}
@override
Widget build(BuildContext context) => AlertDialog(
insetPadding: const EdgeInsets.all(20),
contentPadding: const EdgeInsets.all(10),
title: const Text('Termin hinzufügen'),
content: SingleChildScrollView(
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
ListTile(
title: TextField(
controller: _eventName,
autofocus: true,
decoration: const InputDecoration(
labelText: 'Terminname',
border: OutlineInputBorder()
),
onTapOutside: (PointerDownEvent event) => FocusBehaviour.textFieldTapOutside(context),
),
),
ListTile(
title: TextField(
controller: _eventDescription,
maxLines: 2,
minLines: 2,
decoration: const InputDecoration(
labelText: 'Beschreibung',
border: OutlineInputBorder()
),
onTapOutside: (PointerDownEvent event) => FocusBehaviour.textFieldTapOutside(context),
),
),
const Divider(),
ListTile(
leading: const Icon(Icons.date_range_outlined),
title: Text(Jiffy.parseFromDateTime(_date).yMMMd),
subtitle: const Text('Datum'),
onTap: () async {
final pickedDate = await showDatePicker(
context: context,
initialDate: _date,
firstDate: DateTime.now().subtract(const Duration(days: 30)),
lastDate: DateTime.now().add(const Duration(days: 30)),
);
if (pickedDate != null && pickedDate != _date) {
setState(() {
_date = pickedDate;
});
}
},
),
ListTile(
leading: const Icon(Icons.access_time_outlined),
title: Text('${_startTime.format(context).toString()} - ${_endTime.format(context).toString()}'),
subtitle: const Text('Zeitraum'),
onTap: () async {
TimeRange timeRange = await showTimeRangePicker(
context: context,
start: _startTime,
end: _endTime,
disabledTime: TimeRange(startTime: const TimeOfDay(hour: 16, minute: 30), endTime: const TimeOfDay(hour: 08, minute: 00)),
disabledColor: Colors.grey,
paintingStyle: PaintingStyle.fill,
interval: const Duration(minutes: 5),
fromText: 'Beginnend',
toText: 'Endend',
strokeColor: Theme.of(context).colorScheme.secondary,
minDuration: const Duration(minutes: 15),
selectedColor: Theme.of(context).primaryColor,
ticks: 24,
);
setState(() {
_startTime = timeRange.startTime;
_endTime = timeRange.endTime;
});
},
),
const Divider(),
ListTile(
leading: const Icon(Icons.color_lens_outlined),
title: const Text('Farbgebung'),
trailing: DropdownButton<CustomTimetableColors>(
value: _customTimetableColor,
icon: const Icon(Icons.arrow_drop_down),
items: CustomTimetableColors.values.map((e) => DropdownMenuItem<CustomTimetableColors>(
value: e,
enabled: e != _customTimetableColor,
child: Row(
children: [
Icon(Icons.circle, color: TimetableColors.getDisplayOptions(e).color),
const SizedBox(width: 10),
Text(TimetableColors.getDisplayOptions(e).displayName),
],
),
)).toList(),
onChanged: (e) {
setState(() {
_customTimetableColor = e!;
});
},
),
),
const Divider(),
RRuleGenerator(
config: RRuleGeneratorConfig(
headerEnabled: true,
weekdayBackgroundColor: Theme.of(context).colorScheme.secondary,
weekdaySelectedBackgroundColor: Theme.of(context).primaryColor,
weekdayColor: Colors.black,
),
initialRRule: _recurringRule,
textDelegate: const GermanRRuleTextDelegate(),
onChange: (String newValue) {
log('Rule: $newValue');
setState(() {
_recurringRule = newValue;
});
},
)
],
),
),
actions: <Widget>[
TextButton(
onPressed: () {
Navigator.of(context).pop();
},
child: const Text('Abbrechen'),
),
TextButton(
onPressed: () {
if(!validate()) return;
var editedEvent = CustomTimetableEvent(
id: '',
title: _eventName.text,
description: _eventDescription.text,
startDate: _date.withTime(_startTime),
endDate: _date.withTime(_endTime),
color: _customTimetableColor.name,
rrule: _recurringRule,
createdAt: DateTime.now(),
updatedAt: DateTime.now(),
);
if(!isEditingExisting) {
AddCustomTimetableEvent(
AddCustomTimetableEventParams(
AccountData().getUserSecret(),
editedEvent
)
).run().then((value) {
Navigator.of(context).pop();
fetchTimetable();
})
.catchError((error, stack) {
InfoDialog.show(context, error.toString());
});
} else {
UpdateCustomTimetableEvent(
UpdateCustomTimetableEventParams(
widget.existingEvent?.id ?? '',
editedEvent
)
).run().then((value) {
Navigator.of(context).pop();
fetchTimetable();
})
.catchError((error, stack) {
InfoDialog.show(context, error.toString());
});
}
},
child: Text(isEditingExisting ? 'Speichern' : 'Erstellen'),
),
],
);
}