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 createState() => _AddCustomTimetableEventDialogState(); } class _AddCustomTimetableEventDialogState extends State { 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(context, listen: false).run(renew: true); } @override Widget build(BuildContext context) { return 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: [ 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 DateTime? 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( value: _customTimetableColor, icon: const Icon(Icons.arrow_drop_down), items: CustomTimetableColors.values.map((e) => DropdownMenuItem( 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: [ TextButton( onPressed: () { Navigator.of(context).pop(); }, child: const Text('Abbrechen'), ), TextButton( onPressed: () { if(!validate()) return; CustomTimetableEvent 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'), ), ], ); } }