import 'package:flutter/material.dart'; import '../../app_theme.dart'; import '../../model/requests/create_alarm_request.dart'; import '../../model/requests/create_relative_time_alarm_request.dart'; import '../../service/validators.dart'; class RelativeTimeAlarmForm extends StatefulWidget { const RelativeTimeAlarmForm({ super.key, required this.request, required this.onChanged, }); final CreateRelativeTimeAlarmRequest request; final ValueChanged onChanged; @override State createState() => _RelativeTimeAlarmFormState(); } class _RelativeTimeAlarmFormState extends State { final timeController = TextEditingController(); static const List> timeUnitOptions = [ DropdownMenuEntry(value: TimeUnit.minute, label: 'Minutes'), DropdownMenuEntry(value: TimeUnit.hour, label: 'Hours'), DropdownMenuEntry(value: TimeUnit.day, label: 'Days'), ]; static const List> timeRelationOptions = [ DropdownMenuEntry( value: TimeRelation.before, label: 'Before', ), DropdownMenuEntry(value: TimeRelation.after, label: 'After'), ]; late TimeUnit selectedTimeUnit; late TimeRelation selectedTimeRelation; @override void initState() { super.initState(); if (widget.request.triggerAt == null) { selectedTimeUnit = TimeUnit.minute; selectedTimeRelation = TimeRelation.before; return; } final duration = widget.request.triggerAt!; selectedTimeRelation = duration.isNegative ? TimeRelation.before : TimeRelation.after; final absDuration = duration.abs(); if (absDuration.inMinutes <= 99 && absDuration.inMinutes % 60 != 0) { selectedTimeUnit = TimeUnit.minute; timeController.text = absDuration.inMinutes.toString(); } else if (absDuration.inHours <= 99 && absDuration.inHours % 24 != 0) { selectedTimeUnit = TimeUnit.hour; timeController.text = absDuration.inHours.toString(); } else { selectedTimeUnit = TimeUnit.day; timeController.text = absDuration.inDays.toString(); } } @override Widget build(BuildContext context) { return Flex( direction: Axis.horizontal, spacing: AppTheme.formColumnSpacing, children: [ Flexible( flex: 7, child: TextFormField( controller: timeController, maxLength: 2, onChanged: onTimeChanged, validator: (value) => notEmptyValidator(value) ?? wholeNumberValidator(value), keyboardType: TextInputType.number, textInputAction: TextInputAction.next, decoration: InputDecoration(label: Text('Time'), counterText: ''), ), ), Flexible( flex: 10, child: DropdownMenuFormField( dropdownMenuEntries: timeUnitOptions, initialSelection: selectedTimeUnit, showTrailingIcon: false, onSelected: (value) { selectedTimeUnit = value!; onTimeChanged(timeController.text); }, ), ), Flexible( flex: 10, child: DropdownMenuFormField( dropdownMenuEntries: timeRelationOptions, initialSelection: selectedTimeRelation, showTrailingIcon: false, onSelected: (value) { selectedTimeRelation = value!; onTimeChanged(timeController.text); }, ), ), ], ); } void onTimeChanged(String value) { int? time = int.tryParse(value); if (wholeNumberValidator(value) != null || time == null) return; Duration duration; int signedTime = selectedTimeRelation.apply(time); switch (selectedTimeUnit) { case TimeUnit.minute: duration = Duration(minutes: signedTime); case TimeUnit.hour: duration = Duration(hours: signedTime); case TimeUnit.day: duration = Duration(days: signedTime); } widget.onChanged(CreateRelativeTimeAlarmRequest(triggerAt: duration)); } } enum TimeRelation { before, after; int apply(int value) => switch (this) { TimeRelation.before => -value, TimeRelation.after => value, }; } enum TimeUnit { minute, hour, day }