main
1import 'package:blood_pressure_app/components/fullscreen_dialoge.dart';
2import 'package:blood_pressure_app/features/settings/tiles/color_picker_list_tile.dart';
3import 'package:blood_pressure_app/model/storage/settings_store.dart';
4import 'package:flutter/material.dart';
5import 'package:flutter/services.dart';
6import 'package:blood_pressure_app/l10n/app_localizations.dart';
7import 'package:health_data_store/health_data_store.dart';
8import 'package:provider/provider.dart';
9
10/// Dialoge to enter values for a [Medicine].
11class AddMedicationDialoge extends StatefulWidget {
12 /// Create a dialoge to enter values for a [Medicine].
13 const AddMedicationDialoge({super.key, this.initialValue});
14
15 /// Medicine to use to prefill input fields.
16 final Medicine? initialValue;
17
18 @override
19 State<AddMedicationDialoge> createState() => _AddMedicationDialogeState();
20}
21
22class _AddMedicationDialogeState extends State<AddMedicationDialoge> {
23 final formKey = GlobalKey<FormState>();
24 final nameFocusNode = FocusNode();
25
26 Color _color = Colors.transparent;
27
28 String? _designation;
29
30 /// Selected default dosis in mg.
31 double? _defaultDosis;
32
33 @override
34 void initState() {
35 super.initState();
36 if (widget.initialValue != null) {
37 _color = Color(widget.initialValue!.color ?? 0);
38 _designation = widget.initialValue!.designation;
39 _defaultDosis = widget.initialValue!.dosis?.mg;
40 }
41 nameFocusNode.requestFocus();
42 }
43
44 @override
45 Widget build(BuildContext context) {
46 final localizations = AppLocalizations.of(context)!;
47 final settings = context.watch<Settings>();
48 return FullscreenDialoge(
49 actionButtonText: localizations.btnSave,
50 onActionButtonPressed: () {
51 formKey.currentState?.save();
52 Navigator.pop(context, Medicine(
53 designation: _designation ?? '',
54 color: _color.toARGB32(),
55 dosis: _defaultDosis == null ? null : Weight.mg(_defaultDosis!),
56 ),);
57 },
58 bottomAppBar: settings.bottomAppBars,
59 body: Form(
60 key: formKey,
61 child: ListView(
62 children: [
63 TextFormField(
64 focusNode: nameFocusNode,
65 decoration: _getInputDecoration(context, localizations.name),
66 initialValue: _designation,
67 onSaved: (value) => _designation = value,
68 ),
69 const SizedBox(height: 8,),
70 ColorSelectionListTile(
71 title: Text(localizations.color),
72 onMainColorChanged: (value) => setState(() {
73 _color = value;
74 }),
75 initialColor: _color,
76 shape: _getBorder(),
77 ),
78 const SizedBox(height: 8,),
79 TextFormField(
80 keyboardType: TextInputType.number,
81 decoration: _getInputDecoration(context, localizations.defaultDosis),
82 inputFormatters: [FilteringTextInputFormatter.allow(RegExp(r'([0-9]+(\.([0-9]*))?)')),],
83 initialValue: _defaultDosis?.toString(),
84 onSaved: (value) => _defaultDosis = double.tryParse(value ?? '')
85 ?? int.tryParse(value ?? '')?.toDouble(),
86 ),
87 ],
88 ),
89 ),
90 );
91 }
92
93 InputDecoration _getInputDecoration(BuildContext context, String? labelText) => InputDecoration(
94 hintText: labelText,
95 labelText: labelText,
96 errorMaxLines: 5,
97 border: _getBorder(),
98 enabledBorder: _getBorder(),
99 );
100
101 OutlineInputBorder _getBorder() => OutlineInputBorder(
102 borderSide: BorderSide(
103 width: 3,
104 color: Theme.of(context).primaryColor,
105 ),
106 borderRadius: BorderRadius.circular(20),
107 );
108}
109
110/// Shows a full screen dialoge to input a medicine.
111///
112/// The created medicine gets an index that was never in settings.
113Future<Medicine?> showAddMedicineDialoge(BuildContext context, {
114 Medicine? initialValue,
115}) =>
116 showDialog<Medicine?>(context: context,
117 builder: (context) => AddMedicationDialoge(initialValue: initialValue),
118 );