Commit 7a2262d

derdilla <82763757+NobodyForNothing@users.noreply.github.com>
2023-12-28 16:32:45
complete medicine manager
Signed-off-by: derdilla <82763757+NobodyForNothing@users.noreply.github.com>
1 parent 30f8a99
lib/components/dialoges/add_measurement_dialoge.dart
@@ -3,6 +3,7 @@ import 'dart:math';
 import 'package:blood_pressure_app/components/date_time_picker.dart';
 import 'package:blood_pressure_app/components/dialoges/fullscreen_dialoge.dart';
 import 'package:blood_pressure_app/components/settings/settings_widgets.dart';
+import 'package:blood_pressure_app/model/blood_pressure/medicine/medicine_intake.dart';
 import 'package:blood_pressure_app/model/blood_pressure/needle_pin.dart';
 import 'package:blood_pressure_app/model/blood_pressure/record.dart';
 import 'package:blood_pressure_app/model/storage/storage.dart';
@@ -12,11 +13,11 @@ import 'package:flutter_gen/gen_l10n/app_localizations.dart';
 import 'package:intl/intl.dart';
 
 /// Input mask for entering measurements.
-class AddMeasurementDialoge extends StatefulWidget {
+class AddEntryDialoge extends StatefulWidget {
   /// Create a input mask for entering measurements.
   /// 
-  /// This is usually created through the [showAddMeasurementDialoge] function.
-  const AddMeasurementDialoge({super.key,
+  /// This is usually created through the [showAddEntryDialoge] function.
+  const AddEntryDialoge({super.key,
     required this.settings,
     this.initialRecord,
   });
@@ -30,10 +31,10 @@ class AddMeasurementDialoge extends StatefulWidget {
   final BloodPressureRecord? initialRecord;
 
   @override
-  State<AddMeasurementDialoge> createState() => _AddMeasurementDialogeState();
+  State<AddEntryDialoge> createState() => _AddEntryDialogeState();
 }
 
-class _AddMeasurementDialogeState extends State<AddMeasurementDialoge> {
+class _AddEntryDialogeState extends State<AddEntryDialoge> {
   final formKey = GlobalKey<FormState>();
   final sysFocusNode = FocusNode();
   final diaFocusNode = FocusNode();
@@ -59,6 +60,15 @@ class _AddMeasurementDialogeState extends State<AddMeasurementDialoge> {
 
   /// Last [FormState.save]d note.
   String? notes;
+  
+  /// Index of the medicine intake that can me entered here.
+  int? medicineId;
+
+  /// Whether to show the medication dosis input
+  bool _showMedicineDosisInput = false;
+
+  /// Entered dosis of medication.
+  double? medicineDosis;
 
   @override
   void initState() {
@@ -99,13 +109,7 @@ class _AddMeasurementDialogeState extends State<AddMeasurementDialoge> {
     ListTile(
       title: Text(DateFormat(widget.settings.dateFormatString).format(time)),
       trailing: const Icon(Icons.edit),
-      shape: RoundedRectangleBorder(
-          side: BorderSide(
-              width: 2,
-              color: Theme.of(context).primaryColor
-          ),
-          borderRadius: BorderRadius.circular(20)
-      ),
+      shape: buildListTileBorder(),
       onTap: () async {
         final messenger = ScaffoldMessenger.of(context);
         var selectedTime = await showDateTimePicker(
@@ -156,6 +160,11 @@ class _AddMeasurementDialogeState extends State<AddMeasurementDialoge> {
           }
         },
         validator: (String? value) {
+          // Indicates that only a medicine intake is wanted.
+          if (_showMedicineDosisInput && medicineDosis != null &&
+              medicineId != null && systolic == null && diastolic == null &&
+              pulse == null && notes == null && needlePin == null) return null;
+
           if (!widget.settings.allowMissingValues && (value == null || value.isEmpty || int.tryParse(value) == null)) {
             return localizations.errNaN;
           } else if (widget.settings.validateInputs && (int.tryParse(value ?? '') ?? -1) <= 30) {
@@ -188,6 +197,14 @@ class _AddMeasurementDialogeState extends State<AddMeasurementDialoge> {
     );
   }
 
+  RoundedRectangleBorder buildListTileBorder([Color? color]) => RoundedRectangleBorder(
+    side: BorderSide(
+      width: 2,
+      color: color ?? Theme.of(context).primaryColor
+    ),
+    borderRadius: BorderRadius.circular(20)
+  );
+
   @override
   Widget build(BuildContext context) {
     final localizations = AppLocalizations.of(context)!;
@@ -195,8 +212,21 @@ class _AddMeasurementDialogeState extends State<AddMeasurementDialoge> {
       onActionButtonPressed: () {
         if (formKey.currentState?.validate() ?? false) {
           formKey.currentState?.save();
-          final record = BloodPressureRecord(time, systolic, diastolic, pulse, notes ?? '', needlePin: needlePin);
-          Navigator.of(context).pop(record);
+          MedicineIntake? intake;
+          if (_showMedicineDosisInput && medicineDosis != null && medicineId != null) {
+            intake = MedicineIntake(
+              timestamp: time,
+              medicine: widget.settings.medications.where((e) => e.id == medicineId).first,
+              dosis: medicineDosis!,
+            );
+          }
+          BloodPressureRecord? record;
+          if (systolic != null && diastolic != null && pulse != null
+              && notes != null && needlePin != null) {
+            record = BloodPressureRecord(time, systolic, diastolic, pulse, notes ?? '', needlePin: needlePin);
+          }
+
+          Navigator.of(context).pop((record, intake));
         }
       },
       actionButtonText: localizations.btnSave,
@@ -248,6 +278,7 @@ class _AddMeasurementDialogeState extends State<AddMeasurementDialoge> {
                 decoration: getInputDecoration(localizations.addNote),
                 minLines: 1,
                 //maxLines: 4, There is a bug in the flutter framework: https://github.com/flutter/flutter/issues/138219
+                // TODO Material.of(context).markNeedsPaint()
                 onSaved: (value) => setState(() => notes = value),
               ),
             ),
@@ -259,14 +290,78 @@ class _AddMeasurementDialogeState extends State<AddMeasurementDialoge> {
                 });
               },
               initialColor: needlePin?.color ?? Colors.transparent,
-              shape: RoundedRectangleBorder(
-                  side: BorderSide(
-                      width: 2,
-                      color: needlePin?.color ?? Theme.of(context).primaryColor
-                  ),
-                  borderRadius: BorderRadius.circular(20)
-              )
+              shape: buildListTileBorder(needlePin?.color)
             ),
+            if (widget.settings.medications.isNotEmpty)
+              Padding(
+                padding: const EdgeInsets.symmetric(vertical: 16),
+                child: Row(
+                  children: [
+                    Expanded(
+                      child: ListTile(
+                        shape: buildListTileBorder(),
+                        title: DropdownButton( // TODO medicine intake
+                          isExpanded: true,
+                          value: widget.settings.medications
+                              .where((e) => e.id == medicineId).firstOrNull,
+                          underline: const SizedBox.shrink(),
+                          items: [
+                            for (final e in widget.settings.medications)
+                              DropdownMenuItem(
+                                value: e,
+                                child: Text(e.designation),
+                              ),
+                            DropdownMenuItem(
+                              value: null,
+                              child: Text(localizations.noMedication),
+                            )
+                          ],
+                          onChanged: (v) {
+                            setState(() {
+                              if (v != null) {
+                                _showMedicineDosisInput = true;
+                                medicineId = v.id;
+                                medicineDosis = v.defaultDosis;
+                              } else {
+                                _showMedicineDosisInput = false;
+                                medicineId = null;
+                              }
+                              Material.of(context).markNeedsPaint();
+                            });
+                            // TODO
+                          }
+                        ),
+                      ),
+                    ),
+                    if (_showMedicineDosisInput)
+                      const SizedBox(width: 16,),
+                    if (_showMedicineDosisInput)
+                      Expanded(
+                        child: TextFormField(
+                          initialValue: medicineDosis?.toString(),
+                          decoration: getInputDecoration(localizations.dosis),
+                          keyboardType: TextInputType.number,
+                          onSaved: (value) => setState(() {
+                            final dosis = int.tryParse(value ?? '')?.toDouble()
+                                ?? double.tryParse(value ?? '');
+                            if(dosis != null && dosis > 0) medicineDosis = dosis;
+                          }),
+                          inputFormatters: [FilteringTextInputFormatter.allow(
+                              RegExp(r'([0-9]+(\.([0-9]*))?)'))],
+                          validator: (String? value) {
+                            if (!_showMedicineDosisInput) return null;
+                            if (((int.tryParse(value ?? '')?.toDouble()
+                                ?? double.tryParse(value ?? '')) ?? 0) <= 0) {
+                              return localizations.errNaN;
+                            }
+                            return null;
+                          },
+                        ),
+                      ),
+
+                  ],
+                ),
+              ),
           ],
         ),
       ),
@@ -275,7 +370,16 @@ class _AddMeasurementDialogeState extends State<AddMeasurementDialoge> {
 }
 
 /// Shows a dialoge to input a blood pressure measurement.
-Future<BloodPressureRecord?> showAddMeasurementDialoge(BuildContext context, Settings settings, [BloodPressureRecord? initialRecord]) =>
-  showDialog<BloodPressureRecord?>(context: context, builder: (context) => Dialog.fullscreen(
-    child: AddMeasurementDialoge(settings: settings, initialRecord: initialRecord,),
-  ));
\ No newline at end of file
+Future<(BloodPressureRecord?, MedicineIntake?)?> showAddEntryDialoge(
+    BuildContext context,
+    Settings settings,
+    [BloodPressureRecord? initialRecord]) =>
+  showDialog<(BloodPressureRecord?, MedicineIntake?)>(
+      context: context, builder: (context) =>
+      Dialog.fullscreen(
+        child: AddEntryDialoge(
+          settings: settings,
+          initialRecord: initialRecord
+        ),
+      )
+  );
\ No newline at end of file
lib/components/measurement_list/measurement_list_entry.dart
@@ -32,15 +32,18 @@ class MeasurementListRow extends StatelessWidget {
             children: [
               IconButton(
                 onPressed: () async {
-                  final future = showAddMeasurementDialoge(context, settings, record);
                   final model = Provider.of<BloodPressureModel>(context, listen: false);
-                  final measurement = await future;
-                  if (measurement == null) return;
-                  if (context.mounted) {
-                    model.addAndExport(context, measurement);
-                  } else {
-                    model.add(measurement);
-                    assert(false, 'context not mounted');
+                  final entry = await showAddEntryDialoge(context,
+                      Provider.of<Settings>(context, listen: false));
+                  if (entry?.$1 != null) {
+                    if (context.mounted) {
+                      model.addAndExport(context, entry!.$1!);
+                    } else {
+                      model.add(entry!.$1!);
+                    }
+                  }
+                  if (entry?.$2 != null) {
+                    // TODO: save medicine intake
                   }
                 },
                 icon: const Icon(Icons.edit),
lib/l10n/app_en.arb
@@ -496,5 +496,9 @@
   "name": "Name",
   "@name": {},
   "defaultDosis": "default dosis",
-  "@defaultDosis": {}
+  "@defaultDosis": {},
+  "noMedication": "No medication",
+  "@noMedication": {},
+  "dosis": "Dosis",
+  "@dosis": {}
 }
lib/screens/elements/legacy_measurement_list.dart
@@ -83,14 +83,18 @@ class LegacyMeasurementsList extends StatelessWidget {
                             confirmDismiss: (direction) async {
                               final model = Provider.of<BloodPressureModel>(context, listen: false);
                               if (direction == DismissDirection.startToEnd) { // edit
-                                final future = showAddMeasurementDialoge(context, settings, data[index]);
                                 final model = Provider.of<BloodPressureModel>(context, listen: false);
-                                final measurement = await future;
-                                if (measurement == null) return false;
-                                if (context.mounted) {
-                                  model.addAndExport(context, measurement);
-                                } else {
-                                  model.add(measurement);
+                                final entry = await showAddEntryDialoge(context,
+                                    Provider.of<Settings>(context, listen: false));
+                                if (entry?.$1 != null) {
+                                  if (context.mounted) {
+                                    model.addAndExport(context, entry!.$1!);
+                                  } else {
+                                    model.add(entry!.$1!);
+                                  }
+                                }
+                                if (entry?.$2 != null) {
+                                  // TODO: save medicine intake
                                 }
                                 return false;
                               } else { // delete
lib/screens/home_screen.dart
@@ -28,14 +28,18 @@ class AppHome extends StatelessWidget {
     if (_appStart) {
       if (Provider.of<Settings>(context, listen: false).startWithAddMeasurementPage) {
         SchedulerBinding.instance.addPostFrameCallback((_) async {
-          final future = showAddMeasurementDialoge(context, Provider.of<Settings>(context, listen: false));
           final model = Provider.of<BloodPressureModel>(context, listen: false);
-          final measurement = await future;
+          final measurement = await showAddEntryDialoge(context, Provider.of<Settings>(context, listen: false));
           if (measurement == null) return;
-          if (context.mounted) {
-            model.addAndExport(context, measurement);
-          } else {
-            model.add(measurement);
+          if (measurement.$1 != null) {
+            if (context.mounted) {
+              model.addAndExport(context, measurement.$1!);
+            } else {
+              model.add(measurement.$1!);
+            }
+          }
+          if (measurement.$2 != null) {
+            // TODO: save medicine intake
           }
         });
       }
@@ -94,14 +98,18 @@ class AppHome extends StatelessWidget {
                       tooltip: localizations.addMeasurement,
                       autofocus: true,
                       onPressed: () async {
-                        final future = showAddMeasurementDialoge(context, settings);
                         final model = Provider.of<BloodPressureModel>(context, listen: false);
-                        final measurement = await future;
+                        final measurement = await showAddEntryDialoge(context, Provider.of<Settings>(context, listen: false));
                         if (measurement == null) return;
-                        if (context.mounted) {
-                          model.addAndExport(context, measurement);
-                        } else {
-                          model.add(measurement);
+                        if (measurement.$1 != null) {
+                          if (context.mounted) {
+                            model.addAndExport(context, measurement.$1!);
+                          } else {
+                            model.add(measurement.$1!);
+                          }
+                        }
+                        if (measurement.$2 != null) {
+                          // TODO: save medicine intake
                         }
                       },
                       child: const Icon(Icons.add,),
test/ui/components/add_measurement_dialoge_test.dart
@@ -13,10 +13,10 @@ import 'settings/color_picker_list_tile_test.dart';
 import 'util.dart';
 
 void main() {
-  group('AddMeasurementDialoge', () {
+  group('AddEntryDialoge', () {
     testWidgets('should show everything on initial page', (widgetTester) async {
       await widgetTester.pumpWidget(materialApp(
-        AddMeasurementDialoge(
+        AddEntryDialoge(
           settings: Settings(),
         )
       ));
@@ -30,7 +30,7 @@ void main() {
     });
     testWidgets('should prefill initialRecord values', (widgetTester) async {
       await widgetTester.pumpWidget(materialApp(
-          AddMeasurementDialoge(
+          AddEntryDialoge(
             settings: Settings(),
             initialRecord: BloodPressureRecord(
               DateTime.now(), 123, 56, 43, 'Test note',
@@ -50,32 +50,32 @@ void main() {
       having((p0) => p0.initialColor, 'ColorSelectionListTile should have correct initial color', Colors.teal));
     });
   });
-  group('showAddMeasurementDialoge', () {
+  group('showAddEntryDialoge', () {
     testWidgets('should return null on cancel', (widgetTester) async {
       dynamic result = 'not null';
       await loadDialoge(widgetTester, (context) async
-        => result = await showAddMeasurementDialoge(context, Settings(),
+        => result = await showAddEntryDialoge(context, Settings(),
           mockRecord(sys: 123, dia: 56, pul: 43, note: 'Test note', pin: Colors.teal)));
 
-      expect(find.byType(AddMeasurementDialoge), findsOneWidget);
+      expect(find.byType(AddEntryDialoge), findsOneWidget);
       await widgetTester.tap(find.byIcon(Icons.close));
       await widgetTester.pumpAndSettle();
-      expect(find.byType(AddMeasurementDialoge), findsNothing);
+      expect(find.byType(AddEntryDialoge), findsNothing);
 
       expect(result, null);
     });
-    testWidgets('should return values on cancel', (widgetTester) async {
+    testWidgets('should return values on edit cancel', (widgetTester) async {
       dynamic result = 'not null';
       final record = mockRecord(sys: 123, dia: 56, pul: 43, note: 'Test note', pin: Colors.teal);
       await loadDialoge(widgetTester, (context) async
-        => result = await showAddMeasurementDialoge(context, Settings(), record));
+        => result = await showAddEntryDialoge(context, Settings(), record));
 
-      expect(find.byType(AddMeasurementDialoge), findsOneWidget);
+      expect(find.byType(AddEntryDialoge), findsOneWidget);
       await widgetTester.tap(find.text('SAVE'));
       await widgetTester.pumpAndSettle();
-      expect(find.byType(AddMeasurementDialoge), findsNothing);
+      expect(find.byType(AddEntryDialoge), findsNothing);
 
-      expect(result, isA<BloodPressureRecord>().having(
+      expect(result?.$1, isA<BloodPressureRecord>().having(
               (p0) => (p0.creationTime, p0.systolic, p0.diastolic, p0.pulse, p0.notes, p0.needlePin!.color),
           'should return initial values as they were not modified',
           (record.creationTime, record.systolic, record.diastolic, record.pulse, record.notes, record.needlePin!.color)));
@@ -83,7 +83,7 @@ void main() {
     testWidgets('should be able to input values', (WidgetTester widgetTester) async {
       dynamic result = 'not null';
       await loadDialoge(widgetTester, (context) async
-        => result = await showAddMeasurementDialoge(context, Settings()));
+        => result = await showAddEntryDialoge(context, Settings()));
 
       await widgetTester.enterText(find.ancestor(of: find.text('Systolic').first, matching: find.byType(TextFormField)), '123');
       await widgetTester.enterText(find.ancestor(of: find.text('Diastolic').first, matching: find.byType(TextFormField)), '67');
@@ -99,19 +99,19 @@ void main() {
       await widgetTester.tap(find.text('SAVE'));
       await widgetTester.pumpAndSettle();
 
-      expect(result, isA<BloodPressureRecord>());
-      BloodPressureRecord castResult = result;
-      expect(castResult.systolic, 123);
-      expect(castResult.diastolic, 67);
-      expect(castResult.pulse, 89);
-      expect(castResult.notes, 'Test note');
-      expect(castResult.needlePin?.color, Colors.red);
+      expect(result?.$1, isA<BloodPressureRecord>()
+        .having((p0) => p0.systolic, 'systolic', 123)
+        .having((p0) => p0.diastolic, 'diastolic', 67)
+        .having((p0) => p0.pulse, 'pulse', 89)
+        .having((p0) => p0.notes, 'notes', 'Test note')
+        .having((p0) => p0.needlePin?.color, 'needlePin', Colors.red)
+      );
     });
     testWidgets('should not allow invalid values', (widgetTester) async {
-      await loadDialoge(widgetTester, (context) => showAddMeasurementDialoge(context, Settings()));
+      await loadDialoge(widgetTester, (context) => showAddEntryDialoge(context, Settings()));
       final localizations = await AppLocalizations.delegate.load(const Locale('en'));
 
-      expect(find.byType(AddMeasurementDialoge), findsOneWidget);
+      expect(find.byType(AddEntryDialoge), findsOneWidget);
       expect(find.text(localizations.errNaN), findsNothing);
       expect(find.text(localizations.errLt30), findsNothing);
       expect(find.text(localizations.errUnrealistic), findsNothing);
@@ -122,7 +122,7 @@ void main() {
 
       await widgetTester.tap(find.text('SAVE'));
       await widgetTester.pumpAndSettle();
-      expect(find.byType(AddMeasurementDialoge), findsOneWidget);
+      expect(find.byType(AddEntryDialoge), findsOneWidget);
       expect(find.text(localizations.errNaN), findsOneWidget);
       expect(find.text(localizations.errLt30), findsNothing);
       expect(find.text(localizations.errUnrealistic), findsNothing);
@@ -131,7 +131,7 @@ void main() {
       await widgetTester.enterText(find.ancestor(of: find.text('Pulse').first, matching: find.byType(TextFormField)), '20');
       await widgetTester.tap(find.text('SAVE'));
       await widgetTester.pumpAndSettle();
-      expect(find.byType(AddMeasurementDialoge), findsOneWidget);
+      expect(find.byType(AddEntryDialoge), findsOneWidget);
       expect(find.text(localizations.errNaN), findsNothing);
       expect(find.text(localizations.errLt30), findsOneWidget);
       expect(find.text(localizations.errUnrealistic), findsNothing);
@@ -141,7 +141,7 @@ void main() {
       await widgetTester.enterText(find.ancestor(of: find.text('Diastolic').first, matching: find.byType(TextFormField)), '500');
       await widgetTester.tap(find.text('SAVE'));
       await widgetTester.pumpAndSettle();
-      expect(find.byType(AddMeasurementDialoge), findsOneWidget);
+      expect(find.byType(AddEntryDialoge), findsOneWidget);
       expect(find.text(localizations.errNaN), findsNothing);
       expect(find.text(localizations.errLt30), findsNothing);
       expect(find.text(localizations.errUnrealistic), findsOneWidget);
@@ -151,7 +151,7 @@ void main() {
       await widgetTester.enterText(find.ancestor(of: find.text('Systolic').first, matching: find.byType(TextFormField)), '90');
       await widgetTester.tap(find.text('SAVE'));
       await widgetTester.pumpAndSettle();
-      expect(find.byType(AddMeasurementDialoge), findsOneWidget);
+      expect(find.byType(AddEntryDialoge), findsOneWidget);
       expect(find.text(localizations.errNaN), findsNothing);
       expect(find.text(localizations.errLt30), findsNothing);
       expect(find.text(localizations.errUnrealistic), findsNothing);
@@ -162,7 +162,7 @@ void main() {
       await widgetTester.enterText(find.ancestor(of: find.text('Systolic').first, matching: find.byType(TextFormField)), '123');
       await widgetTester.tap(find.text('SAVE'));
       await widgetTester.pumpAndSettle();
-      expect(find.byType(AddMeasurementDialoge), findsNothing);
+      expect(find.byType(AddEntryDialoge), findsNothing);
       expect(find.text(localizations.errNaN), findsNothing);
       expect(find.text(localizations.errLt30), findsNothing);
       expect(find.text(localizations.errUnrealistic), findsNothing);
@@ -170,23 +170,23 @@ void main() {
     });
     testWidgets('should allow invalid values when setting is set', (widgetTester) async {
       await loadDialoge(widgetTester, (context) =>
-          showAddMeasurementDialoge(context, Settings(validateInputs: false, allowMissingValues: true)));
+          showAddEntryDialoge(context, Settings(validateInputs: false, allowMissingValues: true)));
 
       await widgetTester.enterText(find.ancestor(of: find.text('Systolic').first, matching: find.byType(TextFormField)), '2');
       await widgetTester.enterText(find.ancestor(of: find.text('Diastolic').first, matching: find.byType(TextFormField)), '500');
       await widgetTester.tap(find.text('SAVE'));
       await widgetTester.pumpAndSettle();
-      expect(find.byType(AddMeasurementDialoge), findsNothing);
+      expect(find.byType(AddEntryDialoge), findsNothing);
     });
     testWidgets('should respect settings.allowManualTimeInput', (widgetTester) async {
       await loadDialoge(widgetTester, (context) =>
-          showAddMeasurementDialoge(context, Settings(allowManualTimeInput: false)));
+          showAddEntryDialoge(context, Settings(allowManualTimeInput: false)));
 
       expect(find.byIcon(Icons.edit), findsNothing);
     });
     testWidgets('should start with sys input focused', (widgetTester) async {
       await loadDialoge(widgetTester, (context) =>
-          showAddMeasurementDialoge(context, Settings(), mockRecord(sys: 12)));
+          showAddEntryDialoge(context, Settings(), mockRecord(sys: 12)));
 
       final primaryFocus = FocusManager.instance.primaryFocus;
       expect(primaryFocus?.context?.widget, isNotNull);
@@ -200,7 +200,7 @@ void main() {
     });
     testWidgets('should focus next on input finished', (widgetTester) async {
       await loadDialoge(widgetTester, (context) =>
-          showAddMeasurementDialoge(context, Settings(), mockRecord(sys: 12, dia: 3, pul: 4, note: 'note')));
+          showAddEntryDialoge(context, Settings(), mockRecord(sys: 12, dia: 3, pul: 4, note: 'note')));
 
       await widgetTester.enterText(find.ancestor(of: find.text('Systolic').first, matching: find.byType(TextFormField)), '123');
 
@@ -241,7 +241,7 @@ void main() {
 
     testWidgets('should focus last input field on backspace pressed in empty input field', (widgetTester) async {
       await loadDialoge(widgetTester, (context) =>
-          showAddMeasurementDialoge(context, Settings(), mockRecord(sys: 12, dia: 3, pul: 4, note: 'note')));
+          showAddEntryDialoge(context, Settings(), mockRecord(sys: 12, dia: 3, pul: 4, note: 'note')));
 
 
       await widgetTester.enterText(find.ancestor(of: find.text('note').first, matching: find.byType(TextFormField)), '');
@@ -299,5 +299,6 @@ void main() {
       expect(fourthFocusedTextFormField, findsOneWidget);
       expect(find.descendant(of: fourthFocusedTextFormField, matching: find.text('Systolic')), findsWidgets);
     });
+    // TODO: test medicine_intake
   });
 }
\ No newline at end of file
test/ui/navigation_test.dart
@@ -25,7 +25,7 @@ void main() {
       await widgetTester.tap(find.byIcon(Icons.add));
       await widgetTester.pumpAndSettle();
 
-      expect(find.byType(AddMeasurementDialoge), findsOneWidget);
+      expect(find.byType(AddEntryDialoge), findsOneWidget);
     });
     testWidgets('should navigate to settings page', (widgetTester) async {
       await pumpAppRoot(widgetTester);
pubspec.lock
@@ -325,6 +325,22 @@ packages:
       url: "https://pub.dev"
     source: hosted
     version: "1.3.0"
+  leak_tracker:
+    dependency: transitive
+    description:
+      name: leak_tracker
+      sha256: "04be76c4a4bb50f14904e64749237e541e7c7bcf7ec0b196907322ab5d2fc739"
+      url: "https://pub.dev"
+    source: hosted
+    version: "9.0.16"
+  leak_tracker_testing:
+    dependency: transitive
+    description:
+      name: leak_tracker_testing
+      sha256: b06739349ec2477e943055aea30172c5c7000225f79dad4702e2ec0eda79a6ff
+      url: "https://pub.dev"
+    source: hosted
+    version: "1.0.5"
   lints:
     dependency: transitive
     description:
@@ -361,18 +377,18 @@ packages:
     dependency: transitive
     description:
       name: material_color_utilities
-      sha256: "9528f2f296073ff54cb9fee677df673ace1218163c3bc7628093e7eed5203d41"
+      sha256: "0e0a020085b65b6083975e499759762399b4475f766c21668c4ecca34ea74e5a"
       url: "https://pub.dev"
     source: hosted
-    version: "0.5.0"
+    version: "0.8.0"
   meta:
     dependency: transitive
     description:
       name: meta
-      sha256: a6e590c838b18133bb482a2745ad77c5bb7715fb0451209e1a7567d416678b8e
+      sha256: d584fa6707a52763a52446f02cc621b077888fb63b93bbcb1143a7be5a0c0c04
       url: "https://pub.dev"
     source: hosted
-    version: "1.10.0"
+    version: "1.11.0"
   mockito:
     dependency: "direct dev"
     description:
@@ -770,6 +786,14 @@ packages:
       url: "https://pub.dev"
     source: hosted
     version: "2.1.4"
+  vm_service:
+    dependency: transitive
+    description:
+      name: vm_service
+      sha256: b3d56ff4341b8f182b96aceb2fa20e3dcb336b9f867bc0eafc0de10f1048e957
+      url: "https://pub.dev"
+    source: hosted
+    version: "13.0.0"
   watcher:
     dependency: transitive
     description:
@@ -782,10 +806,10 @@ packages:
     dependency: transitive
     description:
       name: web
-      sha256: afe077240a270dcfd2aafe77602b4113645af95d0ad31128cc02bce5ac5d5152
+      sha256: edc8a9573dd8c5a83a183dae1af2b6fd4131377404706ca4e5420474784906fa
       url: "https://pub.dev"
     source: hosted
-    version: "0.3.0"
+    version: "0.4.0"
   win32:
     dependency: transitive
     description: