main
  1import 'package:blood_pressure_app/components/confirm_deletion_dialoge.dart';
  2import 'package:blood_pressure_app/data_util/consistent_future_builder.dart';
  3import 'package:blood_pressure_app/features/settings/add_medication_dialoge.dart';
  4import 'package:blood_pressure_app/model/storage/settings_store.dart';
  5import 'package:flutter/material.dart';
  6import 'package:flutter_bloc/flutter_bloc.dart';
  7import 'package:blood_pressure_app/l10n/app_localizations.dart';
  8import 'package:health_data_store/health_data_store.dart';
  9
 10/// Screen to view and edit medications saved in [Settings].
 11///
 12/// This screen allows adding and removing medication but not modifying them in
 13/// order to keep the code simple and maintainable.
 14class MedicineManagerScreen extends StatelessWidget {
 15  /// Create a screen to manage medications in settings.
 16  const MedicineManagerScreen({super.key});
 17
 18  Widget _buildMedicine(BuildContext context, Medicine med) => ListTile(
 19    leading: med.color == Colors.transparent.toARGB32()
 20        || med.color == null
 21        ? null
 22        : Container(
 23      width: 40.0,
 24      height: 40.0,
 25      decoration: BoxDecoration(
 26        color: Color(med.color!),
 27        shape: BoxShape.circle,
 28      ),
 29    ),
 30    title: Text(med.designation),
 31    subtitle: med.dosis == null ? null
 32        : Text('${AppLocalizations.of(context)!.defaultDosis}: '
 33        '${med.dosis!.mg} mg'),
 34    trailing: Row(
 35      mainAxisSize: MainAxisSize.min,
 36      children: [
 37        IconButton(
 38          icon: const Icon(Icons.edit),
 39          onPressed: () async {
 40            final medRepo = RepositoryProvider.of<MedicineRepository>(context);
 41            final newMed = await showAddMedicineDialoge(context,
 42                initialValue: med);
 43            if (newMed != null) {
 44              // We can not edit the med directly since this could skew old
 45              // entries. Marking a medicine as removed just hides it from the
 46              // selection list, while editing it would alter old the default
 47              // dosis of old records.
 48              await medRepo.remove(med);
 49              await medRepo.add(newMed);
 50            }
 51          },
 52        ),
 53        IconButton(
 54          icon: const Icon(Icons.delete),
 55          onPressed: () async {
 56            if (await showConfirmDeletionDialoge(context) && context.mounted) {
 57              await RepositoryProvider.of<MedicineRepository>(context).remove(med);
 58            }
 59          },
 60        ),
 61      ],
 62    ),
 63  );
 64
 65  Widget _buildAddMed(BuildContext context) => ListTile(
 66    leading: const Icon(Icons.add),
 67    title: Text(AppLocalizations.of(context)!.addMedication),
 68    onTap: () async {
 69      final medRepo = RepositoryProvider.of<MedicineRepository>(context);
 70      final medicine = await showAddMedicineDialoge(context);
 71      if (medicine != null) {
 72        await medRepo.add(medicine);
 73      }
 74    },
 75  );
 76
 77 @override
 78  Widget build(BuildContext context) => Scaffold(
 79    appBar: AppBar(
 80      forceMaterialTransparency: true,
 81    ),
 82    body: Center(
 83      child: StreamBuilder(
 84        stream: RepositoryProvider.of<MedicineRepository>(context).subscribe(),
 85        builder: (context, _) => ConsistentFutureBuilder(
 86          future: RepositoryProvider.of<MedicineRepository>(context).getAll(),
 87          onData: (context, medicines) => ListView.builder(
 88            itemCount: medicines.length + 1,
 89            itemBuilder: (context, i) {
 90              if (i == medicines.length) { // last row
 91                return _buildAddMed(context);
 92              }
 93              return _buildMedicine(context, medicines[i]);
 94            },
 95          ),
 96        ),
 97      ),
 98    ),
 99  );
100}