import 'package:diameter/utils/dialog_utils.dart'; import 'package:diameter/components/forms/auto_complete_dropdown_button.dart'; import 'package:diameter/models/basal.dart'; import 'package:diameter/models/settings.dart'; import 'package:diameter/navigation.dart'; import 'package:flutter/material.dart'; import 'package:diameter/models/basal_profile.dart'; import 'package:diameter/screens/basal/basal_profile_detail.dart'; class BasalProfileListScreen extends StatefulWidget { static const String routeName = '/basal-profiles'; const BasalProfileListScreen({Key? key}) : super(key: key); @override _BasalProfileListScreenState createState() => _BasalProfileListScreenState(); } class _BasalProfileListScreenState extends State { final ScrollController _scrollController = ScrollController(); late List _basalProfiles; Widget banner = Container(); final BasalProfile? _activeProfile = BasalProfile.getActive(DateTime.now()); @override void initState() { super.initState(); reload(); } @override void dispose() { _scrollController.dispose(); super.dispose(); } void reload({String? message}) { setState(() { _basalProfiles = BasalProfile.getAll(); }); updateBanner(); setState(() { if (message != null) { var snackBar = SnackBar( content: Text(message), duration: const Duration(seconds: 2), ); ScaffoldMessenger.of(context) ..removeCurrentSnackBar() ..showSnackBar(snackBar); } }); } void updateBanner() { int activeProfileCount = BasalProfile.activeCount(); setState(() { banner = activeProfileCount != 1 ? MaterialBanner( content: Text(activeProfileCount == 0 ? 'You currently do not have an active Basal Profile.' : 'More than one active Basal Profile has been found.'), leading: const CircleAvatar(child: Icon(Icons.warning)), forceActionsBelow: true, actions: activeProfileCount == 0 ? [ _basalProfiles.isNotEmpty ? TextButton( child: const Text('ACTIVATE A PROFILE'), onPressed: handlePickActiveProfileAction, ) : Container(), TextButton( child: const Text('CREATE A NEW PROFILE'), onPressed: () => onNew(true), ), ] : [ TextButton( child: const Text('PICK A PROFILE'), onPressed: handlePickActiveProfileAction, ), ], ) : Container(); }); } void handleDuplicateAction(BasalProfile basalProfile) async { final copy = BasalProfile( active: false, name: 'Copy of ${basalProfile.name}', ); BasalProfile.put(copy); final rates = Basal.getAllForProfile(basalProfile.id); for (Basal rate in rates) { final basal = Basal( endTime: rate.endTime, startTime: rate.startTime, units: rate.units, ); basal.basalProfile.target = copy; Basal.put(basal); } reload(message: 'Added copy of ${basalProfile.name}'); } void onDelete(BasalProfile basalProfile) { BasalProfile.remove(basalProfile.id); reload(message: 'Basal Profile deleted'); } void handleDeleteAction(BasalProfile basalProfile) async { if (Settings.get().showConfirmationDialogOnDelete) { DialogUtils.showConfirmationDialog( context: context, onConfirm: () => onDelete(basalProfile), message: 'Are you sure you want to delete this Basal Profile?', ); } else { onDelete(basalProfile); } } void onPickActive(BasalProfile? basalProfile) { if (basalProfile != null) { BasalProfile.setAllInactive; basalProfile.active = true; BasalProfile.put(basalProfile); reload( message: '${basalProfile.name} has been set as your active Profile'); } } void handlePickActiveProfileAction() { setState(() { banner = MaterialBanner( content: AutoCompleteDropdownButton( controller: TextEditingController(text: ''), items: _basalProfiles, label: 'Default Basal Profile', onChanged: onPickActive, ), leading: const CircleAvatar(child: Icon(Icons.info)), forceActionsBelow: true, actions: [ TextButton( child: const Text('CREATE A NEW PROFILE INSTEAD'), onPressed: () => onNew(true), ), ], ); }); } void showDetailScreen({BasalProfile? basalProfile, bool active = false}) { Navigator.push( context, MaterialPageRoute( builder: (context) => BasalProfileDetailScreen(id: basalProfile?.id ?? 0, active: active), ), ).then((result) => reload(message: result?[0])); } void onNew(bool active) { showDetailScreen(active: active); } void onEdit(BasalProfile basalProfile) { showDetailScreen(basalProfile: basalProfile); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text('Basal Profiles'), actions: [ IconButton(onPressed: reload, icon: const Icon(Icons.refresh)) ], ), drawer: const Navigation(currentLocation: BasalProfileListScreen.routeName), body: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ banner, Expanded( child: _basalProfiles.isNotEmpty ? Scrollbar( controller: _scrollController, child: ListView.builder( padding: const EdgeInsets.all(10.0), controller: _scrollController, itemCount: _basalProfiles.length, itemBuilder: (context, index) { final basalProfile = _basalProfiles[index]; double dailyTotal = Basal.getDailyTotalForProfile(basalProfile.id); String activeProfileText = basalProfile.active ? ' (Default Profile)' : basalProfile.id == _activeProfile?.id ? ' (Current Active Profile)' : ''; return Card( child: ListTile( isThreeLine: true, selected: basalProfile.active || basalProfile.id == _activeProfile?.id, onTap: () => onEdit(basalProfile), title: Text( basalProfile.name.toUpperCase() + activeProfileText, style: Theme.of(context).textTheme.subtitle2, ), subtitle: Padding( padding: const EdgeInsets.only(top: 10.0), child: Row( children: [ Text(basalProfile.notes ?? ''), Expanded( child: Column( children: dailyTotal > 0 ? [ Text(dailyTotal .toStringAsPrecision(3)), const Text('U/day', textScaleFactor: 0.75), ] : [], ), ), ], ), ), trailing: Row( mainAxisSize: MainAxisSize.min, children: [ IconButton( icon: const Icon( Icons.copy, color: Colors.blue, ), onPressed: () => handleDuplicateAction(basalProfile), ), IconButton( icon: const Icon( Icons.delete, color: Colors.blue, ), onPressed: () => handleDeleteAction(basalProfile), ), ], ), ), ); }, ), ) : const Center( child: Text('You have not created any Basal Profiles yet!'), ), ), ], ), floatingActionButton: FloatingActionButton( onPressed: () => onNew(false), child: const Icon(Icons.add), ), ); } }