import 'package:diameter/components/dialogs.dart'; import 'package:diameter/models/settings.dart'; import 'package:diameter/utils/date_time_utils.dart'; import 'package:flutter/material.dart'; import 'package:diameter/models/bolus.dart'; import 'package:diameter/models/bolus_profile.dart'; import 'package:diameter/screens/bolus/bolus_detail.dart'; class BolusListScreen extends StatefulWidget { final BolusProfile bolusProfile; final List bolusRates; final Function() reload; const BolusListScreen( {Key? key, required this.bolusProfile, this.bolusRates = const [], required this.reload}) : super(key: key); @override _BolusListScreenState createState() => _BolusListScreenState(); } class _BolusListScreenState extends State { final ScrollController _scrollController = ScrollController(); void reload({String? message}) { widget.reload(); setState(() { if (message != null) { var snackBar = SnackBar( content: Text(message), duration: const Duration(seconds: 2), ); ScaffoldMessenger.of(context) ..removeCurrentSnackBar() ..showSnackBar(snackBar); } }); } void handleEditAction(Bolus bolus) { Navigator.push( context, MaterialPageRoute( builder: (context) => BolusDetailScreen( bolusProfileId: widget.bolusProfile.id, id: bolus.id, ), ), ).then((result) => reload(message: result?[0])); } void onDelete(Bolus bolus) { Bolus.remove(bolus.id); reload(message: 'Bolus Rate deleted'); } void handleDeleteAction(Bolus bolus) async { if (Settings.get().showConfirmationDialogOnDelete) { Dialogs.showConfirmationDialog( context: context, onConfirm: () => onDelete(bolus), message: 'Are you sure you want to delete this Bolus Rate?', ); } else { onDelete(bolus); } } String? validateTimePeriod(int index) { List bolusRates = widget.bolusRates; Bolus bolus = bolusRates[index]; if (index == 0 && (bolus.startTime.toLocal().hour != 0 || bolus.startTime.minute != 0)) { return 'First Bolus of the day needs to start at 00:00'; } if (index > 0) { var lastEndTime = bolusRates[index - 1].endTime; if (bolus.startTime.isAfter(lastEndTime)) { return 'There\'s a time gap between this and the previous rate'; } } if (index == bolusRates.length - 1 && (bolus.endTime.toLocal().hour != 0 || bolus.endTime.minute != 0)) { return 'Last Bolus of the day needs to end at 00:00'; } // check for duplicates if (bolusRates .where((other) => bolus != other && bolus.startTime == other.startTime) .isNotEmpty) { return 'There are multiple rates with this start time'; } if (bolusRates .where((other) => bolus.startTime.isBefore(other.startTime) && bolus.endTime.isAfter(other.startTime)) .isNotEmpty) { return 'This rate\'s time period overlaps with another one'; } } @override Widget build(BuildContext context) { return widget.bolusRates.isNotEmpty ? Scrollbar( controller: _scrollController, child: ListView.builder( padding: const EdgeInsets.all(10.0), controller: _scrollController, shrinkWrap: true, itemCount: widget.bolusRates.length, itemBuilder: (context, index) { final bolus = widget.bolusRates[index]; final error = validateTimePeriod(index); return Card( child: Column( children: [ error != null ? Padding( padding: const EdgeInsets.all(5.0), child: Row( mainAxisAlignment: MainAxisAlignment.center, children: [ Icon(Icons.warning, color: Theme.of(context).errorColor), Text( error, style: TextStyle(color: Theme.of(context).errorColor) ), ], ), ) : Container(), ListTile( onTap: () { handleEditAction(bolus); }, isThreeLine: true, title: Text('${DateTimeUtils.displayTime(bolus.startTime)} - ${DateTimeUtils.displayTime(bolus.endTime)}'), subtitle: Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ Expanded( child: Column( children: (bolus.units > 0 && bolus.carbs > 0) ? [ Text((bolus.carbs / bolus.units).toStringAsPrecision(2)), Text('${Settings.nutritionMeasurementSuffix} carbs per U', textAlign: TextAlign.center, textScaleFactor: 0.75), ] : [], ), ), Expanded( child: Column( children: (bolus.units > 0 && bolus.carbs > 0) ? [ Text((bolus.units / bolus.carbs * 12).toStringAsPrecision(2)), const Text('U per bread unit', textAlign: TextAlign.center, textScaleFactor: 0.75), ] : [], ), ), Expanded( child: Column( children: (bolus.units > 0 && (bolus.mgPerDl ?? bolus.mmolPerL ?? 0) > 0) ? [ Text((((Settings.glucoseMeasurement == GlucoseMeasurement.mgPerDl ? bolus.mgPerDl : bolus.mmolPerL ?? 0)! / bolus.units)).toString()), Text('${Settings.glucoseMeasurementSuffix} per unit', textAlign: TextAlign.center, textScaleFactor: 0.75), ] : [], ), ), ], ), trailing: Row( mainAxisSize: MainAxisSize.min, children: [ IconButton( icon: const Icon( Icons.delete, color: Colors.blue, ), onPressed: () => handleDeleteAction(bolus), ), ], ), ), ], ), ); }, ), ) : const Center( child: Text('You have not created any Bolus Rates yet!'), ); } }