import 'package:diameter/components/detail.dart'; import 'package:diameter/components/dialogs.dart'; import 'package:diameter/components/dropdown.dart'; import 'package:diameter/components/forms.dart'; import 'package:diameter/config.dart'; import 'package:diameter/models/bolus.dart'; import 'package:diameter/models/log_bolus.dart'; import 'package:diameter/models/log_entry.dart'; import 'package:diameter/models/log_meal.dart'; import 'package:diameter/navigation.dart'; import 'package:diameter/settings.dart'; import 'package:flutter/material.dart'; class LogBolusDetailScreen extends StatefulWidget { static const String routeName = '/log-bolus'; final int logEntryId; final int id; const LogBolusDetailScreen({Key? key, this.logEntryId = 0, this.id = 0}) : super(key: key); @override _LogBolusDetailScreenState createState() => _LogBolusDetailScreenState(); } class _LogBolusDetailScreenState extends State { LogEntry? _logEntry; LogBolus? _logBolus; bool _isNew = true; bool _isSaving = false; final GlobalKey _logBolusForm = GlobalKey(); final _unitsController = TextEditingController(text: ''); final _carbsController = TextEditingController(text: ''); final _mgPerDlController = TextEditingController(text: ''); final _mmolPerLController = TextEditingController(text: ''); final _delayController = TextEditingController(text: ''); final _notesController = TextEditingController(text: ''); bool _manuallyAdjusted = false; LogMeal? _meal; Bolus? _rate; List _logMeals = []; @override void initState() { super.initState(); reload(); _logEntry = LogEntry.get(widget.logEntryId); _logMeals = _logEntry?.meals ?? []; if (widget.id != 0) { _unitsController.text = _logBolus!.units.toString(); _carbsController.text = (_logBolus!.carbs ?? '').toString(); _mgPerDlController.text = (_logBolus!.mgPerDl ?? '').toString(); _mmolPerLController.text = (_logBolus!.mmolPerL ?? '').toString(); _delayController.text = (_logBolus!.delay ?? '').toString(); _notesController.text = _logBolus!.notes ?? ''; _manuallyAdjusted = _logBolus!.manuallyAdjusted; _meal = _logBolus!.meal.target; _rate = _logBolus!.rate.target ?? Bolus.getRateForTime(_logEntry?.time); } } void reload() { if (widget.id != 0) { setState(() { _logBolus = LogBolus.get(widget.id); }); } _isNew = _logBolus == null; } Future onSelectMeal(LogMeal meal) async { setState(() { _meal = meal; if (meal.carbsPerPortion != null) { _carbsController.text = meal.carbsPerPortion.toString(); if (_rate != null) { _unitsController.text = (meal.carbsPerPortion ?? 0 / (_rate!.carbs / _rate!.units)) .toString(); } } }); } void handleSaveAction() async { setState(() { _isSaving = true; }); if (_logBolusForm.currentState!.validate()) { LogBolus logBolus = LogBolus( id: widget.id, units: double.tryParse(_unitsController.text) ?? 0, carbs: double.tryParse(_carbsController.text), mgPerDl: int.tryParse(_mgPerDlController.text), mmolPerL: double.tryParse(_mmolPerLController.text), delay: int.tryParse(_delayController.text), manuallyAdjusted: _manuallyAdjusted, notes: _notesController.text, ); logBolus.logEntry.target = _logEntry; logBolus.meal.target = _meal; logBolus.rate.target = _rate; LogBolus.put(logBolus); Navigator.pop(context, '${_isNew ? 'New' : ''} Bolus Saved'); } setState(() { _isSaving = false; }); } void handleCancelAction() { if (showConfirmationDialogOnCancel && ((_isNew && (_unitsController.text != '' || _carbsController.text != '' || _mgPerDlController.text != '' || _mmolPerLController.text != '' || _delayController.text != '' || _manuallyAdjusted || _notesController.text != '')) || (!_isNew && (double.tryParse(_unitsController.text) != _logBolus!.units || double.tryParse(_carbsController.text) != _logBolus!.carbs || int.tryParse(_mgPerDlController.text) != _logBolus!.mgPerDl || double.tryParse(_mmolPerLController.text) != _logBolus!.mmolPerL || int.tryParse(_delayController.text) != _logBolus!.delay || _manuallyAdjusted != _logBolus!.manuallyAdjusted || _notesController.text != (_logBolus!.notes ?? ''))))) { Dialogs.showCancelConfirmationDialog( context: context, isNew: _isNew, onSave: handleSaveAction, ); } else { Navigator.pop(context); } } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text(_isNew ? 'New Bolus' : 'Edit Bolus'), ), drawer: const Navigation(currentLocation: LogBolusDetailScreen.routeName), body: SingleChildScrollView( child: Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ FormWrapper( formState: _logBolusForm, fields: [ TextFormField( decoration: const InputDecoration( labelText: 'Bolus Units', suffixText: ' U', ), controller: _unitsController, keyboardType: const TextInputType.numberWithOptions(decimal: true), ), AutoCompleteDropdownButton( selectedItem: _meal, label: 'Meal', items: _logMeals, renderItem: (item) => item.value, onChanged: (value) { if (value != null) { onSelectMeal(value); } }, ), Expanded( child: TextFormField( decoration: InputDecoration( labelText: 'Carbs', suffixText: nutritionMeasurement == NutritionMeasurement.grams ? 'g' : nutritionMeasurement == NutritionMeasurement.ounces ? 'oz' : '', ), controller: _carbsController, keyboardType: const TextInputType.numberWithOptions( decimal: true), ), ), TextFormField( decoration: const InputDecoration( labelText: 'Delayed Bolus Duration', suffixText: ' min', ), controller: _delayController, keyboardType: const TextInputType.numberWithOptions(), ), TextFormField( controller: _notesController, decoration: const InputDecoration( labelText: 'Notes', alignLabelWithHint: true, ), keyboardType: TextInputType.multiline, ), ], ), ], ), ), bottomNavigationBar: DetailBottomRow( onCancel: handleCancelAction, onSave: _isSaving ? null : handleSaveAction, ), ); } }