import 'package:flutter/material.dart'; import 'package:nextcloud_reminder/repeating_task.dart'; class AddTaskWidget extends StatefulWidget { const AddTaskWidget({super.key, this.restorationId, required this.onSave}); final ValueChanged onSave; final String? restorationId; @override State createState() => _AddTaskWidgetState(); } //TODO: make _repeat changeable. class _AddTaskWidgetState extends State with RestorationMixin { final _formKey = GlobalKey(); final _titleController = TextEditingController(); final int _repeat = 1; final RestorableDateTime _beginDate = RestorableDateTime(DateTime.now()); @override void dispose() { _titleController.dispose(); super.dispose(); } @override String? get restorationId => widget.restorationId; late final RestorableRouteFuture _restorableDatePickerRouteFuture = RestorableRouteFuture( onComplete: _selectDate, onPresent: (NavigatorState navigator, Object? arguments) { return navigator.restorablePush( _datePickerRoute, arguments: _beginDate.value.millisecondsSinceEpoch, ); }, ); static Route _datePickerRoute( BuildContext context, Object? arguments, ) { return DialogRoute( context: context, builder: (BuildContext context) { return DatePickerDialog( restorationId: 'date_picker_dialog', initialEntryMode: DatePickerEntryMode.calendarOnly, initialDate: DateTime.fromMillisecondsSinceEpoch(arguments! as int), firstDate: DateTime(2000), lastDate: DateTime(2100), ); }, ); } @override void restoreState(RestorationBucket? oldBucket, bool initialRestore) { registerForRestoration(_beginDate, 'selected_date'); registerForRestoration( _restorableDatePickerRouteFuture, 'date_picker_route_future'); } void _selectDate(DateTime? newSelectedDate) { if (newSelectedDate != null) { setState(() { _beginDate.value = newSelectedDate; }); } } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text('Add new repeating Task') ), body: Form( key: _formKey, child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ TextFormField( // The validator receives the text that the user has entered. validator: (value) { if (value == null || value.isEmpty) { return 'Please enter a name'; } return null; }, controller: _titleController, decoration: const InputDecoration( labelText: "Taskname" ), ), Container( decoration: const BoxDecoration(), child: Row( children: [ Text("Begin: ", style: Theme.of(context).textTheme.labelLarge), Expanded( child: Text("${_beginDate.value.year}-${_beginDate.value.month.toString().padLeft(2,'0')}-${_beginDate.value.day.toString().padLeft(2,'0')}") ), IconButton( onPressed: () => _restorableDatePickerRouteFuture.present(), icon: Icon(Icons.date_range, color: Theme.of(context).focusColor)) ] ) ), Padding( padding: const EdgeInsets.symmetric(vertical: 16.0), child: ElevatedButton( onPressed: () { // Validate returns true if the form is valid, or false otherwise. if (_formKey.currentState!.validate()) { // If the form is valid, display a snackbar. In the real world, // you'd often call a server or save the information in a database. ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text('Task added.')), ); widget.onSave(RepeatingTask( title: _titleController.text, begin: _beginDate.value, repeat: _repeat,)); Navigator.pop(context); } }, child: const Text('Submit'), ), ), ], ), ) ); } }