import 'package:diameter/components/dialogs.dart'; import 'package:diameter/config.dart'; import 'package:diameter/settings.dart'; import 'package:diameter/utils/date_time_utils.dart'; import 'package:flutter/material.dart'; import 'package:diameter/components/progress_indicator.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; const BolusListScreen({Key? key, this.bolusProfile}) : super(key: key); @override _BolusListScreenState createState() => _BolusListScreenState(); } class _BolusListScreenState extends State { void refresh({String? message}) { setState(() { if (widget.bolusProfile != null) { widget.bolusProfile!.bolusRates = Bolus.fetchAllForBolusProfile(widget.bolusProfile!); } }); 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( bolusProfile: widget.bolusProfile!, bolus: bolus, ), ), ).then((message) => refresh(message: message)); } void onDelete(Bolus bolus) { bolus.delete().then((_) => refresh(message: 'Bolus Rate deleted')); } void handleDeleteAction(Bolus bolus) async { if (showConfirmationDialogOnDelete) { Dialogs.showConfirmationDialog( context: context, onConfirm: () => onDelete(bolus), message: 'Are you sure you want to delete this Bolus Rate?', ); } else { onDelete(bolus); } } String? validateTimePeriod(List bolusRates, int index) { Bolus bolus = bolusRates[index]; // check for gaps 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 void initState() { super.initState(); refresh(); } @override Widget build(BuildContext context) { return SingleChildScrollView( padding: const EdgeInsets.only(top: 10.0), child: Column( children: [ FutureBuilder>( future: widget.bolusProfile!.bolusRates, builder: (context, snapshot) { return ViewWithProgressIndicator( snapshot: snapshot, child: snapshot.data == null || snapshot.data!.isEmpty ? const Padding( padding: EdgeInsets.all(10.0), child: Text('No Basal Rates for this Profile'), ) : ListView.builder( shrinkWrap: true, itemCount: snapshot.data != null ? snapshot.data!.length : 0, itemBuilder: (context, index) { final bolus = snapshot.data![index]; final error = validateTimePeriod(snapshot.data!, index); return ListTile( isThreeLine: true, tileColor: error != null ? Colors.red.shade100 : null, onTap: () { handleEditAction(bolus); }, title: Text( '${DateTimeUtils.displayTime(bolus.startTime)} - ${DateTimeUtils.displayTime(bolus.endTime)}'), subtitle: Column( mainAxisSize: MainAxisSize.max, crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( '${bolus.units} U per ${bolus.carbs}${nutritionMeasurement == NutritionMeasurement.grams ? ' g' : ' oz'} carbs/${glucoseMeasurement == GlucoseMeasurement.mgPerDl ? bolus.mgPerDl : bolus.mmolPerL} ${glucoseMeasurement == GlucoseMeasurement.mgPerDl ? 'mg/dl' : 'mmol/l'}'), error != null ? Text(error, style: const TextStyle( color: Colors.red)) : const Text('') ]), trailing: Row( mainAxisSize: MainAxisSize.min, children: [ IconButton( icon: const Icon( Icons.delete, color: Colors.blue, ), onPressed: () => handleDeleteAction(bolus), ), ], ), ); }, ), ); }, ), ], ), ); } }