From a32c91b8314347919582841fdfcb13d0fe2d1844 Mon Sep 17 00:00:00 2001 From: Yasien Mac Mini Date: Tue, 3 Jun 2025 16:09:40 +0200 Subject: [PATCH 01/52] creat new MIH form wdget --- .../mih_package_components/mih_form.dart | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 Frontend/lib/mih_components/mih_package_components/mih_form.dart diff --git a/Frontend/lib/mih_components/mih_package_components/mih_form.dart b/Frontend/lib/mih_components/mih_package_components/mih_form.dart new file mode 100644 index 00000000..6c880b97 --- /dev/null +++ b/Frontend/lib/mih_components/mih_package_components/mih_form.dart @@ -0,0 +1,27 @@ +import 'package:flutter/material.dart'; + +class MihForm extends StatefulWidget { + final GlobalKey formKey; + final List formFields; + const MihForm({ + super.key, + required this.formKey, + required this.formFields, + }); + + @override + State createState() => _MihFormState(); +} + +class _MihFormState extends State { + @override + Widget build(BuildContext context) { + return Form( + key: widget.formKey, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: widget.formFields, + ), + ); + } +} From 14e55eb9fbda9c9a5b31e3fd2051d8c2ad2272dd Mon Sep 17 00:00:00 2001 From: Yasien Mac Mini Date: Tue, 3 Jun 2025 16:09:54 +0200 Subject: [PATCH 02/52] create new mih form field --- .../mih_text_form_field.dart | 283 ++++++++++++++++++ 1 file changed, 283 insertions(+) create mode 100644 Frontend/lib/mih_components/mih_package_components/mih_text_form_field.dart diff --git a/Frontend/lib/mih_components/mih_package_components/mih_text_form_field.dart b/Frontend/lib/mih_components/mih_package_components/mih_text_form_field.dart new file mode 100644 index 00000000..b5257660 --- /dev/null +++ b/Frontend/lib/mih_components/mih_package_components/mih_text_form_field.dart @@ -0,0 +1,283 @@ +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:mzansi_innovation_hub/main.dart'; + +class MihTextFormField extends StatefulWidget { + final double? width; + final double? height; + final Color fillColor; + final Color inputColor; + final TextEditingController controller; + final bool? hasError; + final String hintText; + final double? borderRadius; + final bool? multiLineInput; + final bool? editable; + final bool? passwordMode; + final bool? numberMode; + final bool requiredText; + final FormFieldValidator? validator; + final List? autofillHints; + final double? elevation; + + const MihTextFormField({ + Key? key, + this.width, + this.height, + required this.fillColor, + required this.inputColor, + required this.controller, + this.hasError, + required this.hintText, + required this.requiredText, + this.borderRadius, + this.multiLineInput, + this.editable, + this.passwordMode, + this.numberMode, + this.validator, + this.autofillHints, + this.elevation, + }) : super(key: key); + + @override + State createState() => _MihTextFormFieldState(); +} + +class _MihTextFormFieldState extends State { + late bool _obscureText; + + @override + void initState() { + super.initState(); + _obscureText = widget.passwordMode ?? false; + } + + @override + Widget build(BuildContext context) { + return Theme( + data: Theme.of(context).copyWith( + textSelectionTheme: TextSelectionThemeData( + selectionColor: widget.inputColor.withValues(alpha: 0.3), + selectionHandleColor: widget.inputColor, + ), + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + widget.hintText, + textAlign: TextAlign.left, + style: TextStyle( + color: widget.fillColor, + fontSize: 15, + fontWeight: FontWeight.bold, + ), + ), + Visibility( + visible: !widget.requiredText, + child: Text( + "(Optional)", + textAlign: TextAlign.right, + style: TextStyle( + color: widget.fillColor, + fontSize: 15, + fontWeight: FontWeight.bold, + ), + ), + ), + ], + ), + const SizedBox(height: 4), + FormField( + validator: widget.validator, + autovalidateMode: AutovalidateMode.onUserInteraction, + builder: (field) { + return Column( + crossAxisAlignment: + CrossAxisAlignment.start, // <-- Add this line + children: [ + Material( + elevation: widget.elevation ?? 4.0, + borderRadius: + BorderRadius.circular(widget.borderRadius ?? 8.0), + child: SizedBox( + width: widget.width, + height: widget.height, + child: TextFormField( + controller: widget.controller, + cursorColor: widget.inputColor, + autofillHints: widget.autofillHints, + textAlign: TextAlign.start, + textAlignVertical: widget.multiLineInput == true + ? TextAlignVertical.top + : TextAlignVertical.center, + obscureText: + widget.passwordMode == true ? _obscureText : false, + expands: widget.passwordMode == true + ? false + : (widget.multiLineInput ?? false), + maxLines: widget.passwordMode == true ? 1 : null, + readOnly: widget.editable ?? false, + keyboardType: widget.numberMode == true + ? TextInputType.number + : null, + inputFormatters: widget.numberMode == true + ? [FilteringTextInputFormatter.digitsOnly] + : null, + style: TextStyle( + color: widget.inputColor, + fontWeight: FontWeight.w500, + ), + decoration: InputDecoration( + suffixIcon: widget.passwordMode == true + ? IconButton( + icon: Icon( + _obscureText + ? Icons.visibility_off + : Icons.visibility, + color: widget.inputColor, + ), + onPressed: () { + setState(() { + _obscureText = !_obscureText; + }); + }, + ) + : null, + errorStyle: const TextStyle( + height: 0, fontSize: 0), // <-- Add this line + // errorStyle: TextStyle( + // color: MzanziInnovationHub.of(context)! + // .theme + // .errorColor(), + // fontWeight: FontWeight.bold, + // ), + contentPadding: const EdgeInsets.symmetric( + horizontal: 10.0, vertical: 8.0), + filled: true, + fillColor: widget.fillColor, + border: OutlineInputBorder( + borderRadius: BorderRadius.circular( + widget.borderRadius ?? 8.0), + borderSide: field.hasError + ? BorderSide( + color: MzanziInnovationHub.of(context)! + .theme + .errorColor(), + width: 2.0, + ) + : BorderSide.none, + ), + enabledBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular( + widget.borderRadius ?? 8.0), + borderSide: BorderSide.none, + ), + focusedBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular( + widget.borderRadius ?? 8.0), + borderSide: BorderSide( + color: field.hasError + ? MzanziInnovationHub.of(context)! + .theme + .errorColor() + : widget.inputColor, + width: 2.0, + ), + ), + errorBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular( + widget.borderRadius ?? 8.0), + borderSide: BorderSide( + color: MzanziInnovationHub.of(context)! + .theme + .errorColor(), + width: 2.0, + ), + ), + focusedErrorBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular( + widget.borderRadius ?? 8.0), + borderSide: BorderSide( + color: MzanziInnovationHub.of(context)! + .theme + .errorColor(), + width: 2.0, + ), + ), + // border: OutlineInputBorder( + // borderRadius: BorderRadius.circular( + // widget.borderRadius ?? 8.0), + // borderSide: BorderSide.none, + // ), + // enabledBorder: OutlineInputBorder( + // borderRadius: BorderRadius.circular( + // widget.borderRadius ?? 8.0), + // borderSide: BorderSide.none, + // ), + // focusedBorder: OutlineInputBorder( + // borderRadius: BorderRadius.circular( + // widget.borderRadius ?? 8.0), + // borderSide: BorderSide( + // color: widget.inputColor, + // width: 2.0, + // ), + // ), + // errorBorder: OutlineInputBorder( + // borderRadius: BorderRadius.circular( + // widget.borderRadius ?? 8.0), + // borderSide: BorderSide( + // color: MzanziInnovationHub.of(context)! + // .theme + // .errorColor(), + // width: 2.0, + // ), + // ), + // focusedErrorBorder: OutlineInputBorder( + // borderRadius: BorderRadius.circular( + // widget.borderRadius ?? 8.0), + // borderSide: BorderSide( + // color: MzanziInnovationHub.of(context)! + // .theme + // .errorColor(), + // width: 2.0, + // ), + // ), + ), + onChanged: (value) { + field.didChange(value); + }, + ), + ), + ), + if (field.hasError) + Row( + children: [ + Padding( + padding: const EdgeInsets.only(left: 8.0, top: 4.0), + child: Text( + field.errorText ?? '', + style: TextStyle( + fontSize: 12, + color: MzanziInnovationHub.of(context)! + .theme + .errorColor(), + fontWeight: FontWeight.bold, + ), + ), + ), + ], + ), + ], + ); + }, + ), + ], + ), + ); + } +} From ed9a15d6ca391fd7b8e9be4a27a1ea054e754f08 Mon Sep 17 00:00:00 2001 From: Yasien Mac Mini Date: Tue, 3 Jun 2025 16:10:03 +0200 Subject: [PATCH 03/52] add validation service --- .../lib/mih_apis/mih_validation_services.dart | 67 +++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 Frontend/lib/mih_apis/mih_validation_services.dart diff --git a/Frontend/lib/mih_apis/mih_validation_services.dart b/Frontend/lib/mih_apis/mih_validation_services.dart new file mode 100644 index 00000000..ad896182 --- /dev/null +++ b/Frontend/lib/mih_apis/mih_validation_services.dart @@ -0,0 +1,67 @@ +class MihValidationServices { + String? validateEmail(String? email) { + if (email == null || email.isEmpty) { + return "Email is required"; + } + final emailRegex = + RegExp(r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$'); + if (!emailRegex.hasMatch(email)) { + return "Invalid Email Format"; + } + return null; + } + + String? validateUsername(String? username) { + String? errorMessage = ""; + if (username == null || username.isEmpty) { + errorMessage += "Username is required"; + return errorMessage; + } + if (!RegExp(r'^[a-zA-Z]').hasMatch(username)) { + errorMessage += "\n• Your username should start with a letter."; + } + if (!RegExp(r'^[a-zA-Z0-9_]+$').hasMatch(username)) { + errorMessage += + "\n• You can use letters, numbers, and/or underscores only."; + } + if (username.length < 6 || username.length > 30) { + errorMessage += "\n• Keep it between 6 and 30 characters."; + } + if (RegExp(r'[@#\$]').hasMatch(username)) { + errorMessage += "\n• Avoid special characters like @, #, or \$."; + } + + if (errorMessage.isEmpty) { + return null; // No errors, username is valid + } + return "Let's create a great username for you!$errorMessage"; + } + + String? validatePassword(String? password) { + String? errorMessage = ""; + if (password == null || password.isEmpty) { + errorMessage += "Password is required"; + return errorMessage; + } + if (password.length < 8) { + errorMessage += "\n• Contains at least 8 characters long"; + } + if (!RegExp(r'[A-Z]').hasMatch(password)) { + errorMessage += "\n• Contains at least 1 uppercase letter"; + } + if (!RegExp(r'[a-z]').hasMatch(password)) { + errorMessage += "\n• Contains at least 1 lowercase letter"; + } + if (!RegExp(r'[0-9]').hasMatch(password)) { + errorMessage += "\n• Contains at least 1 digit"; + } + if (!RegExp(r'[!@#$%^&*]').hasMatch(password)) { + errorMessage += "\n• Contains at least 1 special character (!@#\$%^&*)"; + } + if (errorMessage.isEmpty) { + return null; // No errors, password is valid + } + errorMessage = "Let's create a great password for you!$errorMessage"; + return errorMessage; + } +} From 27c3b8039e2a2d90839bcdf17252b03149f38ae5 Mon Sep 17 00:00:00 2001 From: Yasien Mac Mini Date: Tue, 3 Jun 2025 16:10:11 +0200 Subject: [PATCH 04/52] remove comments --- .../mih_components/mih_inputs_and_buttons/mih_text_input.dart | 4 ---- 1 file changed, 4 deletions(-) diff --git a/Frontend/lib/mih_components/mih_inputs_and_buttons/mih_text_input.dart b/Frontend/lib/mih_components/mih_inputs_and_buttons/mih_text_input.dart index afa4d714..301b8ce7 100644 --- a/Frontend/lib/mih_components/mih_inputs_and_buttons/mih_text_input.dart +++ b/Frontend/lib/mih_components/mih_inputs_and_buttons/mih_text_input.dart @@ -147,16 +147,12 @@ class _MIHTextFieldState extends State { }), decoration: InputDecoration( label: setRequiredText(), - //labelStyle: TextStyle(color: MzanziInnovationHub.of(context)!.theme.primaryColor()), fillColor: MzanziInnovationHub.of(context)!.theme.primaryColor(), filled: true, errorText: _errorText, errorStyle: TextStyle( color: MzanziInnovationHub.of(context)!.theme.errorColor(), fontWeight: FontWeight.bold), - //errorBorder: const InputBorder(), - //hintText: hintText, - //hintStyle: TextStyle(color: Colors.blueGrey[400]), disabledBorder: OutlineInputBorder( borderSide: BorderSide( color: MzanziInnovationHub.of(context)!.theme.secondaryColor(), From 59131234e1a02b759db9eb16e7aa3fa05d98f784 Mon Sep 17 00:00:00 2001 From: Yasien Mac Mini Date: Tue, 3 Jun 2025 16:10:21 +0200 Subject: [PATCH 05/52] create example --- .../package_tools/package_tool_one.dart | 121 ++++++++++++++++++ 1 file changed, 121 insertions(+) diff --git a/Frontend/lib/mih_components/mih_package_components/Example/package_tools/package_tool_one.dart b/Frontend/lib/mih_components/mih_package_components/Example/package_tools/package_tool_one.dart index 26108ce5..917f3fb9 100644 --- a/Frontend/lib/mih_components/mih_package_components/Example/package_tools/package_tool_one.dart +++ b/Frontend/lib/mih_components/mih_package_components/Example/package_tools/package_tool_one.dart @@ -2,9 +2,11 @@ import 'package:file_picker/file_picker.dart'; import 'package:flutter/material.dart'; import 'package:flutter_speed_dial/flutter_speed_dial.dart'; import 'package:mzansi_innovation_hub/main.dart'; +import 'package:mzansi_innovation_hub/mih_apis/mih_validation_services.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_inputs_and_buttons/mih_text_input.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_layout/mih_single_child_scroll.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_button.dart'; +import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_form.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package_tool_body.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package_window.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_circle_avatar.dart'; @@ -12,6 +14,7 @@ import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_ import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_icons.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_image_display.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_search_bar.dart'; +import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_text_form_field.dart'; class PackageToolOne extends StatefulWidget { const PackageToolOne({super.key}); @@ -27,7 +30,14 @@ class _PackageToolOneState extends State { TextEditingController _fileNameController = TextEditingController(); TextEditingController _imagefileController = TextEditingController(); TextEditingController _searchController = TextEditingController(); + TextEditingController _textFieldZeroController = TextEditingController(); + TextEditingController _textFieldOneController = TextEditingController(); + TextEditingController _textFieldTwoController = TextEditingController(); + TextEditingController _textFieldThreeController = TextEditingController(); + TextEditingController _textFieldFourController = TextEditingController(); final FocusNode searchFocusNode = FocusNode(); + final _formKey = GlobalKey(); + void showTestFullWindow() { showDialog( context: context, @@ -136,6 +146,117 @@ class _PackageToolOneState extends State { ], ), const SizedBox(height: 20), + MihForm( + formKey: _formKey, + formFields: [ + MihTextFormField( + fillColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + inputColor: + MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: _textFieldZeroController, + multiLineInput: false, + requiredText: true, + hintText: "Username", + validator: (value) { + return MihValidationServices().validateUsername(value); + }, + ), + const SizedBox(height: 10), + MihTextFormField( + fillColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + inputColor: + MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: _textFieldOneController, + multiLineInput: false, + requiredText: true, + hintText: "Email", + autofillHints: [AutofillHints.email], + validator: (value) { + return MihValidationServices().validateEmail(value); + }, + ), + const SizedBox(height: 10), + MihTextFormField( + fillColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + inputColor: + MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: _textFieldTwoController, + multiLineInput: false, + requiredText: true, + hintText: "Password", + passwordMode: true, + autofillHints: [AutofillHints.password], + validator: (value) { + return MihValidationServices().validatePassword(value); + }, + ), + const SizedBox(height: 10), + MihTextFormField( + fillColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + inputColor: + MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: _textFieldThreeController, + multiLineInput: false, + requiredText: true, + hintText: "Numbers Only", + numberMode: true, + validator: (value) => value == null || value.isEmpty + ? 'This Field is required' + : null, + ), + const SizedBox(height: 10), + MihTextFormField( + height: 250, + fillColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + inputColor: + MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: _textFieldFourController, + multiLineInput: true, + requiredText: false, + hintText: "Enter Multi Line Text", + ), + const SizedBox(height: 20), + Align( + alignment: Alignment.center, + child: MihButton( + onPressed: () { + if (_formKey.currentState!.validate()) { + // Process data + ScaffoldMessenger.of(context).showSnackBar( + const SnackBar(content: Text("Input Valid")), + ); + } + }, + buttonColor: MzanziInnovationHub.of(context)! + .theme + .secondaryColor(), + elevation: 10, + width: 300, + child: Text( + "Click Me", + style: TextStyle( + color: MzanziInnovationHub.of(context)! + .theme + .primaryColor(), + fontSize: 20, + fontWeight: FontWeight.bold, + ), + ), + ), + ), + ], + ), + const SizedBox(height: 10), + Divider( + color: MzanziInnovationHub.of(context)!.theme.secondaryColor(), + thickness: 2, + ), + const SizedBox(height: 10), MihSearchBar( controller: _searchController, hintText: "Ask Mzansi", From b94196b41ef08865aa695cf6087be6dcc0e1109d Mon Sep 17 00:00:00 2001 From: Yasien Mac Mini Date: Wed, 4 Jun 2025 11:12:14 +0200 Subject: [PATCH 06/52] fix text field to hanlde controller changes --- .../mih_text_form_field.dart | 81 ++++++++----------- 1 file changed, 34 insertions(+), 47 deletions(-) diff --git a/Frontend/lib/mih_components/mih_package_components/mih_text_form_field.dart b/Frontend/lib/mih_components/mih_package_components/mih_text_form_field.dart index b5257660..347ad768 100644 --- a/Frontend/lib/mih_components/mih_package_components/mih_text_form_field.dart +++ b/Frontend/lib/mih_components/mih_package_components/mih_text_form_field.dart @@ -46,11 +46,40 @@ class MihTextFormField extends StatefulWidget { class _MihTextFormFieldState extends State { late bool _obscureText; + FormFieldState? _formFieldState; @override void initState() { super.initState(); _obscureText = widget.passwordMode ?? false; + widget.controller.addListener(_onControllerTextChanged); + } + + @override + void didUpdateWidget(covariant MihTextFormField oldWidget) { + super.didUpdateWidget(oldWidget); + // If the controller itself changes, remove listener from old and add to new + if (widget.controller != oldWidget.controller) { + oldWidget.controller.removeListener(_onControllerTextChanged); + widget.controller.addListener(_onControllerTextChanged); + // Immediately update form field state if controller changed and has value + _formFieldState?.didChange(widget.controller.text); + } + } + + void _onControllerTextChanged() { + // Only update the FormField's value if it's not already the same + // and if the formFieldState is available. + if (_formFieldState != null && + _formFieldState!.value != widget.controller.text) { + _formFieldState!.didChange(widget.controller.text); + } + } + + @override + void dispose() { + widget.controller.removeListener(_onControllerTextChanged); + super.dispose(); } @override @@ -93,9 +122,11 @@ class _MihTextFormFieldState extends State { ), const SizedBox(height: 4), FormField( + initialValue: widget.controller.text, validator: widget.validator, autovalidateMode: AutovalidateMode.onUserInteraction, builder: (field) { + _formFieldState = field; return Column( crossAxisAlignment: CrossAxisAlignment.start, // <-- Add this line @@ -150,12 +181,6 @@ class _MihTextFormFieldState extends State { : null, errorStyle: const TextStyle( height: 0, fontSize: 0), // <-- Add this line - // errorStyle: TextStyle( - // color: MzanziInnovationHub.of(context)! - // .theme - // .errorColor(), - // fontWeight: FontWeight.bold, - // ), contentPadding: const EdgeInsets.symmetric( horizontal: 10.0, vertical: 8.0), filled: true, @@ -186,7 +211,7 @@ class _MihTextFormFieldState extends State { .theme .errorColor() : widget.inputColor, - width: 2.0, + width: 3.0, ), ), errorBorder: OutlineInputBorder( @@ -196,7 +221,7 @@ class _MihTextFormFieldState extends State { color: MzanziInnovationHub.of(context)! .theme .errorColor(), - width: 2.0, + width: 3.0, ), ), focusedErrorBorder: OutlineInputBorder( @@ -206,47 +231,9 @@ class _MihTextFormFieldState extends State { color: MzanziInnovationHub.of(context)! .theme .errorColor(), - width: 2.0, + width: 3.0, ), ), - // border: OutlineInputBorder( - // borderRadius: BorderRadius.circular( - // widget.borderRadius ?? 8.0), - // borderSide: BorderSide.none, - // ), - // enabledBorder: OutlineInputBorder( - // borderRadius: BorderRadius.circular( - // widget.borderRadius ?? 8.0), - // borderSide: BorderSide.none, - // ), - // focusedBorder: OutlineInputBorder( - // borderRadius: BorderRadius.circular( - // widget.borderRadius ?? 8.0), - // borderSide: BorderSide( - // color: widget.inputColor, - // width: 2.0, - // ), - // ), - // errorBorder: OutlineInputBorder( - // borderRadius: BorderRadius.circular( - // widget.borderRadius ?? 8.0), - // borderSide: BorderSide( - // color: MzanziInnovationHub.of(context)! - // .theme - // .errorColor(), - // width: 2.0, - // ), - // ), - // focusedErrorBorder: OutlineInputBorder( - // borderRadius: BorderRadius.circular( - // widget.borderRadius ?? 8.0), - // borderSide: BorderSide( - // color: MzanziInnovationHub.of(context)! - // .theme - // .errorColor(), - // width: 2.0, - // ), - // ), ), onChanged: (value) { field.didChange(value); From 15b7ac1778457c82f6949fa762ed410bbe10d90b Mon Sep 17 00:00:00 2001 From: Yasien Mac Mini Date: Wed, 4 Jun 2025 11:12:29 +0200 Subject: [PATCH 07/52] update test --- .../package_tools/package_tool_one.dart | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/Frontend/lib/mih_components/mih_package_components/Example/package_tools/package_tool_one.dart b/Frontend/lib/mih_components/mih_package_components/Example/package_tools/package_tool_one.dart index 917f3fb9..dc3b36d9 100644 --- a/Frontend/lib/mih_components/mih_package_components/Example/package_tools/package_tool_one.dart +++ b/Frontend/lib/mih_components/mih_package_components/Example/package_tools/package_tool_one.dart @@ -3,7 +3,6 @@ import 'package:flutter/material.dart'; import 'package:flutter_speed_dial/flutter_speed_dial.dart'; import 'package:mzansi_innovation_hub/main.dart'; import 'package:mzansi_innovation_hub/mih_apis/mih_validation_services.dart'; -import 'package:mzansi_innovation_hub/mih_components/mih_inputs_and_buttons/mih_text_input.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_layout/mih_single_child_scroll.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_button.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_form.dart'; @@ -150,6 +149,7 @@ class _PackageToolOneState extends State { formKey: _formKey, formFields: [ MihTextFormField( + width: 100, fillColor: MzanziInnovationHub.of(context)!.theme.secondaryColor(), inputColor: @@ -373,11 +373,15 @@ class _PackageToolOneState extends State { }, ), const SizedBox(height: 10), - MIHTextField( + MihTextFormField( + fillColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + inputColor: + MzanziInnovationHub.of(context)!.theme.primaryColor(), controller: _fileNameController, hintText: "Selected Avatar File", + requiredText: false, editable: false, - required: false, ), const SizedBox(height: 10), MihImageDisplay( @@ -394,12 +398,17 @@ class _PackageToolOneState extends State { }, ), const SizedBox(height: 10), - MIHTextField( + MihTextFormField( + fillColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + inputColor: + MzanziInnovationHub.of(context)!.theme.primaryColor(), controller: _imagefileController, hintText: "Selected Image File", + requiredText: false, editable: false, - required: false, ), + const SizedBox(height: 10), ], ), ), From 16eec990d6525bd06fe72bd4dd47af90234cc639 Mon Sep 17 00:00:00 2001 From: Yasien Mac Mini Date: Wed, 4 Jun 2025 11:12:40 +0200 Subject: [PATCH 08/52] remove keys --- Frontend/lib/mih_env/env.dart | 3 --- 1 file changed, 3 deletions(-) diff --git a/Frontend/lib/mih_env/env.dart b/Frontend/lib/mih_env/env.dart index c96e44e0..842552b8 100644 --- a/Frontend/lib/mih_env/env.dart +++ b/Frontend/lib/mih_env/env.dart @@ -22,9 +22,6 @@ abstract class AppEnviroment { // baseApiUrl = "http://localhost:8080"; // baseFileUrl = "http://localhost:9000"; // baseAiUrl = "http://localhost:11434"; - whatsappAccessToken = - "EAAPINXuNFdYBOzBjTcvZA2iPXEHbHRF9uNXyP3ihkPRUcBqKNru5g9NKRRKkFaiaITEzO3BMo6CjdUmlDH4qYTW2mzDrZB4Q21ZCEZBgECZCu27vfaOXJZCYQLNxwoXkrZBRYv8ZAP37f69r3z9JxLQxdxn9gwqA3oNZAlBBRapJQzxOr6pZBTdI3bbjbu17ZBIwRcF4JCqPDCNLEZCI3bmHwEd2i2niNMYZD"; - //fingerPrintPluginKey = 'h5X7a5j14iUZCobI1ZeX'; break; } case Enviroment.prod: From 4fb9992dfa0e1a8a0552adbd94a33431234f888b Mon Sep 17 00:00:00 2001 From: Yasien Mac Mini Date: Wed, 4 Jun 2025 11:19:30 +0200 Subject: [PATCH 09/52] Add new mih text form field to Auth --- .../authentication/forgot_password.dart | 78 +-- .../mih_packages/authentication/register.dart | 216 ++++---- .../authentication/reset_password.dart | 161 +++--- .../mih_packages/authentication/signin.dart | 474 +++++++++--------- 4 files changed, 488 insertions(+), 441 deletions(-) diff --git a/Frontend/lib/mih_packages/authentication/forgot_password.dart b/Frontend/lib/mih_packages/authentication/forgot_password.dart index 0b267854..3b6f5771 100644 --- a/Frontend/lib/mih_packages/authentication/forgot_password.dart +++ b/Frontend/lib/mih_packages/authentication/forgot_password.dart @@ -2,11 +2,13 @@ import 'dart:convert'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; +import 'package:mzansi_innovation_hub/mih_apis/mih_validation_services.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_button.dart'; +import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_form.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package_alert.dart'; +import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_text_form_field.dart'; import '../../main.dart'; import 'package:supertokens_flutter/http.dart' as http; -import '../../mih_components/mih_inputs_and_buttons/mih_text_input.dart'; import '../../mih_components/mih_layout/mih_action.dart'; import '../../mih_components/mih_layout/mih_body.dart'; import '../../mih_components/mih_layout/mih_header.dart'; @@ -25,6 +27,7 @@ class ForgotPassword extends StatefulWidget { class _ForgotPasswordState extends State { final emailController = TextEditingController(); + final _formKey = GlobalKey(); //bool _obscureText = true; bool successfulForgotPassword = false; @@ -244,40 +247,53 @@ class _ForgotPasswordState extends State { .secondaryColor(), ), ), - //spacer const SizedBox(height: 25), - - //email input - SizedBox( - width: 500.0, - child: MIHTextField( - controller: emailController, - hintText: 'Email', - editable: true, - required: true, - ), - ), - - //spacer - const SizedBox(height: 25), - MihButton( - onPressed: () { - prePassResteWarning(); - }, - buttonColor: MzanziInnovationHub.of(context)! - .theme - .secondaryColor(), - width: 300, - child: Text( - "Reset Password", - style: TextStyle( - color: MzanziInnovationHub.of(context)! + MihForm( + formKey: _formKey, + formFields: [ + MihTextFormField( + fillColor: MzanziInnovationHub.of(context)! + .theme + .secondaryColor(), + inputColor: MzanziInnovationHub.of(context)! .theme .primaryColor(), - fontSize: 20, - fontWeight: FontWeight.bold, + controller: emailController, + multiLineInput: false, + requiredText: true, + hintText: "Email", + validator: (value) { + return MihValidationServices() + .validateEmail(value); + }, ), - ), + //spacer + const SizedBox(height: 20), + Align( + alignment: Alignment.center, + child: MihButton( + onPressed: () { + if (_formKey.currentState!.validate()) { + prePassResteWarning(); + } + }, + buttonColor: MzanziInnovationHub.of(context)! + .theme + .secondaryColor(), + width: 300, + child: Text( + "Reset Password", + style: TextStyle( + color: MzanziInnovationHub.of(context)! + .theme + .primaryColor(), + fontSize: 20, + fontWeight: FontWeight.bold, + ), + ), + ), + ), + ], ), ], ), diff --git a/Frontend/lib/mih_packages/authentication/register.dart b/Frontend/lib/mih_packages/authentication/register.dart index 229bc938..50112e8d 100644 --- a/Frontend/lib/mih_packages/authentication/register.dart +++ b/Frontend/lib/mih_packages/authentication/register.dart @@ -1,18 +1,16 @@ import 'dart:convert'; +import 'package:mzansi_innovation_hub/mih_apis/mih_validation_services.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_button.dart'; +import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_form.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_icons.dart'; +import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_text_form_field.dart'; import 'package:mzansi_innovation_hub/mih_objects/arguments.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import '../../main.dart'; -//import '../objects/sessionST.dart'; -//import 'package:supertokens_flutter/supertokens.dart'; import 'package:supertokens_flutter/http.dart' as http; import 'package:supertokens_flutter/supertokens.dart'; - -import '../../mih_components/mih_inputs_and_buttons/mih_pass_input.dart'; -import '../../mih_components/mih_inputs_and_buttons/mih_text_input.dart'; import '../../mih_components/mih_layout/mih_action.dart'; import '../../mih_components/mih_layout/mih_body.dart'; import '../../mih_components/mih_layout/mih_header.dart'; @@ -37,6 +35,7 @@ class _RegisterState extends State { final officeID = TextEditingController(); final baseAPI = AppEnviroment.baseApiUrl; final FocusNode _focusNode = FocusNode(); + final _formKey = GlobalKey(); bool _obscureText = true; bool successfulSignUp = false; @@ -218,19 +217,8 @@ class _RegisterState extends State { ); } - void validateInput() async { - if (emailController.text.isEmpty || - passwordController.text.isEmpty || - confirmPasswordController.text.isEmpty) { - showDialog( - context: context, - builder: (context) { - return const MIHErrorMessage(errorType: "Input Error"); - }, - ); - } else { - await signUserUp(); - } + void submitFormInput() async { + await signUserUp(); } void toggle() { @@ -325,7 +313,9 @@ class _RegisterState extends State { onKeyEvent: (event) async { if (event is KeyDownEvent && event.logicalKey == LogicalKeyboardKey.enter) { - validateInput(); + if (_formKey.currentState!.validate()) { + submitFormInput(); + } } }, child: SafeArea( @@ -360,92 +350,128 @@ class _RegisterState extends State { ), //spacer const SizedBox(height: 25), - //email input - SizedBox( - width: 500.0, - child: MIHTextField( - controller: emailController, - hintText: 'Email', - editable: true, - required: true, - ), - ), - //spacer - const SizedBox(height: 10), - //password input - SizedBox( - width: 500.0, - child: MIHPassField( - controller: passwordController, - hintText: 'Password', - required: true, - signIn: false, - ), - ), - //spacer - const SizedBox(height: 10), - //password input - SizedBox( - width: 500.0, - child: MIHPassField( - controller: confirmPasswordController, - hintText: 'Confirm Password', - required: true, - signIn: false, - ), - ), - //spacer - const SizedBox(height: 25), - // sign up button - MihButton( - onPressed: () { - validateInput(); - }, - buttonColor: - MzanziInnovationHub.of(context)!.theme.successColor(), - width: 300, - child: Text( - "Create New Account", - style: TextStyle( - color: MzanziInnovationHub.of(context)! + MihForm( + formKey: _formKey, + formFields: [ + //email input + MihTextFormField( + fillColor: MzanziInnovationHub.of(context)! + .theme + .secondaryColor(), + inputColor: MzanziInnovationHub.of(context)! .theme .primaryColor(), - fontSize: 20, - fontWeight: FontWeight.bold, + controller: emailController, + multiLineInput: false, + requiredText: true, + hintText: "Email", + autofillHints: const [AutofillHints.email], + validator: (value) { + return MihValidationServices().validateEmail(value); + }, ), - ), - ), - - const SizedBox(height: 10), - //register text - SizedBox( - width: 500.0, - //height: 100.0, - child: Row( - mainAxisAlignment: MainAxisAlignment.end, - children: [ - const Text( - 'Already a User?', - style: TextStyle(fontSize: 18, color: Colors.grey), - ), - const SizedBox( - width: 6, - ), - GestureDetector( - onTap: widget.onTap, + //spacer + const SizedBox(height: 10), + //password input + MihTextFormField( + fillColor: MzanziInnovationHub.of(context)! + .theme + .secondaryColor(), + inputColor: MzanziInnovationHub.of(context)! + .theme + .primaryColor(), + controller: passwordController, + multiLineInput: false, + requiredText: true, + hintText: "Password", + passwordMode: true, + autofillHints: const [AutofillHints.password], + validator: (value) { + return MihValidationServices() + .validatePassword(value); + }, + ), + //spacer + const SizedBox(height: 10), + MihTextFormField( + fillColor: MzanziInnovationHub.of(context)! + .theme + .secondaryColor(), + inputColor: MzanziInnovationHub.of(context)! + .theme + .primaryColor(), + controller: confirmPasswordController, + multiLineInput: false, + requiredText: true, + hintText: "Confirm Password", + passwordMode: true, + autofillHints: const [AutofillHints.password], + validator: (value) { + return MihValidationServices() + .validatePassword(value); + }, + ), + //spacer + const SizedBox(height: 20), + // sign up button + Center( + child: MihButton( + onPressed: () { + if (_formKey.currentState!.validate()) { + submitFormInput(); + } + }, + buttonColor: MzanziInnovationHub.of(context)! + .theme + .successColor(), + width: 300, child: Text( - 'Sign In', + "Create New Account", style: TextStyle( - fontSize: 18, color: MzanziInnovationHub.of(context)! .theme - .secondaryColor(), + .primaryColor(), + fontSize: 20, fontWeight: FontWeight.bold, ), ), - ) - ], - ), + ), + ), + + const SizedBox(height: 10), + //register text + SizedBox( + width: 300.0, + //height: 100.0, + child: Row( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + const Text( + 'Already a User?', + style: + TextStyle(fontSize: 18, color: Colors.grey), + ), + const SizedBox( + width: 6, + ), + GestureDetector( + onTap: widget.onTap, + child: Text( + 'Sign In', + style: TextStyle( + fontSize: 18, + color: MzanziInnovationHub.of(context)! + .theme + .secondaryColor(), + fontWeight: FontWeight.bold, + ), + ), + ) + ], + ), + //here + ), + ], ) ], ), diff --git a/Frontend/lib/mih_packages/authentication/reset_password.dart b/Frontend/lib/mih_packages/authentication/reset_password.dart index d12f8ef7..1c97a81d 100644 --- a/Frontend/lib/mih_packages/authentication/reset_password.dart +++ b/Frontend/lib/mih_packages/authentication/reset_password.dart @@ -2,10 +2,12 @@ import 'dart:convert'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; +import 'package:mzansi_innovation_hub/mih_apis/mih_validation_services.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_button.dart'; +import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_form.dart'; +import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_text_form_field.dart'; import '../../main.dart'; import 'package:supertokens_flutter/http.dart' as http; -import '../../mih_components/mih_inputs_and_buttons/mih_pass_input.dart'; import '../../mih_components/mih_layout/mih_action.dart'; import '../../mih_components/mih_layout/mih_body.dart'; import '../../mih_components/mih_layout/mih_header.dart'; @@ -35,6 +37,7 @@ class _ResetPasswordState extends State { bool acceptWarning = false; // focus node to capture keyboard events final FocusNode _focusNode = FocusNode(); + final _formKey = GlobalKey(); final baseAPI = AppEnviroment.baseApiUrl; @@ -131,16 +134,8 @@ class _ResetPasswordState extends State { ); } - void validateInput() async { - if (passwordController.text.isEmpty || - confirmPasswordController.text.isEmpty) { - showDialog( - context: context, - builder: (context) { - return const MIHErrorMessage(errorType: "Input Error"); - }, - ); - } else if (passwordController.text != confirmPasswordController.text) { + void submitFormInput() async { + if (passwordController.text != confirmPasswordController.text) { passwordError(); } else { await submitPasswodReset(); @@ -195,7 +190,9 @@ class _ResetPasswordState extends State { onKeyEvent: (event) async { if (event is KeyDownEvent && event.logicalKey == LogicalKeyboardKey.enter) { - validateInput(); + if (_formKey.currentState!.validate()) { + submitFormInput(); + } } }, child: SafeArea( @@ -229,63 +226,97 @@ class _ResetPasswordState extends State { ), ), //spacer - // const SizedBox(height: 15), - // Text( - // 'token: ${widget.token}', - // style: TextStyle( - // fontSize: 15, - // fontWeight: FontWeight.bold, - // color: MzanziInnovationHub.of(context)! - // .theme - // .secondaryColor(), - // ), - // ), - //spacer const SizedBox(height: 25), - //email input - SizedBox( - width: 500.0, - child: MIHPassField( - controller: passwordController, - hintText: 'New Password', - required: true, - signIn: false, - ), - ), - //spacer - const SizedBox(height: 10), - //password input - SizedBox( - width: 500.0, - child: MIHPassField( - controller: confirmPasswordController, - hintText: 'Confirm New Password', - required: true, - signIn: false, - ), - ), - - //spacer - const SizedBox(height: 25), - // sign in button - MihButton( - onPressed: () { - validateInput(); - }, - buttonColor: MzanziInnovationHub.of(context)! - .theme - .secondaryColor(), - width: 300, - child: Text( - "Reset Password", - style: TextStyle( - color: MzanziInnovationHub.of(context)! + MihForm( + formKey: _formKey, + formFields: [ + MihTextFormField( + fillColor: MzanziInnovationHub.of(context)! + .theme + .secondaryColor(), + inputColor: MzanziInnovationHub.of(context)! .theme .primaryColor(), - fontSize: 20, - fontWeight: FontWeight.bold, + controller: passwordController, + multiLineInput: false, + requiredText: true, + hintText: "Password", + passwordMode: true, + autofillHints: const [AutofillHints.password], + validator: (value) { + return MihValidationServices() + .validatePassword(value); + }, ), - ), + //spacer + const SizedBox(height: 10), + MihTextFormField( + fillColor: MzanziInnovationHub.of(context)! + .theme + .secondaryColor(), + inputColor: MzanziInnovationHub.of(context)! + .theme + .primaryColor(), + controller: confirmPasswordController, + multiLineInput: false, + requiredText: true, + hintText: "Confirm Password", + passwordMode: true, + autofillHints: const [AutofillHints.password], + validator: (value) { + return MihValidationServices() + .validatePassword(value); + }, + ), + + // //email input + // SizedBox( + // width: 500.0, + // child: MIHPassField( + // controller: passwordController, + // hintText: 'New Password', + // required: true, + // signIn: false, + // ), + // ), + // //spacer + // const SizedBox(height: 10), + // //password input + // SizedBox( + // width: 500.0, + // child: MIHPassField( + // controller: confirmPasswordController, + // hintText: 'Confirm New Password', + // required: true, + // signIn: false, + // ), + // ), + + //spacer + const SizedBox(height: 25), + // sign in button + MihButton( + onPressed: () { + if (_formKey.currentState!.validate()) { + submitFormInput(); + } + }, + buttonColor: MzanziInnovationHub.of(context)! + .theme + .secondaryColor(), + width: 300, + child: Text( + "Reset Password", + style: TextStyle( + color: MzanziInnovationHub.of(context)! + .theme + .primaryColor(), + fontSize: 20, + fontWeight: FontWeight.bold, + ), + ), + ), + ], ), ], ), diff --git a/Frontend/lib/mih_packages/authentication/signin.dart b/Frontend/lib/mih_packages/authentication/signin.dart index 85d01399..5f71c918 100644 --- a/Frontend/lib/mih_packages/authentication/signin.dart +++ b/Frontend/lib/mih_packages/authentication/signin.dart @@ -1,13 +1,14 @@ import 'dart:convert'; +import 'package:mzansi_innovation_hub/mih_apis/mih_validation_services.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_button.dart'; +import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_form.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_icons.dart'; +import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_text_form_field.dart'; import 'package:mzansi_innovation_hub/mih_objects/arguments.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import '../../main.dart'; import 'package:supertokens_flutter/http.dart' as http; -import '../../mih_components/mih_inputs_and_buttons/mih_pass_input.dart'; -import '../../mih_components/mih_inputs_and_buttons/mih_text_input.dart'; import '../../mih_components/mih_layout/mih_action.dart'; import '../../mih_components/mih_layout/mih_body.dart'; import '../../mih_components/mih_layout/mih_header.dart'; @@ -34,6 +35,7 @@ class _SignInState extends State { // focus node to capture keyboard events final FocusNode _focusNode = FocusNode(); + final _formKey = GlobalKey(); final baseAPI = AppEnviroment.baseApiUrl; @@ -99,7 +101,9 @@ class _SignInState extends State { emailController.text = "testpatient@mzansi-innovation-hub.co.za"; passwordController.text = "Testprofile@1234"; }); - validateInput(); + if (_formKey.currentState!.validate()) { + submitSignInForm(); + } }, tileName: "Patient", tileIcon: Icon( @@ -116,7 +120,9 @@ class _SignInState extends State { emailController.text = "testdoctor@mzansi-innovation-hub.co.za"; passwordController.text = "Testprofile@1234"; }); - validateInput(); + if (_formKey.currentState!.validate()) { + submitSignInForm(); + } }, tileName: "Doctor", tileIcon: Icon( @@ -134,7 +140,9 @@ class _SignInState extends State { emailController.text = "test-business@mzansi-innovation-hub.co.za"; passwordController.text = "Testprofile@1234"; }); - validateInput(); + if (_formKey.currentState!.validate()) { + submitSignInForm(); + } }, tileName: "Business", tileIcon: Icon( @@ -151,7 +159,9 @@ class _SignInState extends State { emailController.text = "test@mzansi-innovation-hub.co.za"; passwordController.text = "Testprofile@1234"; }); - validateInput(); + if (_formKey.currentState!.validate()) { + submitSignInForm(); + } }, tileName: "Test", tileIcon: Icon( @@ -174,27 +184,17 @@ class _SignInState extends State { ); } - void validateInput() async { - if (emailController.text.isEmpty || passwordController.text.isEmpty) { - showDialog( - context: context, - builder: (context) { - return const MIHErrorMessage(errorType: "Input Error"); - }, + void submitSignInForm() async { + await signUserIn(); + if (successfulSignIn) { + Navigator.of(context).pushNamedAndRemoveUntil( + '/', + (route) => false, + arguments: AuthArguments( + true, + true, + ), ); - } else { - await signUserIn(); - if (successfulSignIn) { - // TextInput.finishAutofillContext(); - Navigator.of(context).pushNamedAndRemoveUntil( - '/', - (route) => false, - arguments: AuthArguments( - true, - true, - ), - ); - } } } @@ -371,7 +371,9 @@ class _SignInState extends State { onKeyEvent: (event) async { if (event is KeyDownEvent && event.logicalKey == LogicalKeyboardKey.enter) { - validateInput(); + if (_formKey.currentState!.validate()) { + submitSignInForm(); + } } }, child: SafeArea( @@ -407,241 +409,213 @@ class _SignInState extends State { ), //spacer const SizedBox(height: 25), - - // SizedBox( - // width: 500.0, - // //height: 100.0, - // child: Row( - // mainAxisAlignment: MainAxisAlignment.start, - // children: [ - // GestureDetector( - // onTap: () { - // showSandboxProfiles(); - // }, - // child: Text( - // 'Sandbox Profile', - // style: TextStyle( - // fontSize: 18, - // color: MzanziInnovationHub.of(context)! - // .theme - // .secondaryColor(), - // fontWeight: FontWeight.bold, - // ), - // ), - // ), - // ], - // ), - // ), - // const SizedBox(height: 10), - //email input - SizedBox( - width: 500.0, - child: MIHTextField( - controller: emailController, - hintText: 'Email', - editable: true, - required: true, - autoFillHintGroup: const [AutofillHints.email], - textInputAction: TextInputAction.next, - ), - ), - - //spacer - const SizedBox(height: 10), - //password input - SizedBox( - width: 500.0, - child: MIHPassField( - controller: passwordController, - hintText: 'Password', - required: true, - signIn: true, - autoFillHintGroup: const [AutofillHints.password], - ), - ), - SizedBox( - width: 500.0, - //height: 100.0, - child: Row( - mainAxisAlignment: MainAxisAlignment.end, - children: [ - GestureDetector( - onTap: () { - Navigator.of(context).pushNamed( - '/forgot-password', - ); - }, - child: Text( - 'Forgot Password?', - style: TextStyle( - fontSize: 15, - color: MzanziInnovationHub.of(context)! - .theme - .secondaryColor(), - fontWeight: FontWeight.bold, - ), - ), - ), - ], - ), - ), - - //spacer - const SizedBox(height: 30), - // sign in button - MihButton( - onPressed: () { - validateInput(); - }, - buttonColor: MzanziInnovationHub.of(context)! - .theme - .secondaryColor(), - width: 300, - child: Text( - "Sign In", - style: TextStyle( - color: MzanziInnovationHub.of(context)! + MihForm( + formKey: _formKey, + formFields: [ + MihTextFormField( + fillColor: MzanziInnovationHub.of(context)! + .theme + .secondaryColor(), + inputColor: MzanziInnovationHub.of(context)! .theme .primaryColor(), - fontSize: 20, - fontWeight: FontWeight.bold, + controller: emailController, + multiLineInput: false, + requiredText: true, + hintText: "Email", + autofillHints: const [AutofillHints.email], + validator: (value) { + return MihValidationServices() + .validateEmail(value); + }, ), - ), - ), - const SizedBox(height: 10), - MihButton( - onPressed: widget.onTap, - buttonColor: MzanziInnovationHub.of(context)! - .theme - .successColor(), - width: 300, - child: Text( - "Create New Account", - style: TextStyle( - color: MzanziInnovationHub.of(context)! + //spacer + const SizedBox(height: 10), + //password input + MihTextFormField( + fillColor: MzanziInnovationHub.of(context)! + .theme + .secondaryColor(), + inputColor: MzanziInnovationHub.of(context)! .theme .primaryColor(), - fontSize: 20, - fontWeight: FontWeight.bold, + controller: passwordController, + multiLineInput: false, + requiredText: true, + hintText: "Password", + passwordMode: true, + autofillHints: const [AutofillHints.password], + validator: (value) { + return MihValidationServices() + .validatePassword(value); + }, ), - ), - ), - //spacer - const SizedBox(height: 10), - //register text - // SizedBox( - // width: 500.0, - // //height: 100.0, - // child: Row( - // mainAxisAlignment: MainAxisAlignment.end, - // children: [ - // Text( - // 'New User?', - // style: TextStyle( - // fontSize: 18, - // color: MzanziInnovationHub.of(context)! - // .theme - // .messageTextColor()), - // ), - // const SizedBox( - // width: 6, - // ), - // GestureDetector( - // onTap: widget.onTap, - // child: Text( - // 'Register Now', - // style: TextStyle( - // fontSize: 18, - // color: MzanziInnovationHub.of(context)! - // .theme - // .secondaryColor(), - // fontWeight: FontWeight.bold, - // ), - // ), - // ), - // ], - // ), - // ), - //spacer - const SizedBox(height: 15), - SizedBox( - width: 500.0, - //height: 100.0, - child: Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - const Flexible( - flex: 1, - child: Padding( - padding: EdgeInsets.only(right: 10.0), - child: Divider(), - ), - ), - Flexible( - flex: 1, - child: GestureDetector( - child: Text( - 'Use Sandox Profile', - textAlign: TextAlign.center, - style: TextStyle( - fontWeight: FontWeight.bold, + SizedBox( + width: 500.0, + //height: 100.0, + child: Row( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + GestureDetector( + onTap: () { + Navigator.of(context).pushNamed( + '/forgot-password', + ); + }, + child: Text( + 'Forgot Password?', + style: TextStyle( fontSize: 15, color: MzanziInnovationHub.of(context)! .theme - .secondaryColor()), + .secondaryColor(), + fontWeight: FontWeight.bold, + ), + ), ), - onTap: () { - setState(() { - showProfiles = !showProfiles; - }); - }, - ), + ], ), - const Flexible( - flex: 1, - child: Padding( - padding: EdgeInsets.only(left: 10.0), - child: Divider(), - ), - ), - ], - ), - ), - const SizedBox(height: 10), - Visibility( - visible: showProfiles, - child: SizedBox( - width: 500, - child: Column( - //mainAxisSize: MainAxisSize.max, - children: [ - GridView.builder( - physics: const NeverScrollableScrollPhysics(), - shrinkWrap: true, - itemCount: sandboxProfileList.length, - gridDelegate: - const SliverGridDelegateWithMaxCrossAxisExtent( - mainAxisSpacing: 10, - maxCrossAxisExtent: 100), - itemBuilder: (context, index) { - return sandboxProfileList[index]; - }, - ), - const SizedBox(height: 20), - Text( - "NB: These accounts are used for test purposes. Please do not store personal information on these profiles.", - textAlign: TextAlign.center, - style: TextStyle( - color: MzanziInnovationHub.of(context)! - .theme - .secondaryColor(), - fontSize: 15.0, - fontWeight: FontWeight.bold, - ), - ), - ], ), - ), + + //spacer + const SizedBox(height: 20), + // sign in button + Center( + child: Wrap( + alignment: WrapAlignment.center, + runAlignment: WrapAlignment.center, + spacing: 10, + runSpacing: 10, + children: [ + MihButton( + onPressed: () { + if (_formKey.currentState!.validate()) { + submitSignInForm(); + } + }, + buttonColor: + MzanziInnovationHub.of(context)! + .theme + .secondaryColor(), + width: 300, + child: Text( + "Sign In", + style: TextStyle( + color: MzanziInnovationHub.of(context)! + .theme + .primaryColor(), + fontSize: 20, + fontWeight: FontWeight.bold, + ), + ), + ), + const SizedBox(height: 10), + MihButton( + onPressed: widget.onTap, + buttonColor: + MzanziInnovationHub.of(context)! + .theme + .successColor(), + width: 300, + child: Text( + "Create New Account", + style: TextStyle( + color: MzanziInnovationHub.of(context)! + .theme + .primaryColor(), + fontSize: 20, + fontWeight: FontWeight.bold, + ), + ), + ), + ], + ), + ), + + //spacer + const SizedBox(height: 20), + SizedBox( + width: 500.0, + //height: 100.0, + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + const Flexible( + flex: 1, + child: Padding( + padding: EdgeInsets.only(right: 10.0), + child: Divider(), + ), + ), + Flexible( + flex: 1, + child: GestureDetector( + child: Text( + 'Use Sandox Profile', + textAlign: TextAlign.center, + style: TextStyle( + fontWeight: FontWeight.bold, + fontSize: 15, + color: + MzanziInnovationHub.of(context)! + .theme + .secondaryColor()), + ), + onTap: () { + setState(() { + showProfiles = !showProfiles; + }); + }, + ), + ), + const Flexible( + flex: 1, + child: Padding( + padding: EdgeInsets.only(left: 10.0), + child: Divider(), + ), + ), + ], + ), + ), + const SizedBox(height: 10), + Visibility( + visible: showProfiles, + child: SizedBox( + width: 500, + child: Column( + //mainAxisSize: MainAxisSize.max, + children: [ + GridView.builder( + physics: + const NeverScrollableScrollPhysics(), + shrinkWrap: true, + itemCount: sandboxProfileList.length, + gridDelegate: + const SliverGridDelegateWithMaxCrossAxisExtent( + mainAxisSpacing: 10, + maxCrossAxisExtent: 100), + itemBuilder: (context, index) { + return sandboxProfileList[index]; + }, + ), + const SizedBox(height: 20), + Text( + "NB: These accounts are used for test purposes. Please do not store personal information on these profiles.", + textAlign: TextAlign.center, + style: TextStyle( + color: MzanziInnovationHub.of(context)! + .theme + .secondaryColor(), + fontSize: 15.0, + fontWeight: FontWeight.bold, + ), + ), + ], + ), + ), + ), + ], ), ], ), From 46e41d9c8b270c1276f3a02bfc8823e6004ac10b Mon Sep 17 00:00:00 2001 From: Yasien Mac Mini Date: Wed, 4 Jun 2025 11:33:12 +0200 Subject: [PATCH 10/52] isEmpty validation added to service --- Frontend/lib/mih_apis/mih_validation_services.dart | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Frontend/lib/mih_apis/mih_validation_services.dart b/Frontend/lib/mih_apis/mih_validation_services.dart index ad896182..b855ba57 100644 --- a/Frontend/lib/mih_apis/mih_validation_services.dart +++ b/Frontend/lib/mih_apis/mih_validation_services.dart @@ -1,4 +1,11 @@ class MihValidationServices { + String? isEmpty(String? value) { + if (value == null || value.isEmpty) { + return "This field is required"; + } + return null; + } + String? validateEmail(String? email) { if (email == null || email.isEmpty) { return "Email is required"; From 9bd56de1707a6f3be881277055b8841260da0da2 Mon Sep 17 00:00:00 2001 From: Yasien Mac Mini Date: Wed, 4 Jun 2025 11:56:04 +0200 Subject: [PATCH 11/52] changhe editable to readonly --- .../mih_package_components/mih_text_form_field.dart | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Frontend/lib/mih_components/mih_package_components/mih_text_form_field.dart b/Frontend/lib/mih_components/mih_package_components/mih_text_form_field.dart index 347ad768..50c50d36 100644 --- a/Frontend/lib/mih_components/mih_package_components/mih_text_form_field.dart +++ b/Frontend/lib/mih_components/mih_package_components/mih_text_form_field.dart @@ -12,7 +12,7 @@ class MihTextFormField extends StatefulWidget { final String hintText; final double? borderRadius; final bool? multiLineInput; - final bool? editable; + final bool? readOnly; final bool? passwordMode; final bool? numberMode; final bool requiredText; @@ -32,7 +32,7 @@ class MihTextFormField extends StatefulWidget { required this.requiredText, this.borderRadius, this.multiLineInput, - this.editable, + this.readOnly, this.passwordMode, this.numberMode, this.validator, @@ -152,7 +152,7 @@ class _MihTextFormFieldState extends State { ? false : (widget.multiLineInput ?? false), maxLines: widget.passwordMode == true ? 1 : null, - readOnly: widget.editable ?? false, + readOnly: widget.readOnly ?? false, keyboardType: widget.numberMode == true ? TextInputType.number : null, From a86a2285a9ed2acf3f6ea0c2918693d9e9df78ca Mon Sep 17 00:00:00 2001 From: Yasien Mac Mini Date: Wed, 4 Jun 2025 11:56:15 +0200 Subject: [PATCH 12/52] update test --- .../Example/package_tools/package_tool_one.dart | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Frontend/lib/mih_components/mih_package_components/Example/package_tools/package_tool_one.dart b/Frontend/lib/mih_components/mih_package_components/Example/package_tools/package_tool_one.dart index dc3b36d9..d899911b 100644 --- a/Frontend/lib/mih_components/mih_package_components/Example/package_tools/package_tool_one.dart +++ b/Frontend/lib/mih_components/mih_package_components/Example/package_tools/package_tool_one.dart @@ -149,7 +149,6 @@ class _PackageToolOneState extends State { formKey: _formKey, formFields: [ MihTextFormField( - width: 100, fillColor: MzanziInnovationHub.of(context)!.theme.secondaryColor(), inputColor: @@ -381,7 +380,7 @@ class _PackageToolOneState extends State { controller: _fileNameController, hintText: "Selected Avatar File", requiredText: false, - editable: false, + readOnly: false, ), const SizedBox(height: 10), MihImageDisplay( @@ -406,7 +405,7 @@ class _PackageToolOneState extends State { controller: _imagefileController, hintText: "Selected Image File", requiredText: false, - editable: false, + readOnly: false, ), const SizedBox(height: 10), ], From 29dae4f16cdcf28b7d8cde5d408c1b0e48add443 Mon Sep 17 00:00:00 2001 From: Yasien Mac Mini Date: Wed, 4 Jun 2025 11:56:33 +0200 Subject: [PATCH 13/52] Add new mih text form field to Appointments --- .../builder/build_appointment_list.dart | 316 ++++++++++-------- .../calendar/package_tools/appointments.dart | 131 +++++--- 2 files changed, 258 insertions(+), 189 deletions(-) diff --git a/Frontend/lib/mih_packages/calendar/builder/build_appointment_list.dart b/Frontend/lib/mih_packages/calendar/builder/build_appointment_list.dart index 63070957..405ea621 100644 --- a/Frontend/lib/mih_packages/calendar/builder/build_appointment_list.dart +++ b/Frontend/lib/mih_packages/calendar/builder/build_appointment_list.dart @@ -1,12 +1,13 @@ import 'package:flutter_speed_dial/flutter_speed_dial.dart'; import 'package:mzansi_innovation_hub/main.dart'; import 'package:mzansi_innovation_hub/mih_apis/mih_mzansi_calendar_apis.dart'; +import 'package:mzansi_innovation_hub/mih_apis/mih_validation_services.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_inputs_and_buttons/mih_date_input.dart'; -import 'package:mzansi_innovation_hub/mih_components/mih_inputs_and_buttons/mih_multiline_text_input.dart'; -import 'package:mzansi_innovation_hub/mih_components/mih_inputs_and_buttons/mih_text_input.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_inputs_and_buttons/mih_time_input.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_button.dart'; +import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_form.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package_window.dart'; +import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_text_form_field.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_pop_up_messages/mih_delete_message.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_pop_up_messages/mih_error_message.dart'; import 'package:mzansi_innovation_hub/mih_env/env.dart'; @@ -57,6 +58,7 @@ class _BuildAppointmentListState extends State { TextEditingController fnameController = TextEditingController(); TextEditingController lnameController = TextEditingController(); TextEditingController daysExtensionController = TextEditingController(); + final _formKey = GlobalKey(); int counter = 0; late double width; late double height; @@ -203,43 +205,53 @@ class _BuildAppointmentListState extends State { windowBody: Column( children: [ const SizedBox(height: 10), - SizedBox( - // width: 500, - child: MIHTextField( - controller: widget.titleController, - hintText: "Title", - editable: false, - required: false, - ), + MihTextFormField( + fillColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + inputColor: + MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: widget.titleController, + multiLineInput: false, + requiredText: true, + readOnly: true, + hintText: "Appointment Title", ), const SizedBox(height: 10), - SizedBox( - // width: 500, - child: MIHTextField( + MihTextFormField( + fillColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + inputColor: + MzanziInnovationHub.of(context)!.theme.primaryColor(), controller: widget.dateController, + multiLineInput: false, + requiredText: true, + readOnly: true, hintText: "Date", - editable: false, - required: false, - )), + ), const SizedBox(height: 10), - SizedBox( - // width: 500, - child: MIHTextField( + MihTextFormField( + fillColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + inputColor: + MzanziInnovationHub.of(context)!.theme.primaryColor(), controller: widget.timeController, + multiLineInput: false, + requiredText: true, + readOnly: true, hintText: "Time", - editable: false, - required: false, - )), + ), const SizedBox(height: 10), - SizedBox( - // width: 500, + MihTextFormField( + fillColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + inputColor: + MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: widget.descriptionIDController, + multiLineInput: true, height: 250, - child: MIHMLTextField( - controller: widget.descriptionIDController, - hintText: "Description", - editable: false, - required: false, - ), + requiredText: true, + readOnly: true, + hintText: "Appointment Description", ), const SizedBox(height: 10), ], @@ -304,55 +316,66 @@ class _BuildAppointmentListState extends State { }, windowBody: Column( children: [ - SizedBox( - // width: 500, - child: MIHTextField( - controller: widget.titleController, - hintText: "Title", - editable: false, - required: false, - ), + const SizedBox(height: 10), + MihTextFormField( + fillColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + inputColor: + MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: widget.titleController, + multiLineInput: false, + requiredText: true, + readOnly: true, + hintText: "Appointment Title", ), const SizedBox(height: 10), - SizedBox( - // width: 500, - child: MIHTextField( - controller: widget.titleController, - hintText: "Patient ID Number", - editable: false, - required: false, - ), - ), - const SizedBox(height: 10), - SizedBox( - // width: 500, - child: MIHTextField( + MihTextFormField( + fillColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + inputColor: + MzanziInnovationHub.of(context)!.theme.primaryColor(), controller: widget.dateController, + multiLineInput: false, + requiredText: true, + readOnly: true, hintText: "Date", - editable: false, - required: false, - )), - const SizedBox(height: 10), - SizedBox( - // width: 500, - child: MIHTextField( - controller: widget.timeController, - hintText: "Time", - editable: false, - required: false, - )), - const SizedBox(height: 10), - SizedBox( - // width: 500, - height: 250, - child: MIHMLTextField( - controller: widget.descriptionIDController, - hintText: "Description", - editable: false, - required: false, - ), ), - const SizedBox(height: 20), + const SizedBox(height: 10), + MihTextFormField( + fillColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + inputColor: + MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: widget.timeController, + multiLineInput: false, + requiredText: true, + readOnly: true, + hintText: "Time", + ), + const SizedBox(height: 10), + MihTextFormField( + fillColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + inputColor: + MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: widget.descriptionIDController, + multiLineInput: true, + height: 250, + requiredText: true, + readOnly: true, + hintText: "Appointment Description", + ), + const SizedBox(height: 10), + // SizedBox( + // // width: 500, + // child: MIHTextField( + // controller: widget.titleController, + // hintText: "Patient ID Number", + // editable: false, + // required: false, + // ), + // ), + // const SizedBox(height: 10), ], ), ); @@ -384,70 +407,95 @@ class _BuildAppointmentListState extends State { }, windowBody: Column( children: [ - SizedBox( - // width: 500, - child: MIHTextField( - controller: widget.titleController, - hintText: "Title", - editable: true, - required: true, - ), - ), - const SizedBox(height: 10), - SizedBox( - // width: 500, - child: MIHDateField( - controller: widget.dateController, - lableText: "Date", - required: true, - ), - ), - const SizedBox(height: 10), - SizedBox( - // width: 500, - child: MIHTimeField( - controller: widget.timeController, - lableText: "Time", - required: true, - ), - ), - const SizedBox(height: 10), - SizedBox( - // width: 500, - height: 250, - child: MIHMLTextField( - controller: widget.descriptionIDController, - hintText: "Description", - editable: true, - required: true, - ), - ), - const SizedBox(height: 20), - Wrap( - alignment: WrapAlignment.center, - runSpacing: 10, - spacing: 10, - children: [ - MihButton( - onPressed: () { - updateAppointmentCall(index); + MihForm( + formKey: _formKey, + formFields: [ + MihTextFormField( + fillColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + inputColor: + MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: widget.titleController, + multiLineInput: false, + requiredText: true, + hintText: "Appointment Title", + validator: (value) { + return MihValidationServices().isEmpty(value); }, - buttonColor: - MzanziInnovationHub.of(context)!.theme.successColor(), - width: 300, - child: Text( - "Update", - style: TextStyle( - color: MzanziInnovationHub.of(context)! - .theme - .primaryColor(), - fontSize: 20, - fontWeight: FontWeight.bold, - ), + ), + // SizedBox( + // // width: 500, + // child: MIHTextField( + // controller: widget.titleController, + // hintText: "Title", + // editable: true, + // required: true, + // ), + // ), + const SizedBox(height: 10), + SizedBox( + // width: 500, + child: MIHDateField( + controller: widget.dateController, + lableText: "Date", + required: true, + ), + ), + const SizedBox(height: 10), + SizedBox( + // width: 500, + child: MIHTimeField( + controller: widget.timeController, + lableText: "Time", + required: true, + ), + ), + const SizedBox(height: 10), + MihTextFormField( + fillColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + inputColor: + MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: widget.descriptionIDController, + multiLineInput: true, + height: 250, + requiredText: true, + hintText: "Appointment Description", + validator: (value) { + return MihValidationServices().isEmpty(value); + }, + ), + const SizedBox(height: 20), + Center( + child: Wrap( + alignment: WrapAlignment.center, + runSpacing: 10, + spacing: 10, + children: [ + MihButton( + onPressed: () { + updateAppointmentCall(index); + }, + buttonColor: MzanziInnovationHub.of(context)! + .theme + .successColor(), + width: 300, + child: Text( + "Update", + style: TextStyle( + color: MzanziInnovationHub.of(context)! + .theme + .primaryColor(), + fontSize: 20, + fontWeight: FontWeight.bold, + ), + ), + ), + ], ), ), ], - ) + ), ], ), ); diff --git a/Frontend/lib/mih_packages/calendar/package_tools/appointments.dart b/Frontend/lib/mih_packages/calendar/package_tools/appointments.dart index abf7f20b..d556bc74 100644 --- a/Frontend/lib/mih_packages/calendar/package_tools/appointments.dart +++ b/Frontend/lib/mih_packages/calendar/package_tools/appointments.dart @@ -1,14 +1,15 @@ import 'package:flutter_speed_dial/flutter_speed_dial.dart'; import 'package:mzansi_innovation_hub/mih_apis/mih_mzansi_calendar_apis.dart'; +import 'package:mzansi_innovation_hub/mih_apis/mih_validation_services.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_inputs_and_buttons/mih_date_input.dart'; -import 'package:mzansi_innovation_hub/mih_components/mih_inputs_and_buttons/mih_multiline_text_input.dart'; -import 'package:mzansi_innovation_hub/mih_components/mih_inputs_and_buttons/mih_text_input.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_inputs_and_buttons/mih_time_input.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_layout/mih_single_child_scroll.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_button.dart'; +import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_form.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package_tool_body.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_floating_menu.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package_window.dart'; +import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_text_form_field.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_pop_up_messages/mih_error_message.dart'; import 'package:mzansi_innovation_hub/mih_objects/appointment.dart'; import 'package:mzansi_innovation_hub/mih_objects/business.dart'; @@ -59,6 +60,8 @@ class _PatientAccessRequestState extends State { late Future> businessAppointmentResults; late Future> appointmentResults; + final _formKey = GlobalKey(); + Widget displayAppointmentList(List appointmentList) { if (appointmentList.isNotEmpty) { return Expanded( @@ -113,61 +116,79 @@ class _PatientAccessRequestState extends State { }, windowBody: Column( children: [ - SizedBox( - // width: 500, - child: MIHTextField( - controller: _appointmentTitleController, - hintText: "Title", - editable: true, - required: true, - ), - ), - const SizedBox(height: 10), - SizedBox( - // width: 500, - child: MIHDateField( - controller: _appointmentDateController, - lableText: "Date", - required: true, - ), - ), - const SizedBox(height: 10), - SizedBox( - // width: 500, - child: MIHTimeField( - controller: _appointmentTimeController, - lableText: "Time", - required: true, - ), - ), - const SizedBox(height: 10), - SizedBox( - // width: 500, - height: 250, - child: MIHMLTextField( - controller: _appointmentDescriptionIDController, - hintText: "Description", - editable: true, - required: true, - ), - ), - const SizedBox(height: 20), - MihButton( - onPressed: () { - addAppointmentCall(); - }, - buttonColor: - MzanziInnovationHub.of(context)!.theme.successColor(), - width: 300, - child: Text( - "Add", - style: TextStyle( - color: + MihForm( + formKey: _formKey, + formFields: [ + MihTextFormField( + fillColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + inputColor: MzanziInnovationHub.of(context)!.theme.primaryColor(), - fontSize: 20, - fontWeight: FontWeight.bold, + controller: _appointmentTitleController, + multiLineInput: false, + requiredText: true, + hintText: "Appointment Title", + validator: (value) { + return MihValidationServices().isEmpty(value); + }, ), - ), + const SizedBox(height: 10), + SizedBox( + // width: 500, + child: MIHDateField( + controller: _appointmentDateController, + lableText: "Date", + required: true, + ), + ), + const SizedBox(height: 10), + SizedBox( + // width: 500, + child: MIHTimeField( + controller: _appointmentTimeController, + lableText: "Time", + required: true, + ), + ), + const SizedBox(height: 10), + MihTextFormField( + fillColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + inputColor: + MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: _appointmentDescriptionIDController, + multiLineInput: true, + height: 250, + requiredText: true, + hintText: "Appointment Description", + validator: (value) { + return MihValidationServices().isEmpty(value); + }, + ), + const SizedBox(height: 20), + Center( + child: MihButton( + onPressed: () { + if (_formKey.currentState!.validate()) { + addAppointmentCall(); + } + }, + buttonColor: + MzanziInnovationHub.of(context)!.theme.successColor(), + width: 300, + child: Text( + "Add", + style: TextStyle( + color: MzanziInnovationHub.of(context)! + .theme + .primaryColor(), + fontSize: 20, + fontWeight: FontWeight.bold, + ), + ), + ), + ), + ], ), ], ), From 93158b3aa110e32b93c2ff99e1e52026f0914a95 Mon Sep 17 00:00:00 2001 From: Yasien Mac Mini Date: Wed, 4 Jun 2025 11:57:39 +0200 Subject: [PATCH 14/52] remove comments --- .../calendar/builder/build_appointment_list.dart | 9 --------- 1 file changed, 9 deletions(-) diff --git a/Frontend/lib/mih_packages/calendar/builder/build_appointment_list.dart b/Frontend/lib/mih_packages/calendar/builder/build_appointment_list.dart index 405ea621..fa829c9c 100644 --- a/Frontend/lib/mih_packages/calendar/builder/build_appointment_list.dart +++ b/Frontend/lib/mih_packages/calendar/builder/build_appointment_list.dart @@ -423,15 +423,6 @@ class _BuildAppointmentListState extends State { return MihValidationServices().isEmpty(value); }, ), - // SizedBox( - // // width: 500, - // child: MIHTextField( - // controller: widget.titleController, - // hintText: "Title", - // editable: true, - // required: true, - // ), - // ), const SizedBox(height: 10), SizedBox( // width: 500, From 2ca97f1ef29c4197093815b0b23f21ade3c67089 Mon Sep 17 00:00:00 2001 From: Yasien Mac Mini Date: Wed, 4 Jun 2025 12:00:52 +0200 Subject: [PATCH 15/52] Add new mih text form field to Mzansi AI --- .../mzansi_ai/package_tools/ai_chat.dart | 22 ++++++++++++------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/Frontend/lib/mih_packages/mzansi_ai/package_tools/ai_chat.dart b/Frontend/lib/mih_packages/mzansi_ai/package_tools/ai_chat.dart index 96f7c2fe..669ba269 100644 --- a/Frontend/lib/mih_packages/mzansi_ai/package_tools/ai_chat.dart +++ b/Frontend/lib/mih_packages/mzansi_ai/package_tools/ai_chat.dart @@ -4,10 +4,10 @@ import 'dart:convert'; import 'package:flutter_speed_dial/flutter_speed_dial.dart'; import 'package:mzansi_innovation_hub/main.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_inputs_and_buttons/mih_dropdown_input.dart'; -import 'package:mzansi_innovation_hub/mih_components/mih_inputs_and_buttons/mih_text_input.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package_tool_body.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package_window.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_floating_menu.dart'; +import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_text_form_field.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_pop_up_messages/mih_loading_circle.dart'; import 'package:mzansi_innovation_hub/mih_env/env.dart'; import 'package:mzansi_innovation_hub/mih_objects/app_user.dart'; @@ -436,6 +436,7 @@ class _AiChatState extends State { const SizedBox(height: 15), Row( mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.center, children: [ IconButton.filled( onPressed: () { @@ -450,14 +451,19 @@ class _AiChatState extends State { ), ), const SizedBox(width: 10), - SizedBox( + MihTextFormField( width: 200, - child: MIHTextField( - controller: _fontSizeController, - hintText: "Chat Font Size", - editable: false, - required: true, - ), + fillColor: MzanziInnovationHub.of(context)! + .theme + .secondaryColor(), + inputColor: MzanziInnovationHub.of(context)! + .theme + .primaryColor(), + controller: _fontSizeController, + multiLineInput: false, + requiredText: true, + readOnly: true, + hintText: "Time", ), const SizedBox(width: 10), IconButton.filled( From 1d8663919a731a21b37be5b1d87029c0bdd1724d Mon Sep 17 00:00:00 2001 From: Yasien Mac Mini Date: Wed, 4 Jun 2025 12:30:22 +0200 Subject: [PATCH 16/52] Add new mih text form field to Set Up Business --- .../profile_business_add.dart | 535 ++++++++++-------- 1 file changed, 310 insertions(+), 225 deletions(-) diff --git a/Frontend/lib/mih_packages/mzansi_profile/business_profile/profile_business_add.dart b/Frontend/lib/mih_packages/mzansi_profile/business_profile/profile_business_add.dart index 17b48760..1a883b6c 100644 --- a/Frontend/lib/mih_packages/mzansi_profile/business_profile/profile_business_add.dart +++ b/Frontend/lib/mih_packages/mzansi_profile/business_profile/profile_business_add.dart @@ -6,13 +6,15 @@ import 'package:mzansi_innovation_hub/mih_apis/mih_business_details_apis.dart'; import 'package:mzansi_innovation_hub/mih_apis/mih_file_api.dart'; import 'package:mzansi_innovation_hub/mih_apis/mih_location_api.dart'; import 'package:mzansi_innovation_hub/mih_apis/mih_my_business_user_apis.dart'; +import 'package:mzansi_innovation_hub/mih_apis/mih_validation_services.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_inputs_and_buttons/mih_dropdown_input.dart'; -import 'package:mzansi_innovation_hub/mih_components/mih_inputs_and_buttons/mih_text_input.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_layout/mih_action.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_layout/mih_body.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_layout/mih_header.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_layout/mih_layout_builder.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_button.dart'; +import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_form.dart'; +import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_text_form_field.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_pop_up_messages/mih_error_message.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_pop_up_messages/mih_success_message.dart'; import 'package:mzansi_innovation_hub/mih_env/env.dart'; @@ -60,6 +62,7 @@ class _ProfileBusinessAddState extends State { PlatformFile? selectedSignature; final ValueNotifier busType = ValueNotifier(""); + final _formKey = GlobalKey(); late String env; // Future uploadSelectedFile( @@ -217,17 +220,9 @@ class _ProfileBusinessAddState extends State { } bool isFieldsFilled() { - if (nameController.text.isEmpty || - typeController.text.isEmpty || - regController.text.isEmpty || - // logonameController.text.isEmpty || - fnameController.text.isEmpty || - lnameController.text.isEmpty || + if (typeController.text.isEmpty || titleController.text.isEmpty || - // signtureController.text.isEmpty || - accessController.text.isEmpty || - contactController.text.isEmpty || - emailController.text.isEmpty) { + accessController.text.isEmpty) { return false; } else { return true; @@ -235,9 +230,7 @@ class _ProfileBusinessAddState extends State { } void submitForm() { - if (!isEmailValid()) { - emailError(); - } else if (isFieldsFilled()) { + if (isFieldsFilled()) { print("Inside submit method"); createBusinessProfileAPICall(); } else { @@ -306,7 +299,7 @@ class _ProfileBusinessAddState extends State { MIHBody getBody() { return MIHBody( - borderOn: true, + borderOn: false, bodyItems: [ KeyboardListener( focusNode: _focusNode, @@ -314,13 +307,14 @@ class _ProfileBusinessAddState extends State { onKeyEvent: (event) async { if (event is KeyDownEvent && event.logicalKey == LogicalKeyboardKey.enter) { - submitForm(); + if (_formKey.currentState!.validate()) { + submitForm(); + } } }, child: SingleChildScrollView( child: Column( children: [ - //const SizedBox(height: 15), const Text( "My Business Details", style: TextStyle( @@ -333,223 +327,314 @@ class _ProfileBusinessAddState extends State { .theme .secondaryColor()), const SizedBox(height: 10.0), - // MihCircleAvatar( - // imageFile: logoPreview, - // width: 150, - // editable: true, - // fileNameController: logonameController, - // userSelectedfile: selectedLogo, - // frameColor: - // MzanziInnovationHub.of(context)!.theme.secondaryColor(), - // backgroundColor: - // MzanziInnovationHub.of(context)!.theme.primaryColor(), - // onChange: (selectedfile) { - // setState(() { - // selectedLogo = selectedfile; - // }); - // }, - // ), - // const SizedBox(height: 10.0), - // Visibility( - // visible: true, - // child: MIHTextField( - // controller: logonameController, - // hintText: "Selected Logo File Name", - // editable: false, - // required: true, - // ), - // ), - // const SizedBox(height: 10.0), - MIHTextField( - controller: regController, - hintText: "Registration No.", - editable: true, - required: true, - ), - const SizedBox(height: 10.0), - MIHTextField( - controller: nameController, - hintText: "Business Name", - editable: true, - required: true, - ), - const SizedBox(height: 10.0), - MIHDropdownField( - controller: typeController, - hintText: "Business Type", - dropdownOptions: const ["Doctors Office", "Other"], - required: true, - editable: true, - enableSearch: false, - ), - const SizedBox(height: 10.0), - ValueListenableBuilder( - valueListenable: busType, - builder: (BuildContext context, String value, Widget? child) { - return Visibility( - visible: value == "Doctors Office", - child: MIHTextField( - controller: practiceNoController, - hintText: "Practice Number", - editable: true, - required: true, - ), - ); - }, - ), - const SizedBox(height: 10.0), - MIHTextField( - controller: vatNoController, - hintText: "VAT Number", - editable: true, - required: true, - ), - const SizedBox(height: 10.0), - MIHTextField( - controller: contactController, - hintText: "Contact Number", - editable: true, - required: true, - ), - const SizedBox(height: 10.0), - MIHTextField( - controller: emailController, - hintText: "Email", - editable: true, - required: true, - ), - const SizedBox(height: 10.0), - // MIHFileField( - // controller: logonameController, - // hintText: "Logo", - // editable: false, - // required: true, - // onPressed: () async { - // FilePickerResult? result = - // await FilePicker.platform.pickFiles( - // type: FileType.custom, - // allowedExtensions: ['jpg', 'png', 'pdf'], - // ); - // if (result == null) return; - // final selectedFile = result.files.first; - // setState(() { - // selectedLogo = selectedFile; - // }); - // setState(() { - // logonameController.text = selectedFile.name; - // }); - // }, - // ), - const SizedBox(height: 10.0), - Row( - children: [ - Flexible( - child: MIHTextField( - controller: locationController, - hintText: "Location", - editable: false, - required: false, - ), - ), - const SizedBox(width: 10.0), - MihButton( - onPressed: () { - MIHLocationAPI() - .getGPSPosition(context) - .then((position) { - if (position != null) { - setState(() { - locationController.text = - "${position.latitude}, ${position.longitude}"; - }); - } - }); - }, - buttonColor: MzanziInnovationHub.of(context)! + MihForm( + formKey: _formKey, + formFields: [ + MihTextFormField( + fillColor: MzanziInnovationHub.of(context)! .theme .secondaryColor(), - width: 100, - child: Text( - "Set", - style: TextStyle( - color: MzanziInnovationHub.of(context)! + inputColor: + MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: regController, + multiLineInput: false, + requiredText: true, + hintText: "Registration No.", + validator: (value) { + return MihValidationServices().isEmpty(value); + }, + ), + // MIHTextField( + // controller: regController, + // hintText: "Registration No.", + // editable: true, + // required: true, + // ), + const SizedBox(height: 10.0), + MihTextFormField( + fillColor: MzanziInnovationHub.of(context)! + .theme + .secondaryColor(), + inputColor: + MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: nameController, + multiLineInput: false, + requiredText: true, + hintText: "Business Name", + validator: (value) { + return MihValidationServices().isEmpty(value); + }, + ), + // MIHTextField( + // controller: nameController, + // hintText: "Business Name", + // editable: true, + // required: true, + // ), + const SizedBox(height: 15.0), + MIHDropdownField( + controller: typeController, + hintText: "Business Type", + dropdownOptions: const ["Doctors Office", "Other"], + required: true, + editable: true, + enableSearch: false, + ), + const SizedBox(height: 10.0), + ValueListenableBuilder( + valueListenable: busType, + builder: + (BuildContext context, String value, Widget? child) { + return Visibility( + visible: value == "Doctors Office", + child: MihTextFormField( + fillColor: MzanziInnovationHub.of(context)! + .theme + .secondaryColor(), + inputColor: MzanziInnovationHub.of(context)! + .theme + .primaryColor(), + controller: practiceNoController, + multiLineInput: false, + requiredText: true, + hintText: "Practice Number", + validator: (validateValue) { + if (value == "Doctors Office") { + return MihValidationServices() + .isEmpty(validateValue); + } + return null; + }, + ), + ); + // MIHTextField( + // controller: practiceNoController, + // hintText: "Practice Number", + // editable: true, + // required: true, + // ), + // ); + }, + ), + const SizedBox(height: 10.0), + MihTextFormField( + fillColor: MzanziInnovationHub.of(context)! + .theme + .secondaryColor(), + inputColor: + MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: vatNoController, + multiLineInput: false, + requiredText: true, + hintText: "VAT Number", + validator: (value) { + return MihValidationServices().isEmpty(value); + }, + ), + // MIHTextField( + // controller: vatNoController, + // hintText: "VAT Number", + // editable: true, + // required: true, + // ), + const SizedBox(height: 10.0), + MihTextFormField( + fillColor: MzanziInnovationHub.of(context)! + .theme + .secondaryColor(), + inputColor: + MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: contactController, + multiLineInput: false, + requiredText: true, + hintText: "Contact Number", + validator: (value) { + return MihValidationServices().isEmpty(value); + }, + ), + // MIHTextField( + // controller: contactController, + // hintText: "Contact Number", + // editable: true, + // required: true, + // ), + const SizedBox(height: 10.0), + MihTextFormField( + fillColor: MzanziInnovationHub.of(context)! + .theme + .secondaryColor(), + inputColor: + MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: emailController, + multiLineInput: false, + requiredText: true, + hintText: "Business Email", + validator: (value) { + return MihValidationServices().validateEmail(value); + }, + ), + // MIHTextField( + // controller: emailController, + // hintText: "Email", + // editable: true, + // required: true, + // ), + const SizedBox(height: 10.0), + Row( + crossAxisAlignment: CrossAxisAlignment.end, + children: [ + Flexible( + child: MihTextFormField( + fillColor: MzanziInnovationHub.of(context)! + .theme + .secondaryColor(), + inputColor: MzanziInnovationHub.of(context)! + .theme + .primaryColor(), + controller: locationController, + multiLineInput: false, + requiredText: true, + hintText: "GPS Location", + ), + // MIHTextField( + // controller: locationController, + // hintText: "Location", + // editable: false, + // required: false, + // ), + ), + const SizedBox(width: 10.0), + MihButton( + onPressed: () { + MIHLocationAPI() + .getGPSPosition(context) + .then((position) { + if (position != null) { + setState(() { + locationController.text = + "${position.latitude}, ${position.longitude}"; + }); + } + }); + }, + buttonColor: MzanziInnovationHub.of(context)! .theme - .primaryColor(), - fontSize: 20, + .secondaryColor(), + width: 100, + child: Text( + "Set", + style: TextStyle( + color: MzanziInnovationHub.of(context)! + .theme + .primaryColor(), + fontSize: 20, + fontWeight: FontWeight.bold, + ), + ), + ), + ], + ), + const SizedBox(height: 15.0), + //const SizedBox(height: 15.0), + const Center( + child: Text( + "My Business User", + style: TextStyle( fontWeight: FontWeight.bold, + fontSize: 22, + ), + ), + ), + Divider( + color: MzanziInnovationHub.of(context)! + .theme + .secondaryColor()), + const SizedBox(height: 10.0), + MIHDropdownField( + controller: titleController, + hintText: "Title", + dropdownOptions: const ["Doctor", "Assistant"], + required: true, + editable: true, + enableSearch: false, + ), + const SizedBox(height: 10.0), + MihTextFormField( + fillColor: MzanziInnovationHub.of(context)! + .theme + .secondaryColor(), + inputColor: + MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: fnameController, + multiLineInput: false, + requiredText: true, + hintText: "First Name", + validator: (value) { + return MihValidationServices().isEmpty(value); + }, + ), + // MIHTextField( + // controller: fnameController, + // hintText: "Name", + // editable: false, + // required: true, + // ), + const SizedBox(height: 10.0), + MihTextFormField( + fillColor: MzanziInnovationHub.of(context)! + .theme + .secondaryColor(), + inputColor: + MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: lnameController, + multiLineInput: false, + requiredText: true, + hintText: "Surname", + validator: (value) { + return MihValidationServices().isEmpty(value); + }, + ), + // MIHTextField( + // controller: lnameController, + // hintText: "Surname", + // editable: false, + // required: true, + // ), + const SizedBox(height: 15.0), + MIHDropdownField( + controller: accessController, + hintText: "Access", + dropdownOptions: const ["Full", "Partial"], + required: true, + editable: false, + enableSearch: false, + ), + const SizedBox(height: 20.0), + Center( + child: MihButton( + onPressed: () { + if (_formKey.currentState!.validate()) { + submitForm(); + } + }, + buttonColor: MzanziInnovationHub.of(context)! + .theme + .secondaryColor(), + width: 300, + child: Text( + "Add", + style: TextStyle( + color: MzanziInnovationHub.of(context)! + .theme + .primaryColor(), + fontSize: 20, + fontWeight: FontWeight.bold, + ), ), ), ), ], ), - - const SizedBox(height: 15.0), - Divider( - color: - MzanziInnovationHub.of(context)?.theme.secondaryColor(), - ), - //const SizedBox(height: 15.0), - const Text( - "My Business User", - style: TextStyle( - fontWeight: FontWeight.bold, - fontSize: 22, - ), - ), - Divider( - color: MzanziInnovationHub.of(context)! - .theme - .secondaryColor()), - const SizedBox(height: 10.0), - MIHDropdownField( - controller: titleController, - hintText: "Title", - dropdownOptions: const ["Doctor", "Assistant"], - required: true, - editable: true, - enableSearch: false, - ), - const SizedBox(height: 10.0), - MIHTextField( - controller: fnameController, - hintText: "Name", - editable: false, - required: true, - ), - const SizedBox(height: 10.0), - MIHTextField( - controller: lnameController, - hintText: "Surname", - editable: false, - required: true, - ), - const SizedBox(height: 15.0), - MIHDropdownField( - controller: accessController, - hintText: "Access", - dropdownOptions: const ["Full", "Partial"], - required: true, - editable: false, - enableSearch: false, - ), - const SizedBox(height: 30.0), - MihButton( - onPressed: () { - submitForm(); - }, - buttonColor: - MzanziInnovationHub.of(context)!.theme.secondaryColor(), - width: 300, - child: Text( - "Add", - style: TextStyle( - color: - MzanziInnovationHub.of(context)!.theme.primaryColor(), - fontSize: 20, - fontWeight: FontWeight.bold, - ), - ), - ), ], ), ), From f7dace81159f399aff07c5025c886c595e1ef7b2 Mon Sep 17 00:00:00 2001 From: Yasien Mac Mini Date: Wed, 4 Jun 2025 12:32:07 +0200 Subject: [PATCH 17/52] remove comments --- .../profile_business_add.dart | 55 ------------------- 1 file changed, 55 deletions(-) diff --git a/Frontend/lib/mih_packages/mzansi_profile/business_profile/profile_business_add.dart b/Frontend/lib/mih_packages/mzansi_profile/business_profile/profile_business_add.dart index 1a883b6c..7f5818a2 100644 --- a/Frontend/lib/mih_packages/mzansi_profile/business_profile/profile_business_add.dart +++ b/Frontend/lib/mih_packages/mzansi_profile/business_profile/profile_business_add.dart @@ -344,12 +344,6 @@ class _ProfileBusinessAddState extends State { return MihValidationServices().isEmpty(value); }, ), - // MIHTextField( - // controller: regController, - // hintText: "Registration No.", - // editable: true, - // required: true, - // ), const SizedBox(height: 10.0), MihTextFormField( fillColor: MzanziInnovationHub.of(context)! @@ -365,12 +359,6 @@ class _ProfileBusinessAddState extends State { return MihValidationServices().isEmpty(value); }, ), - // MIHTextField( - // controller: nameController, - // hintText: "Business Name", - // editable: true, - // required: true, - // ), const SizedBox(height: 15.0), MIHDropdownField( controller: typeController, @@ -407,13 +395,6 @@ class _ProfileBusinessAddState extends State { }, ), ); - // MIHTextField( - // controller: practiceNoController, - // hintText: "Practice Number", - // editable: true, - // required: true, - // ), - // ); }, ), const SizedBox(height: 10.0), @@ -431,12 +412,6 @@ class _ProfileBusinessAddState extends State { return MihValidationServices().isEmpty(value); }, ), - // MIHTextField( - // controller: vatNoController, - // hintText: "VAT Number", - // editable: true, - // required: true, - // ), const SizedBox(height: 10.0), MihTextFormField( fillColor: MzanziInnovationHub.of(context)! @@ -452,12 +427,6 @@ class _ProfileBusinessAddState extends State { return MihValidationServices().isEmpty(value); }, ), - // MIHTextField( - // controller: contactController, - // hintText: "Contact Number", - // editable: true, - // required: true, - // ), const SizedBox(height: 10.0), MihTextFormField( fillColor: MzanziInnovationHub.of(context)! @@ -473,12 +442,6 @@ class _ProfileBusinessAddState extends State { return MihValidationServices().validateEmail(value); }, ), - // MIHTextField( - // controller: emailController, - // hintText: "Email", - // editable: true, - // required: true, - // ), const SizedBox(height: 10.0), Row( crossAxisAlignment: CrossAxisAlignment.end, @@ -496,12 +459,6 @@ class _ProfileBusinessAddState extends State { requiredText: true, hintText: "GPS Location", ), - // MIHTextField( - // controller: locationController, - // hintText: "Location", - // editable: false, - // required: false, - // ), ), const SizedBox(width: 10.0), MihButton( @@ -573,12 +530,6 @@ class _ProfileBusinessAddState extends State { return MihValidationServices().isEmpty(value); }, ), - // MIHTextField( - // controller: fnameController, - // hintText: "Name", - // editable: false, - // required: true, - // ), const SizedBox(height: 10.0), MihTextFormField( fillColor: MzanziInnovationHub.of(context)! @@ -594,12 +545,6 @@ class _ProfileBusinessAddState extends State { return MihValidationServices().isEmpty(value); }, ), - // MIHTextField( - // controller: lnameController, - // hintText: "Surname", - // editable: false, - // required: true, - // ), const SizedBox(height: 15.0), MIHDropdownField( controller: accessController, From 6b6697789e11ef6e535a272b115df4c418e6c86a Mon Sep 17 00:00:00 2001 From: Yasien Mac Mini Date: Wed, 4 Jun 2025 12:41:31 +0200 Subject: [PATCH 18/52] fix update appointment validation on submit --- .../calendar/builder/build_appointment_list.dart | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Frontend/lib/mih_packages/calendar/builder/build_appointment_list.dart b/Frontend/lib/mih_packages/calendar/builder/build_appointment_list.dart index fa829c9c..21db4f68 100644 --- a/Frontend/lib/mih_packages/calendar/builder/build_appointment_list.dart +++ b/Frontend/lib/mih_packages/calendar/builder/build_appointment_list.dart @@ -465,7 +465,9 @@ class _BuildAppointmentListState extends State { children: [ MihButton( onPressed: () { - updateAppointmentCall(index); + if (_formKey.currentState!.validate()) { + updateAppointmentCall(index); + } }, buttonColor: MzanziInnovationHub.of(context)! .theme @@ -495,9 +497,7 @@ class _BuildAppointmentListState extends State { } bool isAppointmentInputValid() { - if (widget.titleController.text.isEmpty || - widget.descriptionIDController.text.isEmpty || - widget.dateController.text.isEmpty || + if (widget.dateController.text.isEmpty || widget.timeController.text.isEmpty) { return false; } else { From d1716db1e7faad58192b185638cbceb7b9db57fc Mon Sep 17 00:00:00 2001 From: Yasien Mac Mini Date: Wed, 4 Jun 2025 13:39:02 +0200 Subject: [PATCH 19/52] Add new mih text form field to Business Profile --- .../builders/build_employee_list.dart | 137 +++++--- .../builders/build_user_list.dart | 154 +++++---- .../package_tools/mih_business_details.dart | 324 ++++++++++-------- .../package_tools/mih_my_business_user.dart | 281 +++++++++------ 4 files changed, 526 insertions(+), 370 deletions(-) diff --git a/Frontend/lib/mih_packages/mzansi_profile/business_profile/builders/build_employee_list.dart b/Frontend/lib/mih_packages/mzansi_profile/business_profile/builders/build_employee_list.dart index ee7cd38d..fd1ab642 100644 --- a/Frontend/lib/mih_packages/mzansi_profile/business_profile/builders/build_employee_list.dart +++ b/Frontend/lib/mih_packages/mzansi_profile/business_profile/builders/build_employee_list.dart @@ -3,9 +3,10 @@ import 'dart:convert'; import 'package:flutter_speed_dial/flutter_speed_dial.dart'; import 'package:mzansi_innovation_hub/main.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_inputs_and_buttons/mih_dropdown_input.dart'; -import 'package:mzansi_innovation_hub/mih_components/mih_inputs_and_buttons/mih_text_input.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_button.dart'; +import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_form.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package_window.dart'; +import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_text_form_field.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_pop_up_messages/mih_delete_message.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_pop_up_messages/mih_error_message.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_pop_up_messages/mih_loading_circle.dart'; @@ -36,6 +37,7 @@ class _BuildEmployeeListState extends State { TextEditingController fnameController = TextEditingController(); TextEditingController lnameController = TextEditingController(); + final _formKey = GlobalKey(); final baseAPI = AppEnviroment.baseApiUrl; Future updateEmployeeAPICall(int index) async { @@ -178,63 +180,84 @@ class _BuildEmployeeListState extends State { }, windowBody: Column( children: [ - const SizedBox(height: 10.0), - MIHTextField( - controller: fnameController, - hintText: "First Name", - editable: false, - required: true, - ), - const SizedBox(height: 10.0), - MIHTextField( - controller: lnameController, - hintText: "Surname", - editable: false, - required: true, - ), - const SizedBox(height: 10.0), - MIHDropdownField( - controller: typeController, - hintText: "Title", - dropdownOptions: const ["Doctor", "Assistant"], - required: true, - editable: true, - enableSearch: false, - ), - const SizedBox(height: 10.0), - MIHDropdownField( - controller: accessController, - hintText: "Access", - dropdownOptions: const ["Full", "Partial"], - required: true, - editable: true, - enableSearch: false, - ), - const SizedBox(height: 15.0), - MihButton( - onPressed: () { - if (isRequiredFieldsCaptured()) { - updateEmployeeAPICall(index); - } else { - showDialog( - context: context, - builder: (context) { - return const MIHErrorMessage(errorType: "Input Error"); - }, - ); - } - }, - buttonColor: - MzanziInnovationHub.of(context)!.theme.secondaryColor(), - width: 300, - child: Text( - "Update", - style: TextStyle( - color: MzanziInnovationHub.of(context)!.theme.primaryColor(), - fontSize: 20, - fontWeight: FontWeight.bold, + MihForm( + formKey: _formKey, + formFields: [ + MihTextFormField( + fillColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + inputColor: + MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: fnameController, + multiLineInput: false, + requiredText: true, + readOnly: true, + hintText: "First Name", ), - ), + const SizedBox(height: 10.0), + MihTextFormField( + fillColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + inputColor: + MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: lnameController, + multiLineInput: false, + requiredText: true, + readOnly: true, + hintText: "Surname", + ), + const SizedBox(height: 15.0), + MIHDropdownField( + controller: typeController, + hintText: "Title", + dropdownOptions: const ["Doctor", "Assistant"], + required: true, + editable: true, + enableSearch: false, + ), + const SizedBox(height: 10.0), + MIHDropdownField( + controller: accessController, + hintText: "Access", + dropdownOptions: const ["Full", "Partial"], + required: true, + editable: true, + enableSearch: false, + ), + const SizedBox(height: 20.0), + Center( + child: MihButton( + onPressed: () { + if (_formKey.currentState!.validate()) { + if (isRequiredFieldsCaptured()) { + updateEmployeeAPICall(index); + } else { + showDialog( + context: context, + builder: (context) { + return const MIHErrorMessage( + errorType: "Input Error"); + }, + ); + } + } + }, + buttonColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + width: 300, + child: Text( + "Update", + style: TextStyle( + color: MzanziInnovationHub.of(context)! + .theme + .primaryColor(), + fontSize: 20, + fontWeight: FontWeight.bold, + ), + ), + ), + ), + ], ), ], ), diff --git a/Frontend/lib/mih_packages/mzansi_profile/business_profile/builders/build_user_list.dart b/Frontend/lib/mih_packages/mzansi_profile/business_profile/builders/build_user_list.dart index 14d0998a..a5ba1ebe 100644 --- a/Frontend/lib/mih_packages/mzansi_profile/business_profile/builders/build_user_list.dart +++ b/Frontend/lib/mih_packages/mzansi_profile/business_profile/builders/build_user_list.dart @@ -2,9 +2,10 @@ import 'dart:convert'; import 'package:mzansi_innovation_hub/main.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_inputs_and_buttons/mih_dropdown_input.dart'; -import 'package:mzansi_innovation_hub/mih_components/mih_inputs_and_buttons/mih_text_input.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_button.dart'; +import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_form.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package_window.dart'; +import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_text_form_field.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_pop_up_messages/mih_error_message.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_pop_up_messages/mih_loading_circle.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_pop_up_messages/mih_success_message.dart'; @@ -31,9 +32,10 @@ class BuildUserList extends StatefulWidget { class _BuildUserListState extends State { TextEditingController accessController = TextEditingController(); TextEditingController typeController = TextEditingController(); - TextEditingController fnameController = TextEditingController(); - TextEditingController lnameController = TextEditingController(); + TextEditingController usernameController = TextEditingController(); + TextEditingController emailController = TextEditingController(); + final _formKey = GlobalKey(); final baseAPI = AppEnviroment.baseApiUrl; Future createBusinessUserAPICall(int index) async { @@ -118,8 +120,8 @@ class _BuildUserListState extends State { //typeController.text = widget.users[index].title; // var fnameInitial = widget.users[index].fname[0]; // var lnameInitial = widget.users[index].lname[0]; - fnameController.text = widget.users[index].username; - lnameController.text = hideEmail(widget.users[index].email); + usernameController.text = widget.users[index].username; + emailController.text = hideEmail(widget.users[index].email); }); showDialog( context: context, @@ -129,67 +131,89 @@ class _BuildUserListState extends State { windowTitle: "Add Employee", windowBody: Column( children: [ - const SizedBox(height: 10.0), - MIHTextField( - controller: fnameController, - hintText: "Username Name", - editable: false, - required: true, - ), - const SizedBox(height: 10.0), - MIHTextField( - controller: lnameController, - hintText: "Email", - editable: false, - required: true, - ), - const SizedBox(height: 10.0), - MIHDropdownField( - controller: typeController, - hintText: "Title", - dropdownOptions: const ["Doctor", "Assistant"], - required: true, - editable: true, - enableSearch: false, - ), - const SizedBox(height: 10.0), - MIHDropdownField( - controller: accessController, - hintText: "Access", - dropdownOptions: const ["Full", "Partial"], - required: true, - editable: true, - enableSearch: false, - ), - const SizedBox(height: 15.0), - MihButton( - onPressed: () { - if (isRequiredFieldsCaptured()) { - createBusinessUserAPICall(index); - } else { - showDialog( - context: context, - builder: (context) { - return const MIHErrorMessage( - errorType: "Input Error"); - }, - ); - } - }, - buttonColor: - MzanziInnovationHub.of(context)!.theme.secondaryColor(), - width: 300, - child: Text( - "Add", - style: TextStyle( - color: + MihForm( + formKey: _formKey, + formFields: [ + MihTextFormField( + fillColor: MzanziInnovationHub.of(context)! + .theme + .secondaryColor(), + inputColor: MzanziInnovationHub.of(context)!.theme.primaryColor(), - fontSize: 20, - fontWeight: FontWeight.bold, + controller: usernameController, + multiLineInput: false, + requiredText: true, + readOnly: true, + hintText: "Username", ), - ), + const SizedBox(height: 10.0), + MihTextFormField( + fillColor: MzanziInnovationHub.of(context)! + .theme + .secondaryColor(), + inputColor: + MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: emailController, + multiLineInput: false, + requiredText: true, + readOnly: true, + hintText: "Email", + ), + const SizedBox(height: 15.0), + MIHDropdownField( + controller: typeController, + hintText: "Title", + dropdownOptions: const ["Doctor", "Assistant"], + required: true, + editable: true, + enableSearch: false, + ), + const SizedBox(height: 10.0), + MIHDropdownField( + controller: accessController, + hintText: "Access", + dropdownOptions: const ["Full", "Partial"], + required: true, + editable: true, + enableSearch: false, + ), + const SizedBox(height: 15.0), + Center( + child: MihButton( + onPressed: () { + if (_formKey.currentState!.validate()) { + if (isRequiredFieldsCaptured()) { + createBusinessUserAPICall(index); + } else { + showDialog( + context: context, + builder: (context) { + return const MIHErrorMessage( + errorType: "Input Error"); + }, + ); + } + } + }, + buttonColor: MzanziInnovationHub.of(context)! + .theme + .secondaryColor(), + width: 300, + child: Text( + "Add", + style: TextStyle( + color: MzanziInnovationHub.of(context)! + .theme + .primaryColor(), + fontSize: 20, + fontWeight: FontWeight.bold, + ), + ), + ), + ), + const SizedBox(height: 10.0), + ], ), - const SizedBox(height: 10.0), ], ), onWindowTapClose: () { @@ -201,8 +225,8 @@ class _BuildUserListState extends State { void dispose() { accessController.dispose(); typeController.dispose(); - fnameController.dispose(); - lnameController.dispose(); + usernameController.dispose(); + emailController.dispose(); super.dispose(); } diff --git a/Frontend/lib/mih_packages/mzansi_profile/business_profile/package_tools/mih_business_details.dart b/Frontend/lib/mih_packages/mzansi_profile/business_profile/package_tools/mih_business_details.dart index 3e764e39..42a35ed1 100644 --- a/Frontend/lib/mih_packages/mzansi_profile/business_profile/package_tools/mih_business_details.dart +++ b/Frontend/lib/mih_packages/mzansi_profile/business_profile/package_tools/mih_business_details.dart @@ -4,12 +4,15 @@ import 'package:mzansi_innovation_hub/main.dart'; import 'package:mzansi_innovation_hub/mih_apis/mih_business_details_apis.dart'; import 'package:mzansi_innovation_hub/mih_apis/mih_file_api.dart'; import 'package:mzansi_innovation_hub/mih_apis/mih_location_api.dart'; -import 'package:mzansi_innovation_hub/mih_components/mih_inputs_and_buttons/mih_text_input.dart'; +import 'package:mzansi_innovation_hub/mih_apis/mih_validation_services.dart'; +import 'package:mzansi_innovation_hub/mih_components/mih_inputs_and_buttons/mih_dropdown_input.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_layout/mih_single_child_scroll.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_button.dart'; +import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_form.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package_tool_body.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package_alert.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_circle_avatar.dart'; +import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_text_form_field.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_pop_up_messages/mih_error_message.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_pop_up_messages/mih_success_message.dart'; import 'package:mzansi_innovation_hub/mih_env/env.dart'; @@ -39,17 +42,11 @@ class _MihBusinessDetailsState extends State { final contactController = TextEditingController(); final emailController = TextEditingController(); final locationController = TextEditingController(); + final _formKey = GlobalKey(); late String env; Future submitForm() async { - if (!isEmailValid()) { - showDialog( - context: context, - builder: (context) { - return const MIHErrorMessage(errorType: "Invalid Email"); - }, - ); - } else if (isFormFilled()) { + if (isFormFilled()) { int statusCode = 0; statusCode = await MihBusinessDetailsApi().updateBusinessDetails( widget.arguments.business!.business_id, @@ -180,14 +177,7 @@ class _MihBusinessDetailsState extends State { } bool isFormFilled() { - if (regController.text.isEmpty || - nameController.text.isEmpty || - typeController.text.isEmpty || - practiceNoController.text.isEmpty || - vatNoController.text.isEmpty || - contactController.text.isEmpty || - emailController.text.isEmpty || - locationController.text.isEmpty) { + if (typeController.text.isEmpty) { return false; } else { return true; @@ -244,132 +234,196 @@ class _MihBusinessDetailsState extends State { return MihSingleChildScroll( child: Column( children: [ - MihCircleAvatar( - imageFile: widget.logoImage, - width: 150, - editable: true, - fileNameController: fileNameController, - userSelectedfile: imageFile, - frameColor: MzanziInnovationHub.of(context)!.theme.secondaryColor(), - backgroundColor: - MzanziInnovationHub.of(context)!.theme.primaryColor(), - onChange: (selectedfile) { - setState(() { - imageFile = selectedfile; - }); - }, - ), - Visibility( - visible: false, - child: MIHTextField( - controller: fileNameController, - hintText: "Selected File Name", - editable: false, - required: false, - ), - ), - const SizedBox(height: 20), - MIHTextField( - controller: regController, - hintText: "Registration No.", - editable: true, - required: true, - ), - const SizedBox(height: 10), - MIHTextField( - controller: nameController, - hintText: "Business Name", - editable: true, - required: true, - ), - const SizedBox(height: 10), - MIHTextField( - controller: typeController, - hintText: "Business Type", - editable: true, - required: true, - ), - const SizedBox(height: 10), - MIHTextField( - controller: practiceNoController, - hintText: "Practice Number", - editable: true, - required: true, - ), - const SizedBox(height: 10), - MIHTextField( - controller: vatNoController, - hintText: "VAT Number", - editable: true, - required: true, - ), - const SizedBox(height: 10), - MIHTextField( - controller: contactController, - hintText: "Contact Number", - editable: true, - required: true, - ), - const SizedBox(height: 10), - MIHTextField( - controller: emailController, - hintText: "Email", - editable: true, - required: true, - ), - const SizedBox(height: 10), - Row( - children: [ - Flexible( - child: MIHTextField( - controller: locationController, - hintText: "Location", - editable: false, - required: false, + MihForm( + formKey: _formKey, + formFields: [ + Center( + child: MihCircleAvatar( + imageFile: widget.logoImage, + width: 150, + editable: true, + fileNameController: fileNameController, + userSelectedfile: imageFile, + frameColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + backgroundColor: + MzanziInnovationHub.of(context)!.theme.primaryColor(), + onChange: (selectedfile) { + setState(() { + imageFile = selectedfile; + }); + }, ), ), - const SizedBox(width: 10.0), - MihButton( - onPressed: () { - MIHLocationAPI().getGPSPosition(context).then((position) { - if (position != null) { - setState(() { - locationController.text = - "${position.latitude}, ${position.longitude}"; - }); - } - }); - }, - buttonColor: + Visibility( + visible: false, + child: MihTextFormField( + fillColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + inputColor: + MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: fileNameController, + multiLineInput: false, + requiredText: true, + readOnly: true, + hintText: "Selected File Name", + ), + ), + const SizedBox(height: 20), + MihTextFormField( + fillColor: MzanziInnovationHub.of(context)!.theme.secondaryColor(), - width: 100, - child: Text( - "Set", - style: TextStyle( - color: MzanziInnovationHub.of(context)!.theme.primaryColor(), - fontSize: 20, - fontWeight: FontWeight.bold, + inputColor: MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: regController, + multiLineInput: false, + requiredText: true, + hintText: "Registration No.", + validator: (value) { + return MihValidationServices().isEmpty(value); + }, + ), + const SizedBox(height: 10), + MihTextFormField( + fillColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + inputColor: MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: nameController, + multiLineInput: false, + requiredText: true, + hintText: "Business Name", + validator: (value) { + return MihValidationServices().isEmpty(value); + }, + ), + const SizedBox(height: 15), + MIHDropdownField( + controller: typeController, + hintText: "Business Type", + dropdownOptions: const ["Doctors Office", "Other"], + required: true, + editable: true, + enableSearch: false, + ), + const SizedBox(height: 10), + MihTextFormField( + fillColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + inputColor: MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: practiceNoController, + multiLineInput: false, + requiredText: typeController.text == "Doctors Office", + hintText: "Practice Number", + validator: (validateValue) { + return MihValidationServices().isEmpty(validateValue); + }, + ), + const SizedBox(height: 10), + MihTextFormField( + fillColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + inputColor: MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: vatNoController, + multiLineInput: false, + requiredText: true, + hintText: "VAT Number", + validator: (value) { + return MihValidationServices().isEmpty(value); + }, + ), + const SizedBox(height: 10), + MihTextFormField( + fillColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + inputColor: MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: contactController, + multiLineInput: false, + requiredText: true, + hintText: "Contact Number", + validator: (value) { + return MihValidationServices().isEmpty(value); + }, + ), + const SizedBox(height: 10), + MihTextFormField( + fillColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + inputColor: MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: emailController, + multiLineInput: false, + requiredText: true, + hintText: "Business Email", + validator: (value) { + return MihValidationServices().validateEmail(value); + }, + ), + const SizedBox(height: 10), + Row( + crossAxisAlignment: CrossAxisAlignment.end, + children: [ + Flexible( + child: MihTextFormField( + fillColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + inputColor: + MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: locationController, + multiLineInput: false, + requiredText: true, + hintText: "GPS Location", + ), + ), + const SizedBox(width: 10.0), + MihButton( + onPressed: () { + MIHLocationAPI().getGPSPosition(context).then((position) { + if (position != null) { + setState(() { + locationController.text = + "${position.latitude}, ${position.longitude}"; + }); + } + }); + }, + buttonColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + width: 100, + child: Text( + "Set", + style: TextStyle( + color: + MzanziInnovationHub.of(context)!.theme.primaryColor(), + fontSize: 20, + fontWeight: FontWeight.bold, + ), + ), + ), + ], + ), + const SizedBox(height: 15), + Center( + child: MihButton( + onPressed: () { + if (_formKey.currentState!.validate()) { + submitForm(); + } + }, + buttonColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + width: 300, + child: Text( + "Update", + style: TextStyle( + color: + MzanziInnovationHub.of(context)!.theme.primaryColor(), + fontSize: 20, + fontWeight: FontWeight.bold, + ), ), ), ), + const SizedBox(height: 20), ], ), - const SizedBox(height: 15), - MihButton( - onPressed: () { - submitForm(); - }, - buttonColor: MzanziInnovationHub.of(context)!.theme.secondaryColor(), - width: 300, - child: Text( - "Update", - style: TextStyle( - color: MzanziInnovationHub.of(context)!.theme.primaryColor(), - fontSize: 20, - fontWeight: FontWeight.bold, - ), - ), - ), ], )); } diff --git a/Frontend/lib/mih_packages/mzansi_profile/business_profile/package_tools/mih_my_business_user.dart b/Frontend/lib/mih_packages/mzansi_profile/business_profile/package_tools/mih_my_business_user.dart index a847e052..99cc5a99 100644 --- a/Frontend/lib/mih_packages/mzansi_profile/business_profile/package_tools/mih_my_business_user.dart +++ b/Frontend/lib/mih_packages/mzansi_profile/business_profile/package_tools/mih_my_business_user.dart @@ -3,14 +3,16 @@ import 'package:flutter/material.dart'; import 'package:mzansi_innovation_hub/main.dart'; import 'package:mzansi_innovation_hub/mih_apis/mih_file_api.dart'; import 'package:mzansi_innovation_hub/mih_apis/mih_my_business_user_apis.dart'; +import 'package:mzansi_innovation_hub/mih_apis/mih_validation_services.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_inputs_and_buttons/mih_dropdown_input.dart'; -import 'package:mzansi_innovation_hub/mih_components/mih_inputs_and_buttons/mih_text_input.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_layout/mih_single_child_scroll.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_button.dart'; +import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_form.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package_tool_body.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package_alert.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_circle_avatar.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_image_display.dart'; +import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_text_form_field.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_pop_up_messages/mih_error_message.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_pop_up_messages/mih_success_message.dart'; import 'package:mzansi_innovation_hub/mih_env/env.dart'; @@ -42,15 +44,11 @@ class _MihMyBusinessUserState extends State { final lnameController = TextEditingController(); final accessController = TextEditingController(); final signtureController = TextEditingController(); + final _formKey = GlobalKey(); late String env; bool isFormFilled() { - if (signtureController.text.isEmpty || - titleDropdownController.text.isEmpty || - titleTextController.text.isEmpty || - fnameController.text.isEmpty || - lnameController.text.isEmpty || - accessController.text.isEmpty) { + if (titleDropdownController.text.isEmpty) { return false; } else { return true; @@ -216,114 +214,171 @@ class _MihMyBusinessUserState extends State { return MihSingleChildScroll( child: Column( children: [ - MihCircleAvatar( - imageFile: widget.userProPicImage, - width: 150, - editable: false, - fileNameController: fileNameController, - userSelectedfile: userPicFile, - frameColor: MzanziInnovationHub.of(context)!.theme.secondaryColor(), - backgroundColor: - MzanziInnovationHub.of(context)!.theme.primaryColor(), - onChange: (_) {}, - ), - Visibility( - visible: false, - child: MIHTextField( - controller: fileNameController, - hintText: "Selected File Name", - editable: false, - required: false, - ), - ), - const SizedBox(height: 20), - MIHDropdownField( - controller: titleDropdownController, - hintText: "Title", - dropdownOptions: const ["Doctor", "Assistant", "Other"], - required: true, - editable: true, - enableSearch: false, - ), - const SizedBox(height: 10), - MIHTextField( - controller: titleTextController, - hintText: "Other Title", - editable: true, - required: true, - ), - const SizedBox(height: 10), - MIHTextField( - controller: fnameController, - hintText: "Name", - editable: false, - required: true, - ), - const SizedBox(height: 10), - MIHTextField( - controller: lnameController, - hintText: "Surname", - editable: false, - required: true, - ), - const SizedBox(height: 10), - MIHTextField( - controller: accessController, - hintText: "Access Level", - editable: false, - required: true, - ), - const SizedBox(height: 10), - Container( - width: 300, - alignment: Alignment.topLeft, - child: const Text( - "Signature:", - style: TextStyle( - fontSize: 15, - fontWeight: FontWeight.bold, + MihForm( + formKey: _formKey, + formFields: [ + Center( + child: MihCircleAvatar( + imageFile: widget.userProPicImage, + width: 150, + editable: false, + fileNameController: fileNameController, + userSelectedfile: userPicFile, + frameColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + backgroundColor: + MzanziInnovationHub.of(context)!.theme.primaryColor(), + onChange: (_) {}, + ), ), - ), - ), - MihImageDisplay( - imageFile: widget.userSignatureImage, - width: 300, - height: 200, - editable: true, - fileNameController: signtureController, - userSelectedfile: userSignatureFile, - onChange: (selectedFile) { - setState(() { - userSignatureFile = selectedFile; - }); - }, - ), - const SizedBox(height: 10), - Visibility( - visible: false, - child: MIHTextField( - controller: signtureController, - hintText: "Selected Signature File", - editable: false, - required: true, - ), - ), - const SizedBox(height: 15), - MihButton( - onPressed: () { - submitForm(); - }, - buttonColor: - MzanziInnovationHub.of(context)!.theme.secondaryColor(), - width: 300, - child: Text( - "Update", - style: TextStyle( - color: MzanziInnovationHub.of(context)!.theme.primaryColor(), - fontSize: 20, - fontWeight: FontWeight.bold, + Visibility( + visible: false, + child: MihTextFormField( + fillColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + inputColor: + MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: fileNameController, + multiLineInput: false, + requiredText: true, + readOnly: true, + hintText: "Selected File Name", + ), ), - ), + const SizedBox(height: 20), + MIHDropdownField( + controller: titleDropdownController, + hintText: "Title", + dropdownOptions: const ["Doctor", "Assistant", "Other"], + required: true, + editable: true, + enableSearch: false, + ), + const SizedBox(height: 10), + MihTextFormField( + fillColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + inputColor: + MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: titleTextController, + multiLineInput: false, + requiredText: true, + hintText: "Other Title", + validator: (value) { + return MihValidationServices().isEmpty(value); + }, + ), + const SizedBox(height: 10), + MihTextFormField( + fillColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + inputColor: + MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: fnameController, + multiLineInput: false, + requiredText: true, + readOnly: true, + hintText: "First Name", + validator: (value) { + return MihValidationServices().isEmpty(value); + }, + ), + const SizedBox(height: 10), + MihTextFormField( + fillColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + inputColor: + MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: lnameController, + multiLineInput: false, + requiredText: true, + readOnly: true, + hintText: "Surname", + validator: (value) { + return MihValidationServices().isEmpty(value); + }, + ), + const SizedBox(height: 10), + MihTextFormField( + fillColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + inputColor: + MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: accessController, + multiLineInput: false, + requiredText: true, + hintText: "Access Level", + readOnly: true, + validator: (value) { + return MihValidationServices().isEmpty(value); + }, + ), + const SizedBox(height: 10), + Container( + width: 300, + alignment: Alignment.topLeft, + child: const Text( + "Signature:", + style: TextStyle( + fontSize: 15, + fontWeight: FontWeight.bold, + ), + ), + ), + Center( + child: MihImageDisplay( + imageFile: widget.userSignatureImage, + width: 300, + height: 200, + editable: true, + fileNameController: signtureController, + userSelectedfile: userSignatureFile, + onChange: (selectedFile) { + setState(() { + userSignatureFile = selectedFile; + }); + }, + ), + ), + const SizedBox(height: 10), + Visibility( + visible: false, + child: MihTextFormField( + fillColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + inputColor: + MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: fileNameController, + multiLineInput: false, + requiredText: true, + readOnly: true, + hintText: "Selected Signature File", + ), + ), + const SizedBox(height: 15), + Center( + child: MihButton( + onPressed: () { + if (_formKey.currentState!.validate()) { + submitForm(); + } + }, + buttonColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + width: 300, + child: Text( + "Update", + style: TextStyle( + color: + MzanziInnovationHub.of(context)!.theme.primaryColor(), + fontSize: 20, + fontWeight: FontWeight.bold, + ), + ), + ), + ), + const SizedBox(height: 20), + ], ), ], ), From 5c7ff346dfd8e72293e66e6c529a9230d28a93f0 Mon Sep 17 00:00:00 2001 From: Yasien Mac Mini Date: Wed, 4 Jun 2025 13:50:47 +0200 Subject: [PATCH 20/52] Add new mih text form field to Mzansi Profile --- .../package_tools/mih_personal_profile.dart | 287 ++++++++---------- 1 file changed, 135 insertions(+), 152 deletions(-) diff --git a/Frontend/lib/mih_packages/mzansi_profile/personal_profile/package_tools/mih_personal_profile.dart b/Frontend/lib/mih_packages/mzansi_profile/personal_profile/package_tools/mih_personal_profile.dart index f6811854..63c65973 100644 --- a/Frontend/lib/mih_packages/mzansi_profile/personal_profile/package_tools/mih_personal_profile.dart +++ b/Frontend/lib/mih_packages/mzansi_profile/personal_profile/package_tools/mih_personal_profile.dart @@ -3,13 +3,14 @@ import 'dart:convert'; import 'package:mzansi_innovation_hub/main.dart'; import 'package:mzansi_innovation_hub/mih_apis/mih_file_api.dart'; import 'package:mzansi_innovation_hub/mih_apis/mih_user_apis.dart'; -import 'package:mzansi_innovation_hub/mih_components/mih_inputs_and_buttons/mih_file_input.dart'; -import 'package:mzansi_innovation_hub/mih_components/mih_inputs_and_buttons/mih_text_input.dart'; +import 'package:mzansi_innovation_hub/mih_apis/mih_validation_services.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_layout/mih_single_child_scroll.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_button.dart'; +import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_form.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package_tool_body.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package_alert.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_circle_avatar.dart'; +import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_text_form_field.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_pop_up_messages/mih_error_message.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_pop_up_messages/mih_success_message.dart'; import 'package:mzansi_innovation_hub/mih_env/env.dart'; @@ -39,6 +40,7 @@ class _MihPersonalProfileState extends State { late bool businessUser; late String oldProPicName; late String env; + final _formKey = GlobalKey(); void notUniqueAlert() { showDialog( @@ -65,38 +67,19 @@ class _MihPersonalProfileState extends State { Future submitForm() async { // print("============\nsubmiit form\n================="); - if (isFieldsFilled()) { - if (widget.arguments.signedInUser.username != usernameController.text) { - bool isUsernameUnique = await MihUserApis.isUsernameUnique( - usernameController.text, context); - print("isUsernameUnique: $isUsernameUnique"); - if (isUsernameUnique == false) { - notUniqueAlert(); - return; - } + if (widget.arguments.signedInUser.username != usernameController.text) { + bool isUsernameUnique = + await MihUserApis.isUsernameUnique(usernameController.text, context); + print("isUsernameUnique: $isUsernameUnique"); + if (isUsernameUnique == false) { + notUniqueAlert(); + return; } - if (oldProPicName != proPicController.text) { - await uploadSelectedFile(proPic); - } - await updateUserApiCall(); - } else { - showDialog( - context: context, - builder: (context) { - return const MIHErrorMessage(errorType: "Input Error"); - }, - ); } - } - - bool isFieldsFilled() { - if (fnameController.text.isEmpty || - lnameController.text.isEmpty || - usernameController.text.isEmpty) { - return false; - } else { - return true; + if (oldProPicName != proPicController.text) { + await uploadSelectedFile(proPic); } + await updateUserApiCall(); } bool isBusinessUser() { @@ -263,133 +246,133 @@ class _MihPersonalProfileState extends State { return MihSingleChildScroll( child: Column( children: [ - //displayProPic(), - MihCircleAvatar( - imageFile: propicPreview, - width: 150, - editable: true, - fileNameController: proPicController, - userSelectedfile: proPic, - frameColor: MzanziInnovationHub.of(context)!.theme.secondaryColor(), - backgroundColor: - MzanziInnovationHub.of(context)!.theme.primaryColor(), - onChange: (selectedImage) { - setState(() { - proPic = selectedImage; - }); - }, - ), - // MIHProfilePicture( - // profilePictureFile: widget.arguments.propicFile, - // proPicController: proPicController, - // proPic: proPic, - // width: 155, - // radius: 70, - // drawerMode: false, - // editable: true, - // frameColor: MzanziInnovationHub.of(context)!.theme.secondaryColor(), - // onChange: (newProPic) { - // setState(() { - // proPic = newProPic; - // }); - // }, - // ), - const SizedBox(height: 25.0), - Visibility( - visible: false, - child: MIHFileField( - controller: proPicController, - hintText: "Profile Picture", - editable: false, - required: false, - onPressed: () async { - FilePickerResult? result = await FilePicker.platform.pickFiles( - type: FileType.custom, - allowedExtensions: ['jpg', 'png'], - withData: true, - ); - if (result == null) return; - final selectedFile = result.files.first; - setState(() { - proPic = selectedFile; - propicPreview = MemoryImage(proPic!.bytes!); - }); - - setState(() { - proPicController.text = selectedFile.name; - }); - }, - ), - ), - // const SizedBox(height: 10.0), - // MIHTextField( - // controller: proPicController, - // hintText: "Pro Pic", - // editable: true, - // required: true, - // ), - const SizedBox(height: 10.0), - MIHTextField( - controller: usernameController, - hintText: "Username", - editable: true, - required: true, - ), - const SizedBox(height: 10.0), - MIHTextField( - controller: fnameController, - hintText: "First Name", - editable: true, - required: true, - ), - const SizedBox(height: 10.0), - MIHTextField( - controller: lnameController, - hintText: "Last Name", - editable: true, - required: true, - ), - const SizedBox(height: 10.0), - Row( - mainAxisAlignment: MainAxisAlignment.start, - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - const Text( - "Activate Business Account", - style: TextStyle( - fontWeight: FontWeight.bold, - fontSize: 20, + MihForm( + formKey: _formKey, + formFields: [ + Center( + child: MihCircleAvatar( + imageFile: propicPreview, + width: 150, + editable: true, + fileNameController: proPicController, + userSelectedfile: proPic, + frameColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + backgroundColor: + MzanziInnovationHub.of(context)!.theme.primaryColor(), + onChange: (selectedImage) { + setState(() { + proPic = selectedImage; + }); + }, ), ), - const SizedBox( - width: 10, + const SizedBox(height: 25.0), + Visibility( + visible: true, + child: MihTextFormField( + fillColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + inputColor: + MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: proPicController, + multiLineInput: false, + requiredText: true, + readOnly: true, + hintText: "Selected File Name", + ), ), - Switch( - value: businessUser, - onChanged: (bool value) { - setState(() { - businessUser = value; - }); + const SizedBox(height: 10.0), + MihTextFormField( + fillColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + inputColor: + MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: usernameController, + multiLineInput: false, + requiredText: true, + hintText: "Username", + validator: (value) { + return MihValidationServices().validateUsername(value); }, ), - ], - ), - const SizedBox(height: 30.0), - MihButton( - onPressed: () { - submitForm(); - }, - buttonColor: - MzanziInnovationHub.of(context)!.theme.secondaryColor(), - width: 300, - child: Text( - "Update", - style: TextStyle( - color: MzanziInnovationHub.of(context)!.theme.primaryColor(), - fontSize: 20, - fontWeight: FontWeight.bold, + const SizedBox(height: 10.0), + MihTextFormField( + fillColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + inputColor: + MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: fnameController, + multiLineInput: false, + requiredText: true, + hintText: "First Name", + validator: (value) { + return MihValidationServices().isEmpty(value); + }, ), - ), + const SizedBox(height: 10.0), + MihTextFormField( + fillColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + inputColor: + MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: lnameController, + multiLineInput: false, + requiredText: true, + hintText: "Last Name", + validator: (value) { + return MihValidationServices().isEmpty(value); + }, + ), + const SizedBox(height: 10.0), + Row( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + const Text( + "Activate Business Account", + style: TextStyle( + fontWeight: FontWeight.bold, + fontSize: 20, + ), + ), + const SizedBox( + width: 10, + ), + Switch( + value: businessUser, + onChanged: (bool value) { + setState(() { + businessUser = value; + }); + }, + ), + ], + ), + const SizedBox(height: 30.0), + Center( + child: MihButton( + onPressed: () { + //Add validation here + if (_formKey.currentState!.validate()) { + submitForm(); + } + }, + buttonColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + width: 300, + child: Text( + "Update", + style: TextStyle( + color: + MzanziInnovationHub.of(context)!.theme.primaryColor(), + fontSize: 20, + fontWeight: FontWeight.bold, + ), + ), + ), + ), + ], ), ], ), From 31253b75110f35a2332aa0b3bb461223c0d22a8b Mon Sep 17 00:00:00 2001 From: Yasien Mac Mini Date: Wed, 4 Jun 2025 14:10:07 +0200 Subject: [PATCH 21/52] fix add card scan bug fix cancel button in scanner add new fields --- .../builder/build_loyalty_card_list.dart | 142 +++++---- .../components/mih_barcode_scanner.dart | 1 + .../package_tools/mih_cards.dart | 293 ++++++++++-------- 3 files changed, 239 insertions(+), 197 deletions(-) diff --git a/Frontend/lib/mih_packages/mzansi_wallet/builder/build_loyalty_card_list.dart b/Frontend/lib/mih_packages/mzansi_wallet/builder/build_loyalty_card_list.dart index 8b3366df..a972ca49 100644 --- a/Frontend/lib/mih_packages/mzansi_wallet/builder/build_loyalty_card_list.dart +++ b/Frontend/lib/mih_packages/mzansi_wallet/builder/build_loyalty_card_list.dart @@ -1,19 +1,17 @@ import 'package:flutter_speed_dial/flutter_speed_dial.dart'; import 'package:mzansi_innovation_hub/main.dart'; import 'package:mzansi_innovation_hub/mih_apis/mih_mzansi_wallet_apis.dart'; -import 'package:mzansi_innovation_hub/mih_components/mih_inputs_and_buttons/mih_number_input.dart'; -import 'package:mzansi_innovation_hub/mih_components/mih_inputs_and_buttons/mih_text_input.dart'; +import 'package:mzansi_innovation_hub/mih_apis/mih_validation_services.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_button.dart'; +import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_form.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package_alert.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package_window.dart'; +import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_text_form_field.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_pop_up_messages/mih_delete_message.dart'; -import 'package:mzansi_innovation_hub/mih_components/mih_pop_up_messages/mih_error_message.dart'; import 'package:mzansi_innovation_hub/mih_objects/app_user.dart'; import 'package:mzansi_innovation_hub/mih_objects/loyalty_card.dart'; import 'package:mzansi_innovation_hub/mih_packages/mzansi_wallet/components/mih_card_display.dart'; import 'package:flutter/material.dart'; - -// import 'package:syncfusion_flutter_barcodes/barcodes.dart'; import 'package:barcode_widget/barcode_widget.dart'; class BuildLoyaltyCardList extends StatefulWidget { @@ -36,6 +34,7 @@ class _BuildLoyaltyCardListState extends State { final TextEditingController _nicknameController = TextEditingController(); final TextEditingController _cardNumberController = TextEditingController(); late int _noFavourites; + final _formKey = GlobalKey(); void openscanner() async { Navigator.of(context).pushNamed( @@ -58,38 +57,86 @@ class _BuildLoyaltyCardListState extends State { }, windowBody: Column( children: [ - const SizedBox(height: 10), - MIHTextField( - controller: _nicknameController, - hintText: "Card Title", - editable: true, - required: false, - ), - const SizedBox(height: 10), - Row( - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.center, - mainAxisSize: MainAxisSize.max, - children: [ - Flexible( - child: MIHNumberField( - controller: _cardNumberController, - hintText: "Card Number", - editable: true, - required: true, - enableDecimal: false, - ), + MihForm( + formKey: _formKey, + formFields: [ + MihTextFormField( + fillColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + inputColor: + MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: _nicknameController, + multiLineInput: false, + requiredText: false, + hintText: "Card Title", ), - const SizedBox(width: 10), + const SizedBox(height: 10), + Row( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.end, + mainAxisSize: MainAxisSize.max, + children: [ + Flexible( + child: MihTextFormField( + fillColor: MzanziInnovationHub.of(context)! + .theme + .secondaryColor(), + inputColor: MzanziInnovationHub.of(context)! + .theme + .primaryColor(), + controller: _cardNumberController, + multiLineInput: false, + requiredText: true, + hintText: "Card Number", + numberMode: true, + validator: (value) { + return MihValidationServices().isEmpty(value); + }, + ), + ), + const SizedBox(width: 20), + MihButton( + onPressed: () { + openscanner(); + }, + buttonColor: MzanziInnovationHub.of(context)! + .theme + .secondaryColor(), + width: 100, + child: Text( + "Scan", + style: TextStyle( + color: MzanziInnovationHub.of(context)! + .theme + .primaryColor(), + fontSize: 20, + fontWeight: FontWeight.bold, + ), + ), + ), + ], + ), + const SizedBox(height: 15), MihButton( onPressed: () { - openscanner(); + if (_formKey.currentState!.validate()) { + MIHMzansiWalletApis.updateLoyaltyCardAPICall( + widget.signedInUser, + widget.cardList[index].idloyalty_cards, + widget.cardList[index].favourite, + widget.cardList[index].priority_index, + _nicknameController.text, + _cardNumberController.text, + 0, + ctxt, + ); + } }, buttonColor: MzanziInnovationHub.of(context)!.theme.secondaryColor(), - width: 100, + width: 300, child: Text( - "Scan", + "Update", style: TextStyle( color: MzanziInnovationHub.of(context)!.theme.primaryColor(), @@ -100,41 +147,6 @@ class _BuildLoyaltyCardListState extends State { ), ], ), - const SizedBox(height: 15), - MihButton( - onPressed: () { - if (_cardNumberController.text == "") { - showDialog( - context: context, - builder: (context) { - return const MIHErrorMessage(errorType: "Input Error"); - }, - ); - } else { - MIHMzansiWalletApis.updateLoyaltyCardAPICall( - widget.signedInUser, - widget.cardList[index].idloyalty_cards, - widget.cardList[index].favourite, - widget.cardList[index].priority_index, - _nicknameController.text, - _cardNumberController.text, - 0, - ctxt, - ); - } - }, - buttonColor: - MzanziInnovationHub.of(context)!.theme.secondaryColor(), - width: 300, - child: Text( - "Update", - style: TextStyle( - color: MzanziInnovationHub.of(context)!.theme.primaryColor(), - fontSize: 20, - fontWeight: FontWeight.bold, - ), - ), - ), ], ), ), diff --git a/Frontend/lib/mih_packages/mzansi_wallet/components/mih_barcode_scanner.dart b/Frontend/lib/mih_packages/mzansi_wallet/components/mih_barcode_scanner.dart index 9fd7fd2d..52a3e683 100644 --- a/Frontend/lib/mih_packages/mzansi_wallet/components/mih_barcode_scanner.dart +++ b/Frontend/lib/mih_packages/mzansi_wallet/components/mih_barcode_scanner.dart @@ -129,6 +129,7 @@ class _MihBarcodeScannerState extends State .theme .secondaryColor(), width: 100, + height: 50, child: Text( "Cancel", style: TextStyle( diff --git a/Frontend/lib/mih_packages/mzansi_wallet/package_tools/mih_cards.dart b/Frontend/lib/mih_packages/mzansi_wallet/package_tools/mih_cards.dart index 3474ecd2..de1d50d0 100644 --- a/Frontend/lib/mih_packages/mzansi_wallet/package_tools/mih_cards.dart +++ b/Frontend/lib/mih_packages/mzansi_wallet/package_tools/mih_cards.dart @@ -1,15 +1,16 @@ import 'package:flutter_speed_dial/flutter_speed_dial.dart'; import 'package:mzansi_innovation_hub/main.dart'; import 'package:mzansi_innovation_hub/mih_apis/mih_mzansi_wallet_apis.dart'; +import 'package:mzansi_innovation_hub/mih_apis/mih_validation_services.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_inputs_and_buttons/mih_dropdown_input.dart'; -import 'package:mzansi_innovation_hub/mih_components/mih_inputs_and_buttons/mih_number_input.dart'; -import 'package:mzansi_innovation_hub/mih_components/mih_inputs_and_buttons/mih_text_input.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_layout/mih_single_child_scroll.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_button.dart'; +import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_form.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package_tool_body.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_floating_menu.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package_window.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_search_bar.dart'; +import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_text_form_field.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_pop_up_messages/mih_error_message.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_pop_up_messages/mih_loading_circle.dart'; import 'package:mzansi_innovation_hub/mih_objects/app_user.dart'; @@ -36,6 +37,7 @@ class _MihCardsState extends State { final TextEditingController cardNumberController = TextEditingController(); final TextEditingController cardSearchController = TextEditingController(); final FocusNode searchFocusNode = FocusNode(); + final _formKey = GlobalKey(); late Future> cardList; List listOfCards = []; //bool showSelectedCardType = false; @@ -97,104 +99,168 @@ class _MihCardsState extends State { }, windowBody: Column( children: [ - MIHDropdownField( - controller: shopController, - hintText: "Shop Name", - dropdownOptions: const [ - "+More", - "Apple Tree", - "Auchan", - "Best Before", - "Big Save", - "Boxer", - "BP", - "Builders Warehouse", - "Checkers", - "Choppies", - "Clicks", - "Continente", - "Cotton:On", - "Carrefour", - "Dis-Chem", - "Edgars", - "Eskom", - "Exclusive Books", - "Fresh Stop", - "Fresmart", - "Infinity", - "Jet", - "Justrite", - "Kero", - "Leroy Merlin", - "Makro", - "Naivas", - "OK Foods", - "Panarottis", - "Pick n Pay", - "PnA", - "PQ Clothing", - "Rage", - "Sefalana", - "Sasol", - "Shell", - "Shoprite", - "Signature Cosmetics & Fragrances", - "Spar", - "Spur", - "TFG Group", - "Toys R Us", - "Woermann Brock", - "Woolworths" - ], - required: true, - editable: true, - enableSearch: false, - ), - ValueListenableBuilder( - valueListenable: shopName, - builder: (BuildContext context, String value, Widget? child) { - return Visibility( - visible: value != "", - child: Column( - children: [ - const SizedBox(height: 10), - MihCardDisplay( - shopName: shopName.value, nickname: "", height: 200), - ], - ), - ); - }, - ), - const SizedBox(height: 10), - MIHTextField( - controller: _nicknameController, - hintText: "Card Title", - editable: true, - required: false, - ), - const SizedBox(height: 10), - Row( - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.center, - mainAxisSize: MainAxisSize.max, - children: [ - Flexible( - child: MIHNumberField( - controller: cardNumberController, - hintText: "Card Number", - editable: true, - required: true, - enableDecimal: false, - ), + MihForm( + formKey: _formKey, + formFields: [ + MIHDropdownField( + controller: shopController, + hintText: "Shop Name", + dropdownOptions: const [ + "+More", + "Apple Tree", + "Auchan", + "Best Before", + "Big Save", + "Boxer", + "BP", + "Builders Warehouse", + "Checkers", + "Choppies", + "Clicks", + "Continente", + "Cotton:On", + "Carrefour", + "Dis-Chem", + "Edgars", + "Eskom", + "Exclusive Books", + "Fresh Stop", + "Fresmart", + "Infinity", + "Jet", + "Justrite", + "Kero", + "Leroy Merlin", + "Makro", + "Naivas", + "OK Foods", + "Panarottis", + "Pick n Pay", + "PnA", + "PQ Clothing", + "Rage", + "Sefalana", + "Sasol", + "Shell", + "Shoprite", + "Signature Cosmetics & Fragrances", + "Spar", + "Spur", + "TFG Group", + "Toys R Us", + "Woermann Brock", + "Woolworths" + ], + required: true, + editable: true, + enableSearch: false, ), - const SizedBox(width: 10), + ValueListenableBuilder( + valueListenable: shopName, + builder: (BuildContext context, String value, Widget? child) { + return Visibility( + visible: value != "", + child: Column( + children: [ + const SizedBox(height: 10), + MihCardDisplay( + shopName: shopName.value, + nickname: "", + height: 200), + ], + ), + ); + }, + ), + const SizedBox(height: 10), + MihTextFormField( + fillColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + inputColor: + MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: _nicknameController, + multiLineInput: false, + requiredText: false, + hintText: "Card Title", + ), + const SizedBox(height: 10), + Row( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.end, + mainAxisSize: MainAxisSize.max, + children: [ + Flexible( + child: MihTextFormField( + fillColor: MzanziInnovationHub.of(context)! + .theme + .secondaryColor(), + inputColor: MzanziInnovationHub.of(context)! + .theme + .primaryColor(), + controller: cardNumberController, + multiLineInput: false, + requiredText: true, + hintText: "Card Number", + numberMode: true, + validator: (value) { + return MihValidationServices().isEmpty(value); + }, + ), + ), + const SizedBox(width: 20), + MihButton( + onPressed: () { + openscanner(); + }, + buttonColor: MzanziInnovationHub.of(context)! + .theme + .secondaryColor(), + width: 100, + child: Text( + "Scan", + style: TextStyle( + color: MzanziInnovationHub.of(context)! + .theme + .primaryColor(), + fontSize: 20, + fontWeight: FontWeight.bold, + ), + ), + ), + ], + ), + const SizedBox(height: 15), MihButton( - onPressed: () {}, + onPressed: () { + if (_formKey.currentState!.validate()) { + if (shopController.text == "") { + showDialog( + context: context, + builder: (context) { + return const MIHErrorMessage( + errorType: "Input Error"); + }, + ); + } else { + MIHMzansiWalletApis.addLoyaltyCardAPICall( + widget.signedInUser, + widget.signedInUser.app_id, + shopController.text, + cardNumberController.text, + "", + 0, + _nicknameController.text, + 0, + context, + ); + } + } + }, buttonColor: MzanziInnovationHub.of(context)!.theme.secondaryColor(), - width: 100, + width: 300, child: Text( - "Scan", + "Add", style: TextStyle( color: MzanziInnovationHub.of(context)!.theme.primaryColor(), @@ -205,43 +271,6 @@ class _MihCardsState extends State { ), ], ), - const SizedBox(height: 15), - MihButton( - onPressed: () { - if (shopController.text == "" || - cardNumberController.text == "") { - showDialog( - context: context, - builder: (context) { - return const MIHErrorMessage(errorType: "Input Error"); - }, - ); - } else { - MIHMzansiWalletApis.addLoyaltyCardAPICall( - widget.signedInUser, - widget.signedInUser.app_id, - shopController.text, - cardNumberController.text, - "", - 0, - _nicknameController.text, - 0, - context, - ); - } - }, - buttonColor: - MzanziInnovationHub.of(context)!.theme.secondaryColor(), - width: 300, - child: Text( - "Add", - style: TextStyle( - color: MzanziInnovationHub.of(context)!.theme.primaryColor(), - fontSize: 20, - fontWeight: FontWeight.bold, - ), - ), - ), ], ), ), From d392b97e7378ad9c763df1d2a8376bf9a8756158 Mon Sep 17 00:00:00 2001 From: Yasien Mac Mini Date: Wed, 4 Jun 2025 15:23:12 +0200 Subject: [PATCH 22/52] add length validation service --- Frontend/lib/mih_apis/mih_validation_services.dart | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/Frontend/lib/mih_apis/mih_validation_services.dart b/Frontend/lib/mih_apis/mih_validation_services.dart index b855ba57..47601075 100644 --- a/Frontend/lib/mih_apis/mih_validation_services.dart +++ b/Frontend/lib/mih_apis/mih_validation_services.dart @@ -6,6 +6,16 @@ class MihValidationServices { return null; } + String? validateLength(String? value, int maxLength) { + if (value == null || value.isEmpty) { + return "This field is required"; + } + if (value.length > maxLength) { + return "Length must not exceed $maxLength characters"; + } + return null; + } + String? validateEmail(String? email) { if (email == null || email.isEmpty) { return "Email is required"; From 60302c3ceee863c38b3710e41d74b2bc578ac247 Mon Sep 17 00:00:00 2001 From: Yasien Mac Mini Date: Wed, 4 Jun 2025 15:23:58 +0200 Subject: [PATCH 23/52] Add new mih text form field to Pat Prof: Details --- .../package_tools/patient_info.dart | 248 ++++++---- .../pat_profile/patient_add.dart | 422 +++++++++++------ .../pat_profile/patient_edit.dart | 444 +++++++++++------- 3 files changed, 674 insertions(+), 440 deletions(-) diff --git a/Frontend/lib/mih_packages/patient_profile/pat_profile/package_tools/patient_info.dart b/Frontend/lib/mih_packages/patient_profile/pat_profile/package_tools/patient_info.dart index 310c4769..8bab62df 100644 --- a/Frontend/lib/mih_packages/patient_profile/pat_profile/package_tools/patient_info.dart +++ b/Frontend/lib/mih_packages/patient_profile/pat_profile/package_tools/patient_info.dart @@ -1,9 +1,10 @@ import 'package:flutter_speed_dial/flutter_speed_dial.dart'; import 'package:mzansi_innovation_hub/main.dart'; -import 'package:mzansi_innovation_hub/mih_components/mih_inputs_and_buttons/mih_text_input.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_layout/mih_single_child_scroll.dart'; +import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_form.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package_tool_body.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_floating_menu.dart'; +import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_text_form_field.dart'; import 'package:mzansi_innovation_hub/mih_objects/app_user.dart'; import 'package:mzansi_innovation_hub/mih_objects/arguments.dart'; import 'package:mzansi_innovation_hub/mih_objects/patients.dart'; @@ -37,6 +38,7 @@ class _PatientInfoState extends State { final medAidController = TextEditingController(); final medMainMemController = TextEditingController(); final medAidCodeController = TextEditingController(); + final _formKey = GlobalKey(); double textFieldWidth = 400.0; late String medAid; @@ -45,53 +47,69 @@ class _PatientInfoState extends State { spacing: 15, runSpacing: 10, children: [ - SizedBox( + MihTextFormField( width: textFieldWidth, - child: MIHTextField( - controller: idController, - hintText: "ID No.", - editable: false, - required: false), + fillColor: MzanziInnovationHub.of(context)!.theme.secondaryColor(), + inputColor: MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: idController, + multiLineInput: false, + requiredText: true, + readOnly: true, + hintText: "ID No.", + // validator: (value) { + // return MihValidationServices().isEmpty(value); + // }, ), - SizedBox( + MihTextFormField( width: textFieldWidth, - child: MIHTextField( - controller: fnameController, - hintText: "Name", - editable: false, - required: false), + fillColor: MzanziInnovationHub.of(context)!.theme.secondaryColor(), + inputColor: MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: fnameController, + multiLineInput: false, + requiredText: true, + readOnly: true, + hintText: "First Name", ), - SizedBox( + MihTextFormField( width: textFieldWidth, - child: MIHTextField( - controller: lnameController, - hintText: "Surname", - editable: false, - required: false), + fillColor: MzanziInnovationHub.of(context)!.theme.secondaryColor(), + inputColor: MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: lnameController, + multiLineInput: false, + requiredText: true, + hintText: "Surname", + readOnly: true, ), - SizedBox( + MihTextFormField( width: textFieldWidth, - child: MIHTextField( - controller: cellController, - hintText: "Cell No.", - editable: false, - required: false), + fillColor: MzanziInnovationHub.of(context)!.theme.secondaryColor(), + inputColor: MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: cellController, + multiLineInput: false, + requiredText: true, + readOnly: true, + hintText: "Cell No.", ), - SizedBox( + MihTextFormField( width: textFieldWidth, - child: MIHTextField( - controller: emailController, - hintText: "Email", - editable: false, - required: false), + fillColor: MzanziInnovationHub.of(context)!.theme.secondaryColor(), + inputColor: MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: emailController, + multiLineInput: false, + requiredText: true, + readOnly: true, + hintText: "Email", ), - SizedBox( + MihTextFormField( width: textFieldWidth, - child: MIHTextField( - controller: addressController, - hintText: "Address", - editable: false, - required: false), + height: 100, + fillColor: MzanziInnovationHub.of(context)!.theme.secondaryColor(), + inputColor: MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: addressController, + multiLineInput: true, + requiredText: true, + readOnly: true, + hintText: "Address", ), ], ); @@ -99,14 +117,18 @@ class _PatientInfoState extends State { Widget getMedAidDetailsFields() { List medAidDet = []; - medAidDet.add(SizedBox( - width: textFieldWidth, - child: MIHTextField( - controller: medAidController, - hintText: "Medical Aid", - editable: false, - required: false), - )); + medAidDet.add( + MihTextFormField( + width: textFieldWidth, + fillColor: MzanziInnovationHub.of(context)!.theme.secondaryColor(), + inputColor: MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: medAidController, + multiLineInput: false, + requiredText: true, + readOnly: true, + hintText: "Medical Aid", + ), + ); bool req; if (medAid == "Yes") { req = true; @@ -116,64 +138,69 @@ class _PatientInfoState extends State { medAidDet.addAll([ Visibility( visible: req, - child: SizedBox( + child: MihTextFormField( width: textFieldWidth, - child: MIHTextField( - controller: medMainMemController, - hintText: "Main Member", - editable: false, - required: false), + fillColor: MzanziInnovationHub.of(context)!.theme.secondaryColor(), + inputColor: MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: medMainMemController, + multiLineInput: false, + requiredText: true, + readOnly: true, + hintText: "Main Member", ), ), - //const SizedBox(height: 10.0), Visibility( visible: req, - child: SizedBox( + child: MihTextFormField( width: textFieldWidth, - child: MIHTextField( - controller: medNoController, - hintText: "No.", - editable: false, - required: false), + fillColor: MzanziInnovationHub.of(context)!.theme.secondaryColor(), + inputColor: MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: medNoController, + multiLineInput: false, + requiredText: true, + readOnly: true, + hintText: "No.", ), ), - //const SizedBox(height: 10.0), Visibility( visible: req, - child: SizedBox( + child: MihTextFormField( width: textFieldWidth, - child: MIHTextField( - controller: medAidCodeController, - hintText: "Code", - editable: false, - required: false), + fillColor: MzanziInnovationHub.of(context)!.theme.secondaryColor(), + inputColor: MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: medAidCodeController, + multiLineInput: false, + requiredText: true, + readOnly: true, + hintText: "Code", ), ), - //const SizedBox(height: 10.0), Visibility( visible: req, - child: SizedBox( + child: MihTextFormField( width: textFieldWidth, - child: MIHTextField( - controller: medNameController, - hintText: "Name", - editable: false, - required: false), + fillColor: MzanziInnovationHub.of(context)!.theme.secondaryColor(), + inputColor: MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: medNameController, + multiLineInput: false, + requiredText: true, + readOnly: true, + hintText: "Name", ), ), - //const SizedBox(height: 10.0), Visibility( visible: req, - child: SizedBox( + child: MihTextFormField( width: textFieldWidth, - child: MIHTextField( - controller: medSchemeController, - hintText: "Plan", - editable: false, - required: false), + fillColor: MzanziInnovationHub.of(context)!.theme.secondaryColor(), + inputColor: MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: medSchemeController, + multiLineInput: false, + requiredText: true, + readOnly: true, + hintText: "Plan", ), ), - //), ]); return Wrap( spacing: 10, @@ -245,12 +272,35 @@ class _PatientInfoState extends State { MihSingleChildScroll( child: Column( children: [ - Row( - mainAxisAlignment: MainAxisAlignment.center, - //crossAxisAlignment: , - children: [ - Text( - "Personal Details", + MihForm( + formKey: _formKey, + formFields: [ + Row( + mainAxisAlignment: MainAxisAlignment.center, + //crossAxisAlignment: , + children: [ + Text( + "Personal", + textAlign: TextAlign.center, + style: TextStyle( + fontSize: 25, + fontWeight: FontWeight.bold, + color: MzanziInnovationHub.of(context)! + .theme + .secondaryColor(), + ), + ), + ]), + Divider( + color: MzanziInnovationHub.of(context)! + .theme + .secondaryColor()), + const SizedBox(height: 10), + getPatientDetailsField(), + const SizedBox(height: 10), + Center( + child: Text( + "Medical Aid", textAlign: TextAlign.center, style: TextStyle( fontSize: 25, @@ -260,25 +310,15 @@ class _PatientInfoState extends State { .secondaryColor(), ), ), - ]), - const SizedBox(height: 10), - getPatientDetailsField(), - const SizedBox(height: 10), - Text( - "Medical Aid Details", - textAlign: TextAlign.center, - style: TextStyle( - fontSize: 25, - fontWeight: FontWeight.bold, - color: - MzanziInnovationHub.of(context)!.theme.secondaryColor(), - ), + ), + Divider( + color: MzanziInnovationHub.of(context)! + .theme + .secondaryColor()), + const SizedBox(height: 10), + getMedAidDetailsFields(), + ], ), - Divider( - color: - MzanziInnovationHub.of(context)!.theme.secondaryColor()), - const SizedBox(height: 10), - getMedAidDetailsFields(), ], ), ), diff --git a/Frontend/lib/mih_packages/patient_profile/pat_profile/patient_add.dart b/Frontend/lib/mih_packages/patient_profile/pat_profile/patient_add.dart index 4b9fdc32..6887d697 100644 --- a/Frontend/lib/mih_packages/patient_profile/pat_profile/patient_add.dart +++ b/Frontend/lib/mih_packages/patient_profile/pat_profile/patient_add.dart @@ -1,14 +1,15 @@ import 'dart:convert'; import 'package:mzansi_innovation_hub/main.dart'; +import 'package:mzansi_innovation_hub/mih_apis/mih_validation_services.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_inputs_and_buttons/mih_dropdown_input.dart'; -import 'package:mzansi_innovation_hub/mih_components/mih_inputs_and_buttons/mih_text_input.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_layout/mih_action.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_layout/mih_body.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_layout/mih_header.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_layout/mih_layout_builder.dart'; -import 'package:mzansi_innovation_hub/mih_components/mih_layout/mih_single_child_scroll.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_button.dart'; +import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_form.dart'; +import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_text_form_field.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_pop_up_messages/mih_error_message.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_pop_up_messages/mih_success_message.dart'; import 'package:mzansi_innovation_hub/mih_env/env.dart'; @@ -49,6 +50,7 @@ class _AddPatientState extends State { //late bool medRequired; final ValueNotifier medRequired = ValueNotifier(false); final FocusNode _focusNode = FocusNode(); + final _formKey = GlobalKey(); bool isFieldsFilled() { if (medRequired.value) { @@ -159,151 +161,268 @@ class _AddPatientState extends State { } Widget displayForm() { - return MihSingleChildScroll( + return SingleChildScrollView( child: Column( children: [ - Text( - "Personal Details", - textAlign: TextAlign.center, - style: TextStyle( - fontWeight: FontWeight.bold, - fontSize: 22.0, - color: MzanziInnovationHub.of(context)!.theme.secondaryColor(), - ), - ), - Divider( - color: MzanziInnovationHub.of(context)!.theme.secondaryColor()), - const SizedBox(height: 10.0), - MIHTextField( - controller: idController, - hintText: "13 digit ID Number or Passport", - editable: true, - required: true, - ), - const SizedBox(height: 10.0), - MIHTextField( - controller: fnameController, - hintText: "First Name", - editable: false, - required: true, - ), - const SizedBox(height: 10.0), - MIHTextField( - controller: lnameController, - hintText: "Last Name", - editable: false, - required: true, - ), - const SizedBox(height: 10.0), - MIHTextField( - controller: cellController, - hintText: "Cell Number", - editable: true, - required: true, - ), - const SizedBox(height: 10.0), - MIHTextField( - controller: emailController, - hintText: "Email", - editable: false, - required: true, - ), - const SizedBox(height: 10.0), - MIHTextField( - controller: addressController, - hintText: "Address", - editable: true, - required: true, - ), - const SizedBox(height: 15.0), - Text( - "Medical Aid Details", - textAlign: TextAlign.center, - style: TextStyle( - fontWeight: FontWeight.bold, - fontSize: 22.0, - color: MzanziInnovationHub.of(context)!.theme.secondaryColor(), - ), - ), - Divider( - color: MzanziInnovationHub.of(context)!.theme.secondaryColor()), - const SizedBox(height: 10.0), - MIHDropdownField( - controller: medAidController, - hintText: "Medical Aid", - editable: true, - enableSearch: false, - // onSelect: (_) { - // isRequired(); - // }, - required: true, - dropdownOptions: const ["Yes", "No"], - ), - ValueListenableBuilder( - valueListenable: medRequired, - builder: (BuildContext context, bool value, Widget? child) { - return Visibility( - visible: value, - child: Column( - children: [ - const SizedBox(height: 10.0), - MIHDropdownField( - controller: medMainMemController, - hintText: "Main Member", - editable: value, - required: value, - enableSearch: false, - dropdownOptions: const ["Yes", "No"], + MihForm( + formKey: _formKey, + formFields: [ + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text( + "Personal", + textAlign: TextAlign.center, + style: TextStyle( + fontWeight: FontWeight.bold, + fontSize: 25.0, + color: MzanziInnovationHub.of(context)! + .theme + .secondaryColor(), ), - const SizedBox(height: 10.0), - MIHTextField( - controller: medNoController, - hintText: "Medical Aid No.", - editable: value, - required: value, - ), - const SizedBox(height: 10.0), - MIHTextField( - controller: medAidCodeController, - hintText: "Medical Aid Code", - editable: value, - required: value, - ), - const SizedBox(height: 10.0), - MIHTextField( - controller: medNameController, - hintText: "Medical Aid Name", - editable: value, - required: value, - ), - const SizedBox(height: 10.0), - MIHTextField( - controller: medSchemeController, - hintText: "Medical Aid Plan", - editable: value, - required: value, - ), - ], - ), - ); - }, - ), - const SizedBox(height: 30.0), - MihButton( - onPressed: () { - submitForm(); - }, - buttonColor: - MzanziInnovationHub.of(context)!.theme.secondaryColor(), - width: 300, - child: Text( - "Add", - style: TextStyle( - color: MzanziInnovationHub.of(context)!.theme.primaryColor(), - fontSize: 20, - fontWeight: FontWeight.bold, + ), + ], ), - ), + Divider( + color: + MzanziInnovationHub.of(context)!.theme.secondaryColor()), + const SizedBox(height: 10.0), + MihTextFormField( + fillColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + inputColor: + MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: idController, + multiLineInput: false, + requiredText: true, + hintText: "ID No.", + validator: (value) { + return MihValidationServices().isEmpty(value); + }, + ), + const SizedBox(height: 10.0), + MihTextFormField( + fillColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + inputColor: + MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: fnameController, + multiLineInput: false, + requiredText: true, + hintText: "First Name", + validator: (value) { + return MihValidationServices().isEmpty(value); + }, + ), + const SizedBox(height: 10.0), + MihTextFormField( + fillColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + inputColor: + MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: lnameController, + multiLineInput: false, + requiredText: true, + hintText: "Surname", + validator: (value) { + return MihValidationServices().isEmpty(value); + }, + ), + const SizedBox(height: 10.0), + MihTextFormField( + fillColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + inputColor: + MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: cellController, + multiLineInput: false, + requiredText: true, + hintText: "Cell No.", + validator: (value) { + return MihValidationServices().isEmpty(value); + }, + ), + const SizedBox(height: 10.0), + MihTextFormField( + fillColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + inputColor: + MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: emailController, + multiLineInput: false, + requiredText: true, + readOnly: true, + hintText: "Email", + validator: (value) { + return MihValidationServices().validateEmail(value); + }, + ), + const SizedBox(height: 10.0), + MihTextFormField( + height: 100, + fillColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + inputColor: + MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: addressController, + multiLineInput: true, + requiredText: true, + hintText: "Address", + validator: (value) { + return MihValidationServices().isEmpty(value); + }, + ), + const SizedBox(height: 15.0), + Center( + child: Text( + "Medical Aid Details", + textAlign: TextAlign.center, + style: TextStyle( + fontWeight: FontWeight.bold, + fontSize: 25.0, + color: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + ), + ), + ), + Divider( + color: + MzanziInnovationHub.of(context)!.theme.secondaryColor()), + const SizedBox(height: 10.0), + MIHDropdownField( + controller: medAidController, + hintText: "Medical Aid", + editable: true, + required: true, + enableSearch: false, + dropdownOptions: const ["Yes", "No"], + ), + ValueListenableBuilder( + valueListenable: medRequired, + builder: (BuildContext context, bool value, Widget? child) { + return Visibility( + visible: value, + child: Column( + children: [ + const SizedBox(height: 10.0), + MIHDropdownField( + controller: medMainMemController, + hintText: "Main Member", + editable: value, + required: value, + enableSearch: false, + dropdownOptions: const ["Yes", "No"], + ), + const SizedBox(height: 10.0), + MihTextFormField( + fillColor: MzanziInnovationHub.of(context)! + .theme + .secondaryColor(), + inputColor: MzanziInnovationHub.of(context)! + .theme + .primaryColor(), + controller: medNoController, + multiLineInput: false, + requiredText: true, + hintText: "No.", + validator: (validationValue) { + if (value) { + return MihValidationServices() + .isEmpty(validationValue); + } + return null; + }, + ), + const SizedBox(height: 10.0), + MihTextFormField( + fillColor: MzanziInnovationHub.of(context)! + .theme + .secondaryColor(), + inputColor: MzanziInnovationHub.of(context)! + .theme + .primaryColor(), + controller: medAidCodeController, + multiLineInput: false, + requiredText: true, + hintText: "Code", + validator: (validationValue) { + if (value) { + return MihValidationServices() + .isEmpty(validationValue); + } + return null; + }, + ), + const SizedBox(height: 10.0), + MihTextFormField( + fillColor: MzanziInnovationHub.of(context)! + .theme + .secondaryColor(), + inputColor: MzanziInnovationHub.of(context)! + .theme + .primaryColor(), + controller: medNameController, + multiLineInput: false, + requiredText: true, + hintText: "Name", + validator: (validationValue) { + if (value) { + return MihValidationServices() + .isEmpty(validationValue); + } + return null; + }, + ), + const SizedBox(height: 10.0), + MihTextFormField( + fillColor: MzanziInnovationHub.of(context)! + .theme + .secondaryColor(), + inputColor: MzanziInnovationHub.of(context)! + .theme + .primaryColor(), + controller: medSchemeController, + multiLineInput: false, + requiredText: true, + hintText: "Plan", + validator: (validationValue) { + if (value) { + return MihValidationServices() + .isEmpty(validationValue); + } + return null; + }, + ), + const SizedBox(height: 10.0), + ], + ), + ); + }, + ), + const SizedBox(height: 20.0), + Center( + child: MihButton( + onPressed: () { + if (_formKey.currentState!.validate()) { + submitForm(); + } + }, + buttonColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + width: 300, + child: Text( + "Add", + style: TextStyle( + color: + MzanziInnovationHub.of(context)!.theme.primaryColor(), + fontSize: 20, + fontWeight: FontWeight.bold, + ), + ), + ), + ), + const SizedBox(height: 20.0), + ], ), ], ), @@ -311,16 +430,7 @@ class _AddPatientState extends State { } void submitForm() { - if (isFieldsFilled()) { - addPatientAPICall(); - } else { - showDialog( - context: context, - builder: (context) { - return const MIHErrorMessage(errorType: "Input Error"); - }, - ); - } + addPatientAPICall(); } MIHAction getActionButton() { @@ -350,7 +460,7 @@ class _AddPatientState extends State { MIHBody getBody() { return MIHBody( - borderOn: true, + borderOn: false, bodyItems: [ KeyboardListener( focusNode: _focusNode, @@ -358,7 +468,9 @@ class _AddPatientState extends State { onKeyEvent: (event) async { if (event is KeyDownEvent && event.logicalKey == LogicalKeyboardKey.enter) { - submitForm(); + if (_formKey.currentState!.validate()) { + submitForm(); + } } }, child: displayForm(), diff --git a/Frontend/lib/mih_packages/patient_profile/pat_profile/patient_edit.dart b/Frontend/lib/mih_packages/patient_profile/pat_profile/patient_edit.dart index 81ad520a..540fb055 100644 --- a/Frontend/lib/mih_packages/patient_profile/pat_profile/patient_edit.dart +++ b/Frontend/lib/mih_packages/patient_profile/pat_profile/patient_edit.dart @@ -1,13 +1,15 @@ import 'dart:convert'; import 'package:mzansi_innovation_hub/main.dart'; +import 'package:mzansi_innovation_hub/mih_apis/mih_validation_services.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_inputs_and_buttons/mih_dropdown_input.dart'; -import 'package:mzansi_innovation_hub/mih_components/mih_inputs_and_buttons/mih_text_input.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_layout/mih_action.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_layout/mih_body.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_layout/mih_header.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_layout/mih_layout_builder.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_button.dart'; +import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_form.dart'; +import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_text_form_field.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_pop_up_messages/mih_error_message.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_pop_up_messages/mih_success_message.dart'; import 'package:mzansi_innovation_hub/mih_env/env.dart'; @@ -49,6 +51,7 @@ class _EditPatientState extends State { final docOfficeIdApiUrl = "${AppEnviroment.baseApiUrl}/users/profile/"; final apiUrlEdit = "${AppEnviroment.baseApiUrl}/patients/update/"; final apiUrlDelete = "${AppEnviroment.baseApiUrl}/patients/delete/"; + final _formKey = GlobalKey(); late int futureDocOfficeId; late String userEmail; @@ -375,196 +378,273 @@ class _EditPatientState extends State { return SingleChildScrollView( child: Column( children: [ - Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Text( - "Personal Details", - textAlign: TextAlign.center, - style: TextStyle( - fontWeight: FontWeight.bold, - fontSize: 22.0, + MihForm( + formKey: _formKey, + formFields: [ + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text( + "Personal", + textAlign: TextAlign.center, + style: TextStyle( + fontWeight: FontWeight.bold, + fontSize: 25.0, + color: MzanziInnovationHub.of(context)! + .theme + .secondaryColor(), + ), + ), + ], + ), + Divider( color: + MzanziInnovationHub.of(context)!.theme.secondaryColor()), + const SizedBox(height: 10.0), + MihTextFormField( + fillColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + inputColor: + MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: idController, + multiLineInput: false, + requiredText: true, + hintText: "ID No.", + validator: (value) { + return MihValidationServices().isEmpty(value); + }, + ), + const SizedBox(height: 10.0), + MihTextFormField( + fillColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + inputColor: + MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: fnameController, + multiLineInput: false, + requiredText: true, + hintText: "First Name", + validator: (value) { + return MihValidationServices().isEmpty(value); + }, + ), + const SizedBox(height: 10.0), + MihTextFormField( + fillColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + inputColor: + MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: lnameController, + multiLineInput: false, + requiredText: true, + hintText: "Surname", + validator: (value) { + return MihValidationServices().isEmpty(value); + }, + ), + const SizedBox(height: 10.0), + MihTextFormField( + fillColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + inputColor: + MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: cellController, + multiLineInput: false, + requiredText: true, + hintText: "Cell No.", + validator: (value) { + return MihValidationServices().isEmpty(value); + }, + ), + const SizedBox(height: 10.0), + MihTextFormField( + fillColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + inputColor: + MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: emailController, + multiLineInput: false, + requiredText: true, + readOnly: true, + hintText: "Email", + validator: (value) { + return MihValidationServices().validateEmail(value); + }, + ), + const SizedBox(height: 10.0), + MihTextFormField( + height: 100, + fillColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + inputColor: + MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: addressController, + multiLineInput: true, + requiredText: true, + hintText: "Address", + validator: (value) { + return MihValidationServices().isEmpty(value); + }, + ), + const SizedBox(height: 15.0), + Center( + child: Text( + "Medical Aid Details", + textAlign: TextAlign.center, + style: TextStyle( + fontWeight: FontWeight.bold, + fontSize: 25.0, + color: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + ), + ), + ), + Divider( + color: + MzanziInnovationHub.of(context)!.theme.secondaryColor()), + const SizedBox(height: 10.0), + MIHDropdownField( + controller: medAidController, + hintText: "Medical Aid", + editable: true, + required: true, + enableSearch: false, + dropdownOptions: const ["Yes", "No"], + ), + ValueListenableBuilder( + valueListenable: medRequired, + builder: (BuildContext context, bool value, Widget? child) { + return Visibility( + visible: value, + child: Column( + children: [ + const SizedBox(height: 10.0), + MIHDropdownField( + controller: medMainMemController, + hintText: "Main Member", + editable: value, + required: value, + enableSearch: false, + dropdownOptions: const ["Yes", "No"], + ), + const SizedBox(height: 10.0), + MihTextFormField( + fillColor: MzanziInnovationHub.of(context)! + .theme + .secondaryColor(), + inputColor: MzanziInnovationHub.of(context)! + .theme + .primaryColor(), + controller: medNoController, + multiLineInput: false, + requiredText: true, + hintText: "No.", + validator: (validationValue) { + if (value) { + return MihValidationServices() + .isEmpty(validationValue); + } + return null; + }, + ), + const SizedBox(height: 10.0), + MihTextFormField( + fillColor: MzanziInnovationHub.of(context)! + .theme + .secondaryColor(), + inputColor: MzanziInnovationHub.of(context)! + .theme + .primaryColor(), + controller: medAidCodeController, + multiLineInput: false, + requiredText: true, + hintText: "Code", + validator: (validationValue) { + if (value) { + return MihValidationServices() + .isEmpty(validationValue); + } + return null; + }, + ), + const SizedBox(height: 10.0), + MihTextFormField( + fillColor: MzanziInnovationHub.of(context)! + .theme + .secondaryColor(), + inputColor: MzanziInnovationHub.of(context)! + .theme + .primaryColor(), + controller: medNameController, + multiLineInput: false, + requiredText: true, + hintText: "Name", + validator: (validationValue) { + if (value) { + return MihValidationServices() + .isEmpty(validationValue); + } + return null; + }, + ), + const SizedBox(height: 10.0), + MihTextFormField( + fillColor: MzanziInnovationHub.of(context)! + .theme + .secondaryColor(), + inputColor: MzanziInnovationHub.of(context)! + .theme + .primaryColor(), + controller: medSchemeController, + multiLineInput: false, + requiredText: true, + hintText: "Plan", + validator: (validationValue) { + if (value) { + return MihValidationServices() + .isEmpty(validationValue); + } + return null; + }, + ), + const SizedBox(height: 10.0), + ], + ), + ); + }, + ), + const SizedBox(height: 20.0), + Center( + child: MihButton( + onPressed: () { + if (_formKey.currentState!.validate()) { + submitForm(); + } + }, + buttonColor: MzanziInnovationHub.of(context)!.theme.secondaryColor(), + width: 300, + child: Text( + "Update", + style: TextStyle( + color: + MzanziInnovationHub.of(context)!.theme.primaryColor(), + fontSize: 20, + fontWeight: FontWeight.bold, + ), + ), ), ), - // IconButton( - // icon: const Icon(Icons.delete), - // color: MzanziInnovationHub.of(context)!.theme.secondaryColor(), - // //alignment: Alignment.topRight, - // onPressed: () { - // deletePatientPopUp(); - // }, - // ), + const SizedBox(height: 20.0), ], ), - Divider( - color: MzanziInnovationHub.of(context)!.theme.secondaryColor()), - const SizedBox(height: 10.0), - MIHTextField( - controller: idController, - hintText: "13 digit ID Number or Passport", - editable: false, - required: true, - ), - const SizedBox(height: 10.0), - MIHTextField( - controller: fnameController, - hintText: "First Name", - editable: false, - required: true, - ), - const SizedBox(height: 10.0), - MIHTextField( - controller: lnameController, - hintText: "Last Name", - editable: false, - required: true, - ), - const SizedBox(height: 10.0), - MIHTextField( - controller: cellController, - hintText: "Cell Number", - editable: true, - required: true, - ), - const SizedBox(height: 10.0), - MIHTextField( - controller: emailController, - hintText: "Email", - editable: false, - required: true, - ), - const SizedBox(height: 10.0), - MIHTextField( - controller: addressController, - hintText: "Address", - editable: true, - required: true, - ), - const SizedBox(height: 15.0), - Text( - "Medical Aid Details", - textAlign: TextAlign.center, - style: TextStyle( - fontWeight: FontWeight.bold, - fontSize: 22.0, - color: MzanziInnovationHub.of(context)!.theme.secondaryColor(), - ), - ), - Divider( - color: MzanziInnovationHub.of(context)!.theme.secondaryColor()), - const SizedBox(height: 10.0), - MIHDropdownField( - controller: medAidController, - hintText: "Medical Aid", - // onSelect: (selected) { - // if (selected == "Yes") { - // setState(() { - // medRequired = true; - // }); - // } else { - // setState(() { - // medRequired = false; - // }); - // } - // }, - editable: true, - required: true, - enableSearch: false, - dropdownOptions: const ["Yes", "No"], - ), - ValueListenableBuilder( - valueListenable: medRequired, - builder: (BuildContext context, bool value, Widget? child) { - return Visibility( - visible: value, - child: Column( - children: [ - const SizedBox(height: 10.0), - MIHDropdownField( - controller: medMainMemController, - hintText: "Main Member.", - editable: value, - required: value, - enableSearch: false, - dropdownOptions: const ["Yes", "No"], - ), - const SizedBox(height: 10.0), - MIHTextField( - controller: medNoController, - hintText: "Medical Aid No.", - editable: value, - required: value, - ), - const SizedBox(height: 10.0), - MIHTextField( - controller: medAidCodeController, - hintText: "Medical Aid Code", - editable: value, - required: value, - ), - const SizedBox(height: 10.0), - MIHTextField( - controller: medNameController, - hintText: "Medical Aid Name", - editable: value, - required: value, - ), - const SizedBox(height: 10.0), - MIHTextField( - controller: medSchemeController, - hintText: "Medical Aid Plan", - editable: value, - required: value, - ), - ], - ), - ); - }, - ), - const SizedBox(height: 30.0), - MihButton( - onPressed: () { - submitForm(); - }, - buttonColor: - MzanziInnovationHub.of(context)!.theme.secondaryColor(), - width: 300, - child: Text( - "Update", - style: TextStyle( - color: MzanziInnovationHub.of(context)!.theme.primaryColor(), - fontSize: 20, - fontWeight: FontWeight.bold, - ), - ), - ), ], ), ); } void submitForm() { - if (isFieldsFilled()) { - if (!medRequired.value) { - setState(() { - medMainMemController.text = ""; - medNoController.text = ""; - medAidCodeController.text = ""; - medNameController.text = ""; - medSchemeController.text = ""; - }); - } - updatePatientApiCall(); - } else { - showDialog( - context: context, - builder: (context) { - return const MIHErrorMessage(errorType: "Input Error"); - }, - ); - } + updatePatientApiCall(); } MIHAction getActionButton() { @@ -594,7 +674,7 @@ class _EditPatientState extends State { MIHBody getBody() { return MIHBody( - borderOn: true, + borderOn: false, bodyItems: [ KeyboardListener( focusNode: _focusNode, @@ -602,7 +682,9 @@ class _EditPatientState extends State { onKeyEvent: (event) async { if (event is KeyDownEvent && event.logicalKey == LogicalKeyboardKey.enter) { - submitForm(); + if (_formKey.currentState!.validate()) { + submitForm(); + } } }, child: displayForm(), From 39052c178d1ad8ed68f861b02daa9b21659359d0 Mon Sep 17 00:00:00 2001 From: Yasien Mac Mini Date: Wed, 4 Jun 2025 15:31:09 +0200 Subject: [PATCH 24/52] Add new mih text form field to Pat Prof: Consultations --- .../list_builders/build_notes_list.dart | 62 +++-- .../package_tools/patient_consultation.dart | 213 ++++++++++-------- 2 files changed, 161 insertions(+), 114 deletions(-) diff --git a/Frontend/lib/mih_packages/patient_profile/pat_profile/list_builders/build_notes_list.dart b/Frontend/lib/mih_packages/patient_profile/pat_profile/list_builders/build_notes_list.dart index 77c15290..94dc7368 100644 --- a/Frontend/lib/mih_packages/patient_profile/pat_profile/list_builders/build_notes_list.dart +++ b/Frontend/lib/mih_packages/patient_profile/pat_profile/list_builders/build_notes_list.dart @@ -2,9 +2,8 @@ import 'dart:convert'; import 'package:flutter_speed_dial/flutter_speed_dial.dart'; import 'package:mzansi_innovation_hub/main.dart'; -import 'package:mzansi_innovation_hub/mih_components/mih_inputs_and_buttons/mih_multiline_text_input.dart'; -import 'package:mzansi_innovation_hub/mih_components/mih_inputs_and_buttons/mih_text_input.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package_window.dart'; +import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_text_form_field.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_pop_up_messages/mih_delete_message.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_pop_up_messages/mih_error_message.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_pop_up_messages/mih_success_message.dart'; @@ -148,7 +147,7 @@ class _BuildNotesListState extends State { color: MzanziInnovationHub.of(context)!.theme.primaryColor(), ), - label: "Delete Document", + label: "Delete Note", labelBackgroundColor: MzanziInnovationHub.of(context)!.theme.successColor(), labelStyle: TextStyle( @@ -170,43 +169,62 @@ class _BuildNotesListState extends State { windowBody: Column( children: [ const SizedBox(height: 10.0), - MIHTextField( + MihTextFormField( + fillColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + inputColor: MzanziInnovationHub.of(context)!.theme.primaryColor(), controller: businessNameController, + multiLineInput: false, + requiredText: true, + readOnly: true, hintText: "Office", - editable: false, - required: false, ), const SizedBox(height: 10.0), - MIHTextField( + MihTextFormField( + fillColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + inputColor: MzanziInnovationHub.of(context)!.theme.primaryColor(), controller: userNameController, + multiLineInput: false, + requiredText: true, + readOnly: true, hintText: "Created By", - editable: false, - required: false, ), const SizedBox(height: 10.0), - MIHTextField( + MihTextFormField( + fillColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + inputColor: MzanziInnovationHub.of(context)!.theme.primaryColor(), controller: dateController, + multiLineInput: false, + requiredText: true, + readOnly: true, hintText: "Created Date", - editable: false, - required: false, ), const SizedBox(height: 10.0), - MIHTextField( + MihTextFormField( + fillColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + inputColor: MzanziInnovationHub.of(context)!.theme.primaryColor(), controller: noteTitleController, + multiLineInput: false, + requiredText: true, + readOnly: true, hintText: "Note Title", - editable: false, - required: false, ), const SizedBox(height: 10.0), - SizedBox( + MihTextFormField( height: 250, - child: MIHMLTextField( - controller: noteTextController, - hintText: "Note Details", - editable: false, - required: false, - ), + fillColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + inputColor: MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: noteTextController, + multiLineInput: true, + requiredText: true, + readOnly: true, + hintText: "Note Details", ), + const SizedBox(height: 10.0), ], ), ), diff --git a/Frontend/lib/mih_packages/patient_profile/pat_profile/package_tools/patient_consultation.dart b/Frontend/lib/mih_packages/patient_profile/pat_profile/package_tools/patient_consultation.dart index f07237e6..1e4f0368 100644 --- a/Frontend/lib/mih_packages/patient_profile/pat_profile/package_tools/patient_consultation.dart +++ b/Frontend/lib/mih_packages/patient_profile/pat_profile/package_tools/patient_consultation.dart @@ -1,13 +1,14 @@ import 'dart:convert'; import 'package:flutter_speed_dial/flutter_speed_dial.dart'; import 'package:mzansi_innovation_hub/main.dart'; -import 'package:mzansi_innovation_hub/mih_components/mih_inputs_and_buttons/mih_multiline_text_input.dart'; -import 'package:mzansi_innovation_hub/mih_components/mih_inputs_and_buttons/mih_text_input.dart'; +import 'package:mzansi_innovation_hub/mih_apis/mih_validation_services.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_layout/mih_single_child_scroll.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_button.dart'; +import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_form.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package_tool_body.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_floating_menu.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package_window.dart'; +import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_text_form_field.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_pop_up_messages/mih_error_message.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_pop_up_messages/mih_loading_circle.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_pop_up_messages/mih_success_message.dart'; @@ -51,6 +52,7 @@ class _PatientConsultationState extends State { final doctorController = TextEditingController(); final ValueNotifier _counter = ValueNotifier(0); String endpoint = "${AppEnviroment.baseApiUrl}/notes/patients/"; + final _formKey = GlobalKey(); Future> fetchNotes(String endpoint) async { final response = await http.get(Uri.parse( @@ -94,97 +96,124 @@ class _PatientConsultationState extends State { }, windowBody: Column( children: [ - MIHTextField( - controller: officeController, - hintText: "Office", - editable: false, - required: true, - ), - const SizedBox(height: 10.0), - MIHTextField( - controller: doctorController, - hintText: "Created By", - editable: false, - required: true, - ), - const SizedBox(height: 10.0), - MIHTextField( - controller: dateController, - hintText: "Created Date", - editable: false, - required: true, - ), - const SizedBox(height: 10.0), - MIHTextField( - controller: titleController, - hintText: "Note Title", - editable: true, - required: true, - ), - const SizedBox(height: 10.0), - SizedBox( - //width: 700, - height: 250, - child: MIHMLTextField( - controller: noteTextController, - hintText: "Note Details", - editable: true, - required: true, - ), - ), - SizedBox( - height: 15, - child: ValueListenableBuilder( - builder: (BuildContext context, int value, Widget? child) { - return Row( - mainAxisSize: MainAxisSize.max, - mainAxisAlignment: MainAxisAlignment.end, - children: [ - Text( - "$value", - style: TextStyle( - color: getNoteDetailLimitColor(), - ), - ), - const SizedBox(width: 5), - Text( - "/512", - style: TextStyle( - color: getNoteDetailLimitColor(), - ), - ), - ], - ); - }, - valueListenable: _counter, - ), - ), - const SizedBox(height: 15.0), - MihButton( - onPressed: () { - if (isFieldsFilled()) { - addPatientNoteAPICall(); - Navigator.pop(context); - } else { - showDialog( - context: context, - builder: (context) { - return const MIHErrorMessage(errorType: "Input Error"); - }, - ); - } - }, - buttonColor: - MzanziInnovationHub.of(context)!.theme.secondaryColor(), - width: 300, - child: Text( - "Add Note", - style: TextStyle( - color: MzanziInnovationHub.of(context)!.theme.primaryColor(), - fontSize: 20, - fontWeight: FontWeight.bold, + MihForm( + formKey: _formKey, + formFields: [ + MihTextFormField( + fillColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + inputColor: + MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: officeController, + multiLineInput: false, + requiredText: true, + readOnly: true, + hintText: "Office", ), - ), + const SizedBox(height: 10.0), + MihTextFormField( + fillColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + inputColor: + MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: doctorController, + multiLineInput: false, + requiredText: true, + readOnly: true, + hintText: "Created By", + ), + const SizedBox(height: 10.0), + MihTextFormField( + fillColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + inputColor: + MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: dateController, + multiLineInput: false, + requiredText: true, + readOnly: true, + hintText: "Created Date", + ), + const SizedBox(height: 10.0), + MihTextFormField( + fillColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + inputColor: + MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: titleController, + multiLineInput: false, + requiredText: true, + hintText: "Note Title", + validator: (value) { + return MihValidationServices().isEmpty(value); + }, + ), + const SizedBox(height: 10.0), + MihTextFormField( + height: 250, + fillColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + inputColor: + MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: noteTextController, + multiLineInput: true, + requiredText: true, + hintText: "Note Details", + validator: (value) { + return MihValidationServices().validateLength(value, 512); + }, + ), + SizedBox( + height: 15, + child: ValueListenableBuilder( + builder: (BuildContext context, int value, Widget? child) { + return Row( + mainAxisSize: MainAxisSize.max, + mainAxisAlignment: MainAxisAlignment.end, + children: [ + Text( + "$value", + style: TextStyle( + color: getNoteDetailLimitColor(), + fontWeight: FontWeight.bold, + ), + ), + const SizedBox(width: 5), + Text( + "/512", + style: TextStyle( + color: getNoteDetailLimitColor(), + fontWeight: FontWeight.bold, + ), + ), + ], + ); + }, + valueListenable: _counter, + ), + ), + const SizedBox(height: 15.0), + MihButton( + onPressed: () { + if (_formKey.currentState!.validate()) { + addPatientNoteAPICall(); + Navigator.pop(context); + } + }, + buttonColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + width: 300, + child: Text( + "Add Note", + style: TextStyle( + color: + MzanziInnovationHub.of(context)!.theme.primaryColor(), + fontSize: 20, + fontWeight: FontWeight.bold, + ), + ), + ), + ], ), ], ), From cb4117c35590f7ebd8557c6f651d2c8f4e765155 Mon Sep 17 00:00:00 2001 From: Yasien Mac Mini Date: Wed, 4 Jun 2025 16:00:25 +0200 Subject: [PATCH 25/52] Add new mih text form field to Pat Prof: Claims --- .../components/Claim_Statement_Window.dart | 524 ++++++++++-------- 1 file changed, 293 insertions(+), 231 deletions(-) diff --git a/Frontend/lib/mih_packages/patient_profile/pat_profile/components/Claim_Statement_Window.dart b/Frontend/lib/mih_packages/patient_profile/pat_profile/components/Claim_Statement_Window.dart index 6efd0697..3b846044 100644 --- a/Frontend/lib/mih_packages/patient_profile/pat_profile/components/Claim_Statement_Window.dart +++ b/Frontend/lib/mih_packages/patient_profile/pat_profile/components/Claim_Statement_Window.dart @@ -1,13 +1,16 @@ +import 'package:flutter/foundation.dart'; import 'package:flutter/services.dart'; import 'package:mzansi_innovation_hub/main.dart'; import 'package:mzansi_innovation_hub/mih_apis/mih_claim_statement_generation_api.dart'; import 'package:mzansi_innovation_hub/mih_apis/mih_icd10_code_api.dart'; +import 'package:mzansi_innovation_hub/mih_apis/mih_validation_services.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_inputs_and_buttons/mih_date_input.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_inputs_and_buttons/mih_dropdown_input.dart'; -import 'package:mzansi_innovation_hub/mih_components/mih_inputs_and_buttons/mih_text_input.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_button.dart'; +import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_form.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package_window.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_search_bar.dart'; +import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_text_form_field.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_pop_up_messages/mih_error_message.dart'; import 'package:mzansi_innovation_hub/mih_objects/app_user.dart'; import 'package:mzansi_innovation_hub/mih_objects/arguments.dart'; @@ -66,6 +69,7 @@ class _ClaimStatementWindowState extends State { final ValueNotifier medAid = ValueNotifier(""); List icd10codeList = []; final FocusNode _searchFocusNode = FocusNode(); + final _formKey = GlobalKey(); void icd10SearchWindow(List codeList) { showDialog( @@ -81,215 +85,287 @@ class _ClaimStatementWindowState extends State { Widget getWindowBody() { return Column( children: [ - MIHDropdownField( - controller: _docTypeController, - hintText: "Document Type", - dropdownOptions: const ["Claim", "Statement"], - required: true, - editable: true, - enableSearch: false, - ), - const SizedBox(height: 10), - Text( - "Service Details", - textAlign: TextAlign.center, - style: TextStyle( - fontSize: 20, - fontWeight: FontWeight.bold, - color: MzanziInnovationHub.of(context)!.theme.secondaryColor(), - ), - ), - Divider(color: MzanziInnovationHub.of(context)!.theme.secondaryColor()), - const SizedBox(height: 10), - MIHDateField( - controller: _serviceDateController, - lableText: "Date of Service", - required: true, - ), - const SizedBox(height: 10), - MIHDropdownField( - controller: _serviceDescController, - hintText: "Service Decription", - dropdownOptions: const [ - "Consultation", - "Procedure", - "Other", - ], - required: true, - editable: true, - enableSearch: false, - ), - const SizedBox(height: 10), - ValueListenableBuilder( - valueListenable: serviceDesc, - builder: (BuildContext context, String value, Widget? child) { - Widget returnWidget; - switch (value) { - case 'Consultation': - returnWidget = Column( - children: [ - MIHDropdownField( - controller: _serviceDescOptionsController, - hintText: "Service Decription Options", - dropdownOptions: const [ - "General Consultation", - "Follow-Up Consultation", - "Specialist Consultation", - "Emergency Consultation", - ], - required: true, - editable: true, - enableSearch: false, - ), - const SizedBox(height: 10), - ], - ); - case 'Procedure': - returnWidget = Column( - children: [ - MIHTextField( - controller: _prcedureNameController, - hintText: "Procedure Name", - editable: true, - required: true, - ), - const SizedBox(height: 10), - // MIHDateField( - // controller: _procedureDateController, - // lableText: "Procedure Date", - // required: true, - // ), - // const SizedBox(height: 10), - MIHTextField( - controller: _proceedureAdditionalInfoController, - hintText: "Additional Information", - editable: true, - required: true, - ), - const SizedBox(height: 10), - ], - ); - case 'Other': - returnWidget = Column( - children: [ - MIHTextField( - controller: _serviceDescOptionsController, - hintText: "Service Decription text", - editable: false, - required: true, - ), - const SizedBox(height: 10), - ], - ); - default: - returnWidget = const SizedBox(); - } - return returnWidget; - }, - ), - //const SizedBox(height: 10), - MihSearchBar( - controller: _icd10CodeController, - hintText: "ICD-10 Code & Description", - prefixIcon: Icons.search, - fillColor: MzanziInnovationHub.of(context)!.theme.secondaryColor(), - hintColor: MzanziInnovationHub.of(context)!.theme.primaryColor(), - onPrefixIconTap: () { - MIHIcd10CodeApis.getIcd10Codes(_icd10CodeController.text, context) - .then((result) { - icd10SearchWindow(result); - }); - }, - onClearIconTap: () { - _icd10CodeController.clear(); - }, - searchFocusNode: _searchFocusNode, - ), - const SizedBox(height: 10), - MIHTextField( - controller: _amountController, - hintText: "Amount", - editable: true, - required: true, - ), - Text( - "Additional Infomation", - textAlign: TextAlign.center, - style: TextStyle( - fontSize: 20, - fontWeight: FontWeight.bold, - color: MzanziInnovationHub.of(context)!.theme.secondaryColor(), - ), - ), - Divider(color: MzanziInnovationHub.of(context)!.theme.secondaryColor()), - const SizedBox(height: 10), - MIHTextField( - controller: _preauthNoController, - hintText: "Pre-authorisation No.", - editable: true, - required: false, - ), - const SizedBox(height: 15), - MihButton( - onPressed: () { - if (isInputValid()) { - MIHClaimStatementGenerationApi().generateClaimStatement( - ClaimStatementGenerationArguments( - _docTypeController.text, - widget.selectedPatient.app_id, - _fullNameController.text, - _idController.text, - _medAidController.text, - _medAidNoController.text, - _medAidCodeController.text, - _medAidNameController.text, - _medAidSchemeController.text, - widget.business!.Name, - "*To-Be Added*", - widget.business!.contact_no, - widget.business!.bus_email, - _providerNameController.text, - _practiceNoController.text, - _vatNoController.text, - _serviceDateController.text, - _serviceDescController.text, - _serviceDescOptionsController.text, - _prcedureNameController.text, - _proceedureAdditionalInfoController.text, - _icd10CodeController.text, - _amountController.text, - _preauthNoController.text, - widget.business!.logo_path, - widget.businessUser!.sig_path, - ), - PatientViewArguments( - widget.signedInUser, - widget.selectedPatient, - widget.businessUser, - widget.business, - "business", - ), - widget.env, - context); - } else { - showDialog( - context: context, - builder: (context) { - return const MIHErrorMessage(errorType: "Input Error"); - }, - ); - } - }, - buttonColor: MzanziInnovationHub.of(context)!.theme.secondaryColor(), - width: 300, - child: Text( - "Generate", - style: TextStyle( - color: MzanziInnovationHub.of(context)!.theme.primaryColor(), - fontSize: 20, - fontWeight: FontWeight.bold, + MihForm( + formKey: _formKey, + formFields: [ + MIHDropdownField( + controller: _docTypeController, + hintText: "Document Type", + dropdownOptions: const ["Claim", "Statement"], + required: true, + editable: true, + enableSearch: false, ), - ), + const SizedBox(height: 10), + Center( + child: Text( + "Service Details", + textAlign: TextAlign.center, + style: TextStyle( + fontSize: 25, + fontWeight: FontWeight.bold, + color: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + ), + ), + ), + Divider( + color: MzanziInnovationHub.of(context)!.theme.secondaryColor()), + const SizedBox(height: 10), + MIHDateField( + controller: _serviceDateController, + lableText: "Date of Service", + required: true, + ), + const SizedBox(height: 10), + MIHDropdownField( + controller: _serviceDescController, + hintText: "Service Decription", + dropdownOptions: const [ + "Consultation", + "Procedure", + "Other", + ], + required: true, + editable: true, + enableSearch: false, + ), + const SizedBox(height: 10), + ValueListenableBuilder( + valueListenable: serviceDesc, + builder: (BuildContext context, String value, Widget? child) { + Widget returnWidget; + switch (value) { + case 'Consultation': + returnWidget = Column( + children: [ + SizedBox( + child: MIHDropdownField( + controller: _serviceDescOptionsController, + hintText: "Consultation Type", + dropdownOptions: const [ + "General Consultation", + "Follow-Up Consultation", + "Specialist Consultation", + "Emergency Consultation", + ], + required: true, + editable: true, + enableSearch: false, + ), + ), + const SizedBox(height: 10), + ], + ); + case 'Procedure': + returnWidget = Column( + children: [ + MihTextFormField( + fillColor: MzanziInnovationHub.of(context)! + .theme + .secondaryColor(), + inputColor: MzanziInnovationHub.of(context)! + .theme + .primaryColor(), + controller: _prcedureNameController, + multiLineInput: false, + requiredText: true, + hintText: "Procedure Name", + validator: (value) { + return MihValidationServices().isEmpty(value); + }, + ), + const SizedBox(height: 10), + MihTextFormField( + fillColor: MzanziInnovationHub.of(context)! + .theme + .secondaryColor(), + inputColor: MzanziInnovationHub.of(context)! + .theme + .primaryColor(), + controller: _proceedureAdditionalInfoController, + multiLineInput: false, + requiredText: true, + hintText: "Additional Information", + validator: (value) { + return MihValidationServices().isEmpty(value); + }, + ), + const SizedBox(height: 15), + ], + ); + case 'Other': + returnWidget = Column( + children: [ + MihTextFormField( + fillColor: MzanziInnovationHub.of(context)! + .theme + .secondaryColor(), + inputColor: MzanziInnovationHub.of(context)! + .theme + .primaryColor(), + controller: _serviceDescOptionsController, + multiLineInput: false, + requiredText: true, + hintText: "Service Description Details", + validator: (value) { + return MihValidationServices().isEmpty(value); + }, + ), + const SizedBox(height: 10), + ], + ); + default: + returnWidget = const SizedBox(); + } + return returnWidget; + }, + ), + Column( + children: [ + Align( + alignment: Alignment.centerLeft, + child: Text("ICD-10 Code & Description", + style: TextStyle( + fontSize: 15, + fontWeight: FontWeight.bold, + color: MzanziInnovationHub.of(context)! + .theme + .secondaryColor(), + )), + ), + const SizedBox(height: 4), + MihSearchBar( + controller: _icd10CodeController, + hintText: "ICD-10 Search", + prefixIcon: Icons.search, + fillColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + hintColor: + MzanziInnovationHub.of(context)!.theme.primaryColor(), + onPrefixIconTap: () { + MIHIcd10CodeApis.getIcd10Codes( + _icd10CodeController.text, context) + .then((result) { + icd10SearchWindow(result); + }); + }, + onClearIconTap: () { + _icd10CodeController.clear(); + }, + searchFocusNode: _searchFocusNode, + ), + ], + ), + const SizedBox(height: 10), + MihTextFormField( + fillColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + inputColor: MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: _amountController, + multiLineInput: false, + requiredText: true, + numberMode: true, + hintText: "Service Cost", + validator: (value) { + return MihValidationServices().isEmpty(value); + }, + ), + const SizedBox(height: 10), + Center( + child: Text( + "Additional Infomation", + textAlign: TextAlign.center, + style: TextStyle( + fontSize: 25, + fontWeight: FontWeight.bold, + color: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + ), + ), + ), + Divider( + color: MzanziInnovationHub.of(context)!.theme.secondaryColor()), + const SizedBox(height: 10), + MihTextFormField( + fillColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + inputColor: MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: _preauthNoController, + multiLineInput: false, + requiredText: false, + hintText: "Pre-authorisation No.", + ), + const SizedBox(height: 20), + Center( + child: MihButton( + onPressed: () { + if (_formKey.currentState!.validate()) { + if (isInputValid()) { + MIHClaimStatementGenerationApi().generateClaimStatement( + ClaimStatementGenerationArguments( + _docTypeController.text, + widget.selectedPatient.app_id, + _fullNameController.text, + _idController.text, + _medAidController.text, + _medAidNoController.text, + _medAidCodeController.text, + _medAidNameController.text, + _medAidSchemeController.text, + widget.business!.Name, + "*To-Be Added*", + widget.business!.contact_no, + widget.business!.bus_email, + _providerNameController.text, + _practiceNoController.text, + _vatNoController.text, + _serviceDateController.text, + _serviceDescController.text, + _serviceDescOptionsController.text, + _prcedureNameController.text, + _proceedureAdditionalInfoController.text, + _icd10CodeController.text, + _amountController.text, + _preauthNoController.text, + widget.business!.logo_path, + widget.businessUser!.sig_path, + ), + PatientViewArguments( + widget.signedInUser, + widget.selectedPatient, + widget.businessUser, + widget.business, + "business", + ), + widget.env, + context); + } else { + showDialog( + context: context, + builder: (context) { + return const MIHErrorMessage( + errorType: "Input Error"); + }, + ); + } + } + }, + buttonColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + width: 300, + child: Text( + "Generate", + style: TextStyle( + color: + MzanziInnovationHub.of(context)!.theme.primaryColor(), + fontSize: 20, + fontWeight: FontWeight.bold, + ), + ), + ), + ), + ], ), ], ); @@ -312,28 +388,14 @@ class _ClaimStatementWindowState extends State { } bool isInputValid() { - switch (_serviceDescController.text) { - case 'Procedure': - if (_docTypeController.text.isEmpty || - _serviceDateController.text.isEmpty || - _icd10CodeController.text.isEmpty || - _amountController.text.isEmpty || - _prcedureNameController.text.isEmpty || - _proceedureAdditionalInfoController.text.isEmpty) { - return false; - } else { - return true; - } - default: - if (_docTypeController.text.isEmpty || - _serviceDateController.text.isEmpty || - _icd10CodeController.text.isEmpty || - _amountController.text.isEmpty || - _serviceDescOptionsController.text.isEmpty) { - return false; - } else { - return true; - } + if (_docTypeController.text.isEmpty || + _serviceDateController.text.isEmpty || + _icd10CodeController.text.isEmpty || + _amountController.text.isEmpty || + _serviceDescOptionsController.text.isEmpty) { + return false; + } else { + return true; } } From a1f8884266f0655d91bb31e59595839e5b1493f7 Mon Sep 17 00:00:00 2001 From: Yasien Mac Mini Date: Wed, 4 Jun 2025 16:02:52 +0200 Subject: [PATCH 26/52] Add new mih text form field to Pat Prof: Claims pt2 --- .../components/icd10_search_window.dart | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/Frontend/lib/mih_packages/patient_profile/pat_profile/components/icd10_search_window.dart b/Frontend/lib/mih_packages/patient_profile/pat_profile/components/icd10_search_window.dart index 2e354256..0b9d1a32 100644 --- a/Frontend/lib/mih_packages/patient_profile/pat_profile/components/icd10_search_window.dart +++ b/Frontend/lib/mih_packages/patient_profile/pat_profile/components/icd10_search_window.dart @@ -1,5 +1,7 @@ -import 'package:mzansi_innovation_hub/mih_components/mih_inputs_and_buttons/mih_text_input.dart'; +import 'package:mzansi_innovation_hub/main.dart'; +import 'package:mzansi_innovation_hub/mih_apis/mih_validation_services.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package_window.dart'; +import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_text_form_field.dart'; import 'package:mzansi_innovation_hub/mih_objects/icd10_code.dart.dart'; import 'package:mzansi_innovation_hub/mih_packages/patient_profile/pat_profile/list_builders/build_icd10_code_list.dart'; import 'package:flutter/material.dart'; @@ -21,11 +23,17 @@ class _ICD10SearchWindowState extends State { Widget getWindowBody() { return Column( children: [ - MIHTextField( + MihTextFormField( + fillColor: MzanziInnovationHub.of(context)!.theme.secondaryColor(), + inputColor: MzanziInnovationHub.of(context)!.theme.primaryColor(), controller: widget.icd10CodeController, - hintText: "Search Text", - editable: false, - required: false, + multiLineInput: false, + requiredText: true, + numberMode: true, + hintText: "ICD-10 Code Searched", + validator: (value) { + return MihValidationServices().isEmpty(value); + }, ), BuildICD10CodeList( icd10CodeController: widget.icd10CodeController, From 9ad5e3bf4c5b7180dc98993107d6acca4608add4 Mon Sep 17 00:00:00 2001 From: Yasien Mac Mini Date: Wed, 4 Jun 2025 16:06:33 +0200 Subject: [PATCH 27/52] icd 10 window enhancements --- .../pat_profile/components/icd10_search_window.dart | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/Frontend/lib/mih_packages/patient_profile/pat_profile/components/icd10_search_window.dart b/Frontend/lib/mih_packages/patient_profile/pat_profile/components/icd10_search_window.dart index 0b9d1a32..9ce37354 100644 --- a/Frontend/lib/mih_packages/patient_profile/pat_profile/components/icd10_search_window.dart +++ b/Frontend/lib/mih_packages/patient_profile/pat_profile/components/icd10_search_window.dart @@ -35,6 +35,16 @@ class _ICD10SearchWindowState extends State { return MihValidationServices().isEmpty(value); }, ), + const SizedBox(height: 15), + Text( + "Search for ICD-10 Codes", + style: TextStyle( + color: MzanziInnovationHub.of(context)!.theme.secondaryColor(), + fontSize: 25, + fontWeight: FontWeight.bold, + ), + ), + Divider(color: MzanziInnovationHub.of(context)!.theme.secondaryColor()), BuildICD10CodeList( icd10CodeController: widget.icd10CodeController, icd10codeList: widget.icd10codeList, From 388978265b3dfea32c1030efec6518fb37040904 Mon Sep 17 00:00:00 2001 From: Yasien Mac Mini Date: Wed, 4 Jun 2025 18:49:19 +0200 Subject: [PATCH 28/52] button spacer removed --- Frontend/lib/mih_packages/authentication/signin.dart | 1 - 1 file changed, 1 deletion(-) diff --git a/Frontend/lib/mih_packages/authentication/signin.dart b/Frontend/lib/mih_packages/authentication/signin.dart index 5f71c918..f48125d8 100644 --- a/Frontend/lib/mih_packages/authentication/signin.dart +++ b/Frontend/lib/mih_packages/authentication/signin.dart @@ -509,7 +509,6 @@ class _SignInState extends State { ), ), ), - const SizedBox(height: 10), MihButton( onPressed: widget.onTap, buttonColor: From a412e04424a9e0c57453bc6bd3a96937803e5987 Mon Sep 17 00:00:00 2001 From: Yasien Mac Mini Date: Thu, 5 Jun 2025 09:12:35 +0200 Subject: [PATCH 29/52] . --- .../package_tools/package_tool_one.dart | 544 +++++++++--------- .../package_tools/mih_personal_profile.dart | 2 +- 2 files changed, 278 insertions(+), 268 deletions(-) diff --git a/Frontend/lib/mih_components/mih_package_components/Example/package_tools/package_tool_one.dart b/Frontend/lib/mih_components/mih_package_components/Example/package_tools/package_tool_one.dart index d899911b..485292fb 100644 --- a/Frontend/lib/mih_components/mih_package_components/Example/package_tools/package_tool_one.dart +++ b/Frontend/lib/mih_components/mih_package_components/Example/package_tools/package_tool_one.dart @@ -95,7 +95,7 @@ class _PackageToolOneState extends State { @override Widget build(BuildContext context) { return MihPackageToolBody( - borderOn: true, + borderOn: false, bodyItem: getBody(), ); } @@ -122,121 +122,201 @@ class _PackageToolOneState extends State { Widget getBody() { return Stack( children: [ - MihSingleChildScroll( - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.center, - mainAxisSize: MainAxisSize.max, - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Text( - "Hello", - textAlign: TextAlign.center, - style: TextStyle( - fontSize: 25, - fontWeight: FontWeight.bold, - color: MzanziInnovationHub.of(context)! + Padding( + padding: const EdgeInsets.symmetric(horizontal: 10.0), + child: MihSingleChildScroll( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisSize: MainAxisSize.max, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text( + "Hello", + textAlign: TextAlign.center, + style: TextStyle( + fontSize: 25, + fontWeight: FontWeight.bold, + color: MzanziInnovationHub.of(context)! + .theme + .secondaryColor(), + ), + ), + ], + ), + const SizedBox(height: 20), + MihForm( + formKey: _formKey, + formFields: [ + MihTextFormField( + fillColor: MzanziInnovationHub.of(context)! .theme .secondaryColor(), + inputColor: + MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: _textFieldZeroController, + multiLineInput: false, + requiredText: true, + hintText: "Username", + validator: (value) { + return MihValidationServices().validateUsername(value); + }, + ), + const SizedBox(height: 10), + MihTextFormField( + fillColor: MzanziInnovationHub.of(context)! + .theme + .secondaryColor(), + inputColor: + MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: _textFieldOneController, + multiLineInput: false, + requiredText: true, + hintText: "Email", + autofillHints: [AutofillHints.email], + validator: (value) { + return MihValidationServices().validateEmail(value); + }, + ), + const SizedBox(height: 10), + MihTextFormField( + fillColor: MzanziInnovationHub.of(context)! + .theme + .secondaryColor(), + inputColor: + MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: _textFieldTwoController, + multiLineInput: false, + requiredText: true, + hintText: "Password", + passwordMode: true, + autofillHints: [AutofillHints.password], + validator: (value) { + return MihValidationServices().validatePassword(value); + }, + ), + const SizedBox(height: 10), + MihTextFormField( + fillColor: MzanziInnovationHub.of(context)! + .theme + .secondaryColor(), + inputColor: + MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: _textFieldThreeController, + multiLineInput: false, + requiredText: true, + hintText: "Numbers Only", + numberMode: true, + validator: (value) => value == null || value.isEmpty + ? 'This Field is required' + : null, + ), + const SizedBox(height: 10), + MihTextFormField( + height: 250, + fillColor: MzanziInnovationHub.of(context)! + .theme + .secondaryColor(), + inputColor: + MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: _textFieldFourController, + multiLineInput: true, + requiredText: false, + hintText: "Enter Multi Line Text", + ), + const SizedBox(height: 20), + Align( + alignment: Alignment.center, + child: MihButton( + onPressed: () { + if (_formKey.currentState!.validate()) { + // Process data + ScaffoldMessenger.of(context).showSnackBar( + const SnackBar(content: Text("Input Valid")), + ); + } + }, + buttonColor: MzanziInnovationHub.of(context)! + .theme + .secondaryColor(), + elevation: 10, + width: 300, + child: Text( + "Click Me", + style: TextStyle( + color: MzanziInnovationHub.of(context)! + .theme + .primaryColor(), + fontSize: 20, + fontWeight: FontWeight.bold, + ), + ), + ), + ), + ], + ), + const SizedBox(height: 10), + Divider( + color: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + thickness: 2, + ), + const SizedBox(height: 10), + MihSearchBar( + controller: _searchController, + hintText: "Ask Mzansi", + // prefixIcon: Icons.search, + prefixIcon: Icons.search, + prefixAltIcon: MihIcons.mzansiAi, + width: 300, + fillColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + hintColor: + MzanziInnovationHub.of(context)!.theme.primaryColor(), + onPrefixIconTap: () { + print("Search Icon Pressed: ${_searchController.text}"); + }, + searchFocusNode: searchFocusNode, + ), + const SizedBox(height: 20), + MihButton( + onPressed: () { + print("Button Pressed"); + }, + buttonColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + elevation: 10, + width: 300, + child: Text( + "Click Me", + style: TextStyle( + color: + MzanziInnovationHub.of(context)!.theme.primaryColor(), + fontSize: 20, + fontWeight: FontWeight.bold, ), ), - ], - ), - const SizedBox(height: 20), - MihForm( - formKey: _formKey, - formFields: [ - MihTextFormField( - fillColor: - MzanziInnovationHub.of(context)!.theme.secondaryColor(), - inputColor: - MzanziInnovationHub.of(context)!.theme.primaryColor(), - controller: _textFieldZeroController, - multiLineInput: false, - requiredText: true, - hintText: "Username", - validator: (value) { - return MihValidationServices().validateUsername(value); - }, - ), - const SizedBox(height: 10), - MihTextFormField( - fillColor: - MzanziInnovationHub.of(context)!.theme.secondaryColor(), - inputColor: - MzanziInnovationHub.of(context)!.theme.primaryColor(), - controller: _textFieldOneController, - multiLineInput: false, - requiredText: true, - hintText: "Email", - autofillHints: [AutofillHints.email], - validator: (value) { - return MihValidationServices().validateEmail(value); - }, - ), - const SizedBox(height: 10), - MihTextFormField( - fillColor: - MzanziInnovationHub.of(context)!.theme.secondaryColor(), - inputColor: - MzanziInnovationHub.of(context)!.theme.primaryColor(), - controller: _textFieldTwoController, - multiLineInput: false, - requiredText: true, - hintText: "Password", - passwordMode: true, - autofillHints: [AutofillHints.password], - validator: (value) { - return MihValidationServices().validatePassword(value); - }, - ), - const SizedBox(height: 10), - MihTextFormField( - fillColor: - MzanziInnovationHub.of(context)!.theme.secondaryColor(), - inputColor: - MzanziInnovationHub.of(context)!.theme.primaryColor(), - controller: _textFieldThreeController, - multiLineInput: false, - requiredText: true, - hintText: "Numbers Only", - numberMode: true, - validator: (value) => value == null || value.isEmpty - ? 'This Field is required' - : null, - ), - const SizedBox(height: 10), - MihTextFormField( - height: 250, - fillColor: - MzanziInnovationHub.of(context)!.theme.secondaryColor(), - inputColor: - MzanziInnovationHub.of(context)!.theme.primaryColor(), - controller: _textFieldFourController, - multiLineInput: true, - requiredText: false, - hintText: "Enter Multi Line Text", - ), - const SizedBox(height: 20), - Align( - alignment: Alignment.center, - child: MihButton( - onPressed: () { - if (_formKey.currentState!.validate()) { - // Process data - ScaffoldMessenger.of(context).showSnackBar( - const SnackBar(content: Text("Input Valid")), - ); - } - }, - buttonColor: MzanziInnovationHub.of(context)! - .theme - .secondaryColor(), - elevation: 10, - width: 300, - child: Text( + ), + const SizedBox(height: 40), + MihButton( + onPressed: () { + print("Button Pressed"); + }, + buttonColor: + MzanziInnovationHub.of(context)!.theme.successColor(), + width: 300, + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Icon( + Icons.delete, + color: MzanziInnovationHub.of(context)! + .theme + .primaryColor(), + ), + Text( "Click Me", style: TextStyle( color: MzanziInnovationHub.of(context)! @@ -246,169 +326,99 @@ class _PackageToolOneState extends State { fontWeight: FontWeight.bold, ), ), - ), - ), - ], - ), - const SizedBox(height: 10), - Divider( - color: MzanziInnovationHub.of(context)!.theme.secondaryColor(), - thickness: 2, - ), - const SizedBox(height: 10), - MihSearchBar( - controller: _searchController, - hintText: "Ask Mzansi", - // prefixIcon: Icons.search, - prefixIcon: Icons.search, - prefixAltIcon: MihIcons.mzansiAi, - width: 300, - fillColor: - MzanziInnovationHub.of(context)!.theme.secondaryColor(), - hintColor: - MzanziInnovationHub.of(context)!.theme.primaryColor(), - onPrefixIconTap: () { - print("Search Icon Pressed: ${_searchController.text}"); - }, - searchFocusNode: searchFocusNode, - ), - const SizedBox(height: 20), - MihButton( - onPressed: () { - print("Button Pressed"); - }, - buttonColor: - MzanziInnovationHub.of(context)!.theme.secondaryColor(), - elevation: 10, - width: 300, - child: Text( - "Click Me", - style: TextStyle( - color: - MzanziInnovationHub.of(context)!.theme.primaryColor(), - fontSize: 20, - fontWeight: FontWeight.bold, + ], ), ), - ), - const SizedBox(height: 40), - MihButton( - onPressed: () { - print("Button Pressed"); - }, - buttonColor: - MzanziInnovationHub.of(context)!.theme.successColor(), - width: 300, - child: Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Icon( - Icons.delete, + const SizedBox(height: 10), + MihButton( + onPressed: () { + print("Button Pressed"); + }, + buttonColor: + MzanziInnovationHub.of(context)!.theme.errorColor(), + width: 300, + child: Text( + "Click Me", + style: TextStyle( + color: + MzanziInnovationHub.of(context)!.theme.primaryColor(), + fontSize: 20, + fontWeight: FontWeight.bold, + ), + ), + ), + const SizedBox(height: 10), + Container( + color: Colors.black, + width: 200, + height: 200, + padding: EdgeInsets.zero, + alignment: Alignment.center, + child: IconButton.filled( + onPressed: () {}, + icon: Icon( + MihIcons.mihLogo, color: MzanziInnovationHub.of(context)!.theme.primaryColor(), ), - Text( - "Click Me", - style: TextStyle( - color: MzanziInnovationHub.of(context)! - .theme - .primaryColor(), - fontSize: 20, - fontWeight: FontWeight.bold, - ), - ), - ], - ), - ), - const SizedBox(height: 10), - MihButton( - onPressed: () { - print("Button Pressed"); - }, - buttonColor: - MzanziInnovationHub.of(context)!.theme.errorColor(), - width: 300, - child: Text( - "Click Me", - style: TextStyle( - color: - MzanziInnovationHub.of(context)!.theme.primaryColor(), - fontSize: 20, - fontWeight: FontWeight.bold, ), ), - ), - const SizedBox(height: 10), - Container( - color: Colors.black, - width: 200, - height: 200, - padding: EdgeInsets.zero, - alignment: Alignment.center, - child: IconButton.filled( - onPressed: () {}, - icon: Icon( - MihIcons.mihLogo, - color: - MzanziInnovationHub.of(context)!.theme.primaryColor(), - ), + const SizedBox(height: 10), + MihCircleAvatar( + imageFile: imagePreview, + width: 50, + editable: false, + fileNameController: _fileNameController, + userSelectedfile: file, + frameColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + backgroundColor: + MzanziInnovationHub.of(context)!.theme.primaryColor(), + onChange: (selectedImage) { + setState(() { + file = selectedImage; + }); + }, ), - ), - const SizedBox(height: 10), - MihCircleAvatar( - imageFile: imagePreview, - width: 50, - editable: false, - fileNameController: _fileNameController, - userSelectedfile: file, - frameColor: - MzanziInnovationHub.of(context)!.theme.secondaryColor(), - backgroundColor: - MzanziInnovationHub.of(context)!.theme.primaryColor(), - onChange: (selectedImage) { - setState(() { - file = selectedImage; - }); - }, - ), - const SizedBox(height: 10), - MihTextFormField( - fillColor: - MzanziInnovationHub.of(context)!.theme.secondaryColor(), - inputColor: - MzanziInnovationHub.of(context)!.theme.primaryColor(), - controller: _fileNameController, - hintText: "Selected Avatar File", - requiredText: false, - readOnly: false, - ), - const SizedBox(height: 10), - MihImageDisplay( - imageFile: imagePreview, - width: 300, - height: 200, - editable: true, - fileNameController: _imagefileController, - userSelectedfile: imageFile, - onChange: (selectedFile) { - setState(() { - imageFile = selectedFile; - }); - }, - ), - const SizedBox(height: 10), - MihTextFormField( - fillColor: - MzanziInnovationHub.of(context)!.theme.secondaryColor(), - inputColor: - MzanziInnovationHub.of(context)!.theme.primaryColor(), - controller: _imagefileController, - hintText: "Selected Image File", - requiredText: false, - readOnly: false, - ), - const SizedBox(height: 10), - ], + const SizedBox(height: 10), + MihTextFormField( + fillColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + inputColor: + MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: _fileNameController, + hintText: "Selected Avatar File", + requiredText: false, + readOnly: false, + ), + const SizedBox(height: 10), + MihImageDisplay( + imageFile: imagePreview, + width: 300, + height: 200, + editable: true, + fileNameController: _imagefileController, + userSelectedfile: imageFile, + onChange: (selectedFile) { + setState(() { + imageFile = selectedFile; + }); + }, + ), + const SizedBox(height: 10), + MihTextFormField( + fillColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + inputColor: + MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: _imagefileController, + hintText: "Selected Image File", + requiredText: false, + readOnly: false, + ), + const SizedBox(height: 10), + ], + ), ), ), Positioned( diff --git a/Frontend/lib/mih_packages/mzansi_profile/personal_profile/package_tools/mih_personal_profile.dart b/Frontend/lib/mih_packages/mzansi_profile/personal_profile/package_tools/mih_personal_profile.dart index 63c65973..85a8817f 100644 --- a/Frontend/lib/mih_packages/mzansi_profile/personal_profile/package_tools/mih_personal_profile.dart +++ b/Frontend/lib/mih_packages/mzansi_profile/personal_profile/package_tools/mih_personal_profile.dart @@ -269,7 +269,7 @@ class _MihPersonalProfileState extends State { ), const SizedBox(height: 25.0), Visibility( - visible: true, + visible: false, child: MihTextFormField( fillColor: MzanziInnovationHub.of(context)!.theme.secondaryColor(), From 3d1976d776701d4964cb33c0554180a45fcd2463 Mon Sep 17 00:00:00 2001 From: yaso Date: Thu, 5 Jun 2025 16:04:00 +0200 Subject: [PATCH 30/52] add new text field input into patient manager --- .../build_mih_patient_search_list.dart | 206 +++++++----- .../build_my_patient_list_list.dart | 295 +++++++++++------- .../package_tools/waiting_room.dart | 133 ++++---- .../package_tools/patient_info.dart | 151 ++++----- 4 files changed, 464 insertions(+), 321 deletions(-) diff --git a/Frontend/lib/mih_packages/patient_profile/pat_manager/list_builders/build_mih_patient_search_list.dart b/Frontend/lib/mih_packages/patient_profile/pat_manager/list_builders/build_mih_patient_search_list.dart index 868ffefe..e80e97b0 100644 --- a/Frontend/lib/mih_packages/patient_profile/pat_manager/list_builders/build_mih_patient_search_list.dart +++ b/Frontend/lib/mih_packages/patient_profile/pat_manager/list_builders/build_mih_patient_search_list.dart @@ -2,11 +2,13 @@ import 'dart:convert'; import 'package:mzansi_innovation_hub/main.dart'; import 'package:mzansi_innovation_hub/mih_apis/mih_api_calls.dart'; +import 'package:mzansi_innovation_hub/mih_apis/mih_validation_services.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_inputs_and_buttons/mih_date_input.dart'; -import 'package:mzansi_innovation_hub/mih_components/mih_inputs_and_buttons/mih_text_input.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_inputs_and_buttons/mih_time_input.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_button.dart'; +import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_form.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package_window.dart'; +import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_text_form_field.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_pop_up_messages/mih_error_message.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_pop_up_messages/mih_success_message.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_pop_up_messages/mih_warning_message.dart'; @@ -47,6 +49,7 @@ class _BuildPatientsListState extends State { TextEditingController lnameController = TextEditingController(); TextEditingController accessStatusController = TextEditingController(); final baseAPI = AppEnviroment.baseApiUrl; + final _formKey = GlobalKey(); Future addPatientAccessAPICall(int index) async { var response = await http.post( @@ -175,66 +178,97 @@ class _BuildPatientsListState extends State { }, windowBody: Column( children: [ - MIHTextField( - controller: idController, - hintText: "ID No.", - editable: false, - required: true, - ), - const SizedBox(height: 10.0), - MIHTextField( - controller: fnameController, - hintText: "First Name", - editable: false, - required: true, - ), - const SizedBox(height: 10.0), - MIHTextField( - controller: lnameController, - hintText: "Surname", - editable: false, - required: true, - ), - const SizedBox(height: 10.0), - MIHDateField( - controller: dateController, - lableText: "Date", - required: true, - ), - const SizedBox(height: 10.0), - MIHTimeField( - controller: timeController, - lableText: "Time", - required: true, - ), - const SizedBox(height: 30.0), - MihButton( - onPressed: () { - bool filled = isAppointmentFieldsFilled(); - if (filled) { - //print("here2"); - submitApointment(index); - //print("here3"); - } else { - showDialog( - context: context, - builder: (context) { - return const MIHErrorMessage(errorType: "Input Error"); - }, - ); - } - }, - buttonColor: - MzanziInnovationHub.of(context)!.theme.secondaryColor(), - width: 300, - child: Text( - "Book", - style: TextStyle( - color: MzanziInnovationHub.of(context)!.theme.primaryColor(), - fontSize: 20, - fontWeight: FontWeight.bold, + MihForm( + formKey: _formKey, + formFields: [ + MihTextFormField( + fillColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + inputColor: + MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: idController, + multiLineInput: false, + requiredText: true, + readOnly: true, + hintText: "ID No.", + validator: (value) { + return MihValidationServices().isEmpty(value); + }, ), - ), + const SizedBox(height: 10.0), + MihTextFormField( + fillColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + inputColor: + MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: fnameController, + multiLineInput: false, + requiredText: true, + readOnly: true, + hintText: "First Name", + validator: (value) { + return MihValidationServices().isEmpty(value); + }, + ), + const SizedBox(height: 10.0), + MihTextFormField( + fillColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + inputColor: + MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: lnameController, + multiLineInput: false, + requiredText: true, + readOnly: true, + hintText: "Surname", + validator: (value) { + return MihValidationServices().isEmpty(value); + }, + ), + const SizedBox(height: 10.0), + MIHDateField( + controller: dateController, + lableText: "Date", + required: true, + ), + const SizedBox(height: 10.0), + MIHTimeField( + controller: timeController, + lableText: "Time", + required: true, + ), + const SizedBox(height: 30.0), + MihButton( + onPressed: () { + bool filled = isAppointmentFieldsFilled(); + if (filled) { + //print("here2"); + submitApointment(index); + //print("here3"); + } else { + showDialog( + context: context, + builder: (context) { + return const MIHErrorMessage( + errorType: "Input Error"); + }, + ); + } + }, + buttonColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + width: 300, + child: Text( + "Book", + style: TextStyle( + color: + MzanziInnovationHub.of(context)!.theme.primaryColor(), + fontSize: 20, + fontWeight: FontWeight.bold, + ), + ), + ), + ], ), ], ), @@ -331,32 +365,60 @@ class _BuildPatientsListState extends State { }, windowBody: Column( children: [ - MIHTextField( + MihTextFormField( + fillColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + inputColor: MzanziInnovationHub.of(context)!.theme.primaryColor(), controller: idController, + multiLineInput: false, + requiredText: true, + readOnly: true, hintText: "ID No.", - editable: false, - required: true, + validator: (value) { + return MihValidationServices().isEmpty(value); + }, ), const SizedBox(height: 10.0), - MIHTextField( + MihTextFormField( + fillColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + inputColor: MzanziInnovationHub.of(context)!.theme.primaryColor(), controller: fnameController, + multiLineInput: false, + requiredText: true, + readOnly: true, hintText: "First Name", - editable: false, - required: true, + validator: (value) { + return MihValidationServices().isEmpty(value); + }, ), const SizedBox(height: 10.0), - MIHTextField( + MihTextFormField( + fillColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + inputColor: MzanziInnovationHub.of(context)!.theme.primaryColor(), controller: lnameController, + multiLineInput: false, + requiredText: true, + readOnly: true, hintText: "Surname", - editable: false, - required: true, + validator: (value) { + return MihValidationServices().isEmpty(value); + }, ), const SizedBox(height: 10.0), - MIHTextField( + MihTextFormField( + fillColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + inputColor: MzanziInnovationHub.of(context)!.theme.primaryColor(), controller: accessStatusController, + multiLineInput: false, + requiredText: true, + readOnly: true, hintText: "Access Status", - editable: false, - required: true, + validator: (value) { + return MihValidationServices().isEmpty(value); + }, ), const SizedBox(height: 20.0), Visibility( diff --git a/Frontend/lib/mih_packages/patient_profile/pat_manager/list_builders/build_my_patient_list_list.dart b/Frontend/lib/mih_packages/patient_profile/pat_manager/list_builders/build_my_patient_list_list.dart index c79378fd..eb4661ff 100644 --- a/Frontend/lib/mih_packages/patient_profile/pat_manager/list_builders/build_my_patient_list_list.dart +++ b/Frontend/lib/mih_packages/patient_profile/pat_manager/list_builders/build_my_patient_list_list.dart @@ -1,11 +1,13 @@ import 'package:mzansi_innovation_hub/main.dart'; import 'package:mzansi_innovation_hub/mih_apis/mih_api_calls.dart'; import 'package:mzansi_innovation_hub/mih_apis/mih_mzansi_calendar_apis.dart'; +import 'package:mzansi_innovation_hub/mih_apis/mih_validation_services.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_inputs_and_buttons/mih_date_input.dart'; -import 'package:mzansi_innovation_hub/mih_components/mih_inputs_and_buttons/mih_text_input.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_inputs_and_buttons/mih_time_input.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_button.dart'; +import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_form.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package_window.dart'; +import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_text_form_field.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_pop_up_messages/mih_error_message.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_pop_up_messages/mih_warning_message.dart'; import 'package:mzansi_innovation_hub/mih_env/env.dart'; @@ -41,6 +43,7 @@ class _BuildPatientsListState extends State { TextEditingController idController = TextEditingController(); TextEditingController fnameController = TextEditingController(); TextEditingController lnameController = TextEditingController(); + final _formKey = GlobalKey(); final baseAPI = AppEnviroment.baseApiUrl; @@ -66,18 +69,6 @@ class _BuildPatientsListState extends State { timeController.text, context, ); - // MIHApiCalls.addAppointmentAPICall( - // widget.business!.business_id, - // widget.patientAccesses[index].app_id, - // dateController.text, - // timeController.text, - // BusinessArguments( - // widget.signedInUser, - // widget.businessUser, - // widget.business, - // ), - // context, - // ); } bool isAppointmentFieldsFilled() { @@ -108,64 +99,100 @@ class _BuildPatientsListState extends State { }, windowBody: Column( children: [ - MIHTextField( - controller: idController, - hintText: "ID No.", - editable: false, - required: true, - ), - const SizedBox(height: 10.0), - MIHTextField( - controller: fnameController, - hintText: "First Name", - editable: false, - required: true, - ), - const SizedBox(height: 10.0), - MIHTextField( - controller: lnameController, - hintText: "Surname", - editable: false, - required: true, - ), - const SizedBox(height: 10.0), - MIHDateField( - controller: dateController, - lableText: "Date", - required: true, - ), - const SizedBox(height: 10.0), - MIHTimeField( - controller: timeController, - lableText: "Time", - required: true, - ), - const SizedBox(height: 30.0), - MihButton( - onPressed: () { - bool filled = isAppointmentFieldsFilled(); - if (filled) { - submitApointment(index); - } else { - showDialog( - context: context, - builder: (context) { - return const MIHErrorMessage(errorType: "Input Error"); - }, - ); - } - }, - buttonColor: - MzanziInnovationHub.of(context)!.theme.secondaryColor(), - width: 300, - child: Text( - "Book Appointment", - style: TextStyle( - color: MzanziInnovationHub.of(context)!.theme.primaryColor(), - fontSize: 20, - fontWeight: FontWeight.bold, + MihForm( + formKey: _formKey, + formFields: [ + MihTextFormField( + fillColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + inputColor: + MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: idController, + multiLineInput: false, + requiredText: true, + readOnly: true, + hintText: "ID No.", + validator: (value) { + return MihValidationServices().isEmpty(value); + }, ), - ), + const SizedBox(height: 10.0), + MihTextFormField( + fillColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + inputColor: + MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: fnameController, + multiLineInput: false, + requiredText: true, + readOnly: true, + hintText: "First Name", + validator: (value) { + return MihValidationServices().isEmpty(value); + }, + ), + const SizedBox(height: 10.0), + MihTextFormField( + fillColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + inputColor: + MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: lnameController, + multiLineInput: false, + requiredText: true, + readOnly: true, + hintText: "Surname", + validator: (value) { + return MihValidationServices().isEmpty(value); + }, + ), + const SizedBox(height: 10.0), + MIHDateField( + controller: dateController, + lableText: "Date", + required: true, + ), + const SizedBox(height: 10.0), + MIHTimeField( + controller: timeController, + lableText: "Time", + required: true, + ), + const SizedBox(height: 30.0), + Center( + child: MihButton( + onPressed: () { + if (_formKey.currentState!.validate()) { + bool filled = isAppointmentFieldsFilled(); + if (filled) { + submitApointment(index); + } else { + showDialog( + context: context, + builder: (context) { + return const MIHErrorMessage( + errorType: "Input Error"); + }, + ); + } + } + }, + buttonColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + width: 300, + child: Text( + "Book Appointment", + style: TextStyle( + color: MzanziInnovationHub.of(context)! + .theme + .primaryColor(), + fontSize: 20, + fontWeight: FontWeight.bold, + ), + ), + ), + ), + ], ), ], ), @@ -222,70 +249,100 @@ class _BuildPatientsListState extends State { }, windowBody: Column( children: [ - MIHTextField( + MihTextFormField( + fillColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + inputColor: MzanziInnovationHub.of(context)!.theme.primaryColor(), controller: idController, + multiLineInput: false, + requiredText: true, + readOnly: true, hintText: "ID No.", - editable: false, - required: true, + validator: (value) { + return MihValidationServices().isEmpty(value); + }, ), const SizedBox(height: 10.0), - MIHTextField( + MihTextFormField( + fillColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + inputColor: MzanziInnovationHub.of(context)!.theme.primaryColor(), controller: fnameController, + multiLineInput: false, + requiredText: true, + readOnly: true, hintText: "First Name", - editable: false, - required: true, + validator: (value) { + return MihValidationServices().isEmpty(value); + }, ), const SizedBox(height: 10.0), - MIHTextField( + MihTextFormField( + fillColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + inputColor: MzanziInnovationHub.of(context)!.theme.primaryColor(), controller: lnameController, + multiLineInput: false, + requiredText: true, + readOnly: true, hintText: "Surname", - editable: false, - required: true, + validator: (value) { + return MihValidationServices().isEmpty(value); + }, ), const SizedBox(height: 30.0), - Wrap(runSpacing: 10, spacing: 10, children: [ - MihButton( - onPressed: () { - appointmentPopUp(index); - }, - buttonColor: - MzanziInnovationHub.of(context)!.theme.secondaryColor(), - width: 300, - child: Text( - "Book Appointment", - style: TextStyle( - color: - MzanziInnovationHub.of(context)!.theme.primaryColor(), - fontSize: 20, - fontWeight: FontWeight.bold, + Center( + child: Wrap( + runSpacing: 10, + spacing: 10, + children: [ + MihButton( + onPressed: () { + appointmentPopUp(index); + }, + buttonColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + width: 300, + child: Text( + "Book Appointment", + style: TextStyle( + color: MzanziInnovationHub.of(context)! + .theme + .primaryColor(), + fontSize: 20, + fontWeight: FontWeight.bold, + ), + ), ), - ), - ), - MihButton( - onPressed: () { - Navigator.of(context).pushNamed('/patient-manager/patient', - arguments: PatientViewArguments( - widget.signedInUser, - patientProfile, - widget.businessUser, - widget.business, - "business", - )); - }, - buttonColor: - MzanziInnovationHub.of(context)!.theme.successColor(), - width: 300, - child: Text( - "View Medical Records", - style: TextStyle( - color: - MzanziInnovationHub.of(context)!.theme.primaryColor(), - fontSize: 20, - fontWeight: FontWeight.bold, + MihButton( + onPressed: () { + Navigator.of(context) + .pushNamed('/patient-manager/patient', + arguments: PatientViewArguments( + widget.signedInUser, + patientProfile, + widget.businessUser, + widget.business, + "business", + )); + }, + buttonColor: + MzanziInnovationHub.of(context)!.theme.successColor(), + width: 300, + child: Text( + "View Medical Records", + style: TextStyle( + color: MzanziInnovationHub.of(context)! + .theme + .primaryColor(), + fontSize: 20, + fontWeight: FontWeight.bold, + ), + ), ), - ), + ], ), - ]) + ) ], ), ), diff --git a/Frontend/lib/mih_packages/patient_profile/pat_manager/package_tools/waiting_room.dart b/Frontend/lib/mih_packages/patient_profile/pat_manager/package_tools/waiting_room.dart index 6d378e83..a66db041 100644 --- a/Frontend/lib/mih_packages/patient_profile/pat_manager/package_tools/waiting_room.dart +++ b/Frontend/lib/mih_packages/patient_profile/pat_manager/package_tools/waiting_room.dart @@ -1,16 +1,17 @@ import 'package:flutter_speed_dial/flutter_speed_dial.dart'; import 'package:mzansi_innovation_hub/main.dart'; import 'package:mzansi_innovation_hub/mih_apis/mih_mzansi_calendar_apis.dart'; +import 'package:mzansi_innovation_hub/mih_apis/mih_validation_services.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_calendar.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_inputs_and_buttons/mih_date_input.dart'; -import 'package:mzansi_innovation_hub/mih_components/mih_inputs_and_buttons/mih_multiline_text_input.dart'; -import 'package:mzansi_innovation_hub/mih_components/mih_inputs_and_buttons/mih_text_input.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_inputs_and_buttons/mih_time_input.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_layout/mih_single_child_scroll.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_button.dart'; +import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_form.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package_tool_body.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_floating_menu.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package_window.dart'; +import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_text_form_field.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_pop_up_messages/mih_error_message.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_pop_up_messages/mih_loading_circle.dart'; import 'package:mzansi_innovation_hub/mih_env/env.dart'; @@ -59,6 +60,7 @@ class _WaitingRoomState extends State { late Future> businessAppointmentResults; late Future> appointmentResults; bool inWaitingRoom = true; + final _formKey = GlobalKey(); // Business Appointment Tool Widget getBusinessAppointmentsTool() { @@ -314,61 +316,79 @@ class _WaitingRoomState extends State { }, windowBody: Column( children: [ - SizedBox( - // width: 500, - child: MIHTextField( - controller: _appointmentTitleController, - hintText: "Title", - editable: true, - required: true, - ), - ), - const SizedBox(height: 10), - SizedBox( - // width: 500, - child: MIHDateField( - controller: _appointmentDateController, - lableText: "Date", - required: true, - ), - ), - const SizedBox(height: 10), - SizedBox( - // width: 500, - child: MIHTimeField( - controller: _appointmentTimeController, - lableText: "Time", - required: true, - ), - ), - const SizedBox(height: 10), - SizedBox( - // width: 500, - height: 250, - child: MIHMLTextField( - controller: _appointmentDescriptionIDController, - hintText: "Description", - editable: true, - required: true, - ), - ), - const SizedBox(height: 20), - MihButton( - onPressed: () { - addAppointmentCall(); - }, - buttonColor: - MzanziInnovationHub.of(context)!.theme.successColor(), - width: 300, - child: Text( - "Add", - style: TextStyle( - color: + MihForm( + formKey: _formKey, + formFields: [ + MihTextFormField( + fillColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + inputColor: MzanziInnovationHub.of(context)!.theme.primaryColor(), - fontSize: 20, - fontWeight: FontWeight.bold, + controller: _appointmentTitleController, + multiLineInput: false, + requiredText: true, + hintText: "Appointment Title", + validator: (value) { + return MihValidationServices().isEmpty(value); + }, ), - ), + const SizedBox(height: 10), + SizedBox( + // width: 500, + child: MIHDateField( + controller: _appointmentDateController, + lableText: "Date", + required: true, + ), + ), + const SizedBox(height: 10), + SizedBox( + // width: 500, + child: MIHTimeField( + controller: _appointmentTimeController, + lableText: "Time", + required: true, + ), + ), + const SizedBox(height: 10), + MihTextFormField( + height: 250, + fillColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + inputColor: + MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: _appointmentDescriptionIDController, + multiLineInput: true, + requiredText: true, + hintText: "Description", + validator: (value) { + return MihValidationServices().isEmpty(value); + }, + ), + const SizedBox(height: 20), + Center( + child: MihButton( + onPressed: () { + if (_formKey.currentState!.validate()) { + addAppointmentCall(); + } + }, + buttonColor: + MzanziInnovationHub.of(context)!.theme.successColor(), + width: 300, + child: Text( + "Add", + style: TextStyle( + color: MzanziInnovationHub.of(context)! + .theme + .primaryColor(), + fontSize: 20, + fontWeight: FontWeight.bold, + ), + ), + ), + ), + ], ), ], ), @@ -413,8 +433,7 @@ class _WaitingRoomState extends State { } bool isAppointmentInputValid() { - if (_appointmentTitleController.text.isEmpty || - _appointmentDescriptionIDController.text.isEmpty || + if (_appointmentDescriptionIDController.text.isEmpty || _appointmentDateController.text.isEmpty || _appointmentTimeController.text.isEmpty) { return false; diff --git a/Frontend/lib/mih_packages/patient_profile/pat_profile/package_tools/patient_info.dart b/Frontend/lib/mih_packages/patient_profile/pat_profile/package_tools/patient_info.dart index 8bab62df..b806201b 100644 --- a/Frontend/lib/mih_packages/patient_profile/pat_profile/package_tools/patient_info.dart +++ b/Frontend/lib/mih_packages/patient_profile/pat_profile/package_tools/patient_info.dart @@ -43,75 +43,77 @@ class _PatientInfoState extends State { late String medAid; Widget getPatientDetailsField() { - return Wrap( - spacing: 15, - runSpacing: 10, - children: [ - MihTextFormField( - width: textFieldWidth, - fillColor: MzanziInnovationHub.of(context)!.theme.secondaryColor(), - inputColor: MzanziInnovationHub.of(context)!.theme.primaryColor(), - controller: idController, - multiLineInput: false, - requiredText: true, - readOnly: true, - hintText: "ID No.", - // validator: (value) { - // return MihValidationServices().isEmpty(value); - // }, - ), - MihTextFormField( - width: textFieldWidth, - fillColor: MzanziInnovationHub.of(context)!.theme.secondaryColor(), - inputColor: MzanziInnovationHub.of(context)!.theme.primaryColor(), - controller: fnameController, - multiLineInput: false, - requiredText: true, - readOnly: true, - hintText: "First Name", - ), - MihTextFormField( - width: textFieldWidth, - fillColor: MzanziInnovationHub.of(context)!.theme.secondaryColor(), - inputColor: MzanziInnovationHub.of(context)!.theme.primaryColor(), - controller: lnameController, - multiLineInput: false, - requiredText: true, - hintText: "Surname", - readOnly: true, - ), - MihTextFormField( - width: textFieldWidth, - fillColor: MzanziInnovationHub.of(context)!.theme.secondaryColor(), - inputColor: MzanziInnovationHub.of(context)!.theme.primaryColor(), - controller: cellController, - multiLineInput: false, - requiredText: true, - readOnly: true, - hintText: "Cell No.", - ), - MihTextFormField( - width: textFieldWidth, - fillColor: MzanziInnovationHub.of(context)!.theme.secondaryColor(), - inputColor: MzanziInnovationHub.of(context)!.theme.primaryColor(), - controller: emailController, - multiLineInput: false, - requiredText: true, - readOnly: true, - hintText: "Email", - ), - MihTextFormField( - width: textFieldWidth, - height: 100, - fillColor: MzanziInnovationHub.of(context)!.theme.secondaryColor(), - inputColor: MzanziInnovationHub.of(context)!.theme.primaryColor(), - controller: addressController, - multiLineInput: true, - requiredText: true, - readOnly: true, - hintText: "Address", - ), - ], + return Center( + child: Wrap( + spacing: 15, + runSpacing: 10, + children: [ + MihTextFormField( + width: textFieldWidth, + fillColor: MzanziInnovationHub.of(context)!.theme.secondaryColor(), + inputColor: MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: idController, + multiLineInput: false, + requiredText: true, + readOnly: true, + hintText: "ID No.", + // validator: (value) { + // return MihValidationServices().isEmpty(value); + // }, + ), + MihTextFormField( + width: textFieldWidth, + fillColor: MzanziInnovationHub.of(context)!.theme.secondaryColor(), + inputColor: MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: fnameController, + multiLineInput: false, + requiredText: true, + readOnly: true, + hintText: "First Name", + ), + MihTextFormField( + width: textFieldWidth, + fillColor: MzanziInnovationHub.of(context)!.theme.secondaryColor(), + inputColor: MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: lnameController, + multiLineInput: false, + requiredText: true, + hintText: "Surname", + readOnly: true, + ), + MihTextFormField( + width: textFieldWidth, + fillColor: MzanziInnovationHub.of(context)!.theme.secondaryColor(), + inputColor: MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: cellController, + multiLineInput: false, + requiredText: true, + readOnly: true, + hintText: "Cell No.", + ), + MihTextFormField( + width: textFieldWidth, + fillColor: MzanziInnovationHub.of(context)!.theme.secondaryColor(), + inputColor: MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: emailController, + multiLineInput: false, + requiredText: true, + readOnly: true, + hintText: "Email", + ), + MihTextFormField( + width: textFieldWidth, + height: 100, + fillColor: MzanziInnovationHub.of(context)!.theme.secondaryColor(), + inputColor: MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: addressController, + multiLineInput: true, + requiredText: true, + readOnly: true, + hintText: "Address", + ), + ], + ), ); } @@ -202,10 +204,12 @@ class _PatientInfoState extends State { ), ), ]); - return Wrap( - spacing: 10, - runSpacing: 10, - children: medAidDet, + return Center( + child: Wrap( + spacing: 10, + runSpacing: 10, + children: medAidDet, + ), ); } @@ -271,6 +275,7 @@ class _PatientInfoState extends State { children: [ MihSingleChildScroll( child: Column( + mainAxisAlignment: MainAxisAlignment.center, children: [ MihForm( formKey: _formKey, From 7d663f3b9617d54723cecb1a5246d0843fb3f106 Mon Sep 17 00:00:00 2001 From: yaso Date: Thu, 5 Jun 2025 16:04:14 +0200 Subject: [PATCH 31/52] fix textfield width --- .../mih_text_form_field.dart | 339 +++++++++--------- 1 file changed, 172 insertions(+), 167 deletions(-) diff --git a/Frontend/lib/mih_components/mih_package_components/mih_text_form_field.dart b/Frontend/lib/mih_components/mih_package_components/mih_text_form_field.dart index 50c50d36..d10452ac 100644 --- a/Frontend/lib/mih_components/mih_package_components/mih_text_form_field.dart +++ b/Frontend/lib/mih_components/mih_package_components/mih_text_form_field.dart @@ -84,186 +84,191 @@ class _MihTextFormFieldState extends State { @override Widget build(BuildContext context) { - return Theme( - data: Theme.of(context).copyWith( - textSelectionTheme: TextSelectionThemeData( - selectionColor: widget.inputColor.withValues(alpha: 0.3), - selectionHandleColor: widget.inputColor, + return SizedBox( + width: widget.width, + height: widget.height, + child: Theme( + data: Theme.of(context).copyWith( + textSelectionTheme: TextSelectionThemeData( + selectionColor: widget.inputColor.withValues(alpha: 0.3), + selectionHandleColor: widget.inputColor, + ), ), - ), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Text( - widget.hintText, - textAlign: TextAlign.left, - style: TextStyle( - color: widget.fillColor, - fontSize: 15, - fontWeight: FontWeight.bold, - ), - ), - Visibility( - visible: !widget.requiredText, - child: Text( - "(Optional)", - textAlign: TextAlign.right, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + widget.hintText, + textAlign: TextAlign.left, style: TextStyle( color: widget.fillColor, fontSize: 15, fontWeight: FontWeight.bold, ), ), - ), - ], - ), - const SizedBox(height: 4), - FormField( - initialValue: widget.controller.text, - validator: widget.validator, - autovalidateMode: AutovalidateMode.onUserInteraction, - builder: (field) { - _formFieldState = field; - return Column( - crossAxisAlignment: - CrossAxisAlignment.start, // <-- Add this line - children: [ - Material( - elevation: widget.elevation ?? 4.0, - borderRadius: - BorderRadius.circular(widget.borderRadius ?? 8.0), - child: SizedBox( - width: widget.width, - height: widget.height, - child: TextFormField( - controller: widget.controller, - cursorColor: widget.inputColor, - autofillHints: widget.autofillHints, - textAlign: TextAlign.start, - textAlignVertical: widget.multiLineInput == true - ? TextAlignVertical.top - : TextAlignVertical.center, - obscureText: - widget.passwordMode == true ? _obscureText : false, - expands: widget.passwordMode == true - ? false - : (widget.multiLineInput ?? false), - maxLines: widget.passwordMode == true ? 1 : null, - readOnly: widget.readOnly ?? false, - keyboardType: widget.numberMode == true - ? TextInputType.number - : null, - inputFormatters: widget.numberMode == true - ? [FilteringTextInputFormatter.digitsOnly] - : null, - style: TextStyle( - color: widget.inputColor, - fontWeight: FontWeight.w500, - ), - decoration: InputDecoration( - suffixIcon: widget.passwordMode == true - ? IconButton( - icon: Icon( - _obscureText - ? Icons.visibility_off - : Icons.visibility, - color: widget.inputColor, - ), - onPressed: () { - setState(() { - _obscureText = !_obscureText; - }); - }, - ) - : null, - errorStyle: const TextStyle( - height: 0, fontSize: 0), // <-- Add this line - contentPadding: const EdgeInsets.symmetric( - horizontal: 10.0, vertical: 8.0), - filled: true, - fillColor: widget.fillColor, - border: OutlineInputBorder( - borderRadius: BorderRadius.circular( - widget.borderRadius ?? 8.0), - borderSide: field.hasError - ? BorderSide( - color: MzanziInnovationHub.of(context)! - .theme - .errorColor(), - width: 2.0, - ) - : BorderSide.none, - ), - enabledBorder: OutlineInputBorder( - borderRadius: BorderRadius.circular( - widget.borderRadius ?? 8.0), - borderSide: BorderSide.none, - ), - focusedBorder: OutlineInputBorder( - borderRadius: BorderRadius.circular( - widget.borderRadius ?? 8.0), - borderSide: BorderSide( - color: field.hasError - ? MzanziInnovationHub.of(context)! - .theme - .errorColor() - : widget.inputColor, - width: 3.0, - ), - ), - errorBorder: OutlineInputBorder( - borderRadius: BorderRadius.circular( - widget.borderRadius ?? 8.0), - borderSide: BorderSide( - color: MzanziInnovationHub.of(context)! - .theme - .errorColor(), - width: 3.0, - ), - ), - focusedErrorBorder: OutlineInputBorder( - borderRadius: BorderRadius.circular( - widget.borderRadius ?? 8.0), - borderSide: BorderSide( - color: MzanziInnovationHub.of(context)! - .theme - .errorColor(), - width: 3.0, - ), - ), - ), - onChanged: (value) { - field.didChange(value); - }, - ), + Visibility( + visible: !widget.requiredText, + child: Text( + "(Optional)", + textAlign: TextAlign.right, + style: TextStyle( + color: widget.fillColor, + fontSize: 15, + fontWeight: FontWeight.bold, ), ), - if (field.hasError) - Row( - children: [ - Padding( - padding: const EdgeInsets.only(left: 8.0, top: 4.0), - child: Text( - field.errorText ?? '', - style: TextStyle( - fontSize: 12, - color: MzanziInnovationHub.of(context)! - .theme - .errorColor(), - fontWeight: FontWeight.bold, + ), + ], + ), + const SizedBox(height: 4), + FormField( + initialValue: widget.controller.text, + validator: widget.validator, + autovalidateMode: AutovalidateMode.onUserInteraction, + builder: (field) { + _formFieldState = field; + return Column( + crossAxisAlignment: + CrossAxisAlignment.start, // <-- Add this line + children: [ + Material( + elevation: widget.elevation ?? 4.0, + borderRadius: + BorderRadius.circular(widget.borderRadius ?? 8.0), + child: SizedBox( + height: + widget.height != null ? widget.height! - 25 : null, + child: TextFormField( + controller: widget.controller, + cursorColor: widget.inputColor, + autofillHints: widget.autofillHints, + textAlign: TextAlign.start, + textAlignVertical: widget.multiLineInput == true + ? TextAlignVertical.top + : TextAlignVertical.center, + obscureText: widget.passwordMode == true + ? _obscureText + : false, + expands: widget.passwordMode == true + ? false + : (widget.multiLineInput ?? false), + maxLines: widget.passwordMode == true ? 1 : null, + readOnly: widget.readOnly ?? false, + keyboardType: widget.numberMode == true + ? TextInputType.number + : null, + inputFormatters: widget.numberMode == true + ? [FilteringTextInputFormatter.digitsOnly] + : null, + style: TextStyle( + color: widget.inputColor, + fontWeight: FontWeight.w500, + ), + decoration: InputDecoration( + suffixIcon: widget.passwordMode == true + ? IconButton( + icon: Icon( + _obscureText + ? Icons.visibility_off + : Icons.visibility, + color: widget.inputColor, + ), + onPressed: () { + setState(() { + _obscureText = !_obscureText; + }); + }, + ) + : null, + errorStyle: const TextStyle( + height: 0, fontSize: 0), // <-- Add this line + contentPadding: const EdgeInsets.symmetric( + horizontal: 10.0, vertical: 8.0), + filled: true, + fillColor: widget.fillColor, + border: OutlineInputBorder( + borderRadius: BorderRadius.circular( + widget.borderRadius ?? 8.0), + borderSide: field.hasError + ? BorderSide( + color: MzanziInnovationHub.of(context)! + .theme + .errorColor(), + width: 2.0, + ) + : BorderSide.none, + ), + enabledBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular( + widget.borderRadius ?? 8.0), + borderSide: BorderSide.none, + ), + focusedBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular( + widget.borderRadius ?? 8.0), + borderSide: BorderSide( + color: field.hasError + ? MzanziInnovationHub.of(context)! + .theme + .errorColor() + : widget.inputColor, + width: 3.0, + ), + ), + errorBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular( + widget.borderRadius ?? 8.0), + borderSide: BorderSide( + color: MzanziInnovationHub.of(context)! + .theme + .errorColor(), + width: 3.0, + ), + ), + focusedErrorBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular( + widget.borderRadius ?? 8.0), + borderSide: BorderSide( + color: MzanziInnovationHub.of(context)! + .theme + .errorColor(), + width: 3.0, + ), ), ), + onChanged: (value) { + field.didChange(value); + }, ), - ], + ), ), - ], - ); - }, - ), - ], + if (field.hasError) + Row( + children: [ + Padding( + padding: const EdgeInsets.only(left: 8.0, top: 4.0), + child: Text( + field.errorText ?? '', + style: TextStyle( + fontSize: 12, + color: MzanziInnovationHub.of(context)! + .theme + .errorColor(), + fontWeight: FontWeight.bold, + ), + ), + ), + ], + ), + ], + ); + }, + ), + ], + ), ), ); } From 7d6b42640c0236f049a41c72512062c4e7cba075 Mon Sep 17 00:00:00 2001 From: yaso Date: Thu, 5 Jun 2025 16:04:21 +0200 Subject: [PATCH 32/52] test --- .../Example/package_tools/package_tool_one.dart | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Frontend/lib/mih_components/mih_package_components/Example/package_tools/package_tool_one.dart b/Frontend/lib/mih_components/mih_package_components/Example/package_tools/package_tool_one.dart index 485292fb..9debc4cc 100644 --- a/Frontend/lib/mih_components/mih_package_components/Example/package_tools/package_tool_one.dart +++ b/Frontend/lib/mih_components/mih_package_components/Example/package_tools/package_tool_one.dart @@ -151,6 +151,7 @@ class _PackageToolOneState extends State { formKey: _formKey, formFields: [ MihTextFormField( + width: 200, fillColor: MzanziInnovationHub.of(context)! .theme .secondaryColor(), @@ -158,7 +159,7 @@ class _PackageToolOneState extends State { MzanziInnovationHub.of(context)!.theme.primaryColor(), controller: _textFieldZeroController, multiLineInput: false, - requiredText: true, + requiredText: false, hintText: "Username", validator: (value) { return MihValidationServices().validateUsername(value); From efb90988355d738de810c18d352a5a070f995882 Mon Sep 17 00:00:00 2001 From: yaso Date: Fri, 6 Jun 2025 10:11:51 +0200 Subject: [PATCH 33/52] . --- .../package_tools/package_tool_one.dart | 14 +- .../mih_text_form_field.dart | 346 +++++++++--------- Frontend/lib/mih_env/env.dart | 12 +- .../authentication/forgot_password.dart | 12 +- .../mih_packages/authentication/register.dart | 93 +++-- .../package_tools/mih_personal_profile.dart | 250 +++++++------ 6 files changed, 373 insertions(+), 354 deletions(-) diff --git a/Frontend/lib/mih_components/mih_package_components/Example/package_tools/package_tool_one.dart b/Frontend/lib/mih_components/mih_package_components/Example/package_tools/package_tool_one.dart index 9debc4cc..7954db41 100644 --- a/Frontend/lib/mih_components/mih_package_components/Example/package_tools/package_tool_one.dart +++ b/Frontend/lib/mih_components/mih_package_components/Example/package_tools/package_tool_one.dart @@ -94,9 +94,10 @@ class _PackageToolOneState extends State { @override Widget build(BuildContext context) { + double screenWidth = MediaQuery.of(context).size.width; return MihPackageToolBody( borderOn: false, - bodyItem: getBody(), + bodyItem: getBody(screenWidth), ); } @@ -119,12 +120,15 @@ class _PackageToolOneState extends State { }); } - Widget getBody() { + Widget getBody(double width) { return Stack( children: [ - Padding( - padding: const EdgeInsets.symmetric(horizontal: 10.0), - child: MihSingleChildScroll( + MihSingleChildScroll( + child: Padding( + padding: + MzanziInnovationHub.of(context)!.theme.screenType == "desktop" + ? EdgeInsets.symmetric(horizontal: width * 0.2) + : EdgeInsets.symmetric(horizontal: width * 0.075), child: Column( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center, diff --git a/Frontend/lib/mih_components/mih_package_components/mih_text_form_field.dart b/Frontend/lib/mih_components/mih_package_components/mih_text_form_field.dart index d10452ac..082f4ee0 100644 --- a/Frontend/lib/mih_components/mih_package_components/mih_text_form_field.dart +++ b/Frontend/lib/mih_components/mih_package_components/mih_text_form_field.dart @@ -84,190 +84,194 @@ class _MihTextFormFieldState extends State { @override Widget build(BuildContext context) { - return SizedBox( - width: widget.width, - height: widget.height, - child: Theme( - data: Theme.of(context).copyWith( - textSelectionTheme: TextSelectionThemeData( - selectionColor: widget.inputColor.withValues(alpha: 0.3), - selectionHandleColor: widget.inputColor, + return Center( + child: SizedBox( + width: widget.width, + height: widget.height, + child: Theme( + data: Theme.of(context).copyWith( + textSelectionTheme: TextSelectionThemeData( + selectionColor: widget.inputColor.withValues(alpha: 0.3), + selectionHandleColor: widget.inputColor, + ), ), - ), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Text( - widget.hintText, - textAlign: TextAlign.left, - style: TextStyle( - color: widget.fillColor, - fontSize: 15, - fontWeight: FontWeight.bold, - ), - ), - Visibility( - visible: !widget.requiredText, - child: Text( - "(Optional)", - textAlign: TextAlign.right, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + widget.hintText, + textAlign: TextAlign.left, style: TextStyle( color: widget.fillColor, fontSize: 15, fontWeight: FontWeight.bold, ), ), - ), - ], - ), - const SizedBox(height: 4), - FormField( - initialValue: widget.controller.text, - validator: widget.validator, - autovalidateMode: AutovalidateMode.onUserInteraction, - builder: (field) { - _formFieldState = field; - return Column( - crossAxisAlignment: - CrossAxisAlignment.start, // <-- Add this line - children: [ - Material( - elevation: widget.elevation ?? 4.0, - borderRadius: - BorderRadius.circular(widget.borderRadius ?? 8.0), - child: SizedBox( - height: - widget.height != null ? widget.height! - 25 : null, - child: TextFormField( - controller: widget.controller, - cursorColor: widget.inputColor, - autofillHints: widget.autofillHints, - textAlign: TextAlign.start, - textAlignVertical: widget.multiLineInput == true - ? TextAlignVertical.top - : TextAlignVertical.center, - obscureText: widget.passwordMode == true - ? _obscureText - : false, - expands: widget.passwordMode == true - ? false - : (widget.multiLineInput ?? false), - maxLines: widget.passwordMode == true ? 1 : null, - readOnly: widget.readOnly ?? false, - keyboardType: widget.numberMode == true - ? TextInputType.number - : null, - inputFormatters: widget.numberMode == true - ? [FilteringTextInputFormatter.digitsOnly] - : null, - style: TextStyle( - color: widget.inputColor, - fontWeight: FontWeight.w500, - ), - decoration: InputDecoration( - suffixIcon: widget.passwordMode == true - ? IconButton( - icon: Icon( - _obscureText - ? Icons.visibility_off - : Icons.visibility, - color: widget.inputColor, - ), - onPressed: () { - setState(() { - _obscureText = !_obscureText; - }); - }, - ) - : null, - errorStyle: const TextStyle( - height: 0, fontSize: 0), // <-- Add this line - contentPadding: const EdgeInsets.symmetric( - horizontal: 10.0, vertical: 8.0), - filled: true, - fillColor: widget.fillColor, - border: OutlineInputBorder( - borderRadius: BorderRadius.circular( - widget.borderRadius ?? 8.0), - borderSide: field.hasError - ? BorderSide( - color: MzanziInnovationHub.of(context)! - .theme - .errorColor(), - width: 2.0, - ) - : BorderSide.none, - ), - enabledBorder: OutlineInputBorder( - borderRadius: BorderRadius.circular( - widget.borderRadius ?? 8.0), - borderSide: BorderSide.none, - ), - focusedBorder: OutlineInputBorder( - borderRadius: BorderRadius.circular( - widget.borderRadius ?? 8.0), - borderSide: BorderSide( - color: field.hasError - ? MzanziInnovationHub.of(context)! - .theme - .errorColor() - : widget.inputColor, - width: 3.0, - ), - ), - errorBorder: OutlineInputBorder( - borderRadius: BorderRadius.circular( - widget.borderRadius ?? 8.0), - borderSide: BorderSide( - color: MzanziInnovationHub.of(context)! - .theme - .errorColor(), - width: 3.0, - ), - ), - focusedErrorBorder: OutlineInputBorder( - borderRadius: BorderRadius.circular( - widget.borderRadius ?? 8.0), - borderSide: BorderSide( - color: MzanziInnovationHub.of(context)! - .theme - .errorColor(), - width: 3.0, - ), - ), - ), - onChanged: (value) { - field.didChange(value); - }, - ), + Visibility( + visible: !widget.requiredText, + child: Text( + "(Optional)", + textAlign: TextAlign.right, + style: TextStyle( + color: widget.fillColor, + fontSize: 15, + fontWeight: FontWeight.bold, ), ), - if (field.hasError) - Row( - children: [ - Padding( - padding: const EdgeInsets.only(left: 8.0, top: 4.0), - child: Text( - field.errorText ?? '', - style: TextStyle( - fontSize: 12, - color: MzanziInnovationHub.of(context)! - .theme - .errorColor(), - fontWeight: FontWeight.bold, + ), + ], + ), + const SizedBox(height: 4), + FormField( + initialValue: widget.controller.text, + validator: widget.validator, + autovalidateMode: AutovalidateMode.onUserInteraction, + builder: (field) { + _formFieldState = field; + return Column( + crossAxisAlignment: + CrossAxisAlignment.start, // <-- Add this line + children: [ + Material( + elevation: widget.elevation ?? 4.0, + borderRadius: + BorderRadius.circular(widget.borderRadius ?? 8.0), + child: SizedBox( + height: widget.height != null + ? widget.height! - 25 + : null, + child: TextFormField( + controller: widget.controller, + cursorColor: widget.inputColor, + autofillHints: widget.autofillHints, + textAlign: TextAlign.start, + textAlignVertical: widget.multiLineInput == true + ? TextAlignVertical.top + : TextAlignVertical.center, + obscureText: widget.passwordMode == true + ? _obscureText + : false, + expands: widget.passwordMode == true + ? false + : (widget.multiLineInput ?? false), + maxLines: widget.passwordMode == true ? 1 : null, + readOnly: widget.readOnly ?? false, + keyboardType: widget.numberMode == true + ? TextInputType.number + : null, + inputFormatters: widget.numberMode == true + ? [FilteringTextInputFormatter.digitsOnly] + : null, + style: TextStyle( + color: widget.inputColor, + fontWeight: FontWeight.w500, + ), + decoration: InputDecoration( + suffixIcon: widget.passwordMode == true + ? IconButton( + icon: Icon( + _obscureText + ? Icons.visibility_off + : Icons.visibility, + color: widget.inputColor, + ), + onPressed: () { + setState(() { + _obscureText = !_obscureText; + }); + }, + ) + : null, + errorStyle: const TextStyle( + height: 0, fontSize: 0), // <-- Add this line + contentPadding: const EdgeInsets.symmetric( + horizontal: 10.0, vertical: 8.0), + filled: true, + fillColor: widget.fillColor, + border: OutlineInputBorder( + borderRadius: BorderRadius.circular( + widget.borderRadius ?? 8.0), + borderSide: field.hasError + ? BorderSide( + color: MzanziInnovationHub.of(context)! + .theme + .errorColor(), + width: 2.0, + ) + : BorderSide.none, + ), + enabledBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular( + widget.borderRadius ?? 8.0), + borderSide: BorderSide.none, + ), + focusedBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular( + widget.borderRadius ?? 8.0), + borderSide: BorderSide( + color: field.hasError + ? MzanziInnovationHub.of(context)! + .theme + .errorColor() + : widget.inputColor, + width: 3.0, + ), + ), + errorBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular( + widget.borderRadius ?? 8.0), + borderSide: BorderSide( + color: MzanziInnovationHub.of(context)! + .theme + .errorColor(), + width: 3.0, + ), + ), + focusedErrorBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular( + widget.borderRadius ?? 8.0), + borderSide: BorderSide( + color: MzanziInnovationHub.of(context)! + .theme + .errorColor(), + width: 3.0, + ), ), ), + onChanged: (value) { + field.didChange(value); + }, ), - ], + ), ), - ], - ); - }, - ), - ], + if (field.hasError) + Row( + children: [ + Padding( + padding: + const EdgeInsets.only(left: 8.0, top: 4.0), + child: Text( + field.errorText ?? '', + style: TextStyle( + fontSize: 12, + color: MzanziInnovationHub.of(context)! + .theme + .errorColor(), + fontWeight: FontWeight.bold, + ), + ), + ), + ], + ), + ], + ); + }, + ), + ], + ), ), ), ); diff --git a/Frontend/lib/mih_env/env.dart b/Frontend/lib/mih_env/env.dart index 842552b8..903bcfe5 100644 --- a/Frontend/lib/mih_env/env.dart +++ b/Frontend/lib/mih_env/env.dart @@ -15,13 +15,13 @@ abstract class AppEnviroment { case Enviroment.dev: { //================= Android Dev Urls ================= - baseApiUrl = "http://10.0.2.2:8080"; - baseFileUrl = "http://10.0.2.2:9000"; - baseAiUrl = "http://10.0.2.2:11434"; + // baseApiUrl = "http://10.0.2.2:8080"; + // baseFileUrl = "http://10.0.2.2:9000"; + // baseAiUrl = "http://10.0.2.2:11434"; //================= Web Dev Urls ================= - // baseApiUrl = "http://localhost:8080"; - // baseFileUrl = "http://localhost:9000"; - // baseAiUrl = "http://localhost:11434"; + baseApiUrl = "http://localhost:8080"; + baseFileUrl = "http://localhost:9000"; + baseAiUrl = "http://localhost:11434"; break; } case Enviroment.prod: diff --git a/Frontend/lib/mih_packages/authentication/forgot_password.dart b/Frontend/lib/mih_packages/authentication/forgot_password.dart index 3b6f5771..99282085 100644 --- a/Frontend/lib/mih_packages/authentication/forgot_password.dart +++ b/Frontend/lib/mih_packages/authentication/forgot_password.dart @@ -204,7 +204,7 @@ class _ForgotPasswordState extends State { ); } - MIHBody getBody() { + MIHBody getBody(double width) { return MIHBody( borderOn: false, bodyItems: [ @@ -222,7 +222,12 @@ class _ForgotPasswordState extends State { child: SingleChildScrollView( physics: const BouncingScrollPhysics(), child: Padding( - padding: const EdgeInsets.all(25.0), + padding: MzanziInnovationHub.of(context)!.theme.screenType == + "desktop" + ? EdgeInsets.symmetric( + vertical: 25, horizontal: width * 0.2) + : EdgeInsets.symmetric( + vertical: 25, horizontal: width * 0.075), child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ @@ -320,11 +325,12 @@ class _ForgotPasswordState extends State { @override Widget build(BuildContext context) { + double screenWidth = MediaQuery.of(context).size.width; return MIHLayoutBuilder( actionButton: getActionButton(), header: getHeader(), secondaryActionButton: null, - body: getBody(), + body: getBody(screenWidth), actionDrawer: null, secondaryActionDrawer: null, bottomNavBar: null, diff --git a/Frontend/lib/mih_packages/authentication/register.dart b/Frontend/lib/mih_packages/authentication/register.dart index 50112e8d..e0581428 100644 --- a/Frontend/lib/mih_packages/authentication/register.dart +++ b/Frontend/lib/mih_packages/authentication/register.dart @@ -303,7 +303,7 @@ class _RegisterState extends State { ); } - MIHBody getBody() { + MIHBody getBody(double width) { return MIHBody( borderOn: false, bodyItems: [ @@ -323,7 +323,10 @@ class _RegisterState extends State { child: SingleChildScrollView( physics: const BouncingScrollPhysics(), child: Padding( - padding: const EdgeInsets.all(25.0), + padding: MzanziInnovationHub.of(context)!.theme.screenType == + "desktop" + ? EdgeInsets.symmetric(horizontal: width * 0.2) + : EdgeInsets.symmetric(horizontal: width * 0.075), child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ @@ -415,62 +418,55 @@ class _RegisterState extends State { const SizedBox(height: 20), // sign up button Center( - child: MihButton( - onPressed: () { - if (_formKey.currentState!.validate()) { - submitFormInput(); - } - }, - buttonColor: MzanziInnovationHub.of(context)! - .theme - .successColor(), - width: 300, - child: Text( - "Create New Account", - style: TextStyle( - color: MzanziInnovationHub.of(context)! - .theme - .primaryColor(), - fontSize: 20, - fontWeight: FontWeight.bold, - ), - ), - ), - ), - - const SizedBox(height: 10), - //register text - SizedBox( - width: 300.0, - //height: 100.0, - child: Row( - mainAxisAlignment: MainAxisAlignment.end, + child: Wrap( + alignment: WrapAlignment.center, + runAlignment: WrapAlignment.center, + spacing: 10, + runSpacing: 10, children: [ - const Text( - 'Already a User?', - style: - TextStyle(fontSize: 18, color: Colors.grey), - ), - const SizedBox( - width: 6, - ), - GestureDetector( - onTap: widget.onTap, + MihButton( + onPressed: () { + if (_formKey.currentState!.validate()) { + submitFormInput(); + } + }, + buttonColor: MzanziInnovationHub.of(context)! + .theme + .successColor(), + width: 300, child: Text( - 'Sign In', + "Create New Account", style: TextStyle( - fontSize: 18, color: MzanziInnovationHub.of(context)! .theme - .secondaryColor(), + .primaryColor(), + fontSize: 20, fontWeight: FontWeight.bold, ), ), - ) + ), + MihButton( + onPressed: widget.onTap, + buttonColor: MzanziInnovationHub.of(context)! + .theme + .secondaryColor(), + width: 300, + child: Text( + "I have an account", + style: TextStyle( + color: MzanziInnovationHub.of(context)! + .theme + .primaryColor(), + fontSize: 20, + fontWeight: FontWeight.bold, + ), + ), + ), ], ), - //here ), + + //here ], ) ], @@ -494,11 +490,12 @@ class _RegisterState extends State { @override Widget build(BuildContext context) { + double screenWidth = MediaQuery.of(context).size.width; return MIHLayoutBuilder( actionButton: getActionButton(), header: getHeader(), secondaryActionButton: getSecondaryActionButton(), - body: getBody(), + body: getBody(screenWidth), actionDrawer: null, secondaryActionDrawer: null, bottomNavBar: null, diff --git a/Frontend/lib/mih_packages/mzansi_profile/personal_profile/package_tools/mih_personal_profile.dart b/Frontend/lib/mih_packages/mzansi_profile/personal_profile/package_tools/mih_personal_profile.dart index 85a8817f..d25763ea 100644 --- a/Frontend/lib/mih_packages/mzansi_profile/personal_profile/package_tools/mih_personal_profile.dart +++ b/Frontend/lib/mih_packages/mzansi_profile/personal_profile/package_tools/mih_personal_profile.dart @@ -235,146 +235,154 @@ class _MihPersonalProfileState extends State { @override Widget build(BuildContext context) { + double screenWidth = MediaQuery.of(context).size.width; return MihPackageToolBody( borderOn: false, innerHorizontalPadding: 10, - bodyItem: getBody(), + bodyItem: getBody(screenWidth), ); } - Widget getBody() { + Widget getBody(double width) { return MihSingleChildScroll( - child: Column( - children: [ - MihForm( - formKey: _formKey, - formFields: [ - Center( - child: MihCircleAvatar( - imageFile: propicPreview, - width: 150, - editable: true, - fileNameController: proPicController, - userSelectedfile: proPic, - frameColor: - MzanziInnovationHub.of(context)!.theme.secondaryColor(), - backgroundColor: - MzanziInnovationHub.of(context)!.theme.primaryColor(), - onChange: (selectedImage) { - setState(() { - proPic = selectedImage; - }); - }, + child: Padding( + padding: MzanziInnovationHub.of(context)!.theme.screenType == "desktop" + ? EdgeInsets.symmetric(horizontal: width * 0.2) + : EdgeInsets.symmetric(horizontal: width * 0.075), + child: Column( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + MihForm( + formKey: _formKey, + formFields: [ + Center( + child: MihCircleAvatar( + imageFile: propicPreview, + width: 150, + editable: true, + fileNameController: proPicController, + userSelectedfile: proPic, + frameColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + backgroundColor: + MzanziInnovationHub.of(context)!.theme.primaryColor(), + onChange: (selectedImage) { + setState(() { + proPic = selectedImage; + }); + }, + ), ), - ), - const SizedBox(height: 25.0), - Visibility( - visible: false, - child: MihTextFormField( + const SizedBox(height: 25.0), + Visibility( + visible: false, + child: MihTextFormField( + fillColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + inputColor: + MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: proPicController, + multiLineInput: false, + requiredText: true, + readOnly: true, + hintText: "Selected File Name", + ), + ), + const SizedBox(height: 10.0), + MihTextFormField( fillColor: MzanziInnovationHub.of(context)!.theme.secondaryColor(), inputColor: MzanziInnovationHub.of(context)!.theme.primaryColor(), - controller: proPicController, + controller: usernameController, multiLineInput: false, requiredText: true, - readOnly: true, - hintText: "Selected File Name", - ), - ), - const SizedBox(height: 10.0), - MihTextFormField( - fillColor: - MzanziInnovationHub.of(context)!.theme.secondaryColor(), - inputColor: - MzanziInnovationHub.of(context)!.theme.primaryColor(), - controller: usernameController, - multiLineInput: false, - requiredText: true, - hintText: "Username", - validator: (value) { - return MihValidationServices().validateUsername(value); - }, - ), - const SizedBox(height: 10.0), - MihTextFormField( - fillColor: - MzanziInnovationHub.of(context)!.theme.secondaryColor(), - inputColor: - MzanziInnovationHub.of(context)!.theme.primaryColor(), - controller: fnameController, - multiLineInput: false, - requiredText: true, - hintText: "First Name", - validator: (value) { - return MihValidationServices().isEmpty(value); - }, - ), - const SizedBox(height: 10.0), - MihTextFormField( - fillColor: - MzanziInnovationHub.of(context)!.theme.secondaryColor(), - inputColor: - MzanziInnovationHub.of(context)!.theme.primaryColor(), - controller: lnameController, - multiLineInput: false, - requiredText: true, - hintText: "Last Name", - validator: (value) { - return MihValidationServices().isEmpty(value); - }, - ), - const SizedBox(height: 10.0), - Row( - mainAxisAlignment: MainAxisAlignment.start, - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - const Text( - "Activate Business Account", - style: TextStyle( - fontWeight: FontWeight.bold, - fontSize: 20, - ), - ), - const SizedBox( - width: 10, - ), - Switch( - value: businessUser, - onChanged: (bool value) { - setState(() { - businessUser = value; - }); - }, - ), - ], - ), - const SizedBox(height: 30.0), - Center( - child: MihButton( - onPressed: () { - //Add validation here - if (_formKey.currentState!.validate()) { - submitForm(); - } + hintText: "Username", + validator: (value) { + return MihValidationServices().validateUsername(value); }, - buttonColor: + ), + const SizedBox(height: 10.0), + MihTextFormField( + fillColor: MzanziInnovationHub.of(context)!.theme.secondaryColor(), - width: 300, - child: Text( - "Update", - style: TextStyle( - color: - MzanziInnovationHub.of(context)!.theme.primaryColor(), - fontSize: 20, - fontWeight: FontWeight.bold, + inputColor: + MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: fnameController, + multiLineInput: false, + requiredText: true, + hintText: "First Name", + validator: (value) { + return MihValidationServices().isEmpty(value); + }, + ), + const SizedBox(height: 10.0), + MihTextFormField( + fillColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + inputColor: + MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: lnameController, + multiLineInput: false, + requiredText: true, + hintText: "Last Name", + validator: (value) { + return MihValidationServices().isEmpty(value); + }, + ), + const SizedBox(height: 10.0), + Row( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + const Text( + "Activate Business Account", + style: TextStyle( + fontWeight: FontWeight.bold, + fontSize: 20, + ), + ), + const SizedBox( + width: 10, + ), + Switch( + value: businessUser, + onChanged: (bool value) { + setState(() { + businessUser = value; + }); + }, + ), + ], + ), + const SizedBox(height: 30.0), + Center( + child: MihButton( + onPressed: () { + //Add validation here + if (_formKey.currentState!.validate()) { + submitForm(); + } + }, + buttonColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + width: 300, + child: Text( + "Update", + style: TextStyle( + color: MzanziInnovationHub.of(context)! + .theme + .primaryColor(), + fontSize: 20, + fontWeight: FontWeight.bold, + ), ), ), ), - ), - ], - ), - ], + ], + ), + ], + ), ), ); } From 02e3698beaad3f77e472a68d7744104f6d903676 Mon Sep 17 00:00:00 2001 From: Yasien Mac Mini Date: Fri, 6 Jun 2025 11:30:23 +0200 Subject: [PATCH 34/52] create install services --- .../lib/mih_apis/mih_install_services.dart | 64 +++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100644 Frontend/lib/mih_apis/mih_install_services.dart diff --git a/Frontend/lib/mih_apis/mih_install_services.dart b/Frontend/lib/mih_apis/mih_install_services.dart new file mode 100644 index 00000000..bc2cbdfb --- /dev/null +++ b/Frontend/lib/mih_apis/mih_install_services.dart @@ -0,0 +1,64 @@ +import 'package:flutter/foundation.dart'; +import 'package:flutter/widgets.dart'; +import 'package:mzansi_innovation_hub/main.dart'; +import 'package:pwa_install/pwa_install.dart'; +// import 'package:universal_html/js.dart' as js; +import 'package:url_launcher/url_launcher.dart'; + +class MihInstallServices { + String? errorMessage; + + Future launchSocialUrl(Uri linkUrl) async { + if (!await launchUrl(linkUrl)) { + throw Exception('Could not launch $linkUrl'); + } + } + + void installMihTrigger(BuildContext context) { + final isWebAndroid = + kIsWeb && (defaultTargetPlatform == TargetPlatform.android); + final isWebIos = kIsWeb && (defaultTargetPlatform == TargetPlatform.iOS); + if (isWebAndroid) { + launchSocialUrl( + Uri.parse( + "https://play.google.com/store/apps/details?id=za.co.mzansiinnovationhub.mih", + ), + ); + } else if (isWebIos) { + //Show pop up for IOS + launchSocialUrl( + Uri.parse( + "https://apps.apple.com/za/app/mzansi-innovation-hub/id6743310890", + ), + ); + } else if (MzanziInnovationHub.of(context)!.theme.getPlatform() == + "Android") { + //Installed Android App + launchSocialUrl( + Uri.parse( + "https://play.google.com/store/apps/details?id=za.co.mzansiinnovationhub.mih", + ), + ); + } else if (MzanziInnovationHub.of(context)!.theme.getPlatform() == "iOS") { + launchSocialUrl( + Uri.parse( + "https://apps.apple.com/za/app/mzansi-innovation-hub/id6743310890", + ), + ); + } else { + //Web + if (PWAInstall().installPromptEnabled) { + try { + PWAInstall().promptInstall_(); + } catch (e) { + errorMessage = e.toString(); + debugPrint('Error prompting install: $e'); + } + } else { + // Fallback for unsupported platforms + debugPrint('Install prompt not available for this platform.'); + } + // js.context.callMethod("presentAddToHome"); + } + } +} From 34fd6be2fe7502808923c9436a42a4f2f195bb03 Mon Sep 17 00:00:00 2001 From: Yasien Mac Mini Date: Fri, 6 Jun 2025 11:30:46 +0200 Subject: [PATCH 35/52] config and use new install service --- Frontend/lib/main_dev.dart | 4 ++ Frontend/lib/main_prod.dart | 4 ++ .../about_mih/package_tools/mih_info.dart | 44 +------------------ 3 files changed, 10 insertions(+), 42 deletions(-) diff --git a/Frontend/lib/main_dev.dart b/Frontend/lib/main_dev.dart index 8b4805ea..60936ced 100644 --- a/Frontend/lib/main_dev.dart +++ b/Frontend/lib/main_dev.dart @@ -1,5 +1,6 @@ import 'package:flutter/material.dart'; import 'package:flutter_native_splash/flutter_native_splash.dart'; +import 'package:pwa_install/pwa_install.dart'; import '../mih_env/env.dart'; import '../../main.dart'; import 'package:supertokens_flutter/supertokens.dart'; @@ -14,6 +15,9 @@ void main() async { apiBasePath: "/auth", ); // setUrlStrategy(PathUrlStrategy()); + PWAInstall().setup(installCallback: () { + debugPrint('APP INSTALLED!'); + }); FlutterNativeSplash.remove(); runApp(const MzanziInnovationHub()); } diff --git a/Frontend/lib/main_prod.dart b/Frontend/lib/main_prod.dart index ccae5b4a..c7b3c214 100644 --- a/Frontend/lib/main_prod.dart +++ b/Frontend/lib/main_prod.dart @@ -1,5 +1,6 @@ import 'package:flutter/material.dart'; import 'package:flutter_native_splash/flutter_native_splash.dart'; +import 'package:pwa_install/pwa_install.dart'; import '../mih_env/env.dart'; import '../../main.dart'; import 'package:supertokens_flutter/supertokens.dart'; @@ -15,5 +16,8 @@ void main() async { ); // setUrlStrategy(PathUrlStrategy()); FlutterNativeSplash.remove(); + PWAInstall().setup(installCallback: () { + debugPrint('APP INSTALLED!'); + }); runApp(const MzanziInnovationHub()); } diff --git a/Frontend/lib/mih_packages/about_mih/package_tools/mih_info.dart b/Frontend/lib/mih_packages/about_mih/package_tools/mih_info.dart index f5aa2597..ed6409d8 100644 --- a/Frontend/lib/mih_packages/about_mih/package_tools/mih_info.dart +++ b/Frontend/lib/mih_packages/about_mih/package_tools/mih_info.dart @@ -1,5 +1,6 @@ import 'package:flutter_speed_dial/flutter_speed_dial.dart'; import 'package:mzansi_innovation_hub/main.dart'; +import 'package:mzansi_innovation_hub/mih_apis/mih_install_services.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_layout/mih_single_child_scroll.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_layout/mih_tile.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_button.dart'; @@ -9,7 +10,6 @@ import 'package:flutter/material.dart'; import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_floating_menu.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_icons.dart'; -import "package:universal_html/js.dart" as js; import 'package:url_launcher/url_launcher.dart'; import 'package:share_plus/share_plus.dart'; @@ -41,46 +41,6 @@ class _MihInfoState extends State { final Uri _redditUrl = Uri.parse('https://www.reddit.com/r/Mzani_Innovation_Hub/'); - void installMihTrigger() { - final isWebAndroid = - kIsWeb && (defaultTargetPlatform == TargetPlatform.android); - final isWebIos = kIsWeb && (defaultTargetPlatform == TargetPlatform.iOS); - - if (isWebAndroid) { - launchSocialUrl( - Uri.parse( - "https://play.google.com/store/apps/details?id=za.co.mzansiinnovationhub.mih", - ), - ); - } else if (isWebIos) { - //Show pop up for IOS - // _showIOSInstallationGuide(); - launchSocialUrl( - Uri.parse( - "https://apps.apple.com/za/app/mzansi-innovation-hub/id6743310890", - ), - ); - } else if (MzanziInnovationHub.of(context)!.theme.getPlatform() == - "Android") { - //Installed Android App - // _showIOSInstallationGuide(); - launchSocialUrl( - Uri.parse( - "https://play.google.com/store/apps/details?id=za.co.mzansiinnovationhub.mih", - ), - ); - } else if (MzanziInnovationHub.of(context)!.theme.getPlatform() == "iOS") { - launchSocialUrl( - Uri.parse( - "https://apps.apple.com/za/app/mzansi-innovation-hub/id6743310890", - ), - ); - } else { - //Web - js.context.callMethod("presentAddToHome"); - } - } - Widget founderBio() { String bio = ""; bio += "BSc Computer Science & Information Systems\n"; @@ -553,7 +513,7 @@ class _MihInfoState extends State { children: [ MihButton( onPressed: () { - installMihTrigger(); + MihInstallServices().installMihTrigger(context); }, buttonColor: MzanziInnovationHub.of(context)! .theme From 5e74d8637d51125cd81e058eced6317b74749150 Mon Sep 17 00:00:00 2001 From: Yasien Mac Mini Date: Fri, 6 Jun 2025 11:46:57 +0200 Subject: [PATCH 36/52] pwa install stuff --- Frontend/web/index.html | 95 +++++++++++++++++++++++++++++++---------- 1 file changed, 72 insertions(+), 23 deletions(-) diff --git a/Frontend/web/index.html b/Frontend/web/index.html index 2b93b190..699985ae 100644 --- a/Frontend/web/index.html +++ b/Frontend/web/index.html @@ -1,10 +1,14 @@ - + + + + - + @@ -27,9 +31,40 @@ - - - + + + + + @@ -248,8 +294,11 @@ - - - + + + - \ No newline at end of file + + + \ No newline at end of file From 564ca2e6d916dd560b901d188cd45ccf5435491d Mon Sep 17 00:00:00 2001 From: Yasien Mac Mini Date: Fri, 6 Jun 2025 11:47:08 +0200 Subject: [PATCH 37/52] pwa install config --- Frontend/pubspec.yaml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Frontend/pubspec.yaml b/Frontend/pubspec.yaml index 83c9a961..65884909 100644 --- a/Frontend/pubspec.yaml +++ b/Frontend/pubspec.yaml @@ -77,6 +77,7 @@ dependencies: share_plus: ^10.1.4 app_settings: ^6.1.1 animated_button: ^0.3.1 + pwa_install: ^0.0.6 dev_dependencies: flutter_test: @@ -84,7 +85,7 @@ dev_dependencies: build_runner: ^2.4.8 - build_web_compilers: ^3.2.7 + build_web_compilers: ^4.1.5 # The "flutter_lints" package below contains a set of recommended lints to # encourage good coding practices. The lint set provided by the package is # activated in the `analysis_options.yaml` file located at the root of your From d99a26a9b857cdaa520e172e68e71d860ba9662c Mon Sep 17 00:00:00 2001 From: Yasien Mac Mini Date: Fri, 6 Jun 2025 11:47:38 +0200 Subject: [PATCH 38/52] fix auth padding and install button --- .../mih_packages/authentication/register.dart | 15 +-- .../authentication/reset_password.dart | 48 ++++---- .../mih_packages/authentication/signin.dart | 106 ++++++++++-------- 3 files changed, 89 insertions(+), 80 deletions(-) diff --git a/Frontend/lib/mih_packages/authentication/register.dart b/Frontend/lib/mih_packages/authentication/register.dart index e0581428..c8421ca2 100644 --- a/Frontend/lib/mih_packages/authentication/register.dart +++ b/Frontend/lib/mih_packages/authentication/register.dart @@ -1,5 +1,6 @@ import 'dart:convert'; +import 'package:mzansi_innovation_hub/mih_apis/mih_install_services.dart'; import 'package:mzansi_innovation_hub/mih_apis/mih_validation_services.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_button.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_form.dart'; @@ -235,14 +236,11 @@ class _RegisterState extends State { padding: const EdgeInsets.all(10.0), child: MihButton( onPressed: () { - Navigator.of(context).pushNamed( - '/about', - arguments: 0, - ); + MihInstallServices().installMihTrigger(context); }, buttonColor: MzanziInnovationHub.of(context)!.theme.secondaryColor(), - width: 300, + width: 150, child: Text( "Install MIH", style: TextStyle( @@ -255,10 +253,7 @@ class _RegisterState extends State { ), iconSize: 35, onTap: () { - Navigator.of(context).pushNamed( - '/about', - arguments: 0, - ); + MihInstallServices().installMihTrigger(context); }, ), ); @@ -352,7 +347,7 @@ class _RegisterState extends State { ), ), //spacer - const SizedBox(height: 25), + // const SizedBox(height: 20), MihForm( formKey: _formKey, formFields: [ diff --git a/Frontend/lib/mih_packages/authentication/reset_password.dart b/Frontend/lib/mih_packages/authentication/reset_password.dart index 1c97a81d..767ee600 100644 --- a/Frontend/lib/mih_packages/authentication/reset_password.dart +++ b/Frontend/lib/mih_packages/authentication/reset_password.dart @@ -180,7 +180,7 @@ class _ResetPasswordState extends State { ); } - MIHBody getBody() { + MIHBody getBody(double width) { return MIHBody( borderOn: false, bodyItems: [ @@ -200,7 +200,10 @@ class _ResetPasswordState extends State { child: SingleChildScrollView( physics: const BouncingScrollPhysics(), child: Padding( - padding: const EdgeInsets.all(25.0), + padding: MzanziInnovationHub.of(context)!.theme.screenType == + "desktop" + ? EdgeInsets.symmetric(horizontal: width * 0.2) + : EdgeInsets.symmetric(horizontal: width * 0.075), child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ @@ -295,24 +298,26 @@ class _ResetPasswordState extends State { //spacer const SizedBox(height: 25), // sign in button - MihButton( - onPressed: () { - if (_formKey.currentState!.validate()) { - submitFormInput(); - } - }, - buttonColor: MzanziInnovationHub.of(context)! - .theme - .secondaryColor(), - width: 300, - child: Text( - "Reset Password", - style: TextStyle( - color: MzanziInnovationHub.of(context)! - .theme - .primaryColor(), - fontSize: 20, - fontWeight: FontWeight.bold, + Center( + child: MihButton( + onPressed: () { + if (_formKey.currentState!.validate()) { + submitFormInput(); + } + }, + buttonColor: MzanziInnovationHub.of(context)! + .theme + .secondaryColor(), + width: 300, + child: Text( + "Reset Password", + style: TextStyle( + color: MzanziInnovationHub.of(context)! + .theme + .primaryColor(), + fontSize: 20, + fontWeight: FontWeight.bold, + ), ), ), ), @@ -344,11 +349,12 @@ class _ResetPasswordState extends State { @override Widget build(BuildContext context) { + double screenWidth = MediaQuery.of(context).size.width; return MIHLayoutBuilder( actionButton: getActionButton(), header: getHeader(), secondaryActionButton: null, - body: getBody(), + body: getBody(screenWidth), actionDrawer: null, secondaryActionDrawer: null, bottomNavBar: null, diff --git a/Frontend/lib/mih_packages/authentication/signin.dart b/Frontend/lib/mih_packages/authentication/signin.dart index f48125d8..70ef1c3d 100644 --- a/Frontend/lib/mih_packages/authentication/signin.dart +++ b/Frontend/lib/mih_packages/authentication/signin.dart @@ -1,4 +1,5 @@ import 'dart:convert'; +import 'package:mzansi_innovation_hub/mih_apis/mih_install_Services.dart'; import 'package:mzansi_innovation_hub/mih_apis/mih_validation_services.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_button.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_form.dart'; @@ -293,14 +294,11 @@ class _SignInState extends State { padding: const EdgeInsets.all(10.0), child: MihButton( onPressed: () { - Navigator.of(context).pushNamed( - '/about', - arguments: 0, - ); + MihInstallServices().installMihTrigger(context); }, buttonColor: MzanziInnovationHub.of(context)!.theme.secondaryColor(), - width: 300, + width: 150, child: Text( "Install MIH", style: TextStyle( @@ -361,7 +359,7 @@ class _SignInState extends State { ); } - MIHBody getBody() { + MIHBody getBody(double width) { return MIHBody( borderOn: false, bodyItems: [ @@ -381,7 +379,10 @@ class _SignInState extends State { child: SingleChildScrollView( physics: const BouncingScrollPhysics(), child: Padding( - padding: const EdgeInsets.all(25.0), + padding: MzanziInnovationHub.of(context)!.theme.screenType == + "desktop" + ? EdgeInsets.symmetric(horizontal: width * 0.2) + : EdgeInsets.symmetric(horizontal: width * 0.075), child: AutofillGroup( child: Column( mainAxisAlignment: MainAxisAlignment.center, @@ -408,7 +409,7 @@ class _SignInState extends State { ), ), //spacer - const SizedBox(height: 25), + const SizedBox(height: 10), MihForm( formKey: _formKey, formFields: [ @@ -450,8 +451,9 @@ class _SignInState extends State { .validatePassword(value); }, ), + const SizedBox(height: 10), SizedBox( - width: 500.0, + // width: 500.0, //height: 100.0, child: Row( mainAxisAlignment: MainAxisAlignment.end, @@ -532,49 +534,54 @@ class _SignInState extends State { ), //spacer - const SizedBox(height: 20), - SizedBox( - width: 500.0, - //height: 100.0, - child: Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - const Flexible( - flex: 1, - child: Padding( - padding: EdgeInsets.only(right: 10.0), - child: Divider(), - ), - ), - Flexible( - flex: 1, - child: GestureDetector( - child: Text( - 'Use Sandox Profile', - textAlign: TextAlign.center, - style: TextStyle( - fontWeight: FontWeight.bold, - fontSize: 15, - color: - MzanziInnovationHub.of(context)! + const SizedBox(height: 35), + Visibility( + visible: AppEnviroment.getEnv() == "Dev", + child: Center( + child: SizedBox( + width: width, + //height: 100.0, + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + const Flexible( + flex: 1, + child: Padding( + padding: EdgeInsets.only(right: 10.0), + child: Divider(), + ), + ), + Flexible( + flex: 1, + child: GestureDetector( + child: Text( + 'Use Sandox Profile', + textAlign: TextAlign.center, + style: TextStyle( + fontWeight: FontWeight.bold, + fontSize: 15, + color: MzanziInnovationHub.of( + context)! .theme .secondaryColor()), + ), + onTap: () { + setState(() { + showProfiles = !showProfiles; + }); + }, + ), ), - onTap: () { - setState(() { - showProfiles = !showProfiles; - }); - }, - ), + const Flexible( + flex: 1, + child: Padding( + padding: EdgeInsets.only(left: 10.0), + child: Divider(), + ), + ), + ], ), - const Flexible( - flex: 1, - child: Padding( - padding: EdgeInsets.only(left: 10.0), - child: Divider(), - ), - ), - ], + ), ), ), const SizedBox(height: 10), @@ -647,11 +654,12 @@ class _SignInState extends State { @override Widget build(BuildContext context) { + double screenWidth = MediaQuery.of(context).size.width; return MIHLayoutBuilder( actionButton: getActionButton(), header: getHeader(), secondaryActionButton: getSecondaryActionButton(), - body: getBody(), + body: getBody(screenWidth), actionDrawer: null, secondaryActionDrawer: null, bottomNavBar: null, From 704b50b528d9a96053bb28f75bb4513fc938f39b Mon Sep 17 00:00:00 2001 From: Yasien Mac Mini Date: Fri, 6 Jun 2025 11:49:24 +0200 Subject: [PATCH 39/52] sandbox rofile alignment --- .../mih_packages/authentication/signin.dart | 67 ++++++++++--------- 1 file changed, 35 insertions(+), 32 deletions(-) diff --git a/Frontend/lib/mih_packages/authentication/signin.dart b/Frontend/lib/mih_packages/authentication/signin.dart index 70ef1c3d..4f896fd3 100644 --- a/Frontend/lib/mih_packages/authentication/signin.dart +++ b/Frontend/lib/mih_packages/authentication/signin.dart @@ -585,39 +585,42 @@ class _SignInState extends State { ), ), const SizedBox(height: 10), - Visibility( - visible: showProfiles, - child: SizedBox( - width: 500, - child: Column( - //mainAxisSize: MainAxisSize.max, - children: [ - GridView.builder( - physics: - const NeverScrollableScrollPhysics(), - shrinkWrap: true, - itemCount: sandboxProfileList.length, - gridDelegate: - const SliverGridDelegateWithMaxCrossAxisExtent( - mainAxisSpacing: 10, - maxCrossAxisExtent: 100), - itemBuilder: (context, index) { - return sandboxProfileList[index]; - }, - ), - const SizedBox(height: 20), - Text( - "NB: These accounts are used for test purposes. Please do not store personal information on these profiles.", - textAlign: TextAlign.center, - style: TextStyle( - color: MzanziInnovationHub.of(context)! - .theme - .secondaryColor(), - fontSize: 15.0, - fontWeight: FontWeight.bold, + Center( + child: Visibility( + visible: showProfiles, + child: SizedBox( + width: 500, + child: Column( + //mainAxisSize: MainAxisSize.max, + children: [ + GridView.builder( + physics: + const NeverScrollableScrollPhysics(), + shrinkWrap: true, + itemCount: sandboxProfileList.length, + gridDelegate: + const SliverGridDelegateWithMaxCrossAxisExtent( + mainAxisSpacing: 10, + maxCrossAxisExtent: 100), + itemBuilder: (context, index) { + return sandboxProfileList[index]; + }, ), - ), - ], + const SizedBox(height: 20), + Text( + "NB: These accounts are used for test purposes. Please do not store personal information on these profiles.", + textAlign: TextAlign.center, + style: TextStyle( + color: + MzanziInnovationHub.of(context)! + .theme + .secondaryColor(), + fontSize: 15.0, + fontWeight: FontWeight.bold, + ), + ), + ], + ), ), ), ), From efce3ded64f4fac3009289c016d24dfe63b03a69 Mon Sep 17 00:00:00 2001 From: Yasien Mac Mini Date: Fri, 6 Jun 2025 12:09:26 +0200 Subject: [PATCH 40/52] fix appointment padding and install button --- .../builder/build_appointment_list.dart | 502 +++++++++--------- .../calendar/package_tools/appointments.dart | 164 +++--- 2 files changed, 346 insertions(+), 320 deletions(-) diff --git a/Frontend/lib/mih_packages/calendar/builder/build_appointment_list.dart b/Frontend/lib/mih_packages/calendar/builder/build_appointment_list.dart index 21db4f68..ba9b0617 100644 --- a/Frontend/lib/mih_packages/calendar/builder/build_appointment_list.dart +++ b/Frontend/lib/mih_packages/calendar/builder/build_appointment_list.dart @@ -71,7 +71,7 @@ class _BuildAppointmentListState extends State { } } - Widget displayAppointment(int index) { + Widget displayAppointment(int index, double bodyWidth) { String heading = "${widget.appointmentList[index].date_time.split('T')[1].substring(0, 5)} - ${widget.appointmentList[index].title.toUpperCase()}"; String description = widget.appointmentList[index].description; @@ -102,54 +102,50 @@ class _BuildAppointmentListState extends State { MzanziInnovationHub.of(context)!.theme.messageTextColor(); } - return Padding( - padding: const EdgeInsets.all(5.0), - child: Container( - decoration: BoxDecoration( - border: Border.all( - width: 3.0, - color: appointmentColor, - ), - borderRadius: BorderRadius.circular(20)), - child: ListTile( - title: Text( - heading, - style: TextStyle( - color: appointmentColor, - fontWeight: FontWeight.bold, - ), + return Container( + decoration: BoxDecoration( + border: Border.all( + width: 3.0, + color: appointmentColor, ), - subtitle: Text( - description, - style: TextStyle( - color: appointmentColor, - overflow: TextOverflow.ellipsis, - ), + borderRadius: BorderRadius.circular(20)), + child: ListTile( + title: Text( + heading, + style: TextStyle( + color: appointmentColor, + fontWeight: FontWeight.bold, ), - onTap: () { - setState(() { - widget.titleController.text = widget.appointmentList[index].title; - widget.descriptionIDController.text = - widget.appointmentList[index].description; - widget.dateController.text = - widget.appointmentList[index].date_time.split('T')[0]; - widget.timeController.text = widget - .appointmentList[index].date_time - .split('T')[1] - .substring(0, 5); - }); - if (widget.inWaitingRoom == false) { - appointmentDetailsWindow(index); - } else { - waitingRiinAppointmentDetailsWindow(index); - } - }, ), + subtitle: Text( + description, + style: TextStyle( + color: appointmentColor, + overflow: TextOverflow.ellipsis, + ), + ), + onTap: () { + setState(() { + widget.titleController.text = widget.appointmentList[index].title; + widget.descriptionIDController.text = + widget.appointmentList[index].description; + widget.dateController.text = + widget.appointmentList[index].date_time.split('T')[0]; + widget.timeController.text = widget.appointmentList[index].date_time + .split('T')[1] + .substring(0, 5); + }); + if (widget.inWaitingRoom == false) { + appointmentDetailsWindow(index, bodyWidth); + } else { + waitingRiinAppointmentDetailsWindow(index, bodyWidth); + } + }, ), ); } - void appointmentDetailsWindow(int index) { + void appointmentDetailsWindow(int index, double bodyWidth) { showDialog( context: context, barrierDismissible: false, @@ -173,7 +169,7 @@ class _BuildAppointmentListState extends State { backgroundColor: MzanziInnovationHub.of(context)!.theme.successColor(), onTap: () { - appointmentUpdateWindow(index); + appointmentUpdateWindow(index, bodyWidth); }, ), SpeedDialChild( @@ -202,66 +198,72 @@ class _BuildAppointmentListState extends State { widget.titleController.clear(); widget.descriptionIDController.clear(); }, - windowBody: Column( - children: [ - const SizedBox(height: 10), - MihTextFormField( - fillColor: - MzanziInnovationHub.of(context)!.theme.secondaryColor(), - inputColor: - MzanziInnovationHub.of(context)!.theme.primaryColor(), - controller: widget.titleController, - multiLineInput: false, - requiredText: true, - readOnly: true, - hintText: "Appointment Title", - ), - const SizedBox(height: 10), - MihTextFormField( - fillColor: - MzanziInnovationHub.of(context)!.theme.secondaryColor(), - inputColor: - MzanziInnovationHub.of(context)!.theme.primaryColor(), - controller: widget.dateController, - multiLineInput: false, - requiredText: true, - readOnly: true, - hintText: "Date", - ), - const SizedBox(height: 10), - MihTextFormField( - fillColor: - MzanziInnovationHub.of(context)!.theme.secondaryColor(), - inputColor: - MzanziInnovationHub.of(context)!.theme.primaryColor(), - controller: widget.timeController, - multiLineInput: false, - requiredText: true, - readOnly: true, - hintText: "Time", - ), - const SizedBox(height: 10), - MihTextFormField( - fillColor: - MzanziInnovationHub.of(context)!.theme.secondaryColor(), - inputColor: - MzanziInnovationHub.of(context)!.theme.primaryColor(), - controller: widget.descriptionIDController, - multiLineInput: true, - height: 250, - requiredText: true, - readOnly: true, - hintText: "Appointment Description", - ), - const SizedBox(height: 10), - ], + windowBody: Padding( + padding: + MzanziInnovationHub.of(context)!.theme.screenType == "desktop" + ? EdgeInsets.symmetric(horizontal: width * 0.05) + : const EdgeInsets.symmetric(horizontal: 0), + child: Column( + children: [ + const SizedBox(height: 10), + MihTextFormField( + fillColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + inputColor: + MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: widget.titleController, + multiLineInput: false, + requiredText: true, + readOnly: true, + hintText: "Appointment Title", + ), + const SizedBox(height: 10), + MihTextFormField( + fillColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + inputColor: + MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: widget.dateController, + multiLineInput: false, + requiredText: true, + readOnly: true, + hintText: "Date", + ), + const SizedBox(height: 10), + MihTextFormField( + fillColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + inputColor: + MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: widget.timeController, + multiLineInput: false, + requiredText: true, + readOnly: true, + hintText: "Time", + ), + const SizedBox(height: 10), + MihTextFormField( + fillColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + inputColor: + MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: widget.descriptionIDController, + multiLineInput: true, + height: 250, + requiredText: true, + readOnly: true, + hintText: "Appointment Description", + ), + const SizedBox(height: 10), + ], + ), ), ); }, ); } - void waitingRiinAppointmentDetailsWindow(int index) { + void waitingRiinAppointmentDetailsWindow(int index, double bodyWidth) { showDialog( context: context, barrierDismissible: false, @@ -285,7 +287,7 @@ class _BuildAppointmentListState extends State { backgroundColor: MzanziInnovationHub.of(context)!.theme.successColor(), onTap: () { - appointmentUpdateWindow(index); + appointmentUpdateWindow(index, bodyWidth); }, ), SpeedDialChild( @@ -314,76 +316,82 @@ class _BuildAppointmentListState extends State { widget.titleController.clear(); widget.descriptionIDController.clear(); }, - windowBody: Column( - children: [ - const SizedBox(height: 10), - MihTextFormField( - fillColor: - MzanziInnovationHub.of(context)!.theme.secondaryColor(), - inputColor: - MzanziInnovationHub.of(context)!.theme.primaryColor(), - controller: widget.titleController, - multiLineInput: false, - requiredText: true, - readOnly: true, - hintText: "Appointment Title", - ), - const SizedBox(height: 10), - MihTextFormField( - fillColor: - MzanziInnovationHub.of(context)!.theme.secondaryColor(), - inputColor: - MzanziInnovationHub.of(context)!.theme.primaryColor(), - controller: widget.dateController, - multiLineInput: false, - requiredText: true, - readOnly: true, - hintText: "Date", - ), - const SizedBox(height: 10), - MihTextFormField( - fillColor: - MzanziInnovationHub.of(context)!.theme.secondaryColor(), - inputColor: - MzanziInnovationHub.of(context)!.theme.primaryColor(), - controller: widget.timeController, - multiLineInput: false, - requiredText: true, - readOnly: true, - hintText: "Time", - ), - const SizedBox(height: 10), - MihTextFormField( - fillColor: - MzanziInnovationHub.of(context)!.theme.secondaryColor(), - inputColor: - MzanziInnovationHub.of(context)!.theme.primaryColor(), - controller: widget.descriptionIDController, - multiLineInput: true, - height: 250, - requiredText: true, - readOnly: true, - hintText: "Appointment Description", - ), - const SizedBox(height: 10), - // SizedBox( - // // width: 500, - // child: MIHTextField( - // controller: widget.titleController, - // hintText: "Patient ID Number", - // editable: false, - // required: false, - // ), - // ), - // const SizedBox(height: 10), - ], + windowBody: Padding( + padding: + MzanziInnovationHub.of(context)!.theme.screenType == "desktop" + ? EdgeInsets.symmetric(horizontal: width * 0.05) + : const EdgeInsets.symmetric(horizontal: 0), + child: Column( + children: [ + const SizedBox(height: 10), + MihTextFormField( + fillColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + inputColor: + MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: widget.titleController, + multiLineInput: false, + requiredText: true, + readOnly: true, + hintText: "Appointment Title", + ), + const SizedBox(height: 10), + MihTextFormField( + fillColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + inputColor: + MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: widget.dateController, + multiLineInput: false, + requiredText: true, + readOnly: true, + hintText: "Date", + ), + const SizedBox(height: 10), + MihTextFormField( + fillColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + inputColor: + MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: widget.timeController, + multiLineInput: false, + requiredText: true, + readOnly: true, + hintText: "Time", + ), + const SizedBox(height: 10), + MihTextFormField( + fillColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + inputColor: + MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: widget.descriptionIDController, + multiLineInput: true, + height: 250, + requiredText: true, + readOnly: true, + hintText: "Appointment Description", + ), + const SizedBox(height: 10), + // SizedBox( + // // width: 500, + // child: MIHTextField( + // controller: widget.titleController, + // hintText: "Patient ID Number", + // editable: false, + // required: false, + // ), + // ), + // const SizedBox(height: 10), + ], + ), ), ); }, ); } - void appointmentUpdateWindow(int index) { + void appointmentUpdateWindow(int index, double bodyWidth) { showDialog( context: context, barrierDismissible: false, @@ -405,91 +413,99 @@ class _BuildAppointmentListState extends State { }); Navigator.of(context).pop(); }, - windowBody: Column( - children: [ - MihForm( - formKey: _formKey, - formFields: [ - MihTextFormField( - fillColor: - MzanziInnovationHub.of(context)!.theme.secondaryColor(), - inputColor: - MzanziInnovationHub.of(context)!.theme.primaryColor(), - controller: widget.titleController, - multiLineInput: false, - requiredText: true, - hintText: "Appointment Title", - validator: (value) { - return MihValidationServices().isEmpty(value); - }, - ), - const SizedBox(height: 10), - SizedBox( - // width: 500, - child: MIHDateField( - controller: widget.dateController, - lableText: "Date", - required: true, + windowBody: Padding( + padding: + MzanziInnovationHub.of(context)!.theme.screenType == "desktop" + ? EdgeInsets.symmetric(horizontal: width * 0.05) + : const EdgeInsets.symmetric(horizontal: 0), + child: Column( + children: [ + MihForm( + formKey: _formKey, + formFields: [ + MihTextFormField( + fillColor: MzanziInnovationHub.of(context)! + .theme + .secondaryColor(), + inputColor: + MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: widget.titleController, + multiLineInput: false, + requiredText: true, + hintText: "Appointment Title", + validator: (value) { + return MihValidationServices().isEmpty(value); + }, ), - ), - const SizedBox(height: 10), - SizedBox( - // width: 500, - child: MIHTimeField( - controller: widget.timeController, - lableText: "Time", - required: true, + const SizedBox(height: 10), + SizedBox( + // width: 500, + child: MIHDateField( + controller: widget.dateController, + lableText: "Date", + required: true, + ), ), - ), - const SizedBox(height: 10), - MihTextFormField( - fillColor: - MzanziInnovationHub.of(context)!.theme.secondaryColor(), - inputColor: - MzanziInnovationHub.of(context)!.theme.primaryColor(), - controller: widget.descriptionIDController, - multiLineInput: true, - height: 250, - requiredText: true, - hintText: "Appointment Description", - validator: (value) { - return MihValidationServices().isEmpty(value); - }, - ), - const SizedBox(height: 20), - Center( - child: Wrap( - alignment: WrapAlignment.center, - runSpacing: 10, - spacing: 10, - children: [ - MihButton( - onPressed: () { - if (_formKey.currentState!.validate()) { - updateAppointmentCall(index); - } - }, - buttonColor: MzanziInnovationHub.of(context)! - .theme - .successColor(), - width: 300, - child: Text( - "Update", - style: TextStyle( - color: MzanziInnovationHub.of(context)! - .theme - .primaryColor(), - fontSize: 20, - fontWeight: FontWeight.bold, + const SizedBox(height: 10), + SizedBox( + // width: 500, + child: MIHTimeField( + controller: widget.timeController, + lableText: "Time", + required: true, + ), + ), + const SizedBox(height: 10), + MihTextFormField( + fillColor: MzanziInnovationHub.of(context)! + .theme + .secondaryColor(), + inputColor: + MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: widget.descriptionIDController, + multiLineInput: true, + height: 250, + requiredText: true, + hintText: "Appointment Description", + validator: (value) { + return MihValidationServices().isEmpty(value); + }, + ), + const SizedBox(height: 20), + Center( + child: Wrap( + alignment: WrapAlignment.center, + runSpacing: 10, + spacing: 10, + children: [ + MihButton( + onPressed: () { + if (_formKey.currentState!.validate()) { + updateAppointmentCall(index); + } + }, + buttonColor: MzanziInnovationHub.of(context)! + .theme + .successColor(), + width: 300, + child: Text( + "Update", + style: TextStyle( + color: MzanziInnovationHub.of(context)! + .theme + .primaryColor(), + fontSize: 20, + fontWeight: FontWeight.bold, + ), ), ), - ), - ], + ], + ), ), - ), - ], - ), - ], + ], + ), + ], + ), ), ); }, @@ -624,7 +640,7 @@ class _BuildAppointmentListState extends State { shrinkWrap: true, itemCount: widget.appointmentList.length, itemBuilder: (context, index) { - return displayAppointment(index); + return displayAppointment(index, width); }, ), ); diff --git a/Frontend/lib/mih_packages/calendar/package_tools/appointments.dart b/Frontend/lib/mih_packages/calendar/package_tools/appointments.dart index d556bc74..e72c6717 100644 --- a/Frontend/lib/mih_packages/calendar/package_tools/appointments.dart +++ b/Frontend/lib/mih_packages/calendar/package_tools/appointments.dart @@ -99,7 +99,7 @@ class _PatientAccessRequestState extends State { ); } - void addAppointmentWindow() { + void addAppointmentWindow(double width) { showDialog( context: context, barrierDismissible: false, @@ -114,83 +114,92 @@ class _PatientAccessRequestState extends State { _appointmentTitleController.clear(); _appointmentDescriptionIDController.clear(); }, - windowBody: Column( - children: [ - MihForm( - formKey: _formKey, - formFields: [ - MihTextFormField( - fillColor: - MzanziInnovationHub.of(context)!.theme.secondaryColor(), - inputColor: - MzanziInnovationHub.of(context)!.theme.primaryColor(), - controller: _appointmentTitleController, - multiLineInput: false, - requiredText: true, - hintText: "Appointment Title", - validator: (value) { - return MihValidationServices().isEmpty(value); - }, - ), - const SizedBox(height: 10), - SizedBox( - // width: 500, - child: MIHDateField( - controller: _appointmentDateController, - lableText: "Date", - required: true, - ), - ), - const SizedBox(height: 10), - SizedBox( - // width: 500, - child: MIHTimeField( - controller: _appointmentTimeController, - lableText: "Time", - required: true, - ), - ), - const SizedBox(height: 10), - MihTextFormField( - fillColor: - MzanziInnovationHub.of(context)!.theme.secondaryColor(), - inputColor: - MzanziInnovationHub.of(context)!.theme.primaryColor(), - controller: _appointmentDescriptionIDController, - multiLineInput: true, - height: 250, - requiredText: true, - hintText: "Appointment Description", - validator: (value) { - return MihValidationServices().isEmpty(value); - }, - ), - const SizedBox(height: 20), - Center( - child: MihButton( - onPressed: () { - if (_formKey.currentState!.validate()) { - addAppointmentCall(); - } + windowBody: Padding( + padding: + MzanziInnovationHub.of(context)!.theme.screenType == "desktop" + ? EdgeInsets.symmetric(horizontal: width * 0.05) + : const EdgeInsets.symmetric(horizontal: 0), + child: Column( + children: [ + MihForm( + formKey: _formKey, + formFields: [ + MihTextFormField( + fillColor: MzanziInnovationHub.of(context)! + .theme + .secondaryColor(), + inputColor: + MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: _appointmentTitleController, + multiLineInput: false, + requiredText: true, + hintText: "Appointment Title", + validator: (value) { + return MihValidationServices().isEmpty(value); }, - buttonColor: - MzanziInnovationHub.of(context)!.theme.successColor(), - width: 300, - child: Text( - "Add", - style: TextStyle( - color: MzanziInnovationHub.of(context)! - .theme - .primaryColor(), - fontSize: 20, - fontWeight: FontWeight.bold, + ), + const SizedBox(height: 10), + SizedBox( + // width: 500, + child: MIHDateField( + controller: _appointmentDateController, + lableText: "Date", + required: true, + ), + ), + const SizedBox(height: 10), + SizedBox( + // width: 500, + child: MIHTimeField( + controller: _appointmentTimeController, + lableText: "Time", + required: true, + ), + ), + const SizedBox(height: 10), + MihTextFormField( + fillColor: MzanziInnovationHub.of(context)! + .theme + .secondaryColor(), + inputColor: + MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: _appointmentDescriptionIDController, + multiLineInput: true, + height: 250, + requiredText: true, + hintText: "Appointment Description", + validator: (value) { + return MihValidationServices().isEmpty(value); + }, + ), + const SizedBox(height: 20), + Center( + child: MihButton( + onPressed: () { + if (_formKey.currentState!.validate()) { + addAppointmentCall(); + } + }, + buttonColor: MzanziInnovationHub.of(context)! + .theme + .successColor(), + width: 300, + child: Text( + "Add", + style: TextStyle( + color: MzanziInnovationHub.of(context)! + .theme + .primaryColor(), + fontSize: 20, + fontWeight: FontWeight.bold, + ), ), ), ), - ), - ], - ), - ], + ], + ), + ], + ), ), ); }, @@ -268,7 +277,7 @@ class _PatientAccessRequestState extends State { }); } - Widget getBody() { + Widget getBody(double width) { return Stack( children: [ MihSingleChildScroll( @@ -341,7 +350,7 @@ class _PatientAccessRequestState extends State { backgroundColor: MzanziInnovationHub.of(context)!.theme.successColor(), onTap: () { - addAppointmentWindow(); + addAppointmentWindow(width); }, ) ], @@ -383,9 +392,10 @@ class _PatientAccessRequestState extends State { @override Widget build(BuildContext context) { + double screenWidth = MediaQuery.of(context).size.width; return MihPackageToolBody( borderOn: false, - bodyItem: getBody(), + bodyItem: getBody(screenWidth), ); } } From c42bb62477daea3ed14a4ed011dab44f8c121bf6 Mon Sep 17 00:00:00 2001 From: Yasien Mac Mini Date: Fri, 6 Jun 2025 12:10:33 +0200 Subject: [PATCH 41/52] remove bottom padding --- .../mih_package_components/mih_package_window.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Frontend/lib/mih_components/mih_package_components/mih_package_window.dart b/Frontend/lib/mih_components/mih_package_components/mih_package_window.dart index dc44a614..69f47bbb 100644 --- a/Frontend/lib/mih_components/mih_package_components/mih_package_window.dart +++ b/Frontend/lib/mih_components/mih_package_components/mih_package_window.dart @@ -39,7 +39,7 @@ class _MihPackageWindowState extends State { setState(() { windowTitleSize = 25; horizontralWindowPadding = width / 7; - vertticalWindowPadding = 25; + vertticalWindowPadding = 10; windowWidth = width; windowHeight = height; }); From 42cc4f62ab578147cfebd64425c4ad55ed63383b Mon Sep 17 00:00:00 2001 From: Yasien Mac Mini Date: Fri, 6 Jun 2025 12:23:35 +0200 Subject: [PATCH 42/52] fix biz prof padding --- .../builders/build_employee_list.dart | 168 +++--- .../builders/build_user_list.dart | 174 +++--- .../package_tools/mih_business_details.dart | 358 ++++++------ .../package_tools/mih_my_business_user.dart | 313 +++++------ .../profile_business_add.dart | 508 +++++++++--------- 5 files changed, 786 insertions(+), 735 deletions(-) diff --git a/Frontend/lib/mih_packages/mzansi_profile/business_profile/builders/build_employee_list.dart b/Frontend/lib/mih_packages/mzansi_profile/business_profile/builders/build_employee_list.dart index fd1ab642..138a8033 100644 --- a/Frontend/lib/mih_packages/mzansi_profile/business_profile/builders/build_employee_list.dart +++ b/Frontend/lib/mih_packages/mzansi_profile/business_profile/builders/build_employee_list.dart @@ -142,7 +142,7 @@ class _BuildEmployeeListState extends State { } } - void updateEmployeePopUp(int index) { + void updateEmployeePopUp(int index, double width) { setState(() { accessController.text = widget.employees[index].access; typeController.text = widget.employees[index].title; @@ -178,88 +178,95 @@ class _BuildEmployeeListState extends State { onWindowTapClose: () { Navigator.pop(context); }, - windowBody: Column( - children: [ - MihForm( - formKey: _formKey, - formFields: [ - MihTextFormField( - fillColor: - MzanziInnovationHub.of(context)!.theme.secondaryColor(), - inputColor: - MzanziInnovationHub.of(context)!.theme.primaryColor(), - controller: fnameController, - multiLineInput: false, - requiredText: true, - readOnly: true, - hintText: "First Name", - ), - const SizedBox(height: 10.0), - MihTextFormField( - fillColor: - MzanziInnovationHub.of(context)!.theme.secondaryColor(), - inputColor: - MzanziInnovationHub.of(context)!.theme.primaryColor(), - controller: lnameController, - multiLineInput: false, - requiredText: true, - readOnly: true, - hintText: "Surname", - ), - const SizedBox(height: 15.0), - MIHDropdownField( - controller: typeController, - hintText: "Title", - dropdownOptions: const ["Doctor", "Assistant"], - required: true, - editable: true, - enableSearch: false, - ), - const SizedBox(height: 10.0), - MIHDropdownField( - controller: accessController, - hintText: "Access", - dropdownOptions: const ["Full", "Partial"], - required: true, - editable: true, - enableSearch: false, - ), - const SizedBox(height: 20.0), - Center( - child: MihButton( - onPressed: () { - if (_formKey.currentState!.validate()) { - if (isRequiredFieldsCaptured()) { - updateEmployeeAPICall(index); - } else { - showDialog( - context: context, - builder: (context) { - return const MIHErrorMessage( - errorType: "Input Error"); - }, - ); - } - } - }, - buttonColor: + windowBody: Padding( + padding: + MzanziInnovationHub.of(context)!.theme.screenType == "desktop" + ? EdgeInsets.symmetric(horizontal: width * 0.05) + : const EdgeInsets.symmetric(horizontal: 0), + child: Column( + children: [ + MihForm( + formKey: _formKey, + formFields: [ + MihTextFormField( + fillColor: MzanziInnovationHub.of(context)!.theme.secondaryColor(), - width: 300, - child: Text( - "Update", - style: TextStyle( - color: MzanziInnovationHub.of(context)! - .theme - .primaryColor(), - fontSize: 20, - fontWeight: FontWeight.bold, + inputColor: + MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: fnameController, + multiLineInput: false, + requiredText: true, + readOnly: true, + hintText: "First Name", + ), + const SizedBox(height: 10.0), + MihTextFormField( + fillColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + inputColor: + MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: lnameController, + multiLineInput: false, + requiredText: true, + readOnly: true, + hintText: "Surname", + ), + const SizedBox(height: 15.0), + MIHDropdownField( + controller: typeController, + hintText: "Title", + dropdownOptions: const ["Doctor", "Assistant"], + required: true, + editable: true, + enableSearch: false, + ), + const SizedBox(height: 10.0), + MIHDropdownField( + controller: accessController, + hintText: "Access", + dropdownOptions: const ["Full", "Partial"], + required: true, + editable: true, + enableSearch: false, + ), + const SizedBox(height: 20.0), + Center( + child: MihButton( + onPressed: () { + if (_formKey.currentState!.validate()) { + if (isRequiredFieldsCaptured()) { + updateEmployeeAPICall(index); + } else { + showDialog( + context: context, + builder: (context) { + return const MIHErrorMessage( + errorType: "Input Error"); + }, + ); + } + } + }, + buttonColor: MzanziInnovationHub.of(context)! + .theme + .secondaryColor(), + width: 300, + child: Text( + "Update", + style: TextStyle( + color: MzanziInnovationHub.of(context)! + .theme + .primaryColor(), + fontSize: 20, + fontWeight: FontWeight.bold, + ), ), ), ), - ), - ], - ), - ], + ], + ), + ], + ), ), ), ); @@ -287,6 +294,7 @@ class _BuildEmployeeListState extends State { @override Widget build(BuildContext context) { + double screenWidth = MediaQuery.of(context).size.width; return ListView.separated( shrinkWrap: true, physics: const NeverScrollableScrollPhysics(), @@ -314,7 +322,7 @@ class _BuildEmployeeListState extends State { ), ), onTap: () { - updateEmployeePopUp(index); + updateEmployeePopUp(index, screenWidth); }, ); }, diff --git a/Frontend/lib/mih_packages/mzansi_profile/business_profile/builders/build_user_list.dart b/Frontend/lib/mih_packages/mzansi_profile/business_profile/builders/build_user_list.dart index a5ba1ebe..3ebb3792 100644 --- a/Frontend/lib/mih_packages/mzansi_profile/business_profile/builders/build_user_list.dart +++ b/Frontend/lib/mih_packages/mzansi_profile/business_profile/builders/build_user_list.dart @@ -114,7 +114,7 @@ class _BuildUserListState extends State { return "$firstLetter********@$end"; } - void addEmployeePopUp(int index) { + void addEmployeePopUp(int index, double width) { setState(() { //accessController.text = widget.users[index].access; //typeController.text = widget.users[index].title; @@ -129,92 +129,99 @@ class _BuildUserListState extends State { builder: (context) => MihPackageWindow( fullscreen: false, windowTitle: "Add Employee", - windowBody: Column( - children: [ - MihForm( - formKey: _formKey, - formFields: [ - MihTextFormField( - fillColor: MzanziInnovationHub.of(context)! - .theme - .secondaryColor(), - inputColor: - MzanziInnovationHub.of(context)!.theme.primaryColor(), - controller: usernameController, - multiLineInput: false, - requiredText: true, - readOnly: true, - hintText: "Username", - ), - const SizedBox(height: 10.0), - MihTextFormField( - fillColor: MzanziInnovationHub.of(context)! - .theme - .secondaryColor(), - inputColor: - MzanziInnovationHub.of(context)!.theme.primaryColor(), - controller: emailController, - multiLineInput: false, - requiredText: true, - readOnly: true, - hintText: "Email", - ), - const SizedBox(height: 15.0), - MIHDropdownField( - controller: typeController, - hintText: "Title", - dropdownOptions: const ["Doctor", "Assistant"], - required: true, - editable: true, - enableSearch: false, - ), - const SizedBox(height: 10.0), - MIHDropdownField( - controller: accessController, - hintText: "Access", - dropdownOptions: const ["Full", "Partial"], - required: true, - editable: true, - enableSearch: false, - ), - const SizedBox(height: 15.0), - Center( - child: MihButton( - onPressed: () { - if (_formKey.currentState!.validate()) { - if (isRequiredFieldsCaptured()) { - createBusinessUserAPICall(index); - } else { - showDialog( - context: context, - builder: (context) { - return const MIHErrorMessage( - errorType: "Input Error"); - }, - ); - } - } - }, - buttonColor: MzanziInnovationHub.of(context)! + windowBody: Padding( + padding: + MzanziInnovationHub.of(context)!.theme.screenType == "desktop" + ? EdgeInsets.symmetric(horizontal: width * 0.05) + : const EdgeInsets.symmetric(horizontal: 0), + child: Column( + children: [ + MihForm( + formKey: _formKey, + formFields: [ + MihTextFormField( + fillColor: MzanziInnovationHub.of(context)! .theme .secondaryColor(), - width: 300, - child: Text( - "Add", - style: TextStyle( - color: MzanziInnovationHub.of(context)! - .theme - .primaryColor(), - fontSize: 20, - fontWeight: FontWeight.bold, + inputColor: MzanziInnovationHub.of(context)! + .theme + .primaryColor(), + controller: usernameController, + multiLineInput: false, + requiredText: true, + readOnly: true, + hintText: "Username", + ), + const SizedBox(height: 10.0), + MihTextFormField( + fillColor: MzanziInnovationHub.of(context)! + .theme + .secondaryColor(), + inputColor: MzanziInnovationHub.of(context)! + .theme + .primaryColor(), + controller: emailController, + multiLineInput: false, + requiredText: true, + readOnly: true, + hintText: "Email", + ), + const SizedBox(height: 15.0), + MIHDropdownField( + controller: typeController, + hintText: "Title", + dropdownOptions: const ["Doctor", "Assistant"], + required: true, + editable: true, + enableSearch: false, + ), + const SizedBox(height: 10.0), + MIHDropdownField( + controller: accessController, + hintText: "Access", + dropdownOptions: const ["Full", "Partial"], + required: true, + editable: true, + enableSearch: false, + ), + const SizedBox(height: 15.0), + Center( + child: MihButton( + onPressed: () { + if (_formKey.currentState!.validate()) { + if (isRequiredFieldsCaptured()) { + createBusinessUserAPICall(index); + } else { + showDialog( + context: context, + builder: (context) { + return const MIHErrorMessage( + errorType: "Input Error"); + }, + ); + } + } + }, + buttonColor: MzanziInnovationHub.of(context)! + .theme + .secondaryColor(), + width: 300, + child: Text( + "Add", + style: TextStyle( + color: MzanziInnovationHub.of(context)! + .theme + .primaryColor(), + fontSize: 20, + fontWeight: FontWeight.bold, + ), ), ), ), - ), - const SizedBox(height: 10.0), - ], - ), - ], + ], + ), + ], + ), ), onWindowTapClose: () { Navigator.pop(context); @@ -232,6 +239,7 @@ class _BuildUserListState extends State { @override Widget build(BuildContext context) { + double screenWidth = MediaQuery.of(context).size.width; return ListView.separated( shrinkWrap: true, physics: const NeverScrollableScrollPhysics(), @@ -256,7 +264,7 @@ class _BuildUserListState extends State { ), ), onTap: () { - addEmployeePopUp(index); + addEmployeePopUp(index, screenWidth); }, ); }, diff --git a/Frontend/lib/mih_packages/mzansi_profile/business_profile/package_tools/mih_business_details.dart b/Frontend/lib/mih_packages/mzansi_profile/business_profile/package_tools/mih_business_details.dart index 42a35ed1..30f50114 100644 --- a/Frontend/lib/mih_packages/mzansi_profile/business_profile/package_tools/mih_business_details.dart +++ b/Frontend/lib/mih_packages/mzansi_profile/business_profile/package_tools/mih_business_details.dart @@ -223,172 +223,208 @@ class _MihBusinessDetailsState extends State { @override Widget build(BuildContext context) { + double screenWidth = MediaQuery.of(context).size.width; return MihPackageToolBody( borderOn: false, innerHorizontalPadding: 10, - bodyItem: getBody(context), + bodyItem: getBody(screenWidth, context), ); } - Widget getBody(BuildContext context) { + Widget getBody(double width, BuildContext context) { return MihSingleChildScroll( - child: Column( - children: [ - MihForm( - formKey: _formKey, - formFields: [ - Center( - child: MihCircleAvatar( - imageFile: widget.logoImage, - width: 150, - editable: true, - fileNameController: fileNameController, - userSelectedfile: imageFile, - frameColor: - MzanziInnovationHub.of(context)!.theme.secondaryColor(), - backgroundColor: - MzanziInnovationHub.of(context)!.theme.primaryColor(), - onChange: (selectedfile) { - setState(() { - imageFile = selectedfile; - }); - }, + child: Padding( + padding: MzanziInnovationHub.of(context)!.theme.screenType == "desktop" + ? EdgeInsets.symmetric(horizontal: width * 0.2) + : EdgeInsets.symmetric(horizontal: width * 0.075), + child: Column( + children: [ + MihForm( + formKey: _formKey, + formFields: [ + Center( + child: MihCircleAvatar( + imageFile: widget.logoImage, + width: 150, + editable: true, + fileNameController: fileNameController, + userSelectedfile: imageFile, + frameColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + backgroundColor: + MzanziInnovationHub.of(context)!.theme.primaryColor(), + onChange: (selectedfile) { + setState(() { + imageFile = selectedfile; + }); + }, + ), ), - ), - Visibility( - visible: false, - child: MihTextFormField( + Visibility( + visible: false, + child: MihTextFormField( + fillColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + inputColor: + MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: fileNameController, + multiLineInput: false, + requiredText: true, + readOnly: true, + hintText: "Selected File Name", + ), + ), + const SizedBox(height: 20), + MihTextFormField( fillColor: MzanziInnovationHub.of(context)!.theme.secondaryColor(), inputColor: MzanziInnovationHub.of(context)!.theme.primaryColor(), - controller: fileNameController, + controller: regController, multiLineInput: false, requiredText: true, - readOnly: true, - hintText: "Selected File Name", + hintText: "Registration No.", + validator: (value) { + return MihValidationServices().isEmpty(value); + }, ), - ), - const SizedBox(height: 20), - MihTextFormField( - fillColor: - MzanziInnovationHub.of(context)!.theme.secondaryColor(), - inputColor: MzanziInnovationHub.of(context)!.theme.primaryColor(), - controller: regController, - multiLineInput: false, - requiredText: true, - hintText: "Registration No.", - validator: (value) { - return MihValidationServices().isEmpty(value); - }, - ), - const SizedBox(height: 10), - MihTextFormField( - fillColor: - MzanziInnovationHub.of(context)!.theme.secondaryColor(), - inputColor: MzanziInnovationHub.of(context)!.theme.primaryColor(), - controller: nameController, - multiLineInput: false, - requiredText: true, - hintText: "Business Name", - validator: (value) { - return MihValidationServices().isEmpty(value); - }, - ), - const SizedBox(height: 15), - MIHDropdownField( - controller: typeController, - hintText: "Business Type", - dropdownOptions: const ["Doctors Office", "Other"], - required: true, - editable: true, - enableSearch: false, - ), - const SizedBox(height: 10), - MihTextFormField( - fillColor: - MzanziInnovationHub.of(context)!.theme.secondaryColor(), - inputColor: MzanziInnovationHub.of(context)!.theme.primaryColor(), - controller: practiceNoController, - multiLineInput: false, - requiredText: typeController.text == "Doctors Office", - hintText: "Practice Number", - validator: (validateValue) { - return MihValidationServices().isEmpty(validateValue); - }, - ), - const SizedBox(height: 10), - MihTextFormField( - fillColor: - MzanziInnovationHub.of(context)!.theme.secondaryColor(), - inputColor: MzanziInnovationHub.of(context)!.theme.primaryColor(), - controller: vatNoController, - multiLineInput: false, - requiredText: true, - hintText: "VAT Number", - validator: (value) { - return MihValidationServices().isEmpty(value); - }, - ), - const SizedBox(height: 10), - MihTextFormField( - fillColor: - MzanziInnovationHub.of(context)!.theme.secondaryColor(), - inputColor: MzanziInnovationHub.of(context)!.theme.primaryColor(), - controller: contactController, - multiLineInput: false, - requiredText: true, - hintText: "Contact Number", - validator: (value) { - return MihValidationServices().isEmpty(value); - }, - ), - const SizedBox(height: 10), - MihTextFormField( - fillColor: - MzanziInnovationHub.of(context)!.theme.secondaryColor(), - inputColor: MzanziInnovationHub.of(context)!.theme.primaryColor(), - controller: emailController, - multiLineInput: false, - requiredText: true, - hintText: "Business Email", - validator: (value) { - return MihValidationServices().validateEmail(value); - }, - ), - const SizedBox(height: 10), - Row( - crossAxisAlignment: CrossAxisAlignment.end, - children: [ - Flexible( - child: MihTextFormField( - fillColor: - MzanziInnovationHub.of(context)!.theme.secondaryColor(), - inputColor: - MzanziInnovationHub.of(context)!.theme.primaryColor(), - controller: locationController, - multiLineInput: false, - requiredText: true, - hintText: "GPS Location", + const SizedBox(height: 10), + MihTextFormField( + fillColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + inputColor: + MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: nameController, + multiLineInput: false, + requiredText: true, + hintText: "Business Name", + validator: (value) { + return MihValidationServices().isEmpty(value); + }, + ), + const SizedBox(height: 15), + MIHDropdownField( + controller: typeController, + hintText: "Business Type", + dropdownOptions: const ["Doctors Office", "Other"], + required: true, + editable: true, + enableSearch: false, + ), + const SizedBox(height: 10), + MihTextFormField( + fillColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + inputColor: + MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: practiceNoController, + multiLineInput: false, + requiredText: typeController.text == "Doctors Office", + hintText: "Practice Number", + validator: (validateValue) { + return MihValidationServices().isEmpty(validateValue); + }, + ), + const SizedBox(height: 10), + MihTextFormField( + fillColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + inputColor: + MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: vatNoController, + multiLineInput: false, + requiredText: true, + hintText: "VAT Number", + validator: (value) { + return MihValidationServices().isEmpty(value); + }, + ), + const SizedBox(height: 10), + MihTextFormField( + fillColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + inputColor: + MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: contactController, + multiLineInput: false, + requiredText: true, + hintText: "Contact Number", + validator: (value) { + return MihValidationServices().isEmpty(value); + }, + ), + const SizedBox(height: 10), + MihTextFormField( + fillColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + inputColor: + MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: emailController, + multiLineInput: false, + requiredText: true, + hintText: "Business Email", + validator: (value) { + return MihValidationServices().validateEmail(value); + }, + ), + const SizedBox(height: 10), + Row( + crossAxisAlignment: CrossAxisAlignment.end, + children: [ + Flexible( + child: MihTextFormField( + fillColor: MzanziInnovationHub.of(context)! + .theme + .secondaryColor(), + inputColor: + MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: locationController, + multiLineInput: false, + requiredText: true, + hintText: "GPS Location", + ), ), - ), - const SizedBox(width: 10.0), - MihButton( + const SizedBox(width: 10.0), + MihButton( + onPressed: () { + MIHLocationAPI().getGPSPosition(context).then((position) { + if (position != null) { + setState(() { + locationController.text = + "${position.latitude}, ${position.longitude}"; + }); + } + }); + }, + buttonColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + width: 100, + child: Text( + "Set", + style: TextStyle( + color: MzanziInnovationHub.of(context)! + .theme + .primaryColor(), + fontSize: 20, + fontWeight: FontWeight.bold, + ), + ), + ), + ], + ), + const SizedBox(height: 15), + Center( + child: MihButton( onPressed: () { - MIHLocationAPI().getGPSPosition(context).then((position) { - if (position != null) { - setState(() { - locationController.text = - "${position.latitude}, ${position.longitude}"; - }); - } - }); + if (_formKey.currentState!.validate()) { + submitForm(); + } }, buttonColor: MzanziInnovationHub.of(context)!.theme.secondaryColor(), - width: 100, + width: 300, child: Text( - "Set", + "Update", style: TextStyle( color: MzanziInnovationHub.of(context)!.theme.primaryColor(), @@ -397,34 +433,12 @@ class _MihBusinessDetailsState extends State { ), ), ), - ], - ), - const SizedBox(height: 15), - Center( - child: MihButton( - onPressed: () { - if (_formKey.currentState!.validate()) { - submitForm(); - } - }, - buttonColor: - MzanziInnovationHub.of(context)!.theme.secondaryColor(), - width: 300, - child: Text( - "Update", - style: TextStyle( - color: - MzanziInnovationHub.of(context)!.theme.primaryColor(), - fontSize: 20, - fontWeight: FontWeight.bold, - ), - ), ), - ), - const SizedBox(height: 20), - ], - ), - ], + const SizedBox(height: 20), + ], + ), + ], + ), )); } } diff --git a/Frontend/lib/mih_packages/mzansi_profile/business_profile/package_tools/mih_my_business_user.dart b/Frontend/lib/mih_packages/mzansi_profile/business_profile/package_tools/mih_my_business_user.dart index 99cc5a99..846a3445 100644 --- a/Frontend/lib/mih_packages/mzansi_profile/business_profile/package_tools/mih_my_business_user.dart +++ b/Frontend/lib/mih_packages/mzansi_profile/business_profile/package_tools/mih_my_business_user.dart @@ -203,184 +203,191 @@ class _MihMyBusinessUserState extends State { @override Widget build(BuildContext context) { + double screenWidth = MediaQuery.of(context).size.width; return MihPackageToolBody( borderOn: false, innerHorizontalPadding: 10, - bodyItem: getBody(), + bodyItem: getBody(screenWidth), ); } - Widget getBody() { + Widget getBody(double width) { return MihSingleChildScroll( - child: Column( - children: [ - MihForm( - formKey: _formKey, - formFields: [ - Center( - child: MihCircleAvatar( - imageFile: widget.userProPicImage, - width: 150, - editable: false, - fileNameController: fileNameController, - userSelectedfile: userPicFile, - frameColor: - MzanziInnovationHub.of(context)!.theme.secondaryColor(), - backgroundColor: - MzanziInnovationHub.of(context)!.theme.primaryColor(), - onChange: (_) {}, - ), - ), - Visibility( - visible: false, - child: MihTextFormField( - fillColor: - MzanziInnovationHub.of(context)!.theme.secondaryColor(), - inputColor: - MzanziInnovationHub.of(context)!.theme.primaryColor(), - controller: fileNameController, - multiLineInput: false, - requiredText: true, - readOnly: true, - hintText: "Selected File Name", - ), - ), - const SizedBox(height: 20), - MIHDropdownField( - controller: titleDropdownController, - hintText: "Title", - dropdownOptions: const ["Doctor", "Assistant", "Other"], - required: true, - editable: true, - enableSearch: false, - ), - const SizedBox(height: 10), - MihTextFormField( - fillColor: - MzanziInnovationHub.of(context)!.theme.secondaryColor(), - inputColor: - MzanziInnovationHub.of(context)!.theme.primaryColor(), - controller: titleTextController, - multiLineInput: false, - requiredText: true, - hintText: "Other Title", - validator: (value) { - return MihValidationServices().isEmpty(value); - }, - ), - const SizedBox(height: 10), - MihTextFormField( - fillColor: - MzanziInnovationHub.of(context)!.theme.secondaryColor(), - inputColor: - MzanziInnovationHub.of(context)!.theme.primaryColor(), - controller: fnameController, - multiLineInput: false, - requiredText: true, - readOnly: true, - hintText: "First Name", - validator: (value) { - return MihValidationServices().isEmpty(value); - }, - ), - const SizedBox(height: 10), - MihTextFormField( - fillColor: - MzanziInnovationHub.of(context)!.theme.secondaryColor(), - inputColor: - MzanziInnovationHub.of(context)!.theme.primaryColor(), - controller: lnameController, - multiLineInput: false, - requiredText: true, - readOnly: true, - hintText: "Surname", - validator: (value) { - return MihValidationServices().isEmpty(value); - }, - ), - const SizedBox(height: 10), - MihTextFormField( - fillColor: - MzanziInnovationHub.of(context)!.theme.secondaryColor(), - inputColor: - MzanziInnovationHub.of(context)!.theme.primaryColor(), - controller: accessController, - multiLineInput: false, - requiredText: true, - hintText: "Access Level", - readOnly: true, - validator: (value) { - return MihValidationServices().isEmpty(value); - }, - ), - const SizedBox(height: 10), - Container( - width: 300, - alignment: Alignment.topLeft, - child: const Text( - "Signature:", - style: TextStyle( - fontSize: 15, - fontWeight: FontWeight.bold, + child: Padding( + padding: MzanziInnovationHub.of(context)!.theme.screenType == "desktop" + ? EdgeInsets.symmetric(horizontal: width * 0.2) + : EdgeInsets.symmetric(horizontal: width * 0.075), + child: Column( + children: [ + MihForm( + formKey: _formKey, + formFields: [ + Center( + child: MihCircleAvatar( + imageFile: widget.userProPicImage, + width: 150, + editable: false, + fileNameController: fileNameController, + userSelectedfile: userPicFile, + frameColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + backgroundColor: + MzanziInnovationHub.of(context)!.theme.primaryColor(), + onChange: (_) {}, ), ), - ), - Center( - child: MihImageDisplay( - imageFile: widget.userSignatureImage, - width: 300, - height: 200, - editable: true, - fileNameController: signtureController, - userSelectedfile: userSignatureFile, - onChange: (selectedFile) { - setState(() { - userSignatureFile = selectedFile; - }); - }, + Visibility( + visible: false, + child: MihTextFormField( + fillColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + inputColor: + MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: fileNameController, + multiLineInput: false, + requiredText: true, + readOnly: true, + hintText: "Selected File Name", + ), ), - ), - const SizedBox(height: 10), - Visibility( - visible: false, - child: MihTextFormField( + const SizedBox(height: 20), + MIHDropdownField( + controller: titleDropdownController, + hintText: "Title", + dropdownOptions: const ["Doctor", "Assistant", "Other"], + required: true, + editable: true, + enableSearch: false, + ), + const SizedBox(height: 10), + MihTextFormField( fillColor: MzanziInnovationHub.of(context)!.theme.secondaryColor(), inputColor: MzanziInnovationHub.of(context)!.theme.primaryColor(), - controller: fileNameController, + controller: titleTextController, + multiLineInput: false, + requiredText: true, + hintText: "Other Title", + validator: (value) { + return MihValidationServices().isEmpty(value); + }, + ), + const SizedBox(height: 10), + MihTextFormField( + fillColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + inputColor: + MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: fnameController, multiLineInput: false, requiredText: true, readOnly: true, - hintText: "Selected Signature File", - ), - ), - const SizedBox(height: 15), - Center( - child: MihButton( - onPressed: () { - if (_formKey.currentState!.validate()) { - submitForm(); - } + hintText: "First Name", + validator: (value) { + return MihValidationServices().isEmpty(value); }, - buttonColor: + ), + const SizedBox(height: 10), + MihTextFormField( + fillColor: MzanziInnovationHub.of(context)!.theme.secondaryColor(), + inputColor: + MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: lnameController, + multiLineInput: false, + requiredText: true, + readOnly: true, + hintText: "Surname", + validator: (value) { + return MihValidationServices().isEmpty(value); + }, + ), + const SizedBox(height: 10), + MihTextFormField( + fillColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + inputColor: + MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: accessController, + multiLineInput: false, + requiredText: true, + hintText: "Access Level", + readOnly: true, + validator: (value) { + return MihValidationServices().isEmpty(value); + }, + ), + const SizedBox(height: 10), + Container( width: 300, - child: Text( - "Update", + alignment: Alignment.topLeft, + child: const Text( + "Signature:", style: TextStyle( - color: - MzanziInnovationHub.of(context)!.theme.primaryColor(), - fontSize: 20, + fontSize: 15, fontWeight: FontWeight.bold, ), ), ), - ), - const SizedBox(height: 20), - ], - ), - ], + Center( + child: MihImageDisplay( + imageFile: widget.userSignatureImage, + width: 300, + height: 200, + editable: true, + fileNameController: signtureController, + userSelectedfile: userSignatureFile, + onChange: (selectedFile) { + setState(() { + userSignatureFile = selectedFile; + }); + }, + ), + ), + const SizedBox(height: 10), + Visibility( + visible: false, + child: MihTextFormField( + fillColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + inputColor: + MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: fileNameController, + multiLineInput: false, + requiredText: true, + readOnly: true, + hintText: "Selected Signature File", + ), + ), + const SizedBox(height: 15), + Center( + child: MihButton( + onPressed: () { + if (_formKey.currentState!.validate()) { + submitForm(); + } + }, + buttonColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + width: 300, + child: Text( + "Update", + style: TextStyle( + color: MzanziInnovationHub.of(context)! + .theme + .primaryColor(), + fontSize: 20, + fontWeight: FontWeight.bold, + ), + ), + ), + ), + const SizedBox(height: 20), + ], + ), + ], + ), ), ); } diff --git a/Frontend/lib/mih_packages/mzansi_profile/business_profile/profile_business_add.dart b/Frontend/lib/mih_packages/mzansi_profile/business_profile/profile_business_add.dart index 7f5818a2..38fbfa8e 100644 --- a/Frontend/lib/mih_packages/mzansi_profile/business_profile/profile_business_add.dart +++ b/Frontend/lib/mih_packages/mzansi_profile/business_profile/profile_business_add.dart @@ -297,7 +297,7 @@ class _ProfileBusinessAddState extends State { ); } - MIHBody getBody() { + MIHBody getBody(double width) { return MIHBody( borderOn: false, bodyItems: [ @@ -313,173 +313,273 @@ class _ProfileBusinessAddState extends State { } }, child: SingleChildScrollView( - child: Column( - children: [ - const Text( - "My Business Details", - style: TextStyle( - fontWeight: FontWeight.bold, - fontSize: 25, + child: Padding( + padding: + MzanziInnovationHub.of(context)!.theme.screenType == "desktop" + ? EdgeInsets.symmetric(horizontal: width * 0.2) + : EdgeInsets.symmetric(horizontal: width * 0.075), + child: Column( + children: [ + const Text( + "My Business Details", + style: TextStyle( + fontWeight: FontWeight.bold, + fontSize: 25, + ), ), - ), - Divider( - color: MzanziInnovationHub.of(context)! - .theme - .secondaryColor()), - const SizedBox(height: 10.0), - MihForm( - formKey: _formKey, - formFields: [ - MihTextFormField( - fillColor: MzanziInnovationHub.of(context)! + Divider( + color: MzanziInnovationHub.of(context)! .theme - .secondaryColor(), - inputColor: - MzanziInnovationHub.of(context)!.theme.primaryColor(), - controller: regController, - multiLineInput: false, - requiredText: true, - hintText: "Registration No.", - validator: (value) { - return MihValidationServices().isEmpty(value); - }, - ), - const SizedBox(height: 10.0), - MihTextFormField( - fillColor: MzanziInnovationHub.of(context)! - .theme - .secondaryColor(), - inputColor: - MzanziInnovationHub.of(context)!.theme.primaryColor(), - controller: nameController, - multiLineInput: false, - requiredText: true, - hintText: "Business Name", - validator: (value) { - return MihValidationServices().isEmpty(value); - }, - ), - const SizedBox(height: 15.0), - MIHDropdownField( - controller: typeController, - hintText: "Business Type", - dropdownOptions: const ["Doctors Office", "Other"], - required: true, - editable: true, - enableSearch: false, - ), - const SizedBox(height: 10.0), - ValueListenableBuilder( - valueListenable: busType, - builder: - (BuildContext context, String value, Widget? child) { - return Visibility( - visible: value == "Doctors Office", - child: MihTextFormField( - fillColor: MzanziInnovationHub.of(context)! - .theme - .secondaryColor(), - inputColor: MzanziInnovationHub.of(context)! - .theme - .primaryColor(), - controller: practiceNoController, - multiLineInput: false, - requiredText: true, - hintText: "Practice Number", - validator: (validateValue) { - if (value == "Doctors Office") { - return MihValidationServices() - .isEmpty(validateValue); - } - return null; - }, + .secondaryColor()), + const SizedBox(height: 10.0), + MihForm( + formKey: _formKey, + formFields: [ + MihTextFormField( + fillColor: MzanziInnovationHub.of(context)! + .theme + .secondaryColor(), + inputColor: MzanziInnovationHub.of(context)! + .theme + .primaryColor(), + controller: regController, + multiLineInput: false, + requiredText: true, + hintText: "Registration No.", + validator: (value) { + return MihValidationServices().isEmpty(value); + }, + ), + const SizedBox(height: 10.0), + MihTextFormField( + fillColor: MzanziInnovationHub.of(context)! + .theme + .secondaryColor(), + inputColor: MzanziInnovationHub.of(context)! + .theme + .primaryColor(), + controller: nameController, + multiLineInput: false, + requiredText: true, + hintText: "Business Name", + validator: (value) { + return MihValidationServices().isEmpty(value); + }, + ), + const SizedBox(height: 15.0), + MIHDropdownField( + controller: typeController, + hintText: "Business Type", + dropdownOptions: const ["Doctors Office", "Other"], + required: true, + editable: true, + enableSearch: false, + ), + const SizedBox(height: 10.0), + ValueListenableBuilder( + valueListenable: busType, + builder: (BuildContext context, String value, + Widget? child) { + return Visibility( + visible: value == "Doctors Office", + child: MihTextFormField( + fillColor: MzanziInnovationHub.of(context)! + .theme + .secondaryColor(), + inputColor: MzanziInnovationHub.of(context)! + .theme + .primaryColor(), + controller: practiceNoController, + multiLineInput: false, + requiredText: true, + hintText: "Practice Number", + validator: (validateValue) { + if (value == "Doctors Office") { + return MihValidationServices() + .isEmpty(validateValue); + } + return null; + }, + ), + ); + }, + ), + const SizedBox(height: 10.0), + MihTextFormField( + fillColor: MzanziInnovationHub.of(context)! + .theme + .secondaryColor(), + inputColor: MzanziInnovationHub.of(context)! + .theme + .primaryColor(), + controller: vatNoController, + multiLineInput: false, + requiredText: true, + hintText: "VAT Number", + validator: (value) { + return MihValidationServices().isEmpty(value); + }, + ), + const SizedBox(height: 10.0), + MihTextFormField( + fillColor: MzanziInnovationHub.of(context)! + .theme + .secondaryColor(), + inputColor: MzanziInnovationHub.of(context)! + .theme + .primaryColor(), + controller: contactController, + multiLineInput: false, + requiredText: true, + hintText: "Contact Number", + validator: (value) { + return MihValidationServices().isEmpty(value); + }, + ), + const SizedBox(height: 10.0), + MihTextFormField( + fillColor: MzanziInnovationHub.of(context)! + .theme + .secondaryColor(), + inputColor: MzanziInnovationHub.of(context)! + .theme + .primaryColor(), + controller: emailController, + multiLineInput: false, + requiredText: true, + hintText: "Business Email", + validator: (value) { + return MihValidationServices().validateEmail(value); + }, + ), + const SizedBox(height: 10.0), + Row( + crossAxisAlignment: CrossAxisAlignment.end, + children: [ + Flexible( + child: MihTextFormField( + fillColor: MzanziInnovationHub.of(context)! + .theme + .secondaryColor(), + inputColor: MzanziInnovationHub.of(context)! + .theme + .primaryColor(), + controller: locationController, + multiLineInput: false, + requiredText: true, + hintText: "GPS Location", + ), ), - ); - }, - ), - const SizedBox(height: 10.0), - MihTextFormField( - fillColor: MzanziInnovationHub.of(context)! - .theme - .secondaryColor(), - inputColor: - MzanziInnovationHub.of(context)!.theme.primaryColor(), - controller: vatNoController, - multiLineInput: false, - requiredText: true, - hintText: "VAT Number", - validator: (value) { - return MihValidationServices().isEmpty(value); - }, - ), - const SizedBox(height: 10.0), - MihTextFormField( - fillColor: MzanziInnovationHub.of(context)! - .theme - .secondaryColor(), - inputColor: - MzanziInnovationHub.of(context)!.theme.primaryColor(), - controller: contactController, - multiLineInput: false, - requiredText: true, - hintText: "Contact Number", - validator: (value) { - return MihValidationServices().isEmpty(value); - }, - ), - const SizedBox(height: 10.0), - MihTextFormField( - fillColor: MzanziInnovationHub.of(context)! - .theme - .secondaryColor(), - inputColor: - MzanziInnovationHub.of(context)!.theme.primaryColor(), - controller: emailController, - multiLineInput: false, - requiredText: true, - hintText: "Business Email", - validator: (value) { - return MihValidationServices().validateEmail(value); - }, - ), - const SizedBox(height: 10.0), - Row( - crossAxisAlignment: CrossAxisAlignment.end, - children: [ - Flexible( - child: MihTextFormField( - fillColor: MzanziInnovationHub.of(context)! + const SizedBox(width: 10.0), + MihButton( + onPressed: () { + MIHLocationAPI() + .getGPSPosition(context) + .then((position) { + if (position != null) { + setState(() { + locationController.text = + "${position.latitude}, ${position.longitude}"; + }); + } + }); + }, + buttonColor: MzanziInnovationHub.of(context)! .theme .secondaryColor(), - inputColor: MzanziInnovationHub.of(context)! - .theme - .primaryColor(), - controller: locationController, - multiLineInput: false, - requiredText: true, - hintText: "GPS Location", + width: 100, + child: Text( + "Set", + style: TextStyle( + color: MzanziInnovationHub.of(context)! + .theme + .primaryColor(), + fontSize: 20, + fontWeight: FontWeight.bold, + ), + ), + ), + ], + ), + const SizedBox(height: 15.0), + //const SizedBox(height: 15.0), + const Center( + child: Text( + "My Business User", + style: TextStyle( + fontWeight: FontWeight.bold, + fontSize: 22, ), ), - const SizedBox(width: 10.0), - MihButton( + ), + Divider( + color: MzanziInnovationHub.of(context)! + .theme + .secondaryColor()), + const SizedBox(height: 10.0), + MIHDropdownField( + controller: titleController, + hintText: "Title", + dropdownOptions: const ["Doctor", "Assistant"], + required: true, + editable: true, + enableSearch: false, + ), + const SizedBox(height: 10.0), + MihTextFormField( + fillColor: MzanziInnovationHub.of(context)! + .theme + .secondaryColor(), + inputColor: MzanziInnovationHub.of(context)! + .theme + .primaryColor(), + controller: fnameController, + multiLineInput: false, + requiredText: true, + hintText: "First Name", + validator: (value) { + return MihValidationServices().isEmpty(value); + }, + ), + const SizedBox(height: 10.0), + MihTextFormField( + fillColor: MzanziInnovationHub.of(context)! + .theme + .secondaryColor(), + inputColor: MzanziInnovationHub.of(context)! + .theme + .primaryColor(), + controller: lnameController, + multiLineInput: false, + requiredText: true, + hintText: "Surname", + validator: (value) { + return MihValidationServices().isEmpty(value); + }, + ), + const SizedBox(height: 15.0), + MIHDropdownField( + controller: accessController, + hintText: "Access", + dropdownOptions: const ["Full", "Partial"], + required: true, + editable: false, + enableSearch: false, + ), + const SizedBox(height: 20.0), + Center( + child: MihButton( onPressed: () { - MIHLocationAPI() - .getGPSPosition(context) - .then((position) { - if (position != null) { - setState(() { - locationController.text = - "${position.latitude}, ${position.longitude}"; - }); - } - }); + if (_formKey.currentState!.validate()) { + submitForm(); + } }, buttonColor: MzanziInnovationHub.of(context)! .theme .secondaryColor(), - width: 100, + width: 300, child: Text( - "Set", + "Add", style: TextStyle( color: MzanziInnovationHub.of(context)! .theme @@ -489,98 +589,11 @@ class _ProfileBusinessAddState extends State { ), ), ), - ], - ), - const SizedBox(height: 15.0), - //const SizedBox(height: 15.0), - const Center( - child: Text( - "My Business User", - style: TextStyle( - fontWeight: FontWeight.bold, - fontSize: 22, - ), ), - ), - Divider( - color: MzanziInnovationHub.of(context)! - .theme - .secondaryColor()), - const SizedBox(height: 10.0), - MIHDropdownField( - controller: titleController, - hintText: "Title", - dropdownOptions: const ["Doctor", "Assistant"], - required: true, - editable: true, - enableSearch: false, - ), - const SizedBox(height: 10.0), - MihTextFormField( - fillColor: MzanziInnovationHub.of(context)! - .theme - .secondaryColor(), - inputColor: - MzanziInnovationHub.of(context)!.theme.primaryColor(), - controller: fnameController, - multiLineInput: false, - requiredText: true, - hintText: "First Name", - validator: (value) { - return MihValidationServices().isEmpty(value); - }, - ), - const SizedBox(height: 10.0), - MihTextFormField( - fillColor: MzanziInnovationHub.of(context)! - .theme - .secondaryColor(), - inputColor: - MzanziInnovationHub.of(context)!.theme.primaryColor(), - controller: lnameController, - multiLineInput: false, - requiredText: true, - hintText: "Surname", - validator: (value) { - return MihValidationServices().isEmpty(value); - }, - ), - const SizedBox(height: 15.0), - MIHDropdownField( - controller: accessController, - hintText: "Access", - dropdownOptions: const ["Full", "Partial"], - required: true, - editable: false, - enableSearch: false, - ), - const SizedBox(height: 20.0), - Center( - child: MihButton( - onPressed: () { - if (_formKey.currentState!.validate()) { - submitForm(); - } - }, - buttonColor: MzanziInnovationHub.of(context)! - .theme - .secondaryColor(), - width: 300, - child: Text( - "Add", - style: TextStyle( - color: MzanziInnovationHub.of(context)! - .theme - .primaryColor(), - fontSize: 20, - fontWeight: FontWeight.bold, - ), - ), - ), - ), - ], - ), - ], + ], + ), + ], + ), ), ), ), @@ -626,11 +639,12 @@ class _ProfileBusinessAddState extends State { @override Widget build(BuildContext context) { + double screenWidth = MediaQuery.of(context).size.width; return MIHLayoutBuilder( actionButton: getActionButton(), secondaryActionButton: null, header: getHeader(), - body: getBody(), + body: getBody(screenWidth), actionDrawer: null, secondaryActionDrawer: null, bottomNavBar: null, From 2cd074f230a6048198ec5fae502ec09c695a23da Mon Sep 17 00:00:00 2001 From: Yasien Mac Mini Date: Fri, 6 Jun 2025 12:26:47 +0200 Subject: [PATCH 43/52] remove wrap from settings --- .../package_tools/mih_personal_settings.dart | 56 ++++++++----------- 1 file changed, 23 insertions(+), 33 deletions(-) diff --git a/Frontend/lib/mih_packages/mzansi_profile/personal_profile/package_tools/mih_personal_settings.dart b/Frontend/lib/mih_packages/mzansi_profile/personal_profile/package_tools/mih_personal_settings.dart index f9a7739a..4da80cf9 100644 --- a/Frontend/lib/mih_packages/mzansi_profile/personal_profile/package_tools/mih_personal_settings.dart +++ b/Frontend/lib/mih_packages/mzansi_profile/personal_profile/package_tools/mih_personal_settings.dart @@ -118,40 +118,30 @@ class _MihPersonalSettingsState extends State { ), ), const SizedBox(height: 10.0), - Wrap( - spacing: 10, - runSpacing: 10, - alignment: WrapAlignment.center, - crossAxisAlignment: WrapCrossAlignment.center, - children: [ - Text( - "Would you like to delete your MIH account?", - textAlign: TextAlign.center, - style: TextStyle( - fontSize: 18, - fontWeight: FontWeight.bold, - color: - MzanziInnovationHub.of(context)!.theme.secondaryColor(), - ), + Text( + "Would you like to delete your MIH account?", + textAlign: TextAlign.center, + style: TextStyle( + fontSize: 18, + fontWeight: FontWeight.bold, + color: MzanziInnovationHub.of(context)!.theme.secondaryColor(), + ), + ), + const SizedBox(height: 10.0), + MihButton( + onPressed: () { + deleteAccountPopUp(context); + }, + buttonColor: MzanziInnovationHub.of(context)!.theme.errorColor(), + width: 300, + child: Text( + "Delete Account", + style: TextStyle( + color: MzanziInnovationHub.of(context)!.theme.primaryColor(), + fontSize: 20, + fontWeight: FontWeight.bold, ), - MihButton( - onPressed: () { - deleteAccountPopUp(context); - }, - buttonColor: - MzanziInnovationHub.of(context)!.theme.errorColor(), - width: 300, - child: Text( - "Delete Account", - style: TextStyle( - color: - MzanziInnovationHub.of(context)!.theme.primaryColor(), - fontSize: 20, - fontWeight: FontWeight.bold, - ), - ), - ), - ], + ), ), ], ), From b6183f2a5dec195f0f63ecc2b2adedb7bbd31866 Mon Sep 17 00:00:00 2001 From: Yasien Mac Mini Date: Fri, 6 Jun 2025 12:35:11 +0200 Subject: [PATCH 44/52] fix wallet padding --- .../builder/build_loyalty_card_list.dart | 166 ++++----- .../package_tools/mih_cards.dart | 325 +++++++++--------- 2 files changed, 256 insertions(+), 235 deletions(-) diff --git a/Frontend/lib/mih_packages/mzansi_wallet/builder/build_loyalty_card_list.dart b/Frontend/lib/mih_packages/mzansi_wallet/builder/build_loyalty_card_list.dart index a972ca49..07ba37ae 100644 --- a/Frontend/lib/mih_packages/mzansi_wallet/builder/build_loyalty_card_list.dart +++ b/Frontend/lib/mih_packages/mzansi_wallet/builder/build_loyalty_card_list.dart @@ -43,7 +43,7 @@ class _BuildLoyaltyCardListState extends State { ); } - void editCardWindow(BuildContext ctxt, int index) { + void editCardWindow(BuildContext ctxt, int index, double width) { showDialog( context: context, barrierDismissible: false, @@ -55,56 +55,95 @@ class _BuildLoyaltyCardListState extends State { _nicknameController.clear(); Navigator.pop(context); }, - windowBody: Column( - children: [ - MihForm( - formKey: _formKey, - formFields: [ - MihTextFormField( - fillColor: - MzanziInnovationHub.of(context)!.theme.secondaryColor(), - inputColor: - MzanziInnovationHub.of(context)!.theme.primaryColor(), - controller: _nicknameController, - multiLineInput: false, - requiredText: false, - hintText: "Card Title", - ), - const SizedBox(height: 10), - Row( - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.end, - mainAxisSize: MainAxisSize.max, - children: [ - Flexible( - child: MihTextFormField( - fillColor: MzanziInnovationHub.of(context)! + windowBody: Padding( + padding: + MzanziInnovationHub.of(context)!.theme.screenType == "desktop" + ? EdgeInsets.symmetric(horizontal: width * 0.05) + : EdgeInsets.symmetric(horizontal: width * 0), + child: Column( + children: [ + MihForm( + formKey: _formKey, + formFields: [ + MihTextFormField( + fillColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + inputColor: + MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: _nicknameController, + multiLineInput: false, + requiredText: false, + hintText: "Card Title", + ), + const SizedBox(height: 10), + Row( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.end, + mainAxisSize: MainAxisSize.max, + children: [ + Flexible( + child: MihTextFormField( + fillColor: MzanziInnovationHub.of(context)! + .theme + .secondaryColor(), + inputColor: MzanziInnovationHub.of(context)! + .theme + .primaryColor(), + controller: _cardNumberController, + multiLineInput: false, + requiredText: true, + hintText: "Card Number", + numberMode: true, + validator: (value) { + return MihValidationServices().isEmpty(value); + }, + ), + ), + const SizedBox(width: 20), + MihButton( + onPressed: () { + openscanner(); + }, + buttonColor: MzanziInnovationHub.of(context)! .theme .secondaryColor(), - inputColor: MzanziInnovationHub.of(context)! - .theme - .primaryColor(), - controller: _cardNumberController, - multiLineInput: false, - requiredText: true, - hintText: "Card Number", - numberMode: true, - validator: (value) { - return MihValidationServices().isEmpty(value); - }, + width: 100, + child: Text( + "Scan", + style: TextStyle( + color: MzanziInnovationHub.of(context)! + .theme + .primaryColor(), + fontSize: 20, + fontWeight: FontWeight.bold, + ), + ), ), - ), - const SizedBox(width: 20), - MihButton( + ], + ), + const SizedBox(height: 15), + Center( + child: MihButton( onPressed: () { - openscanner(); + if (_formKey.currentState!.validate()) { + MIHMzansiWalletApis.updateLoyaltyCardAPICall( + widget.signedInUser, + widget.cardList[index].idloyalty_cards, + widget.cardList[index].favourite, + widget.cardList[index].priority_index, + _nicknameController.text, + _cardNumberController.text, + 0, + ctxt, + ); + } }, buttonColor: MzanziInnovationHub.of(context)! .theme .secondaryColor(), - width: 100, + width: 300, child: Text( - "Scan", + "Update", style: TextStyle( color: MzanziInnovationHub.of(context)! .theme @@ -114,40 +153,11 @@ class _BuildLoyaltyCardListState extends State { ), ), ), - ], - ), - const SizedBox(height: 15), - MihButton( - onPressed: () { - if (_formKey.currentState!.validate()) { - MIHMzansiWalletApis.updateLoyaltyCardAPICall( - widget.signedInUser, - widget.cardList[index].idloyalty_cards, - widget.cardList[index].favourite, - widget.cardList[index].priority_index, - _nicknameController.text, - _cardNumberController.text, - 0, - ctxt, - ); - } - }, - buttonColor: - MzanziInnovationHub.of(context)!.theme.secondaryColor(), - width: 300, - child: Text( - "Update", - style: TextStyle( - color: - MzanziInnovationHub.of(context)!.theme.primaryColor(), - fontSize: 20, - fontWeight: FontWeight.bold, - ), ), - ), - ], - ), - ], + ], + ), + ], + ), ), ), ); @@ -290,7 +300,7 @@ class _BuildLoyaltyCardListState extends State { ); } - void viewCardWindow(int index) { + void viewCardWindow(int index, double width) { //print(widget.cardList[index].card_number); String formattedCardNumber = ""; for (int i = 0; i <= widget.cardList[index].card_number.length - 1; i++) { @@ -356,7 +366,7 @@ class _BuildLoyaltyCardListState extends State { _cardNumberController.text = widget.cardList[index].card_number; _nicknameController.text = widget.cardList[index].nickname; }); - editCardWindow(context, index); + editCardWindow(context, index, width); }, ), SpeedDialChild( @@ -500,7 +510,7 @@ class _BuildLoyaltyCardListState extends State { height: 100, ), onTap: () { - viewCardWindow(index); + viewCardWindow(index, size.width); }, ); }, diff --git a/Frontend/lib/mih_packages/mzansi_wallet/package_tools/mih_cards.dart b/Frontend/lib/mih_packages/mzansi_wallet/package_tools/mih_cards.dart index de1d50d0..7378d781 100644 --- a/Frontend/lib/mih_packages/mzansi_wallet/package_tools/mih_cards.dart +++ b/Frontend/lib/mih_packages/mzansi_wallet/package_tools/mih_cards.dart @@ -83,7 +83,7 @@ class _MihCardsState extends State { } } - void addCardWindow(BuildContext ctxt) { + void addCardWindow(BuildContext ctxt, double width) { showDialog( context: context, barrierDismissible: false, @@ -97,127 +97,178 @@ class _MihCardsState extends State { shopName.value = ""; Navigator.pop(context); }, - windowBody: Column( - children: [ - MihForm( - formKey: _formKey, - formFields: [ - MIHDropdownField( - controller: shopController, - hintText: "Shop Name", - dropdownOptions: const [ - "+More", - "Apple Tree", - "Auchan", - "Best Before", - "Big Save", - "Boxer", - "BP", - "Builders Warehouse", - "Checkers", - "Choppies", - "Clicks", - "Continente", - "Cotton:On", - "Carrefour", - "Dis-Chem", - "Edgars", - "Eskom", - "Exclusive Books", - "Fresh Stop", - "Fresmart", - "Infinity", - "Jet", - "Justrite", - "Kero", - "Leroy Merlin", - "Makro", - "Naivas", - "OK Foods", - "Panarottis", - "Pick n Pay", - "PnA", - "PQ Clothing", - "Rage", - "Sefalana", - "Sasol", - "Shell", - "Shoprite", - "Signature Cosmetics & Fragrances", - "Spar", - "Spur", - "TFG Group", - "Toys R Us", - "Woermann Brock", - "Woolworths" - ], - required: true, - editable: true, - enableSearch: false, - ), - ValueListenableBuilder( - valueListenable: shopName, - builder: (BuildContext context, String value, Widget? child) { - return Visibility( - visible: value != "", - child: Column( - children: [ - const SizedBox(height: 10), - MihCardDisplay( - shopName: shopName.value, - nickname: "", - height: 200), - ], + windowBody: Padding( + padding: + MzanziInnovationHub.of(context)!.theme.screenType == "desktop" + ? EdgeInsets.symmetric(horizontal: width * 0.05) + : EdgeInsets.symmetric(horizontal: width * 0), + child: Column( + children: [ + MihForm( + formKey: _formKey, + formFields: [ + MIHDropdownField( + controller: shopController, + hintText: "Shop Name", + dropdownOptions: const [ + "+More", + "Apple Tree", + "Auchan", + "Best Before", + "Big Save", + "Boxer", + "BP", + "Builders Warehouse", + "Checkers", + "Choppies", + "Clicks", + "Continente", + "Cotton:On", + "Carrefour", + "Dis-Chem", + "Edgars", + "Eskom", + "Exclusive Books", + "Fresh Stop", + "Fresmart", + "Infinity", + "Jet", + "Justrite", + "Kero", + "Leroy Merlin", + "Makro", + "Naivas", + "OK Foods", + "Panarottis", + "Pick n Pay", + "PnA", + "PQ Clothing", + "Rage", + "Sefalana", + "Sasol", + "Shell", + "Shoprite", + "Signature Cosmetics & Fragrances", + "Spar", + "Spur", + "TFG Group", + "Toys R Us", + "Woermann Brock", + "Woolworths" + ], + required: true, + editable: true, + enableSearch: false, + ), + ValueListenableBuilder( + valueListenable: shopName, + builder: + (BuildContext context, String value, Widget? child) { + return Visibility( + visible: value != "", + child: Column( + children: [ + const SizedBox(height: 10), + MihCardDisplay( + shopName: shopName.value, + nickname: "", + height: 200), + ], + ), + ); + }, + ), + const SizedBox(height: 10), + MihTextFormField( + fillColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + inputColor: + MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: _nicknameController, + multiLineInput: false, + requiredText: false, + hintText: "Card Title", + ), + const SizedBox(height: 10), + Row( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.end, + mainAxisSize: MainAxisSize.max, + children: [ + Flexible( + child: MihTextFormField( + fillColor: MzanziInnovationHub.of(context)! + .theme + .secondaryColor(), + inputColor: MzanziInnovationHub.of(context)! + .theme + .primaryColor(), + controller: cardNumberController, + multiLineInput: false, + requiredText: true, + hintText: "Card Number", + numberMode: true, + validator: (value) { + return MihValidationServices().isEmpty(value); + }, + ), ), - ); - }, - ), - const SizedBox(height: 10), - MihTextFormField( - fillColor: - MzanziInnovationHub.of(context)!.theme.secondaryColor(), - inputColor: - MzanziInnovationHub.of(context)!.theme.primaryColor(), - controller: _nicknameController, - multiLineInput: false, - requiredText: false, - hintText: "Card Title", - ), - const SizedBox(height: 10), - Row( - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.end, - mainAxisSize: MainAxisSize.max, - children: [ - Flexible( - child: MihTextFormField( - fillColor: MzanziInnovationHub.of(context)! + const SizedBox(width: 20), + MihButton( + onPressed: () { + openscanner(); + }, + buttonColor: MzanziInnovationHub.of(context)! .theme .secondaryColor(), - inputColor: MzanziInnovationHub.of(context)! - .theme - .primaryColor(), - controller: cardNumberController, - multiLineInput: false, - requiredText: true, - hintText: "Card Number", - numberMode: true, - validator: (value) { - return MihValidationServices().isEmpty(value); - }, + width: 100, + child: Text( + "Scan", + style: TextStyle( + color: MzanziInnovationHub.of(context)! + .theme + .primaryColor(), + fontSize: 20, + fontWeight: FontWeight.bold, + ), + ), ), - ), - const SizedBox(width: 20), - MihButton( + ], + ), + const SizedBox(height: 15), + Center( + child: MihButton( onPressed: () { - openscanner(); + if (_formKey.currentState!.validate()) { + if (shopController.text == "") { + showDialog( + context: context, + builder: (context) { + return const MIHErrorMessage( + errorType: "Input Error"); + }, + ); + } else { + MIHMzansiWalletApis.addLoyaltyCardAPICall( + widget.signedInUser, + widget.signedInUser.app_id, + shopController.text, + cardNumberController.text, + "", + 0, + _nicknameController.text, + 0, + context, + ); + } + } }, buttonColor: MzanziInnovationHub.of(context)! .theme .secondaryColor(), - width: 100, + width: 300, child: Text( - "Scan", + "Add", style: TextStyle( color: MzanziInnovationHub.of(context)! .theme @@ -227,51 +278,11 @@ class _MihCardsState extends State { ), ), ), - ], - ), - const SizedBox(height: 15), - MihButton( - onPressed: () { - if (_formKey.currentState!.validate()) { - if (shopController.text == "") { - showDialog( - context: context, - builder: (context) { - return const MIHErrorMessage( - errorType: "Input Error"); - }, - ); - } else { - MIHMzansiWalletApis.addLoyaltyCardAPICall( - widget.signedInUser, - widget.signedInUser.app_id, - shopController.text, - cardNumberController.text, - "", - 0, - _nicknameController.text, - 0, - context, - ); - } - } - }, - buttonColor: - MzanziInnovationHub.of(context)!.theme.secondaryColor(), - width: 300, - child: Text( - "Add", - style: TextStyle( - color: - MzanziInnovationHub.of(context)!.theme.primaryColor(), - fontSize: 20, - fontWeight: FontWeight.bold, - ), ), - ), - ], - ), - ], + ], + ), + ], + ), ), ), ); @@ -388,7 +399,7 @@ class _MihCardsState extends State { backgroundColor: MzanziInnovationHub.of(context)!.theme.successColor(), onTap: () { - addCardWindow(context); + addCardWindow(context, width); }, ) ]), From c475b81e339f6d8b2bc0e3df9a4259350b138465 Mon Sep 17 00:00:00 2001 From: Yasien Mac Mini Date: Fri, 6 Jun 2025 12:39:20 +0200 Subject: [PATCH 45/52] remove unsued functions --- .../build_mih_patient_search_list.dart | 124 ------------------ 1 file changed, 124 deletions(-) diff --git a/Frontend/lib/mih_packages/patient_profile/pat_manager/list_builders/build_mih_patient_search_list.dart b/Frontend/lib/mih_packages/patient_profile/pat_manager/list_builders/build_mih_patient_search_list.dart index e80e97b0..0601d4c0 100644 --- a/Frontend/lib/mih_packages/patient_profile/pat_manager/list_builders/build_mih_patient_search_list.dart +++ b/Frontend/lib/mih_packages/patient_profile/pat_manager/list_builders/build_mih_patient_search_list.dart @@ -3,10 +3,7 @@ import 'dart:convert'; import 'package:mzansi_innovation_hub/main.dart'; import 'package:mzansi_innovation_hub/mih_apis/mih_api_calls.dart'; import 'package:mzansi_innovation_hub/mih_apis/mih_validation_services.dart'; -import 'package:mzansi_innovation_hub/mih_components/mih_inputs_and_buttons/mih_date_input.dart'; -import 'package:mzansi_innovation_hub/mih_components/mih_inputs_and_buttons/mih_time_input.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_button.dart'; -import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_form.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package_window.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_text_form_field.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_pop_up_messages/mih_error_message.dart'; @@ -49,7 +46,6 @@ class _BuildPatientsListState extends State { TextEditingController lnameController = TextEditingController(); TextEditingController accessStatusController = TextEditingController(); final baseAPI = AppEnviroment.baseApiUrl; - final _formKey = GlobalKey(); Future addPatientAccessAPICall(int index) async { var response = await http.post( @@ -156,126 +152,6 @@ class _BuildPatientsListState extends State { } } - void appointmentPopUp(int index) { - var firstLetterFName = widget.patients[index].first_name[0]; - var firstLetterLName = widget.patients[index].last_name[0]; - var fnameStar = '*' * 8; - var lnameStar = '*' * 8; - - setState(() { - idController.text = widget.patients[index].id_no; - fnameController.text = firstLetterFName + fnameStar; - lnameController.text = firstLetterLName + lnameStar; - }); - showDialog( - context: context, - barrierDismissible: false, - builder: (context) => MihPackageWindow( - fullscreen: false, - windowTitle: "Patient Appointment", - onWindowTapClose: () { - Navigator.pop(context); - }, - windowBody: Column( - children: [ - MihForm( - formKey: _formKey, - formFields: [ - MihTextFormField( - fillColor: - MzanziInnovationHub.of(context)!.theme.secondaryColor(), - inputColor: - MzanziInnovationHub.of(context)!.theme.primaryColor(), - controller: idController, - multiLineInput: false, - requiredText: true, - readOnly: true, - hintText: "ID No.", - validator: (value) { - return MihValidationServices().isEmpty(value); - }, - ), - const SizedBox(height: 10.0), - MihTextFormField( - fillColor: - MzanziInnovationHub.of(context)!.theme.secondaryColor(), - inputColor: - MzanziInnovationHub.of(context)!.theme.primaryColor(), - controller: fnameController, - multiLineInput: false, - requiredText: true, - readOnly: true, - hintText: "First Name", - validator: (value) { - return MihValidationServices().isEmpty(value); - }, - ), - const SizedBox(height: 10.0), - MihTextFormField( - fillColor: - MzanziInnovationHub.of(context)!.theme.secondaryColor(), - inputColor: - MzanziInnovationHub.of(context)!.theme.primaryColor(), - controller: lnameController, - multiLineInput: false, - requiredText: true, - readOnly: true, - hintText: "Surname", - validator: (value) { - return MihValidationServices().isEmpty(value); - }, - ), - const SizedBox(height: 10.0), - MIHDateField( - controller: dateController, - lableText: "Date", - required: true, - ), - const SizedBox(height: 10.0), - MIHTimeField( - controller: timeController, - lableText: "Time", - required: true, - ), - const SizedBox(height: 30.0), - MihButton( - onPressed: () { - bool filled = isAppointmentFieldsFilled(); - if (filled) { - //print("here2"); - submitApointment(index); - //print("here3"); - } else { - showDialog( - context: context, - builder: (context) { - return const MIHErrorMessage( - errorType: "Input Error"); - }, - ); - } - }, - buttonColor: - MzanziInnovationHub.of(context)!.theme.secondaryColor(), - width: 300, - child: Text( - "Book", - style: TextStyle( - color: - MzanziInnovationHub.of(context)!.theme.primaryColor(), - fontSize: 20, - fontWeight: FontWeight.bold, - ), - ), - ), - ], - ), - ], - ), - ), - ); - } - void noAccessWarning() { showDialog( context: context, From 2db045cc2ebb94a1a241afc14ee3ccf98e54c8fc Mon Sep 17 00:00:00 2001 From: Yasien Mac Mini Date: Fri, 6 Jun 2025 12:39:25 +0200 Subject: [PATCH 46/52] . --- .../build_mih_patient_search_list.dart | 21 ------------------- 1 file changed, 21 deletions(-) diff --git a/Frontend/lib/mih_packages/patient_profile/pat_manager/list_builders/build_mih_patient_search_list.dart b/Frontend/lib/mih_packages/patient_profile/pat_manager/list_builders/build_mih_patient_search_list.dart index 0601d4c0..ad385451 100644 --- a/Frontend/lib/mih_packages/patient_profile/pat_manager/list_builders/build_mih_patient_search_list.dart +++ b/Frontend/lib/mih_packages/patient_profile/pat_manager/list_builders/build_mih_patient_search_list.dart @@ -131,27 +131,6 @@ class _BuildPatientsListState extends State { ); } - void submitApointment(int index) { - //To-Do: Implement the appointment submission - print("To-do: Implement the appointment submission"); - // MIHApiCalls.addAppointmentAPICall( - // widget.business!.business_id, - // widget.patients[index].app_id, - // dateController.text, - // timeController.text, - // widget.arguments, - // context, - // ); - } - - bool isAppointmentFieldsFilled() { - if (dateController.text.isEmpty || timeController.text.isEmpty) { - return false; - } else { - return true; - } - } - void noAccessWarning() { showDialog( context: context, From 52bf4ed1b6e7d76e5691066ecf60ae1f65b9984f Mon Sep 17 00:00:00 2001 From: Yasien Mac Mini Date: Fri, 6 Jun 2025 13:15:47 +0200 Subject: [PATCH 47/52] fix pat man padding --- .../build_my_patient_list_list.dart | 411 +++++++++--------- .../package_tools/waiting_room.dart | 168 +++---- 2 files changed, 303 insertions(+), 276 deletions(-) diff --git a/Frontend/lib/mih_packages/patient_profile/pat_manager/list_builders/build_my_patient_list_list.dart b/Frontend/lib/mih_packages/patient_profile/pat_manager/list_builders/build_my_patient_list_list.dart index eb4661ff..216583a6 100644 --- a/Frontend/lib/mih_packages/patient_profile/pat_manager/list_builders/build_my_patient_list_list.dart +++ b/Frontend/lib/mih_packages/patient_profile/pat_manager/list_builders/build_my_patient_list_list.dart @@ -79,10 +79,9 @@ class _BuildPatientsListState extends State { } } - void appointmentPopUp(int index) { + void appointmentPopUp(int index, double width) { var firstLetterFName = widget.patientAccesses[index].fname; var firstLetterLName = widget.patientAccesses[index].lname; - setState(() { idController.text = widget.patientAccesses[index].id_no; fnameController.text = firstLetterFName; @@ -97,104 +96,111 @@ class _BuildPatientsListState extends State { onWindowTapClose: () { Navigator.pop(context); }, - windowBody: Column( - children: [ - MihForm( - formKey: _formKey, - formFields: [ - MihTextFormField( - fillColor: - MzanziInnovationHub.of(context)!.theme.secondaryColor(), - inputColor: - MzanziInnovationHub.of(context)!.theme.primaryColor(), - controller: idController, - multiLineInput: false, - requiredText: true, - readOnly: true, - hintText: "ID No.", - validator: (value) { - return MihValidationServices().isEmpty(value); - }, - ), - const SizedBox(height: 10.0), - MihTextFormField( - fillColor: - MzanziInnovationHub.of(context)!.theme.secondaryColor(), - inputColor: - MzanziInnovationHub.of(context)!.theme.primaryColor(), - controller: fnameController, - multiLineInput: false, - requiredText: true, - readOnly: true, - hintText: "First Name", - validator: (value) { - return MihValidationServices().isEmpty(value); - }, - ), - const SizedBox(height: 10.0), - MihTextFormField( - fillColor: - MzanziInnovationHub.of(context)!.theme.secondaryColor(), - inputColor: - MzanziInnovationHub.of(context)!.theme.primaryColor(), - controller: lnameController, - multiLineInput: false, - requiredText: true, - readOnly: true, - hintText: "Surname", - validator: (value) { - return MihValidationServices().isEmpty(value); - }, - ), - const SizedBox(height: 10.0), - MIHDateField( - controller: dateController, - lableText: "Date", - required: true, - ), - const SizedBox(height: 10.0), - MIHTimeField( - controller: timeController, - lableText: "Time", - required: true, - ), - const SizedBox(height: 30.0), - Center( - child: MihButton( - onPressed: () { - if (_formKey.currentState!.validate()) { - bool filled = isAppointmentFieldsFilled(); - if (filled) { - submitApointment(index); - } else { - showDialog( - context: context, - builder: (context) { - return const MIHErrorMessage( - errorType: "Input Error"); - }, - ); - } - } - }, - buttonColor: + windowBody: Padding( + padding: + MzanziInnovationHub.of(context)!.theme.screenType == "desktop" + ? EdgeInsets.symmetric(horizontal: width * 0.056) + : const EdgeInsets.symmetric(horizontal: 0), + child: Column( + children: [ + MihForm( + formKey: _formKey, + formFields: [ + MihTextFormField( + fillColor: MzanziInnovationHub.of(context)!.theme.secondaryColor(), - width: 300, - child: Text( - "Book Appointment", - style: TextStyle( - color: MzanziInnovationHub.of(context)! - .theme - .primaryColor(), - fontSize: 20, - fontWeight: FontWeight.bold, + inputColor: + MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: idController, + multiLineInput: false, + requiredText: true, + readOnly: true, + hintText: "ID No.", + validator: (value) { + return MihValidationServices().isEmpty(value); + }, + ), + const SizedBox(height: 10.0), + MihTextFormField( + fillColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + inputColor: + MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: fnameController, + multiLineInput: false, + requiredText: true, + readOnly: true, + hintText: "First Name", + validator: (value) { + return MihValidationServices().isEmpty(value); + }, + ), + const SizedBox(height: 10.0), + MihTextFormField( + fillColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + inputColor: + MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: lnameController, + multiLineInput: false, + requiredText: true, + readOnly: true, + hintText: "Surname", + validator: (value) { + return MihValidationServices().isEmpty(value); + }, + ), + const SizedBox(height: 10.0), + MIHDateField( + controller: dateController, + lableText: "Date", + required: true, + ), + const SizedBox(height: 10.0), + MIHTimeField( + controller: timeController, + lableText: "Time", + required: true, + ), + const SizedBox(height: 30.0), + Center( + child: MihButton( + onPressed: () { + if (_formKey.currentState!.validate()) { + bool filled = isAppointmentFieldsFilled(); + if (filled) { + submitApointment(index); + } else { + showDialog( + context: context, + builder: (context) { + return const MIHErrorMessage( + errorType: "Input Error"); + }, + ); + } + } + }, + buttonColor: MzanziInnovationHub.of(context)! + .theme + .secondaryColor(), + width: 300, + child: Text( + "Book Appointment", + style: TextStyle( + color: MzanziInnovationHub.of(context)! + .theme + .primaryColor(), + fontSize: 20, + fontWeight: FontWeight.bold, + ), ), ), ), - ), - ], - ), - ], + ], + ), + ], + ), ), ), ); @@ -229,10 +235,10 @@ class _BuildPatientsListState extends State { return hasAccess; } - void patientProfileChoicePopUp(int index, Patient? patientProfile) async { + void patientProfileChoicePopUp( + int index, Patient? patientProfile, double width) async { var firstLetterFName = widget.patientAccesses[index].fname; var firstLetterLName = widget.patientAccesses[index].lname; - setState(() { idController.text = widget.patientAccesses[index].id_no; fnameController.text = firstLetterFName; @@ -247,109 +253,119 @@ class _BuildPatientsListState extends State { onWindowTapClose: () { Navigator.pop(context); }, - windowBody: Column( - children: [ - MihTextFormField( - fillColor: - MzanziInnovationHub.of(context)!.theme.secondaryColor(), - inputColor: MzanziInnovationHub.of(context)!.theme.primaryColor(), - controller: idController, - multiLineInput: false, - requiredText: true, - readOnly: true, - hintText: "ID No.", - validator: (value) { - return MihValidationServices().isEmpty(value); - }, - ), - const SizedBox(height: 10.0), - MihTextFormField( - fillColor: - MzanziInnovationHub.of(context)!.theme.secondaryColor(), - inputColor: MzanziInnovationHub.of(context)!.theme.primaryColor(), - controller: fnameController, - multiLineInput: false, - requiredText: true, - readOnly: true, - hintText: "First Name", - validator: (value) { - return MihValidationServices().isEmpty(value); - }, - ), - const SizedBox(height: 10.0), - MihTextFormField( - fillColor: - MzanziInnovationHub.of(context)!.theme.secondaryColor(), - inputColor: MzanziInnovationHub.of(context)!.theme.primaryColor(), - controller: lnameController, - multiLineInput: false, - requiredText: true, - readOnly: true, - hintText: "Surname", - validator: (value) { - return MihValidationServices().isEmpty(value); - }, - ), - const SizedBox(height: 30.0), - Center( - child: Wrap( - runSpacing: 10, - spacing: 10, - children: [ - MihButton( - onPressed: () { - appointmentPopUp(index); - }, - buttonColor: - MzanziInnovationHub.of(context)!.theme.secondaryColor(), - width: 300, - child: Text( - "Book Appointment", - style: TextStyle( - color: MzanziInnovationHub.of(context)! - .theme - .primaryColor(), - fontSize: 20, - fontWeight: FontWeight.bold, - ), - ), - ), - MihButton( - onPressed: () { - Navigator.of(context) - .pushNamed('/patient-manager/patient', - arguments: PatientViewArguments( - widget.signedInUser, - patientProfile, - widget.businessUser, - widget.business, - "business", - )); - }, - buttonColor: - MzanziInnovationHub.of(context)!.theme.successColor(), - width: 300, - child: Text( - "View Medical Records", - style: TextStyle( - color: MzanziInnovationHub.of(context)! - .theme - .primaryColor(), - fontSize: 20, - fontWeight: FontWeight.bold, - ), - ), - ), - ], + windowBody: Padding( + padding: + MzanziInnovationHub.of(context)!.theme.screenType == "desktop" + ? EdgeInsets.symmetric(horizontal: width * 0.05) + : const EdgeInsets.symmetric(horizontal: 0), + child: Column( + children: [ + MihTextFormField( + fillColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + inputColor: + MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: idController, + multiLineInput: false, + requiredText: true, + readOnly: true, + hintText: "ID No.", + validator: (value) { + return MihValidationServices().isEmpty(value); + }, ), - ) - ], + const SizedBox(height: 10.0), + MihTextFormField( + fillColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + inputColor: + MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: fnameController, + multiLineInput: false, + requiredText: true, + readOnly: true, + hintText: "First Name", + validator: (value) { + return MihValidationServices().isEmpty(value); + }, + ), + const SizedBox(height: 10.0), + MihTextFormField( + fillColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + inputColor: + MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: lnameController, + multiLineInput: false, + requiredText: true, + readOnly: true, + hintText: "Surname", + validator: (value) { + return MihValidationServices().isEmpty(value); + }, + ), + const SizedBox(height: 30.0), + Center( + child: Wrap( + runSpacing: 10, + spacing: 10, + children: [ + MihButton( + onPressed: () { + appointmentPopUp(index, width); + }, + buttonColor: MzanziInnovationHub.of(context)! + .theme + .secondaryColor(), + width: 300, + child: Text( + "Book Appointment", + style: TextStyle( + color: MzanziInnovationHub.of(context)! + .theme + .primaryColor(), + fontSize: 20, + fontWeight: FontWeight.bold, + ), + ), + ), + MihButton( + onPressed: () { + Navigator.of(context) + .pushNamed('/patient-manager/patient', + arguments: PatientViewArguments( + widget.signedInUser, + patientProfile, + widget.businessUser, + widget.business, + "business", + )); + }, + buttonColor: + MzanziInnovationHub.of(context)!.theme.successColor(), + width: 300, + child: Text( + "View Medical Records", + style: TextStyle( + color: MzanziInnovationHub.of(context)! + .theme + .primaryColor(), + fontSize: 20, + fontWeight: FontWeight.bold, + ), + ), + ), + ], + ), + ) + ], + ), ), ), ); } - Widget displayMyPatientTile(int index) { + Widget displayMyPatientTile(int index, double width) { var firstName = ""; var lastName = ""; String access = widget.patientAccesses[index].status.toUpperCase(); @@ -407,7 +423,7 @@ class _BuildPatientsListState extends State { p = result; }); }); - patientProfileChoicePopUp(index, p); + patientProfileChoicePopUp(index, p, width); } else { noAccessWarning(index); } @@ -431,6 +447,7 @@ class _BuildPatientsListState extends State { @override Widget build(BuildContext context) { + double screenWidth = MediaQuery.of(context).size.width; return ListView.separated( shrinkWrap: true, physics: const NeverScrollableScrollPhysics(), @@ -441,7 +458,7 @@ class _BuildPatientsListState extends State { }, itemCount: widget.patientAccesses.length, itemBuilder: (context, index) { - return displayMyPatientTile(index); + return displayMyPatientTile(index, screenWidth); }, ); } diff --git a/Frontend/lib/mih_packages/patient_profile/pat_manager/package_tools/waiting_room.dart b/Frontend/lib/mih_packages/patient_profile/pat_manager/package_tools/waiting_room.dart index a66db041..ef2d2bd1 100644 --- a/Frontend/lib/mih_packages/patient_profile/pat_manager/package_tools/waiting_room.dart +++ b/Frontend/lib/mih_packages/patient_profile/pat_manager/package_tools/waiting_room.dart @@ -63,7 +63,7 @@ class _WaitingRoomState extends State { final _formKey = GlobalKey(); // Business Appointment Tool - Widget getBusinessAppointmentsTool() { + Widget getBusinessAppointmentsTool(double width) { return Stack( children: [ MihSingleChildScroll( @@ -139,7 +139,7 @@ class _WaitingRoomState extends State { MzanziInnovationHub.of(context)!.theme.successColor(), onTap: () { // addAppointmentWindow(); - appointmentTypeSelection(); + appointmentTypeSelection(width); }, ) ], @@ -205,7 +205,7 @@ class _WaitingRoomState extends State { ); } - void appointmentTypeSelection() { + void appointmentTypeSelection(double width) { String question = "What type of appointment would you like to add?"; question += "\n\nExisting Patient: Add an appointment for an patient your practice has access to."; @@ -276,7 +276,7 @@ class _WaitingRoomState extends State { MihButton( onPressed: () { Navigator.pop(context); - addAppointmentWindow(); + addAppointmentWindow(width); }, buttonColor: MzanziInnovationHub.of(context)!.theme.secondaryColor(), @@ -298,7 +298,7 @@ class _WaitingRoomState extends State { ); } - void addAppointmentWindow() { + void addAppointmentWindow(double width) { showDialog( context: context, barrierDismissible: false, @@ -314,83 +314,92 @@ class _WaitingRoomState extends State { _appointmentDescriptionIDController.clear(); _patientController.clear(); }, - windowBody: Column( - children: [ - MihForm( - formKey: _formKey, - formFields: [ - MihTextFormField( - fillColor: - MzanziInnovationHub.of(context)!.theme.secondaryColor(), - inputColor: - MzanziInnovationHub.of(context)!.theme.primaryColor(), - controller: _appointmentTitleController, - multiLineInput: false, - requiredText: true, - hintText: "Appointment Title", - validator: (value) { - return MihValidationServices().isEmpty(value); - }, - ), - const SizedBox(height: 10), - SizedBox( - // width: 500, - child: MIHDateField( - controller: _appointmentDateController, - lableText: "Date", - required: true, - ), - ), - const SizedBox(height: 10), - SizedBox( - // width: 500, - child: MIHTimeField( - controller: _appointmentTimeController, - lableText: "Time", - required: true, - ), - ), - const SizedBox(height: 10), - MihTextFormField( - height: 250, - fillColor: - MzanziInnovationHub.of(context)!.theme.secondaryColor(), - inputColor: - MzanziInnovationHub.of(context)!.theme.primaryColor(), - controller: _appointmentDescriptionIDController, - multiLineInput: true, - requiredText: true, - hintText: "Description", - validator: (value) { - return MihValidationServices().isEmpty(value); - }, - ), - const SizedBox(height: 20), - Center( - child: MihButton( - onPressed: () { - if (_formKey.currentState!.validate()) { - addAppointmentCall(); - } + windowBody: Padding( + padding: + MzanziInnovationHub.of(context)!.theme.screenType == "desktop" + ? EdgeInsets.symmetric(horizontal: width * 0.05) + : const EdgeInsets.symmetric(horizontal: 0), + child: Column( + children: [ + MihForm( + formKey: _formKey, + formFields: [ + MihTextFormField( + fillColor: MzanziInnovationHub.of(context)! + .theme + .secondaryColor(), + inputColor: + MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: _appointmentTitleController, + multiLineInput: false, + requiredText: true, + hintText: "Appointment Title", + validator: (value) { + return MihValidationServices().isEmpty(value); }, - buttonColor: - MzanziInnovationHub.of(context)!.theme.successColor(), - width: 300, - child: Text( - "Add", - style: TextStyle( - color: MzanziInnovationHub.of(context)! - .theme - .primaryColor(), - fontSize: 20, - fontWeight: FontWeight.bold, + ), + const SizedBox(height: 10), + SizedBox( + // width: 500, + child: MIHDateField( + controller: _appointmentDateController, + lableText: "Date", + required: true, + ), + ), + const SizedBox(height: 10), + SizedBox( + // width: 500, + child: MIHTimeField( + controller: _appointmentTimeController, + lableText: "Time", + required: true, + ), + ), + const SizedBox(height: 10), + MihTextFormField( + height: 250, + fillColor: MzanziInnovationHub.of(context)! + .theme + .secondaryColor(), + inputColor: + MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: _appointmentDescriptionIDController, + multiLineInput: true, + requiredText: true, + hintText: "Description", + validator: (value) { + return MihValidationServices().isEmpty(value); + }, + ), + const SizedBox(height: 20), + Center( + child: MihButton( + onPressed: () { + if (_formKey.currentState!.validate()) { + addAppointmentCall(); + } + }, + buttonColor: MzanziInnovationHub.of(context)! + .theme + .successColor(), + width: 300, + child: Text( + "Add", + style: TextStyle( + color: MzanziInnovationHub.of(context)! + .theme + .primaryColor(), + fontSize: 20, + fontWeight: FontWeight.bold, + ), ), ), ), - ), - ], - ), - ], + ], + ), + ], + ), ), ); }, @@ -477,9 +486,10 @@ class _WaitingRoomState extends State { @override Widget build(BuildContext context) { + double screenWidth = MediaQuery.of(context).size.width; return MihPackageToolBody( borderOn: false, - bodyItem: getBusinessAppointmentsTool(), + bodyItem: getBusinessAppointmentsTool(screenWidth), ); } } From 0cfe408bcea764509b9ffd1b87396cbefdd03133 Mon Sep 17 00:00:00 2001 From: Yasien Mac Mini Date: Fri, 6 Jun 2025 13:39:54 +0200 Subject: [PATCH 48/52] fix pat profile padding --- .../components/Claim_Statement_Window.dart | 576 +++++++++--------- .../package_tools/patient_consultation.dart | 289 ++++----- .../package_tools/patient_info.dart | 250 ++++---- .../pat_profile/patient_add.dart | 517 ++++++++-------- .../pat_profile/patient_edit.dart | 564 ++++++++--------- 5 files changed, 1093 insertions(+), 1103 deletions(-) diff --git a/Frontend/lib/mih_packages/patient_profile/pat_profile/components/Claim_Statement_Window.dart b/Frontend/lib/mih_packages/patient_profile/pat_profile/components/Claim_Statement_Window.dart index 3b846044..ffd6732e 100644 --- a/Frontend/lib/mih_packages/patient_profile/pat_profile/components/Claim_Statement_Window.dart +++ b/Frontend/lib/mih_packages/patient_profile/pat_profile/components/Claim_Statement_Window.dart @@ -82,292 +82,301 @@ class _ClaimStatementWindowState extends State { ); } - Widget getWindowBody() { - return Column( - children: [ - MihForm( - formKey: _formKey, - formFields: [ - MIHDropdownField( - controller: _docTypeController, - hintText: "Document Type", - dropdownOptions: const ["Claim", "Statement"], - required: true, - editable: true, - enableSearch: false, - ), - const SizedBox(height: 10), - Center( - child: Text( - "Service Details", - textAlign: TextAlign.center, - style: TextStyle( - fontSize: 25, - fontWeight: FontWeight.bold, - color: - MzanziInnovationHub.of(context)!.theme.secondaryColor(), - ), + Widget getWindowBody(double width) { + return Padding( + padding: MzanziInnovationHub.of(context)!.theme.screenType == "desktop" + ? EdgeInsets.symmetric(horizontal: width * 0.05) + : const EdgeInsets.symmetric(horizontal: 0), + child: Column( + children: [ + MihForm( + formKey: _formKey, + formFields: [ + MIHDropdownField( + controller: _docTypeController, + hintText: "Document Type", + dropdownOptions: const ["Claim", "Statement"], + required: true, + editable: true, + enableSearch: false, ), - ), - Divider( - color: MzanziInnovationHub.of(context)!.theme.secondaryColor()), - const SizedBox(height: 10), - MIHDateField( - controller: _serviceDateController, - lableText: "Date of Service", - required: true, - ), - const SizedBox(height: 10), - MIHDropdownField( - controller: _serviceDescController, - hintText: "Service Decription", - dropdownOptions: const [ - "Consultation", - "Procedure", - "Other", - ], - required: true, - editable: true, - enableSearch: false, - ), - const SizedBox(height: 10), - ValueListenableBuilder( - valueListenable: serviceDesc, - builder: (BuildContext context, String value, Widget? child) { - Widget returnWidget; - switch (value) { - case 'Consultation': - returnWidget = Column( - children: [ - SizedBox( - child: MIHDropdownField( - controller: _serviceDescOptionsController, - hintText: "Consultation Type", - dropdownOptions: const [ - "General Consultation", - "Follow-Up Consultation", - "Specialist Consultation", - "Emergency Consultation", - ], - required: true, - editable: true, - enableSearch: false, - ), - ), - const SizedBox(height: 10), - ], - ); - case 'Procedure': - returnWidget = Column( - children: [ - MihTextFormField( - fillColor: MzanziInnovationHub.of(context)! - .theme - .secondaryColor(), - inputColor: MzanziInnovationHub.of(context)! - .theme - .primaryColor(), - controller: _prcedureNameController, - multiLineInput: false, - requiredText: true, - hintText: "Procedure Name", - validator: (value) { - return MihValidationServices().isEmpty(value); - }, - ), - const SizedBox(height: 10), - MihTextFormField( - fillColor: MzanziInnovationHub.of(context)! - .theme - .secondaryColor(), - inputColor: MzanziInnovationHub.of(context)! - .theme - .primaryColor(), - controller: _proceedureAdditionalInfoController, - multiLineInput: false, - requiredText: true, - hintText: "Additional Information", - validator: (value) { - return MihValidationServices().isEmpty(value); - }, - ), - const SizedBox(height: 15), - ], - ); - case 'Other': - returnWidget = Column( - children: [ - MihTextFormField( - fillColor: MzanziInnovationHub.of(context)! - .theme - .secondaryColor(), - inputColor: MzanziInnovationHub.of(context)! - .theme - .primaryColor(), - controller: _serviceDescOptionsController, - multiLineInput: false, - requiredText: true, - hintText: "Service Description Details", - validator: (value) { - return MihValidationServices().isEmpty(value); - }, - ), - const SizedBox(height: 10), - ], - ); - default: - returnWidget = const SizedBox(); - } - return returnWidget; - }, - ), - Column( - children: [ - Align( - alignment: Alignment.centerLeft, - child: Text("ICD-10 Code & Description", - style: TextStyle( - fontSize: 15, - fontWeight: FontWeight.bold, - color: MzanziInnovationHub.of(context)! - .theme - .secondaryColor(), - )), - ), - const SizedBox(height: 4), - MihSearchBar( - controller: _icd10CodeController, - hintText: "ICD-10 Search", - prefixIcon: Icons.search, - fillColor: - MzanziInnovationHub.of(context)!.theme.secondaryColor(), - hintColor: - MzanziInnovationHub.of(context)!.theme.primaryColor(), - onPrefixIconTap: () { - MIHIcd10CodeApis.getIcd10Codes( - _icd10CodeController.text, context) - .then((result) { - icd10SearchWindow(result); - }); - }, - onClearIconTap: () { - _icd10CodeController.clear(); - }, - searchFocusNode: _searchFocusNode, - ), - ], - ), - const SizedBox(height: 10), - MihTextFormField( - fillColor: - MzanziInnovationHub.of(context)!.theme.secondaryColor(), - inputColor: MzanziInnovationHub.of(context)!.theme.primaryColor(), - controller: _amountController, - multiLineInput: false, - requiredText: true, - numberMode: true, - hintText: "Service Cost", - validator: (value) { - return MihValidationServices().isEmpty(value); - }, - ), - const SizedBox(height: 10), - Center( - child: Text( - "Additional Infomation", - textAlign: TextAlign.center, - style: TextStyle( - fontSize: 25, - fontWeight: FontWeight.bold, - color: - MzanziInnovationHub.of(context)!.theme.secondaryColor(), - ), - ), - ), - Divider( - color: MzanziInnovationHub.of(context)!.theme.secondaryColor()), - const SizedBox(height: 10), - MihTextFormField( - fillColor: - MzanziInnovationHub.of(context)!.theme.secondaryColor(), - inputColor: MzanziInnovationHub.of(context)!.theme.primaryColor(), - controller: _preauthNoController, - multiLineInput: false, - requiredText: false, - hintText: "Pre-authorisation No.", - ), - const SizedBox(height: 20), - Center( - child: MihButton( - onPressed: () { - if (_formKey.currentState!.validate()) { - if (isInputValid()) { - MIHClaimStatementGenerationApi().generateClaimStatement( - ClaimStatementGenerationArguments( - _docTypeController.text, - widget.selectedPatient.app_id, - _fullNameController.text, - _idController.text, - _medAidController.text, - _medAidNoController.text, - _medAidCodeController.text, - _medAidNameController.text, - _medAidSchemeController.text, - widget.business!.Name, - "*To-Be Added*", - widget.business!.contact_no, - widget.business!.bus_email, - _providerNameController.text, - _practiceNoController.text, - _vatNoController.text, - _serviceDateController.text, - _serviceDescController.text, - _serviceDescOptionsController.text, - _prcedureNameController.text, - _proceedureAdditionalInfoController.text, - _icd10CodeController.text, - _amountController.text, - _preauthNoController.text, - widget.business!.logo_path, - widget.businessUser!.sig_path, - ), - PatientViewArguments( - widget.signedInUser, - widget.selectedPatient, - widget.businessUser, - widget.business, - "business", - ), - widget.env, - context); - } else { - showDialog( - context: context, - builder: (context) { - return const MIHErrorMessage( - errorType: "Input Error"); - }, - ); - } - } - }, - buttonColor: - MzanziInnovationHub.of(context)!.theme.secondaryColor(), - width: 300, + const SizedBox(height: 10), + Center( child: Text( - "Generate", + "Service Details", + textAlign: TextAlign.center, style: TextStyle( - color: - MzanziInnovationHub.of(context)!.theme.primaryColor(), - fontSize: 20, + fontSize: 25, fontWeight: FontWeight.bold, + color: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), ), ), ), - ), - ], - ), - ], + Divider( + color: + MzanziInnovationHub.of(context)!.theme.secondaryColor()), + const SizedBox(height: 10), + MIHDateField( + controller: _serviceDateController, + lableText: "Date of Service", + required: true, + ), + const SizedBox(height: 10), + MIHDropdownField( + controller: _serviceDescController, + hintText: "Service Decription", + dropdownOptions: const [ + "Consultation", + "Procedure", + "Other", + ], + required: true, + editable: true, + enableSearch: false, + ), + const SizedBox(height: 10), + ValueListenableBuilder( + valueListenable: serviceDesc, + builder: (BuildContext context, String value, Widget? child) { + Widget returnWidget; + switch (value) { + case 'Consultation': + returnWidget = Column( + children: [ + SizedBox( + child: MIHDropdownField( + controller: _serviceDescOptionsController, + hintText: "Consultation Type", + dropdownOptions: const [ + "General Consultation", + "Follow-Up Consultation", + "Specialist Consultation", + "Emergency Consultation", + ], + required: true, + editable: true, + enableSearch: false, + ), + ), + const SizedBox(height: 10), + ], + ); + case 'Procedure': + returnWidget = Column( + children: [ + MihTextFormField( + fillColor: MzanziInnovationHub.of(context)! + .theme + .secondaryColor(), + inputColor: MzanziInnovationHub.of(context)! + .theme + .primaryColor(), + controller: _prcedureNameController, + multiLineInput: false, + requiredText: true, + hintText: "Procedure Name", + validator: (value) { + return MihValidationServices().isEmpty(value); + }, + ), + const SizedBox(height: 10), + MihTextFormField( + fillColor: MzanziInnovationHub.of(context)! + .theme + .secondaryColor(), + inputColor: MzanziInnovationHub.of(context)! + .theme + .primaryColor(), + controller: _proceedureAdditionalInfoController, + multiLineInput: false, + requiredText: true, + hintText: "Additional Information", + validator: (value) { + return MihValidationServices().isEmpty(value); + }, + ), + const SizedBox(height: 15), + ], + ); + case 'Other': + returnWidget = Column( + children: [ + MihTextFormField( + fillColor: MzanziInnovationHub.of(context)! + .theme + .secondaryColor(), + inputColor: MzanziInnovationHub.of(context)! + .theme + .primaryColor(), + controller: _serviceDescOptionsController, + multiLineInput: false, + requiredText: true, + hintText: "Service Description Details", + validator: (value) { + return MihValidationServices().isEmpty(value); + }, + ), + const SizedBox(height: 10), + ], + ); + default: + returnWidget = const SizedBox(); + } + return returnWidget; + }, + ), + Column( + children: [ + Align( + alignment: Alignment.centerLeft, + child: Text("ICD-10 Code & Description", + style: TextStyle( + fontSize: 15, + fontWeight: FontWeight.bold, + color: MzanziInnovationHub.of(context)! + .theme + .secondaryColor(), + )), + ), + const SizedBox(height: 4), + MihSearchBar( + controller: _icd10CodeController, + hintText: "ICD-10 Search", + prefixIcon: Icons.search, + fillColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + hintColor: + MzanziInnovationHub.of(context)!.theme.primaryColor(), + onPrefixIconTap: () { + MIHIcd10CodeApis.getIcd10Codes( + _icd10CodeController.text, context) + .then((result) { + icd10SearchWindow(result); + }); + }, + onClearIconTap: () { + _icd10CodeController.clear(); + }, + searchFocusNode: _searchFocusNode, + ), + ], + ), + const SizedBox(height: 10), + MihTextFormField( + fillColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + inputColor: + MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: _amountController, + multiLineInput: false, + requiredText: true, + numberMode: true, + hintText: "Service Cost", + validator: (value) { + return MihValidationServices().isEmpty(value); + }, + ), + const SizedBox(height: 10), + Center( + child: Text( + "Additional Infomation", + textAlign: TextAlign.center, + style: TextStyle( + fontSize: 25, + fontWeight: FontWeight.bold, + color: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + ), + ), + ), + Divider( + color: + MzanziInnovationHub.of(context)!.theme.secondaryColor()), + const SizedBox(height: 10), + MihTextFormField( + fillColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + inputColor: + MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: _preauthNoController, + multiLineInput: false, + requiredText: false, + hintText: "Pre-authorisation No.", + ), + const SizedBox(height: 20), + Center( + child: MihButton( + onPressed: () { + if (_formKey.currentState!.validate()) { + if (isInputValid()) { + MIHClaimStatementGenerationApi().generateClaimStatement( + ClaimStatementGenerationArguments( + _docTypeController.text, + widget.selectedPatient.app_id, + _fullNameController.text, + _idController.text, + _medAidController.text, + _medAidNoController.text, + _medAidCodeController.text, + _medAidNameController.text, + _medAidSchemeController.text, + widget.business!.Name, + "*To-Be Added*", + widget.business!.contact_no, + widget.business!.bus_email, + _providerNameController.text, + _practiceNoController.text, + _vatNoController.text, + _serviceDateController.text, + _serviceDescController.text, + _serviceDescOptionsController.text, + _prcedureNameController.text, + _proceedureAdditionalInfoController.text, + _icd10CodeController.text, + _amountController.text, + _preauthNoController.text, + widget.business!.logo_path, + widget.businessUser!.sig_path, + ), + PatientViewArguments( + widget.signedInUser, + widget.selectedPatient, + widget.businessUser, + widget.business, + "business", + ), + widget.env, + context); + } else { + showDialog( + context: context, + builder: (context) { + return const MIHErrorMessage( + errorType: "Input Error"); + }, + ); + } + } + }, + buttonColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + width: 300, + child: Text( + "Generate", + style: TextStyle( + color: + MzanziInnovationHub.of(context)!.theme.primaryColor(), + fontSize: 20, + fontWeight: FontWeight.bold, + ), + ), + ), + ), + ], + ), + ], + ), ); } @@ -459,19 +468,14 @@ class _ClaimStatementWindowState extends State { @override Widget build(BuildContext context) { + double screenWidth = MediaQuery.of(context).size.width; return MihPackageWindow( fullscreen: false, windowTitle: "Generate Claim/ Statement Document", onWindowTapClose: () { - // medicineController.clear(); - // quantityController.clear(); - // dosageController.clear(); - // timesDailyController.clear(); - // noDaysController.clear(); - // noRepeatsController.clear(); Navigator.pop(context); }, - windowBody: getWindowBody(), + windowBody: getWindowBody(screenWidth), ); } } diff --git a/Frontend/lib/mih_packages/patient_profile/pat_profile/package_tools/patient_consultation.dart b/Frontend/lib/mih_packages/patient_profile/pat_profile/package_tools/patient_consultation.dart index 1e4f0368..0f8abc55 100644 --- a/Frontend/lib/mih_packages/patient_profile/pat_profile/package_tools/patient_consultation.dart +++ b/Frontend/lib/mih_packages/patient_profile/pat_profile/package_tools/patient_consultation.dart @@ -69,7 +69,7 @@ class _PatientConsultationState extends State { } } - void addNotePopUp() { + void addNotePopUp(double width) { DateTime now = new DateTime.now(); DateTime date = new DateTime(now.year, now.month, now.day); var title = ""; @@ -94,128 +94,136 @@ class _PatientConsultationState extends State { titleController.clear(); noteTextController.clear(); }, - windowBody: Column( - children: [ - MihForm( - formKey: _formKey, - formFields: [ - MihTextFormField( - fillColor: - MzanziInnovationHub.of(context)!.theme.secondaryColor(), - inputColor: - MzanziInnovationHub.of(context)!.theme.primaryColor(), - controller: officeController, - multiLineInput: false, - requiredText: true, - readOnly: true, - hintText: "Office", - ), - const SizedBox(height: 10.0), - MihTextFormField( - fillColor: - MzanziInnovationHub.of(context)!.theme.secondaryColor(), - inputColor: - MzanziInnovationHub.of(context)!.theme.primaryColor(), - controller: doctorController, - multiLineInput: false, - requiredText: true, - readOnly: true, - hintText: "Created By", - ), - const SizedBox(height: 10.0), - MihTextFormField( - fillColor: - MzanziInnovationHub.of(context)!.theme.secondaryColor(), - inputColor: - MzanziInnovationHub.of(context)!.theme.primaryColor(), - controller: dateController, - multiLineInput: false, - requiredText: true, - readOnly: true, - hintText: "Created Date", - ), - const SizedBox(height: 10.0), - MihTextFormField( - fillColor: - MzanziInnovationHub.of(context)!.theme.secondaryColor(), - inputColor: - MzanziInnovationHub.of(context)!.theme.primaryColor(), - controller: titleController, - multiLineInput: false, - requiredText: true, - hintText: "Note Title", - validator: (value) { - return MihValidationServices().isEmpty(value); - }, - ), - const SizedBox(height: 10.0), - MihTextFormField( - height: 250, - fillColor: - MzanziInnovationHub.of(context)!.theme.secondaryColor(), - inputColor: - MzanziInnovationHub.of(context)!.theme.primaryColor(), - controller: noteTextController, - multiLineInput: true, - requiredText: true, - hintText: "Note Details", - validator: (value) { - return MihValidationServices().validateLength(value, 512); - }, - ), - SizedBox( - height: 15, - child: ValueListenableBuilder( - builder: (BuildContext context, int value, Widget? child) { - return Row( - mainAxisSize: MainAxisSize.max, - mainAxisAlignment: MainAxisAlignment.end, - children: [ - Text( - "$value", - style: TextStyle( - color: getNoteDetailLimitColor(), - fontWeight: FontWeight.bold, - ), - ), - const SizedBox(width: 5), - Text( - "/512", - style: TextStyle( - color: getNoteDetailLimitColor(), - fontWeight: FontWeight.bold, - ), - ), - ], - ); - }, - valueListenable: _counter, + windowBody: Padding( + padding: + MzanziInnovationHub.of(context)!.theme.screenType == "desktop" + ? EdgeInsets.symmetric(horizontal: width * 0.05) + : const EdgeInsets.symmetric(horizontal: 0), + child: Column( + children: [ + MihForm( + formKey: _formKey, + formFields: [ + MihTextFormField( + fillColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + inputColor: + MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: officeController, + multiLineInput: false, + requiredText: true, + readOnly: true, + hintText: "Office", ), - ), - const SizedBox(height: 15.0), - MihButton( - onPressed: () { - if (_formKey.currentState!.validate()) { - addPatientNoteAPICall(); - Navigator.pop(context); - } - }, - buttonColor: - MzanziInnovationHub.of(context)!.theme.secondaryColor(), - width: 300, - child: Text( - "Add Note", - style: TextStyle( - color: - MzanziInnovationHub.of(context)!.theme.primaryColor(), - fontSize: 20, - fontWeight: FontWeight.bold, + const SizedBox(height: 10.0), + MihTextFormField( + fillColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + inputColor: + MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: doctorController, + multiLineInput: false, + requiredText: true, + readOnly: true, + hintText: "Created By", + ), + const SizedBox(height: 10.0), + MihTextFormField( + fillColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + inputColor: + MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: dateController, + multiLineInput: false, + requiredText: true, + readOnly: true, + hintText: "Created Date", + ), + const SizedBox(height: 10.0), + MihTextFormField( + fillColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + inputColor: + MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: titleController, + multiLineInput: false, + requiredText: true, + hintText: "Note Title", + validator: (value) { + return MihValidationServices().isEmpty(value); + }, + ), + const SizedBox(height: 10.0), + MihTextFormField( + height: 250, + fillColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + inputColor: + MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: noteTextController, + multiLineInput: true, + requiredText: true, + hintText: "Note Details", + validator: (value) { + return MihValidationServices().validateLength(value, 512); + }, + ), + SizedBox( + height: 15, + child: ValueListenableBuilder( + builder: + (BuildContext context, int value, Widget? child) { + return Row( + mainAxisSize: MainAxisSize.max, + mainAxisAlignment: MainAxisAlignment.end, + children: [ + Text( + "$value", + style: TextStyle( + color: getNoteDetailLimitColor(), + fontWeight: FontWeight.bold, + ), + ), + const SizedBox(width: 5), + Text( + "/512", + style: TextStyle( + color: getNoteDetailLimitColor(), + fontWeight: FontWeight.bold, + ), + ), + ], + ); + }, + valueListenable: _counter, ), ), - ), - ], - ), - ], + const SizedBox(height: 15.0), + MihButton( + onPressed: () { + if (_formKey.currentState!.validate()) { + addPatientNoteAPICall(); + Navigator.pop(context); + } + }, + buttonColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + width: 300, + child: Text( + "Add Note", + style: TextStyle( + color: MzanziInnovationHub.of(context)! + .theme + .primaryColor(), + fontSize: 20, + fontWeight: FontWeight.bold, + ), + ), + ), + ], + ), + ], + ), ), ), ); @@ -271,40 +279,6 @@ class _PatientConsultationState extends State { } } - List setIcons() { - if (widget.type == "personal") { - return [ - Text( - "Consultation Notes", - textAlign: TextAlign.center, - style: TextStyle( - fontSize: 25, - fontWeight: FontWeight.bold, - color: MzanziInnovationHub.of(context)!.theme.secondaryColor()), - ), - ]; - } else { - return [ - Text( - "Consultation Notes", - textAlign: TextAlign.center, - style: TextStyle( - fontSize: 25, - fontWeight: FontWeight.bold, - color: MzanziInnovationHub.of(context)!.theme.secondaryColor()), - ), - IconButton( - onPressed: () { - // addConsultationNotePopUp(); - addNotePopUp(); - }, - icon: Icon(Icons.add, - color: MzanziInnovationHub.of(context)!.theme.secondaryColor()), - ) - ]; - } - } - void successPopUp(String message) { showDialog( context: context, @@ -349,13 +323,14 @@ class _PatientConsultationState extends State { @override Widget build(BuildContext context) { + double screenWidth = MediaQuery.of(context).size.width; return MihPackageToolBody( borderOn: false, - bodyItem: getBody(), + bodyItem: getBody(screenWidth), ); } - Widget getBody() { + Widget getBody(double width) { return Stack( children: [ MihSingleChildScroll( @@ -413,7 +388,7 @@ class _PatientConsultationState extends State { MzanziInnovationHub.of(context)!.theme.successColor(), onTap: () { // addConsultationNotePopUp(); - addNotePopUp(); + addNotePopUp(width); }, ) ], diff --git a/Frontend/lib/mih_packages/patient_profile/pat_profile/package_tools/patient_info.dart b/Frontend/lib/mih_packages/patient_profile/pat_profile/package_tools/patient_info.dart index b806201b..320b3fd6 100644 --- a/Frontend/lib/mih_packages/patient_profile/pat_profile/package_tools/patient_info.dart +++ b/Frontend/lib/mih_packages/patient_profile/pat_profile/package_tools/patient_info.dart @@ -39,7 +39,7 @@ class _PatientInfoState extends State { final medMainMemController = TextEditingController(); final medAidCodeController = TextEditingController(); final _formKey = GlobalKey(); - double textFieldWidth = 400.0; + double textFieldWidth = 500; late String medAid; Widget getPatientDetailsField() { @@ -48,69 +48,93 @@ class _PatientInfoState extends State { spacing: 15, runSpacing: 10, children: [ - MihTextFormField( + SizedBox( width: textFieldWidth, - fillColor: MzanziInnovationHub.of(context)!.theme.secondaryColor(), - inputColor: MzanziInnovationHub.of(context)!.theme.primaryColor(), - controller: idController, - multiLineInput: false, - requiredText: true, - readOnly: true, - hintText: "ID No.", - // validator: (value) { - // return MihValidationServices().isEmpty(value); - // }, + child: MihTextFormField( + // width: textFieldWidth, + fillColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + inputColor: MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: idController, + multiLineInput: false, + requiredText: true, + readOnly: true, + hintText: "ID No.", + // validator: (value) { + // return MihValidationServices().isEmpty(value); + // }, + ), ), - MihTextFormField( + SizedBox( width: textFieldWidth, - fillColor: MzanziInnovationHub.of(context)!.theme.secondaryColor(), - inputColor: MzanziInnovationHub.of(context)!.theme.primaryColor(), - controller: fnameController, - multiLineInput: false, - requiredText: true, - readOnly: true, - hintText: "First Name", + child: MihTextFormField( + // width: textFieldWidth, + fillColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + inputColor: MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: fnameController, + multiLineInput: false, + requiredText: true, + readOnly: true, + hintText: "First Name", + ), ), - MihTextFormField( + SizedBox( width: textFieldWidth, - fillColor: MzanziInnovationHub.of(context)!.theme.secondaryColor(), - inputColor: MzanziInnovationHub.of(context)!.theme.primaryColor(), - controller: lnameController, - multiLineInput: false, - requiredText: true, - hintText: "Surname", - readOnly: true, + child: MihTextFormField( + // width: textFieldWidth, + fillColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + inputColor: MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: lnameController, + multiLineInput: false, + requiredText: true, + hintText: "Surname", + readOnly: true, + ), ), - MihTextFormField( + SizedBox( width: textFieldWidth, - fillColor: MzanziInnovationHub.of(context)!.theme.secondaryColor(), - inputColor: MzanziInnovationHub.of(context)!.theme.primaryColor(), - controller: cellController, - multiLineInput: false, - requiredText: true, - readOnly: true, - hintText: "Cell No.", + child: MihTextFormField( + // width: textFieldWidth, + fillColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + inputColor: MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: cellController, + multiLineInput: false, + requiredText: true, + readOnly: true, + hintText: "Cell No.", + ), ), - MihTextFormField( + SizedBox( width: textFieldWidth, - fillColor: MzanziInnovationHub.of(context)!.theme.secondaryColor(), - inputColor: MzanziInnovationHub.of(context)!.theme.primaryColor(), - controller: emailController, - multiLineInput: false, - requiredText: true, - readOnly: true, - hintText: "Email", + child: MihTextFormField( + // width: textFieldWidth, + fillColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + inputColor: MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: emailController, + multiLineInput: false, + requiredText: true, + readOnly: true, + hintText: "Email", + ), ), - MihTextFormField( + SizedBox( width: textFieldWidth, - height: 100, - fillColor: MzanziInnovationHub.of(context)!.theme.secondaryColor(), - inputColor: MzanziInnovationHub.of(context)!.theme.primaryColor(), - controller: addressController, - multiLineInput: true, - requiredText: true, - readOnly: true, - hintText: "Address", + child: MihTextFormField( + // width: textFieldWidth, + height: 100, + fillColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + inputColor: MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: addressController, + multiLineInput: true, + requiredText: true, + readOnly: true, + hintText: "Address", + ), ), ], ), @@ -120,15 +144,18 @@ class _PatientInfoState extends State { Widget getMedAidDetailsFields() { List medAidDet = []; medAidDet.add( - MihTextFormField( + SizedBox( width: textFieldWidth, - fillColor: MzanziInnovationHub.of(context)!.theme.secondaryColor(), - inputColor: MzanziInnovationHub.of(context)!.theme.primaryColor(), - controller: medAidController, - multiLineInput: false, - requiredText: true, - readOnly: true, - hintText: "Medical Aid", + child: MihTextFormField( + // width: textFieldWidth, + fillColor: MzanziInnovationHub.of(context)!.theme.secondaryColor(), + inputColor: MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: medAidController, + multiLineInput: false, + requiredText: true, + readOnly: true, + hintText: "Medical Aid", + ), ), ); bool req; @@ -140,67 +167,81 @@ class _PatientInfoState extends State { medAidDet.addAll([ Visibility( visible: req, - child: MihTextFormField( + child: SizedBox( width: textFieldWidth, - fillColor: MzanziInnovationHub.of(context)!.theme.secondaryColor(), - inputColor: MzanziInnovationHub.of(context)!.theme.primaryColor(), - controller: medMainMemController, - multiLineInput: false, - requiredText: true, - readOnly: true, - hintText: "Main Member", + child: MihTextFormField( + // width: textFieldWidth, + fillColor: MzanziInnovationHub.of(context)!.theme.secondaryColor(), + inputColor: MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: medMainMemController, + multiLineInput: false, + requiredText: true, + readOnly: true, + hintText: "Main Member", + ), ), ), Visibility( visible: req, - child: MihTextFormField( + child: SizedBox( width: textFieldWidth, - fillColor: MzanziInnovationHub.of(context)!.theme.secondaryColor(), - inputColor: MzanziInnovationHub.of(context)!.theme.primaryColor(), - controller: medNoController, - multiLineInput: false, - requiredText: true, - readOnly: true, - hintText: "No.", + child: MihTextFormField( + // width: textFieldWidth, + fillColor: MzanziInnovationHub.of(context)!.theme.secondaryColor(), + inputColor: MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: medNoController, + multiLineInput: false, + requiredText: true, + readOnly: true, + hintText: "No.", + ), ), ), Visibility( visible: req, - child: MihTextFormField( + child: SizedBox( width: textFieldWidth, - fillColor: MzanziInnovationHub.of(context)!.theme.secondaryColor(), - inputColor: MzanziInnovationHub.of(context)!.theme.primaryColor(), - controller: medAidCodeController, - multiLineInput: false, - requiredText: true, - readOnly: true, - hintText: "Code", + child: MihTextFormField( + // width: textFieldWidth, + fillColor: MzanziInnovationHub.of(context)!.theme.secondaryColor(), + inputColor: MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: medAidCodeController, + multiLineInput: false, + requiredText: true, + readOnly: true, + hintText: "Code", + ), ), ), Visibility( visible: req, - child: MihTextFormField( - width: textFieldWidth, - fillColor: MzanziInnovationHub.of(context)!.theme.secondaryColor(), - inputColor: MzanziInnovationHub.of(context)!.theme.primaryColor(), - controller: medNameController, - multiLineInput: false, - requiredText: true, - readOnly: true, - hintText: "Name", + child: SizedBox( + child: MihTextFormField( + // width: textFieldWidth, + fillColor: MzanziInnovationHub.of(context)!.theme.secondaryColor(), + inputColor: MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: medNameController, + multiLineInput: false, + requiredText: true, + readOnly: true, + hintText: "Name", + ), ), ), Visibility( visible: req, - child: MihTextFormField( + child: SizedBox( width: textFieldWidth, - fillColor: MzanziInnovationHub.of(context)!.theme.secondaryColor(), - inputColor: MzanziInnovationHub.of(context)!.theme.primaryColor(), - controller: medSchemeController, - multiLineInput: false, - requiredText: true, - readOnly: true, - hintText: "Plan", + child: MihTextFormField( + // width: textFieldWidth, + fillColor: MzanziInnovationHub.of(context)!.theme.secondaryColor(), + inputColor: MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: medSchemeController, + multiLineInput: false, + requiredText: true, + readOnly: true, + hintText: "Plan", + ), ), ), ]); @@ -263,14 +304,15 @@ class _PatientInfoState extends State { @override Widget build(BuildContext context) { + double screenWidth = MediaQuery.of(context).size.width; return MihPackageToolBody( borderOn: false, innerHorizontalPadding: 10, - bodyItem: getBody(), + bodyItem: getBody(screenWidth), ); } - Widget getBody() { + Widget getBody(double width) { return Stack( children: [ MihSingleChildScroll( diff --git a/Frontend/lib/mih_packages/patient_profile/pat_profile/patient_add.dart b/Frontend/lib/mih_packages/patient_profile/pat_profile/patient_add.dart index 6887d697..e3a236c2 100644 --- a/Frontend/lib/mih_packages/patient_profile/pat_profile/patient_add.dart +++ b/Frontend/lib/mih_packages/patient_profile/pat_profile/patient_add.dart @@ -160,18 +160,127 @@ class _AddPatientState extends State { } } - Widget displayForm() { + Widget displayForm(double width) { return SingleChildScrollView( - child: Column( - children: [ - MihForm( - formKey: _formKey, - formFields: [ - Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Text( - "Personal", + child: Padding( + padding: MzanziInnovationHub.of(context)!.theme.screenType == "desktop" + ? EdgeInsets.symmetric(horizontal: width * 0.2) + : EdgeInsets.symmetric(horizontal: width * 0.075), + child: Column( + children: [ + MihForm( + formKey: _formKey, + formFields: [ + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text( + "Personal", + textAlign: TextAlign.center, + style: TextStyle( + fontWeight: FontWeight.bold, + fontSize: 25.0, + color: MzanziInnovationHub.of(context)! + .theme + .secondaryColor(), + ), + ), + ], + ), + Divider( + color: MzanziInnovationHub.of(context)! + .theme + .secondaryColor()), + const SizedBox(height: 10.0), + MihTextFormField( + fillColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + inputColor: + MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: idController, + multiLineInput: false, + requiredText: true, + hintText: "ID No.", + validator: (value) { + return MihValidationServices().isEmpty(value); + }, + ), + const SizedBox(height: 10.0), + MihTextFormField( + fillColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + inputColor: + MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: fnameController, + multiLineInput: false, + requiredText: true, + hintText: "First Name", + validator: (value) { + return MihValidationServices().isEmpty(value); + }, + ), + const SizedBox(height: 10.0), + MihTextFormField( + fillColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + inputColor: + MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: lnameController, + multiLineInput: false, + requiredText: true, + hintText: "Surname", + validator: (value) { + return MihValidationServices().isEmpty(value); + }, + ), + const SizedBox(height: 10.0), + MihTextFormField( + fillColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + inputColor: + MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: cellController, + multiLineInput: false, + requiredText: true, + hintText: "Cell No.", + validator: (value) { + return MihValidationServices().isEmpty(value); + }, + ), + const SizedBox(height: 10.0), + MihTextFormField( + fillColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + inputColor: + MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: emailController, + multiLineInput: false, + requiredText: true, + readOnly: true, + hintText: "Email", + validator: (value) { + return MihValidationServices().validateEmail(value); + }, + ), + const SizedBox(height: 10.0), + MihTextFormField( + height: 100, + fillColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + inputColor: + MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: addressController, + multiLineInput: true, + requiredText: true, + hintText: "Address", + validator: (value) { + return MihValidationServices().isEmpty(value); + }, + ), + const SizedBox(height: 15.0), + Center( + child: Text( + "Medical Aid Details", textAlign: TextAlign.center, style: TextStyle( fontWeight: FontWeight.bold, @@ -181,250 +290,150 @@ class _AddPatientState extends State { .secondaryColor(), ), ), - ], - ), - Divider( - color: - MzanziInnovationHub.of(context)!.theme.secondaryColor()), - const SizedBox(height: 10.0), - MihTextFormField( - fillColor: - MzanziInnovationHub.of(context)!.theme.secondaryColor(), - inputColor: - MzanziInnovationHub.of(context)!.theme.primaryColor(), - controller: idController, - multiLineInput: false, - requiredText: true, - hintText: "ID No.", - validator: (value) { - return MihValidationServices().isEmpty(value); - }, - ), - const SizedBox(height: 10.0), - MihTextFormField( - fillColor: - MzanziInnovationHub.of(context)!.theme.secondaryColor(), - inputColor: - MzanziInnovationHub.of(context)!.theme.primaryColor(), - controller: fnameController, - multiLineInput: false, - requiredText: true, - hintText: "First Name", - validator: (value) { - return MihValidationServices().isEmpty(value); - }, - ), - const SizedBox(height: 10.0), - MihTextFormField( - fillColor: - MzanziInnovationHub.of(context)!.theme.secondaryColor(), - inputColor: - MzanziInnovationHub.of(context)!.theme.primaryColor(), - controller: lnameController, - multiLineInput: false, - requiredText: true, - hintText: "Surname", - validator: (value) { - return MihValidationServices().isEmpty(value); - }, - ), - const SizedBox(height: 10.0), - MihTextFormField( - fillColor: - MzanziInnovationHub.of(context)!.theme.secondaryColor(), - inputColor: - MzanziInnovationHub.of(context)!.theme.primaryColor(), - controller: cellController, - multiLineInput: false, - requiredText: true, - hintText: "Cell No.", - validator: (value) { - return MihValidationServices().isEmpty(value); - }, - ), - const SizedBox(height: 10.0), - MihTextFormField( - fillColor: - MzanziInnovationHub.of(context)!.theme.secondaryColor(), - inputColor: - MzanziInnovationHub.of(context)!.theme.primaryColor(), - controller: emailController, - multiLineInput: false, - requiredText: true, - readOnly: true, - hintText: "Email", - validator: (value) { - return MihValidationServices().validateEmail(value); - }, - ), - const SizedBox(height: 10.0), - MihTextFormField( - height: 100, - fillColor: - MzanziInnovationHub.of(context)!.theme.secondaryColor(), - inputColor: - MzanziInnovationHub.of(context)!.theme.primaryColor(), - controller: addressController, - multiLineInput: true, - requiredText: true, - hintText: "Address", - validator: (value) { - return MihValidationServices().isEmpty(value); - }, - ), - const SizedBox(height: 15.0), - Center( - child: Text( - "Medical Aid Details", - textAlign: TextAlign.center, - style: TextStyle( - fontWeight: FontWeight.bold, - fontSize: 25.0, - color: - MzanziInnovationHub.of(context)!.theme.secondaryColor(), - ), ), - ), - Divider( - color: - MzanziInnovationHub.of(context)!.theme.secondaryColor()), - const SizedBox(height: 10.0), - MIHDropdownField( - controller: medAidController, - hintText: "Medical Aid", - editable: true, - required: true, - enableSearch: false, - dropdownOptions: const ["Yes", "No"], - ), - ValueListenableBuilder( - valueListenable: medRequired, - builder: (BuildContext context, bool value, Widget? child) { - return Visibility( - visible: value, - child: Column( - children: [ - const SizedBox(height: 10.0), - MIHDropdownField( - controller: medMainMemController, - hintText: "Main Member", - editable: value, - required: value, - enableSearch: false, - dropdownOptions: const ["Yes", "No"], - ), - const SizedBox(height: 10.0), - MihTextFormField( - fillColor: MzanziInnovationHub.of(context)! - .theme - .secondaryColor(), - inputColor: MzanziInnovationHub.of(context)! - .theme - .primaryColor(), - controller: medNoController, - multiLineInput: false, - requiredText: true, - hintText: "No.", - validator: (validationValue) { - if (value) { - return MihValidationServices() - .isEmpty(validationValue); - } - return null; - }, - ), - const SizedBox(height: 10.0), - MihTextFormField( - fillColor: MzanziInnovationHub.of(context)! - .theme - .secondaryColor(), - inputColor: MzanziInnovationHub.of(context)! - .theme - .primaryColor(), - controller: medAidCodeController, - multiLineInput: false, - requiredText: true, - hintText: "Code", - validator: (validationValue) { - if (value) { - return MihValidationServices() - .isEmpty(validationValue); - } - return null; - }, - ), - const SizedBox(height: 10.0), - MihTextFormField( - fillColor: MzanziInnovationHub.of(context)! - .theme - .secondaryColor(), - inputColor: MzanziInnovationHub.of(context)! - .theme - .primaryColor(), - controller: medNameController, - multiLineInput: false, - requiredText: true, - hintText: "Name", - validator: (validationValue) { - if (value) { - return MihValidationServices() - .isEmpty(validationValue); - } - return null; - }, - ), - const SizedBox(height: 10.0), - MihTextFormField( - fillColor: MzanziInnovationHub.of(context)! - .theme - .secondaryColor(), - inputColor: MzanziInnovationHub.of(context)! - .theme - .primaryColor(), - controller: medSchemeController, - multiLineInput: false, - requiredText: true, - hintText: "Plan", - validator: (validationValue) { - if (value) { - return MihValidationServices() - .isEmpty(validationValue); - } - return null; - }, - ), - const SizedBox(height: 10.0), - ], - ), - ); - }, - ), - const SizedBox(height: 20.0), - Center( - child: MihButton( - onPressed: () { - if (_formKey.currentState!.validate()) { - submitForm(); - } + Divider( + color: MzanziInnovationHub.of(context)! + .theme + .secondaryColor()), + const SizedBox(height: 10.0), + MIHDropdownField( + controller: medAidController, + hintText: "Medical Aid", + editable: true, + required: true, + enableSearch: false, + dropdownOptions: const ["Yes", "No"], + ), + ValueListenableBuilder( + valueListenable: medRequired, + builder: (BuildContext context, bool value, Widget? child) { + return Visibility( + visible: value, + child: Column( + children: [ + const SizedBox(height: 10.0), + MIHDropdownField( + controller: medMainMemController, + hintText: "Main Member", + editable: value, + required: value, + enableSearch: false, + dropdownOptions: const ["Yes", "No"], + ), + const SizedBox(height: 10.0), + MihTextFormField( + fillColor: MzanziInnovationHub.of(context)! + .theme + .secondaryColor(), + inputColor: MzanziInnovationHub.of(context)! + .theme + .primaryColor(), + controller: medNoController, + multiLineInput: false, + requiredText: true, + hintText: "No.", + validator: (validationValue) { + if (value) { + return MihValidationServices() + .isEmpty(validationValue); + } + return null; + }, + ), + const SizedBox(height: 10.0), + MihTextFormField( + fillColor: MzanziInnovationHub.of(context)! + .theme + .secondaryColor(), + inputColor: MzanziInnovationHub.of(context)! + .theme + .primaryColor(), + controller: medAidCodeController, + multiLineInput: false, + requiredText: true, + hintText: "Code", + validator: (validationValue) { + if (value) { + return MihValidationServices() + .isEmpty(validationValue); + } + return null; + }, + ), + const SizedBox(height: 10.0), + MihTextFormField( + fillColor: MzanziInnovationHub.of(context)! + .theme + .secondaryColor(), + inputColor: MzanziInnovationHub.of(context)! + .theme + .primaryColor(), + controller: medNameController, + multiLineInput: false, + requiredText: true, + hintText: "Name", + validator: (validationValue) { + if (value) { + return MihValidationServices() + .isEmpty(validationValue); + } + return null; + }, + ), + const SizedBox(height: 10.0), + MihTextFormField( + fillColor: MzanziInnovationHub.of(context)! + .theme + .secondaryColor(), + inputColor: MzanziInnovationHub.of(context)! + .theme + .primaryColor(), + controller: medSchemeController, + multiLineInput: false, + requiredText: true, + hintText: "Plan", + validator: (validationValue) { + if (value) { + return MihValidationServices() + .isEmpty(validationValue); + } + return null; + }, + ), + const SizedBox(height: 10.0), + ], + ), + ); }, - buttonColor: - MzanziInnovationHub.of(context)!.theme.secondaryColor(), - width: 300, - child: Text( - "Add", - style: TextStyle( - color: - MzanziInnovationHub.of(context)!.theme.primaryColor(), - fontSize: 20, - fontWeight: FontWeight.bold, + ), + const SizedBox(height: 20.0), + Center( + child: MihButton( + onPressed: () { + if (_formKey.currentState!.validate()) { + submitForm(); + } + }, + buttonColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + width: 300, + child: Text( + "Add", + style: TextStyle( + color: MzanziInnovationHub.of(context)! + .theme + .primaryColor(), + fontSize: 20, + fontWeight: FontWeight.bold, + ), ), ), ), - ), - const SizedBox(height: 20.0), - ], - ), - ], + const SizedBox(height: 20.0), + ], + ), + ], + ), ), ); } @@ -458,7 +467,7 @@ class _AddPatientState extends State { ); } - MIHBody getBody() { + MIHBody getBody(double width) { return MIHBody( borderOn: false, bodyItems: [ @@ -473,7 +482,7 @@ class _AddPatientState extends State { } } }, - child: displayForm(), + child: displayForm(width), ), ], ); @@ -513,12 +522,12 @@ class _AddPatientState extends State { @override Widget build(BuildContext context) { - print("Add Patient"); + double screenWidth = MediaQuery.of(context).size.width; return MIHLayoutBuilder( actionButton: getActionButton(), header: getHeader(), secondaryActionButton: null, - body: getBody(), + body: getBody(screenWidth), actionDrawer: null, secondaryActionDrawer: null, bottomNavBar: null, diff --git a/Frontend/lib/mih_packages/patient_profile/pat_profile/patient_edit.dart b/Frontend/lib/mih_packages/patient_profile/pat_profile/patient_edit.dart index 540fb055..c86e420a 100644 --- a/Frontend/lib/mih_packages/patient_profile/pat_profile/patient_edit.dart +++ b/Frontend/lib/mih_packages/patient_profile/pat_profile/patient_edit.dart @@ -374,18 +374,127 @@ class _EditPatientState extends State { } } - Widget displayForm() { + Widget displayForm(double width) { return SingleChildScrollView( - child: Column( - children: [ - MihForm( - formKey: _formKey, - formFields: [ - Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Text( - "Personal", + child: Padding( + padding: MzanziInnovationHub.of(context)!.theme.screenType == "desktop" + ? EdgeInsets.symmetric(horizontal: width * 0.2) + : EdgeInsets.symmetric(horizontal: width * 0.075), + child: Column( + children: [ + MihForm( + formKey: _formKey, + formFields: [ + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text( + "Personal", + textAlign: TextAlign.center, + style: TextStyle( + fontWeight: FontWeight.bold, + fontSize: 25.0, + color: MzanziInnovationHub.of(context)! + .theme + .secondaryColor(), + ), + ), + ], + ), + Divider( + color: MzanziInnovationHub.of(context)! + .theme + .secondaryColor()), + const SizedBox(height: 10.0), + MihTextFormField( + fillColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + inputColor: + MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: idController, + multiLineInput: false, + requiredText: true, + hintText: "ID No.", + validator: (value) { + return MihValidationServices().isEmpty(value); + }, + ), + const SizedBox(height: 10.0), + MihTextFormField( + fillColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + inputColor: + MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: fnameController, + multiLineInput: false, + requiredText: true, + hintText: "First Name", + validator: (value) { + return MihValidationServices().isEmpty(value); + }, + ), + const SizedBox(height: 10.0), + MihTextFormField( + fillColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + inputColor: + MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: lnameController, + multiLineInput: false, + requiredText: true, + hintText: "Surname", + validator: (value) { + return MihValidationServices().isEmpty(value); + }, + ), + const SizedBox(height: 10.0), + MihTextFormField( + fillColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + inputColor: + MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: cellController, + multiLineInput: false, + requiredText: true, + hintText: "Cell No.", + validator: (value) { + return MihValidationServices().isEmpty(value); + }, + ), + const SizedBox(height: 10.0), + MihTextFormField( + fillColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + inputColor: + MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: emailController, + multiLineInput: false, + requiredText: true, + readOnly: true, + hintText: "Email", + validator: (value) { + return MihValidationServices().validateEmail(value); + }, + ), + const SizedBox(height: 10.0), + MihTextFormField( + height: 100, + fillColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + inputColor: + MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: addressController, + multiLineInput: true, + requiredText: true, + hintText: "Address", + validator: (value) { + return MihValidationServices().isEmpty(value); + }, + ), + const SizedBox(height: 15.0), + Center( + child: Text( + "Medical Aid Details", textAlign: TextAlign.center, style: TextStyle( fontWeight: FontWeight.bold, @@ -395,250 +504,150 @@ class _EditPatientState extends State { .secondaryColor(), ), ), - ], - ), - Divider( - color: - MzanziInnovationHub.of(context)!.theme.secondaryColor()), - const SizedBox(height: 10.0), - MihTextFormField( - fillColor: - MzanziInnovationHub.of(context)!.theme.secondaryColor(), - inputColor: - MzanziInnovationHub.of(context)!.theme.primaryColor(), - controller: idController, - multiLineInput: false, - requiredText: true, - hintText: "ID No.", - validator: (value) { - return MihValidationServices().isEmpty(value); - }, - ), - const SizedBox(height: 10.0), - MihTextFormField( - fillColor: - MzanziInnovationHub.of(context)!.theme.secondaryColor(), - inputColor: - MzanziInnovationHub.of(context)!.theme.primaryColor(), - controller: fnameController, - multiLineInput: false, - requiredText: true, - hintText: "First Name", - validator: (value) { - return MihValidationServices().isEmpty(value); - }, - ), - const SizedBox(height: 10.0), - MihTextFormField( - fillColor: - MzanziInnovationHub.of(context)!.theme.secondaryColor(), - inputColor: - MzanziInnovationHub.of(context)!.theme.primaryColor(), - controller: lnameController, - multiLineInput: false, - requiredText: true, - hintText: "Surname", - validator: (value) { - return MihValidationServices().isEmpty(value); - }, - ), - const SizedBox(height: 10.0), - MihTextFormField( - fillColor: - MzanziInnovationHub.of(context)!.theme.secondaryColor(), - inputColor: - MzanziInnovationHub.of(context)!.theme.primaryColor(), - controller: cellController, - multiLineInput: false, - requiredText: true, - hintText: "Cell No.", - validator: (value) { - return MihValidationServices().isEmpty(value); - }, - ), - const SizedBox(height: 10.0), - MihTextFormField( - fillColor: - MzanziInnovationHub.of(context)!.theme.secondaryColor(), - inputColor: - MzanziInnovationHub.of(context)!.theme.primaryColor(), - controller: emailController, - multiLineInput: false, - requiredText: true, - readOnly: true, - hintText: "Email", - validator: (value) { - return MihValidationServices().validateEmail(value); - }, - ), - const SizedBox(height: 10.0), - MihTextFormField( - height: 100, - fillColor: - MzanziInnovationHub.of(context)!.theme.secondaryColor(), - inputColor: - MzanziInnovationHub.of(context)!.theme.primaryColor(), - controller: addressController, - multiLineInput: true, - requiredText: true, - hintText: "Address", - validator: (value) { - return MihValidationServices().isEmpty(value); - }, - ), - const SizedBox(height: 15.0), - Center( - child: Text( - "Medical Aid Details", - textAlign: TextAlign.center, - style: TextStyle( - fontWeight: FontWeight.bold, - fontSize: 25.0, - color: - MzanziInnovationHub.of(context)!.theme.secondaryColor(), - ), ), - ), - Divider( - color: - MzanziInnovationHub.of(context)!.theme.secondaryColor()), - const SizedBox(height: 10.0), - MIHDropdownField( - controller: medAidController, - hintText: "Medical Aid", - editable: true, - required: true, - enableSearch: false, - dropdownOptions: const ["Yes", "No"], - ), - ValueListenableBuilder( - valueListenable: medRequired, - builder: (BuildContext context, bool value, Widget? child) { - return Visibility( - visible: value, - child: Column( - children: [ - const SizedBox(height: 10.0), - MIHDropdownField( - controller: medMainMemController, - hintText: "Main Member", - editable: value, - required: value, - enableSearch: false, - dropdownOptions: const ["Yes", "No"], - ), - const SizedBox(height: 10.0), - MihTextFormField( - fillColor: MzanziInnovationHub.of(context)! - .theme - .secondaryColor(), - inputColor: MzanziInnovationHub.of(context)! - .theme - .primaryColor(), - controller: medNoController, - multiLineInput: false, - requiredText: true, - hintText: "No.", - validator: (validationValue) { - if (value) { - return MihValidationServices() - .isEmpty(validationValue); - } - return null; - }, - ), - const SizedBox(height: 10.0), - MihTextFormField( - fillColor: MzanziInnovationHub.of(context)! - .theme - .secondaryColor(), - inputColor: MzanziInnovationHub.of(context)! - .theme - .primaryColor(), - controller: medAidCodeController, - multiLineInput: false, - requiredText: true, - hintText: "Code", - validator: (validationValue) { - if (value) { - return MihValidationServices() - .isEmpty(validationValue); - } - return null; - }, - ), - const SizedBox(height: 10.0), - MihTextFormField( - fillColor: MzanziInnovationHub.of(context)! - .theme - .secondaryColor(), - inputColor: MzanziInnovationHub.of(context)! - .theme - .primaryColor(), - controller: medNameController, - multiLineInput: false, - requiredText: true, - hintText: "Name", - validator: (validationValue) { - if (value) { - return MihValidationServices() - .isEmpty(validationValue); - } - return null; - }, - ), - const SizedBox(height: 10.0), - MihTextFormField( - fillColor: MzanziInnovationHub.of(context)! - .theme - .secondaryColor(), - inputColor: MzanziInnovationHub.of(context)! - .theme - .primaryColor(), - controller: medSchemeController, - multiLineInput: false, - requiredText: true, - hintText: "Plan", - validator: (validationValue) { - if (value) { - return MihValidationServices() - .isEmpty(validationValue); - } - return null; - }, - ), - const SizedBox(height: 10.0), - ], - ), - ); - }, - ), - const SizedBox(height: 20.0), - Center( - child: MihButton( - onPressed: () { - if (_formKey.currentState!.validate()) { - submitForm(); - } + Divider( + color: MzanziInnovationHub.of(context)! + .theme + .secondaryColor()), + const SizedBox(height: 10.0), + MIHDropdownField( + controller: medAidController, + hintText: "Medical Aid", + editable: true, + required: true, + enableSearch: false, + dropdownOptions: const ["Yes", "No"], + ), + ValueListenableBuilder( + valueListenable: medRequired, + builder: (BuildContext context, bool value, Widget? child) { + return Visibility( + visible: value, + child: Column( + children: [ + const SizedBox(height: 10.0), + MIHDropdownField( + controller: medMainMemController, + hintText: "Main Member", + editable: value, + required: value, + enableSearch: false, + dropdownOptions: const ["Yes", "No"], + ), + const SizedBox(height: 10.0), + MihTextFormField( + fillColor: MzanziInnovationHub.of(context)! + .theme + .secondaryColor(), + inputColor: MzanziInnovationHub.of(context)! + .theme + .primaryColor(), + controller: medNoController, + multiLineInput: false, + requiredText: true, + hintText: "No.", + validator: (validationValue) { + if (value) { + return MihValidationServices() + .isEmpty(validationValue); + } + return null; + }, + ), + const SizedBox(height: 10.0), + MihTextFormField( + fillColor: MzanziInnovationHub.of(context)! + .theme + .secondaryColor(), + inputColor: MzanziInnovationHub.of(context)! + .theme + .primaryColor(), + controller: medAidCodeController, + multiLineInput: false, + requiredText: true, + hintText: "Code", + validator: (validationValue) { + if (value) { + return MihValidationServices() + .isEmpty(validationValue); + } + return null; + }, + ), + const SizedBox(height: 10.0), + MihTextFormField( + fillColor: MzanziInnovationHub.of(context)! + .theme + .secondaryColor(), + inputColor: MzanziInnovationHub.of(context)! + .theme + .primaryColor(), + controller: medNameController, + multiLineInput: false, + requiredText: true, + hintText: "Name", + validator: (validationValue) { + if (value) { + return MihValidationServices() + .isEmpty(validationValue); + } + return null; + }, + ), + const SizedBox(height: 10.0), + MihTextFormField( + fillColor: MzanziInnovationHub.of(context)! + .theme + .secondaryColor(), + inputColor: MzanziInnovationHub.of(context)! + .theme + .primaryColor(), + controller: medSchemeController, + multiLineInput: false, + requiredText: true, + hintText: "Plan", + validator: (validationValue) { + if (value) { + return MihValidationServices() + .isEmpty(validationValue); + } + return null; + }, + ), + const SizedBox(height: 10.0), + ], + ), + ); }, - buttonColor: - MzanziInnovationHub.of(context)!.theme.secondaryColor(), - width: 300, - child: Text( - "Update", - style: TextStyle( - color: - MzanziInnovationHub.of(context)!.theme.primaryColor(), - fontSize: 20, - fontWeight: FontWeight.bold, + ), + const SizedBox(height: 20.0), + Center( + child: MihButton( + onPressed: () { + if (_formKey.currentState!.validate()) { + submitForm(); + } + }, + buttonColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + width: 300, + child: Text( + "Update", + style: TextStyle( + color: MzanziInnovationHub.of(context)! + .theme + .primaryColor(), + fontSize: 20, + fontWeight: FontWeight.bold, + ), ), ), ), - ), - const SizedBox(height: 20.0), - ], - ), - ], + const SizedBox(height: 20.0), + ], + ), + ], + ), ), ); } @@ -672,7 +681,7 @@ class _EditPatientState extends State { ); } - MIHBody getBody() { + MIHBody getBody(double width) { return MIHBody( borderOn: false, bodyItems: [ @@ -687,7 +696,7 @@ class _EditPatientState extends State { } } }, - child: displayForm(), + child: displayForm(width), ), ], ); @@ -747,61 +756,12 @@ class _EditPatientState extends State { actionButton: getActionButton(), header: getHeader(), secondaryActionButton: null, - body: getBody(), + body: getBody(width), actionDrawer: null, secondaryActionDrawer: null, bottomNavBar: null, pullDownToRefresh: false, onPullDown: () async {}, ); - // return Scaffold( - // // appBar: const MIHAppBar( - // // barTitle: "Edit Patient", - // // propicFile: null, - // // ), - // body: SafeArea( - // child: Stack( - // children: [ - // KeyboardListener( - // focusNode: _focusNode, - // autofocus: true, - // onKeyEvent: (event) async { - // if (event is KeyDownEvent && - // event.logicalKey == LogicalKeyboardKey.enter) { - // submitForm(); - // } - // }, - // child: displayForm(), - // ), - // Positioned( - // top: 10, - // left: 5, - // width: 50, - // height: 50, - // child: IconButton( - // onPressed: () { - // Navigator.of(context).pop(); - // }, - // icon: const Icon(Icons.arrow_back), - // ), - // ), - // Positioned( - // top: 10, - // right: 5, - // width: 50, - // height: 50, - // child: IconButton( - // icon: const Icon(Icons.delete), - // color: - // MzanziInnovationHub.of(context)!.theme.secondaryColor(), - // //alignment: Alignment.topRight, - // onPressed: () { - // deletePatientPopUp(); - // }, - // )) - // ], - // ), - // ), - // ); } } From 01150f9458e5a9bdded0c4606ca25766ff9202eb Mon Sep 17 00:00:00 2001 From: Yasien Mac Mini Date: Fri, 6 Jun 2025 13:50:45 +0200 Subject: [PATCH 49/52] create alert service --- Frontend/lib/mih_apis/mih_alert_services.dart | 58 +++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 Frontend/lib/mih_apis/mih_alert_services.dart diff --git a/Frontend/lib/mih_apis/mih_alert_services.dart b/Frontend/lib/mih_apis/mih_alert_services.dart new file mode 100644 index 00000000..8f9e2a64 --- /dev/null +++ b/Frontend/lib/mih_apis/mih_alert_services.dart @@ -0,0 +1,58 @@ +import 'package:flutter/material.dart'; +import 'package:mzansi_innovation_hub/main.dart'; +import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package_alert.dart'; + +class MihAlertServices { + void formNotFilledCompletely(BuildContext context) { + showDialog( + context: context, + builder: (context) { + return MihPackageAlert( + alertIcon: Icon( + Icons.warning_amber_rounded, + size: 150, + color: MzanziInnovationHub.of(context)!.theme.errorColor(), + ), + alertTitle: "Oops! Looks like some fields are missing.", + alertBody: Column( + children: [ + Text( + "We noticed that some required fields are still empty. To ensure your request is processed smoothly, please fill out all the highlighted fields before submitting the form again.", + style: TextStyle( + color: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + fontSize: 15, + fontWeight: FontWeight.bold, + ), + ), + const SizedBox(height: 25), + RichText( + text: TextSpan( + style: TextStyle( + color: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + fontSize: 15, + fontWeight: FontWeight.bold, + ), + children: [ + TextSpan( + text: "Here's a quick tip: ", + style: TextStyle( + fontStyle: FontStyle.italic, + color: MzanziInnovationHub.of(context)! + .theme + .errorColor())), + const TextSpan( + text: + "Look for fields without the \"(Optional)\" indicator next to them, as these are mandatory."), + ], + ), + ), + ], + ), + alertColour: MzanziInnovationHub.of(context)!.theme.errorColor(), + ); + }, + ); + } +} From e09f4e7d536923794e1dcd3b85e116818d6539f6 Mon Sep 17 00:00:00 2001 From: Yasien Mac Mini Date: Fri, 6 Jun 2025 14:00:33 +0200 Subject: [PATCH 50/52] Add input error pop up on forms --- .../Example/package_tools/package_tool_one.dart | 5 ++++- .../authentication/forgot_password.dart | 4 ++++ .../lib/mih_packages/authentication/register.dart | 6 ++++++ .../authentication/reset_password.dart | 6 ++++++ .../lib/mih_packages/authentication/signin.dart | 14 ++++++++++++++ .../calendar/builder/build_appointment_list.dart | 4 ++++ .../calendar/package_tools/appointments.dart | 3 +++ .../builders/build_employee_list.dart | 3 +++ .../business_profile/builders/build_user_list.dart | 4 ++++ .../package_tools/mih_business_details.dart | 3 +++ .../package_tools/mih_my_business_user.dart | 3 +++ .../business_profile/profile_business_add.dart | 6 ++++++ .../package_tools/mih_personal_profile.dart | 3 +++ .../builder/build_loyalty_card_list.dart | 3 +++ .../mzansi_wallet/package_tools/mih_cards.dart | 3 +++ .../list_builders/build_my_patient_list_list.dart | 3 +++ .../pat_manager/package_tools/waiting_room.dart | 3 +++ .../components/Claim_Statement_Window.dart | 3 +++ .../package_tools/patient_consultation.dart | 3 +++ .../patient_profile/pat_profile/patient_add.dart | 5 +++++ .../patient_profile/pat_profile/patient_edit.dart | 5 +++++ 21 files changed, 91 insertions(+), 1 deletion(-) diff --git a/Frontend/lib/mih_components/mih_package_components/Example/package_tools/package_tool_one.dart b/Frontend/lib/mih_components/mih_package_components/Example/package_tools/package_tool_one.dart index 7954db41..8716ffb2 100644 --- a/Frontend/lib/mih_components/mih_package_components/Example/package_tools/package_tool_one.dart +++ b/Frontend/lib/mih_components/mih_package_components/Example/package_tools/package_tool_one.dart @@ -2,6 +2,7 @@ import 'package:file_picker/file_picker.dart'; import 'package:flutter/material.dart'; import 'package:flutter_speed_dial/flutter_speed_dial.dart'; import 'package:mzansi_innovation_hub/main.dart'; +import 'package:mzansi_innovation_hub/mih_apis/mih_alert_services.dart'; import 'package:mzansi_innovation_hub/mih_apis/mih_validation_services.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_layout/mih_single_child_scroll.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_button.dart'; @@ -241,6 +242,8 @@ class _PackageToolOneState extends State { ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text("Input Valid")), ); + } else { + MihAlertServices().formNotFilledCompletely(context); } }, buttonColor: MzanziInnovationHub.of(context)! @@ -249,7 +252,7 @@ class _PackageToolOneState extends State { elevation: 10, width: 300, child: Text( - "Click Me", + "Submit Form", style: TextStyle( color: MzanziInnovationHub.of(context)! .theme diff --git a/Frontend/lib/mih_packages/authentication/forgot_password.dart b/Frontend/lib/mih_packages/authentication/forgot_password.dart index 99282085..f9705008 100644 --- a/Frontend/lib/mih_packages/authentication/forgot_password.dart +++ b/Frontend/lib/mih_packages/authentication/forgot_password.dart @@ -2,6 +2,7 @@ import 'dart:convert'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; +import 'package:mzansi_innovation_hub/mih_apis/mih_alert_services.dart'; import 'package:mzansi_innovation_hub/mih_apis/mih_validation_services.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_button.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_form.dart'; @@ -280,6 +281,9 @@ class _ForgotPasswordState extends State { onPressed: () { if (_formKey.currentState!.validate()) { prePassResteWarning(); + } else { + MihAlertServices() + .formNotFilledCompletely(context); } }, buttonColor: MzanziInnovationHub.of(context)! diff --git a/Frontend/lib/mih_packages/authentication/register.dart b/Frontend/lib/mih_packages/authentication/register.dart index c8421ca2..57adeeb6 100644 --- a/Frontend/lib/mih_packages/authentication/register.dart +++ b/Frontend/lib/mih_packages/authentication/register.dart @@ -1,5 +1,6 @@ import 'dart:convert'; +import 'package:mzansi_innovation_hub/mih_apis/mih_alert_services.dart'; import 'package:mzansi_innovation_hub/mih_apis/mih_install_services.dart'; import 'package:mzansi_innovation_hub/mih_apis/mih_validation_services.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_button.dart'; @@ -310,6 +311,8 @@ class _RegisterState extends State { event.logicalKey == LogicalKeyboardKey.enter) { if (_formKey.currentState!.validate()) { submitFormInput(); + } else { + MihAlertServices().formNotFilledCompletely(context); } } }, @@ -423,6 +426,9 @@ class _RegisterState extends State { onPressed: () { if (_formKey.currentState!.validate()) { submitFormInput(); + } else { + MihAlertServices() + .formNotFilledCompletely(context); } }, buttonColor: MzanziInnovationHub.of(context)! diff --git a/Frontend/lib/mih_packages/authentication/reset_password.dart b/Frontend/lib/mih_packages/authentication/reset_password.dart index 767ee600..a4ed515b 100644 --- a/Frontend/lib/mih_packages/authentication/reset_password.dart +++ b/Frontend/lib/mih_packages/authentication/reset_password.dart @@ -2,6 +2,7 @@ import 'dart:convert'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; +import 'package:mzansi_innovation_hub/mih_apis/mih_alert_services.dart'; import 'package:mzansi_innovation_hub/mih_apis/mih_validation_services.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_button.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_form.dart'; @@ -192,6 +193,8 @@ class _ResetPasswordState extends State { event.logicalKey == LogicalKeyboardKey.enter) { if (_formKey.currentState!.validate()) { submitFormInput(); + } else { + MihAlertServices().formNotFilledCompletely(context); } } }, @@ -303,6 +306,9 @@ class _ResetPasswordState extends State { onPressed: () { if (_formKey.currentState!.validate()) { submitFormInput(); + } else { + MihAlertServices() + .formNotFilledCompletely(context); } }, buttonColor: MzanziInnovationHub.of(context)! diff --git a/Frontend/lib/mih_packages/authentication/signin.dart b/Frontend/lib/mih_packages/authentication/signin.dart index 4f896fd3..ec17413b 100644 --- a/Frontend/lib/mih_packages/authentication/signin.dart +++ b/Frontend/lib/mih_packages/authentication/signin.dart @@ -1,4 +1,5 @@ import 'dart:convert'; +import 'package:mzansi_innovation_hub/mih_apis/mih_alert_services.dart'; import 'package:mzansi_innovation_hub/mih_apis/mih_install_Services.dart'; import 'package:mzansi_innovation_hub/mih_apis/mih_validation_services.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_button.dart'; @@ -104,6 +105,8 @@ class _SignInState extends State { }); if (_formKey.currentState!.validate()) { submitSignInForm(); + } else { + MihAlertServices().formNotFilledCompletely(context); } }, tileName: "Patient", @@ -123,6 +126,8 @@ class _SignInState extends State { }); if (_formKey.currentState!.validate()) { submitSignInForm(); + } else { + MihAlertServices().formNotFilledCompletely(context); } }, tileName: "Doctor", @@ -143,6 +148,8 @@ class _SignInState extends State { }); if (_formKey.currentState!.validate()) { submitSignInForm(); + } else { + MihAlertServices().formNotFilledCompletely(context); } }, tileName: "Business", @@ -162,6 +169,8 @@ class _SignInState extends State { }); if (_formKey.currentState!.validate()) { submitSignInForm(); + } else { + MihAlertServices().formNotFilledCompletely(context); } }, tileName: "Test", @@ -371,6 +380,8 @@ class _SignInState extends State { event.logicalKey == LogicalKeyboardKey.enter) { if (_formKey.currentState!.validate()) { submitSignInForm(); + } else { + MihAlertServices().formNotFilledCompletely(context); } } }, @@ -493,6 +504,9 @@ class _SignInState extends State { onPressed: () { if (_formKey.currentState!.validate()) { submitSignInForm(); + } else { + MihAlertServices() + .formNotFilledCompletely(context); } }, buttonColor: diff --git a/Frontend/lib/mih_packages/calendar/builder/build_appointment_list.dart b/Frontend/lib/mih_packages/calendar/builder/build_appointment_list.dart index ba9b0617..8b1abed4 100644 --- a/Frontend/lib/mih_packages/calendar/builder/build_appointment_list.dart +++ b/Frontend/lib/mih_packages/calendar/builder/build_appointment_list.dart @@ -1,5 +1,6 @@ import 'package:flutter_speed_dial/flutter_speed_dial.dart'; import 'package:mzansi_innovation_hub/main.dart'; +import 'package:mzansi_innovation_hub/mih_apis/mih_alert_services.dart'; import 'package:mzansi_innovation_hub/mih_apis/mih_mzansi_calendar_apis.dart'; import 'package:mzansi_innovation_hub/mih_apis/mih_validation_services.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_inputs_and_buttons/mih_date_input.dart'; @@ -482,6 +483,9 @@ class _BuildAppointmentListState extends State { onPressed: () { if (_formKey.currentState!.validate()) { updateAppointmentCall(index); + } else { + MihAlertServices() + .formNotFilledCompletely(context); } }, buttonColor: MzanziInnovationHub.of(context)! diff --git a/Frontend/lib/mih_packages/calendar/package_tools/appointments.dart b/Frontend/lib/mih_packages/calendar/package_tools/appointments.dart index e72c6717..f443d574 100644 --- a/Frontend/lib/mih_packages/calendar/package_tools/appointments.dart +++ b/Frontend/lib/mih_packages/calendar/package_tools/appointments.dart @@ -1,4 +1,5 @@ import 'package:flutter_speed_dial/flutter_speed_dial.dart'; +import 'package:mzansi_innovation_hub/mih_apis/mih_alert_services.dart'; import 'package:mzansi_innovation_hub/mih_apis/mih_mzansi_calendar_apis.dart'; import 'package:mzansi_innovation_hub/mih_apis/mih_validation_services.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_inputs_and_buttons/mih_date_input.dart'; @@ -178,6 +179,8 @@ class _PatientAccessRequestState extends State { onPressed: () { if (_formKey.currentState!.validate()) { addAppointmentCall(); + } else { + MihAlertServices().formNotFilledCompletely(context); } }, buttonColor: MzanziInnovationHub.of(context)! diff --git a/Frontend/lib/mih_packages/mzansi_profile/business_profile/builders/build_employee_list.dart b/Frontend/lib/mih_packages/mzansi_profile/business_profile/builders/build_employee_list.dart index 138a8033..8f907457 100644 --- a/Frontend/lib/mih_packages/mzansi_profile/business_profile/builders/build_employee_list.dart +++ b/Frontend/lib/mih_packages/mzansi_profile/business_profile/builders/build_employee_list.dart @@ -2,6 +2,7 @@ import 'dart:convert'; import 'package:flutter_speed_dial/flutter_speed_dial.dart'; import 'package:mzansi_innovation_hub/main.dart'; +import 'package:mzansi_innovation_hub/mih_apis/mih_alert_services.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_inputs_and_buttons/mih_dropdown_input.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_button.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_form.dart'; @@ -245,6 +246,8 @@ class _BuildEmployeeListState extends State { }, ); } + } else { + MihAlertServices().formNotFilledCompletely(context); } }, buttonColor: MzanziInnovationHub.of(context)! diff --git a/Frontend/lib/mih_packages/mzansi_profile/business_profile/builders/build_user_list.dart b/Frontend/lib/mih_packages/mzansi_profile/business_profile/builders/build_user_list.dart index 3ebb3792..c2709027 100644 --- a/Frontend/lib/mih_packages/mzansi_profile/business_profile/builders/build_user_list.dart +++ b/Frontend/lib/mih_packages/mzansi_profile/business_profile/builders/build_user_list.dart @@ -1,6 +1,7 @@ import 'dart:convert'; import 'package:mzansi_innovation_hub/main.dart'; +import 'package:mzansi_innovation_hub/mih_apis/mih_alert_services.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_inputs_and_buttons/mih_dropdown_input.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_button.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_form.dart'; @@ -200,6 +201,9 @@ class _BuildUserListState extends State { }, ); } + } else { + MihAlertServices() + .formNotFilledCompletely(context); } }, buttonColor: MzanziInnovationHub.of(context)! diff --git a/Frontend/lib/mih_packages/mzansi_profile/business_profile/package_tools/mih_business_details.dart b/Frontend/lib/mih_packages/mzansi_profile/business_profile/package_tools/mih_business_details.dart index 30f50114..0d2773cc 100644 --- a/Frontend/lib/mih_packages/mzansi_profile/business_profile/package_tools/mih_business_details.dart +++ b/Frontend/lib/mih_packages/mzansi_profile/business_profile/package_tools/mih_business_details.dart @@ -1,6 +1,7 @@ import 'package:file_picker/file_picker.dart'; import 'package:flutter/material.dart'; import 'package:mzansi_innovation_hub/main.dart'; +import 'package:mzansi_innovation_hub/mih_apis/mih_alert_services.dart'; import 'package:mzansi_innovation_hub/mih_apis/mih_business_details_apis.dart'; import 'package:mzansi_innovation_hub/mih_apis/mih_file_api.dart'; import 'package:mzansi_innovation_hub/mih_apis/mih_location_api.dart'; @@ -418,6 +419,8 @@ class _MihBusinessDetailsState extends State { onPressed: () { if (_formKey.currentState!.validate()) { submitForm(); + } else { + MihAlertServices().formNotFilledCompletely(context); } }, buttonColor: diff --git a/Frontend/lib/mih_packages/mzansi_profile/business_profile/package_tools/mih_my_business_user.dart b/Frontend/lib/mih_packages/mzansi_profile/business_profile/package_tools/mih_my_business_user.dart index 846a3445..06d64467 100644 --- a/Frontend/lib/mih_packages/mzansi_profile/business_profile/package_tools/mih_my_business_user.dart +++ b/Frontend/lib/mih_packages/mzansi_profile/business_profile/package_tools/mih_my_business_user.dart @@ -1,6 +1,7 @@ import 'package:file_picker/file_picker.dart'; import 'package:flutter/material.dart'; import 'package:mzansi_innovation_hub/main.dart'; +import 'package:mzansi_innovation_hub/mih_apis/mih_alert_services.dart'; import 'package:mzansi_innovation_hub/mih_apis/mih_file_api.dart'; import 'package:mzansi_innovation_hub/mih_apis/mih_my_business_user_apis.dart'; import 'package:mzansi_innovation_hub/mih_apis/mih_validation_services.dart'; @@ -366,6 +367,8 @@ class _MihMyBusinessUserState extends State { onPressed: () { if (_formKey.currentState!.validate()) { submitForm(); + } else { + MihAlertServices().formNotFilledCompletely(context); } }, buttonColor: diff --git a/Frontend/lib/mih_packages/mzansi_profile/business_profile/profile_business_add.dart b/Frontend/lib/mih_packages/mzansi_profile/business_profile/profile_business_add.dart index 38fbfa8e..b746bdcb 100644 --- a/Frontend/lib/mih_packages/mzansi_profile/business_profile/profile_business_add.dart +++ b/Frontend/lib/mih_packages/mzansi_profile/business_profile/profile_business_add.dart @@ -2,6 +2,7 @@ import 'dart:convert'; import 'package:http/http.dart'; import 'package:mzansi_innovation_hub/main.dart'; +import 'package:mzansi_innovation_hub/mih_apis/mih_alert_services.dart'; import 'package:mzansi_innovation_hub/mih_apis/mih_business_details_apis.dart'; import 'package:mzansi_innovation_hub/mih_apis/mih_file_api.dart'; import 'package:mzansi_innovation_hub/mih_apis/mih_location_api.dart'; @@ -309,6 +310,8 @@ class _ProfileBusinessAddState extends State { event.logicalKey == LogicalKeyboardKey.enter) { if (_formKey.currentState!.validate()) { submitForm(); + } else { + MihAlertServices().formNotFilledCompletely(context); } } }, @@ -572,6 +575,9 @@ class _ProfileBusinessAddState extends State { onPressed: () { if (_formKey.currentState!.validate()) { submitForm(); + } else { + MihAlertServices() + .formNotFilledCompletely(context); } }, buttonColor: MzanziInnovationHub.of(context)! diff --git a/Frontend/lib/mih_packages/mzansi_profile/personal_profile/package_tools/mih_personal_profile.dart b/Frontend/lib/mih_packages/mzansi_profile/personal_profile/package_tools/mih_personal_profile.dart index d25763ea..973b1f92 100644 --- a/Frontend/lib/mih_packages/mzansi_profile/personal_profile/package_tools/mih_personal_profile.dart +++ b/Frontend/lib/mih_packages/mzansi_profile/personal_profile/package_tools/mih_personal_profile.dart @@ -1,6 +1,7 @@ import 'dart:convert'; import 'package:mzansi_innovation_hub/main.dart'; +import 'package:mzansi_innovation_hub/mih_apis/mih_alert_services.dart'; import 'package:mzansi_innovation_hub/mih_apis/mih_file_api.dart'; import 'package:mzansi_innovation_hub/mih_apis/mih_user_apis.dart'; import 'package:mzansi_innovation_hub/mih_apis/mih_validation_services.dart'; @@ -362,6 +363,8 @@ class _MihPersonalProfileState extends State { //Add validation here if (_formKey.currentState!.validate()) { submitForm(); + } else { + MihAlertServices().formNotFilledCompletely(context); } }, buttonColor: diff --git a/Frontend/lib/mih_packages/mzansi_wallet/builder/build_loyalty_card_list.dart b/Frontend/lib/mih_packages/mzansi_wallet/builder/build_loyalty_card_list.dart index 07ba37ae..a5296b72 100644 --- a/Frontend/lib/mih_packages/mzansi_wallet/builder/build_loyalty_card_list.dart +++ b/Frontend/lib/mih_packages/mzansi_wallet/builder/build_loyalty_card_list.dart @@ -1,5 +1,6 @@ import 'package:flutter_speed_dial/flutter_speed_dial.dart'; import 'package:mzansi_innovation_hub/main.dart'; +import 'package:mzansi_innovation_hub/mih_apis/mih_alert_services.dart'; import 'package:mzansi_innovation_hub/mih_apis/mih_mzansi_wallet_apis.dart'; import 'package:mzansi_innovation_hub/mih_apis/mih_validation_services.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_button.dart'; @@ -136,6 +137,8 @@ class _BuildLoyaltyCardListState extends State { 0, ctxt, ); + } else { + MihAlertServices().formNotFilledCompletely(context); } }, buttonColor: MzanziInnovationHub.of(context)! diff --git a/Frontend/lib/mih_packages/mzansi_wallet/package_tools/mih_cards.dart b/Frontend/lib/mih_packages/mzansi_wallet/package_tools/mih_cards.dart index 7378d781..9459f3be 100644 --- a/Frontend/lib/mih_packages/mzansi_wallet/package_tools/mih_cards.dart +++ b/Frontend/lib/mih_packages/mzansi_wallet/package_tools/mih_cards.dart @@ -1,5 +1,6 @@ import 'package:flutter_speed_dial/flutter_speed_dial.dart'; import 'package:mzansi_innovation_hub/main.dart'; +import 'package:mzansi_innovation_hub/mih_apis/mih_alert_services.dart'; import 'package:mzansi_innovation_hub/mih_apis/mih_mzansi_wallet_apis.dart'; import 'package:mzansi_innovation_hub/mih_apis/mih_validation_services.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_inputs_and_buttons/mih_dropdown_input.dart'; @@ -261,6 +262,8 @@ class _MihCardsState extends State { context, ); } + } else { + MihAlertServices().formNotFilledCompletely(context); } }, buttonColor: MzanziInnovationHub.of(context)! diff --git a/Frontend/lib/mih_packages/patient_profile/pat_manager/list_builders/build_my_patient_list_list.dart b/Frontend/lib/mih_packages/patient_profile/pat_manager/list_builders/build_my_patient_list_list.dart index 216583a6..273e31f0 100644 --- a/Frontend/lib/mih_packages/patient_profile/pat_manager/list_builders/build_my_patient_list_list.dart +++ b/Frontend/lib/mih_packages/patient_profile/pat_manager/list_builders/build_my_patient_list_list.dart @@ -1,4 +1,5 @@ import 'package:mzansi_innovation_hub/main.dart'; +import 'package:mzansi_innovation_hub/mih_apis/mih_alert_services.dart'; import 'package:mzansi_innovation_hub/mih_apis/mih_api_calls.dart'; import 'package:mzansi_innovation_hub/mih_apis/mih_mzansi_calendar_apis.dart'; import 'package:mzansi_innovation_hub/mih_apis/mih_validation_services.dart'; @@ -179,6 +180,8 @@ class _BuildPatientsListState extends State { }, ); } + } else { + MihAlertServices().formNotFilledCompletely(context); } }, buttonColor: MzanziInnovationHub.of(context)! diff --git a/Frontend/lib/mih_packages/patient_profile/pat_manager/package_tools/waiting_room.dart b/Frontend/lib/mih_packages/patient_profile/pat_manager/package_tools/waiting_room.dart index ef2d2bd1..bc5a283e 100644 --- a/Frontend/lib/mih_packages/patient_profile/pat_manager/package_tools/waiting_room.dart +++ b/Frontend/lib/mih_packages/patient_profile/pat_manager/package_tools/waiting_room.dart @@ -1,5 +1,6 @@ import 'package:flutter_speed_dial/flutter_speed_dial.dart'; import 'package:mzansi_innovation_hub/main.dart'; +import 'package:mzansi_innovation_hub/mih_apis/mih_alert_services.dart'; import 'package:mzansi_innovation_hub/mih_apis/mih_mzansi_calendar_apis.dart'; import 'package:mzansi_innovation_hub/mih_apis/mih_validation_services.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_calendar.dart'; @@ -378,6 +379,8 @@ class _WaitingRoomState extends State { onPressed: () { if (_formKey.currentState!.validate()) { addAppointmentCall(); + } else { + MihAlertServices().formNotFilledCompletely(context); } }, buttonColor: MzanziInnovationHub.of(context)! diff --git a/Frontend/lib/mih_packages/patient_profile/pat_profile/components/Claim_Statement_Window.dart b/Frontend/lib/mih_packages/patient_profile/pat_profile/components/Claim_Statement_Window.dart index ffd6732e..61e185c9 100644 --- a/Frontend/lib/mih_packages/patient_profile/pat_profile/components/Claim_Statement_Window.dart +++ b/Frontend/lib/mih_packages/patient_profile/pat_profile/components/Claim_Statement_Window.dart @@ -1,6 +1,7 @@ import 'package:flutter/foundation.dart'; import 'package:flutter/services.dart'; import 'package:mzansi_innovation_hub/main.dart'; +import 'package:mzansi_innovation_hub/mih_apis/mih_alert_services.dart'; import 'package:mzansi_innovation_hub/mih_apis/mih_claim_statement_generation_api.dart'; import 'package:mzansi_innovation_hub/mih_apis/mih_icd10_code_api.dart'; import 'package:mzansi_innovation_hub/mih_apis/mih_validation_services.dart'; @@ -357,6 +358,8 @@ class _ClaimStatementWindowState extends State { }, ); } + } else { + MihAlertServices().formNotFilledCompletely(context); } }, buttonColor: diff --git a/Frontend/lib/mih_packages/patient_profile/pat_profile/package_tools/patient_consultation.dart b/Frontend/lib/mih_packages/patient_profile/pat_profile/package_tools/patient_consultation.dart index 0f8abc55..9787984c 100644 --- a/Frontend/lib/mih_packages/patient_profile/pat_profile/package_tools/patient_consultation.dart +++ b/Frontend/lib/mih_packages/patient_profile/pat_profile/package_tools/patient_consultation.dart @@ -1,6 +1,7 @@ import 'dart:convert'; import 'package:flutter_speed_dial/flutter_speed_dial.dart'; import 'package:mzansi_innovation_hub/main.dart'; +import 'package:mzansi_innovation_hub/mih_apis/mih_alert_services.dart'; import 'package:mzansi_innovation_hub/mih_apis/mih_validation_services.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_layout/mih_single_child_scroll.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_button.dart'; @@ -204,6 +205,8 @@ class _PatientConsultationState extends State { if (_formKey.currentState!.validate()) { addPatientNoteAPICall(); Navigator.pop(context); + } else { + MihAlertServices().formNotFilledCompletely(context); } }, buttonColor: diff --git a/Frontend/lib/mih_packages/patient_profile/pat_profile/patient_add.dart b/Frontend/lib/mih_packages/patient_profile/pat_profile/patient_add.dart index e3a236c2..4afaabfa 100644 --- a/Frontend/lib/mih_packages/patient_profile/pat_profile/patient_add.dart +++ b/Frontend/lib/mih_packages/patient_profile/pat_profile/patient_add.dart @@ -1,6 +1,7 @@ import 'dart:convert'; import 'package:mzansi_innovation_hub/main.dart'; +import 'package:mzansi_innovation_hub/mih_apis/mih_alert_services.dart'; import 'package:mzansi_innovation_hub/mih_apis/mih_validation_services.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_inputs_and_buttons/mih_dropdown_input.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_layout/mih_action.dart'; @@ -412,6 +413,8 @@ class _AddPatientState extends State { onPressed: () { if (_formKey.currentState!.validate()) { submitForm(); + } else { + MihAlertServices().formNotFilledCompletely(context); } }, buttonColor: @@ -479,6 +482,8 @@ class _AddPatientState extends State { event.logicalKey == LogicalKeyboardKey.enter) { if (_formKey.currentState!.validate()) { submitForm(); + } else { + MihAlertServices().formNotFilledCompletely(context); } } }, diff --git a/Frontend/lib/mih_packages/patient_profile/pat_profile/patient_edit.dart b/Frontend/lib/mih_packages/patient_profile/pat_profile/patient_edit.dart index c86e420a..63dd4f86 100644 --- a/Frontend/lib/mih_packages/patient_profile/pat_profile/patient_edit.dart +++ b/Frontend/lib/mih_packages/patient_profile/pat_profile/patient_edit.dart @@ -1,6 +1,7 @@ import 'dart:convert'; import 'package:mzansi_innovation_hub/main.dart'; +import 'package:mzansi_innovation_hub/mih_apis/mih_alert_services.dart'; import 'package:mzansi_innovation_hub/mih_apis/mih_validation_services.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_inputs_and_buttons/mih_dropdown_input.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_layout/mih_action.dart'; @@ -626,6 +627,8 @@ class _EditPatientState extends State { onPressed: () { if (_formKey.currentState!.validate()) { submitForm(); + } else { + MihAlertServices().formNotFilledCompletely(context); } }, buttonColor: @@ -693,6 +696,8 @@ class _EditPatientState extends State { event.logicalKey == LogicalKeyboardKey.enter) { if (_formKey.currentState!.validate()) { submitForm(); + } else { + MihAlertServices().formNotFilledCompletely(context); } } }, From 297a5cba0931a6614328cd2849fb53f492dfddbb Mon Sep 17 00:00:00 2001 From: Yasien Mac Mini Date: Fri, 6 Jun 2025 14:12:31 +0200 Subject: [PATCH 51/52] fix import --- Frontend/lib/mih_packages/authentication/signin.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Frontend/lib/mih_packages/authentication/signin.dart b/Frontend/lib/mih_packages/authentication/signin.dart index ec17413b..188bcd5f 100644 --- a/Frontend/lib/mih_packages/authentication/signin.dart +++ b/Frontend/lib/mih_packages/authentication/signin.dart @@ -1,6 +1,6 @@ import 'dart:convert'; import 'package:mzansi_innovation_hub/mih_apis/mih_alert_services.dart'; -import 'package:mzansi_innovation_hub/mih_apis/mih_install_Services.dart'; +import 'package:mzansi_innovation_hub/mih_apis/mih_install_services.dart'; import 'package:mzansi_innovation_hub/mih_apis/mih_validation_services.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_button.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_form.dart'; From cb70968118c5264c0e88e73f2b49fb4c51e3918d Mon Sep 17 00:00:00 2001 From: Yasien Mac Mini Date: Fri, 6 Jun 2025 14:13:22 +0200 Subject: [PATCH 52/52] add sandbox accounts back --- .../mih_packages/authentication/signin.dart | 81 +++++++++---------- 1 file changed, 39 insertions(+), 42 deletions(-) diff --git a/Frontend/lib/mih_packages/authentication/signin.dart b/Frontend/lib/mih_packages/authentication/signin.dart index 188bcd5f..1f17a7c3 100644 --- a/Frontend/lib/mih_packages/authentication/signin.dart +++ b/Frontend/lib/mih_packages/authentication/signin.dart @@ -549,52 +549,49 @@ class _SignInState extends State { //spacer const SizedBox(height: 35), - Visibility( - visible: AppEnviroment.getEnv() == "Dev", - child: Center( - child: SizedBox( - width: width, - //height: 100.0, - child: Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - const Flexible( - flex: 1, - child: Padding( - padding: EdgeInsets.only(right: 10.0), - child: Divider(), - ), + Center( + child: SizedBox( + width: width, + //height: 100.0, + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + const Flexible( + flex: 1, + child: Padding( + padding: EdgeInsets.only(right: 10.0), + child: Divider(), ), - Flexible( - flex: 1, - child: GestureDetector( - child: Text( - 'Use Sandox Profile', - textAlign: TextAlign.center, - style: TextStyle( - fontWeight: FontWeight.bold, - fontSize: 15, - color: MzanziInnovationHub.of( - context)! - .theme - .secondaryColor()), - ), - onTap: () { - setState(() { - showProfiles = !showProfiles; - }); - }, + ), + Flexible( + flex: 1, + child: GestureDetector( + child: Text( + 'Use Sandox Profile', + textAlign: TextAlign.center, + style: TextStyle( + fontWeight: FontWeight.bold, + fontSize: 15, + color: MzanziInnovationHub.of( + context)! + .theme + .secondaryColor()), ), + onTap: () { + setState(() { + showProfiles = !showProfiles; + }); + }, ), - const Flexible( - flex: 1, - child: Padding( - padding: EdgeInsets.only(left: 10.0), - child: Divider(), - ), + ), + const Flexible( + flex: 1, + child: Padding( + padding: EdgeInsets.only(left: 10.0), + child: Divider(), ), - ], - ), + ), + ], ), ), ),