From cc59c3c6f0af170a1baaa3f666ad05b8dc566e91 Mon Sep 17 00:00:00 2001 From: Yasien Mac Mini Date: Mon, 17 Mar 2025 14:02:43 +0200 Subject: [PATCH 01/17] fix missing business user param --- .../patient_profile/pat_manager/app_tools/waiting_room.dart | 1 - .../mih_packages/patient_profile/pat_manager/pat_manager.dart | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/Frontend/lib/mih_packages/patient_profile/pat_manager/app_tools/waiting_room.dart b/Frontend/lib/mih_packages/patient_profile/pat_manager/app_tools/waiting_room.dart index e7ff178b..6675d2ac 100644 --- a/Frontend/lib/mih_packages/patient_profile/pat_manager/app_tools/waiting_room.dart +++ b/Frontend/lib/mih_packages/patient_profile/pat_manager/app_tools/waiting_room.dart @@ -262,7 +262,6 @@ class _WaitingRoomState extends State { } void addAppointmentWindow() { - print(widget.personalSelected); showDialog( context: context, barrierDismissible: false, diff --git a/Frontend/lib/mih_packages/patient_profile/pat_manager/pat_manager.dart b/Frontend/lib/mih_packages/patient_profile/pat_manager/pat_manager.dart index 851132a3..c517c7a6 100644 --- a/Frontend/lib/mih_packages/patient_profile/pat_manager/pat_manager.dart +++ b/Frontend/lib/mih_packages/patient_profile/pat_manager/pat_manager.dart @@ -38,7 +38,6 @@ class _PatManagerState extends State { setState(() { _selcetedIndex = newValue; }); - print("Index: $_selcetedIndex"); }, ); } @@ -96,6 +95,7 @@ class _PatManagerState extends State { MyPatientList( signedInUser: widget.arguments.signedInUser, business: widget.arguments.business, + businessUser: widget.arguments.businessUser, personalSelected: widget.arguments.personalSelected, ), MihPatientSearch( From 2a746838a95dcda3d7dce4c0cf370cefc617ecb8 Mon Sep 17 00:00:00 2001 From: Yasien Mac Mini Date: Mon, 17 Mar 2025 14:03:36 +0200 Subject: [PATCH 02/17] Update route to new patient profile --- Frontend/lib/mih_router/routeGenerator.dart | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Frontend/lib/mih_router/routeGenerator.dart b/Frontend/lib/mih_router/routeGenerator.dart index 1607893a..ef3908dd 100644 --- a/Frontend/lib/mih_router/routeGenerator.dart +++ b/Frontend/lib/mih_router/routeGenerator.dart @@ -11,19 +11,19 @@ import 'package:Mzansi_Innovation_Hub/mih_packages/mzansi_profile/personal_profi import 'package:Mzansi_Innovation_Hub/mih_packages/mzansi_wallet/components/mih_barcode_scanner.dart'; import 'package:Mzansi_Innovation_Hub/mih_packages/mzansi_wallet/mih_wallet.dart'; import 'package:Mzansi_Innovation_Hub/mih_packages/patient_profile/pat_manager/pat_manager.dart'; +import 'package:Mzansi_Innovation_Hub/mih_packages/patient_profile/pat_profile/add_or_view_patient.dart'; +import 'package:Mzansi_Innovation_Hub/mih_packages/patient_profile/pat_profile/patient_add.dart'; +import 'package:Mzansi_Innovation_Hub/mih_packages/patient_profile/pat_profile/patient_edit.dart'; +import 'package:Mzansi_Innovation_Hub/mih_packages/patient_profile/pat_profile/patient_profile.dart'; import 'package:flutter/material.dart'; import '../mih_components/mih_layout/mih_print_prevew.dart'; import '../mih_components/mih_pop_up_messages/mih_notification_message.dart'; import '../mih_packages/authentication/auth_check.dart'; -import '../mih_packages/patient_profile/add_or_view_patient.dart'; -import '../mih_packages/patient_profile/patient_add.dart'; -import '../mih_packages/patient_profile/patient_edit.dart'; import '../mih_objects/app_user.dart'; import '../mih_objects/arguments.dart'; import '../mih_packages/authentication/forgot_password.dart'; import '../mih_packages/authentication/reset_password.dart'; -import '../mih_packages/patient_profile/full_screen_file.dart'; -import '../mih_packages/patient_profile/patient_view.dart'; +import '../mih_packages/patient_profile/pat_profile/components/full_screen_file.dart'; import '../mih_packages/manage_business/profile_business_add.dart'; class RouteGenerator { @@ -270,7 +270,7 @@ class RouteGenerator { if (args is PatientViewArguments) { return MaterialPageRoute( settings: settings, - builder: (_) => PatientView( + builder: (_) => PatientProfile( arguments: args, ), ); From c8dfe99242f5ab86ddf6a44e29e3b1d5b5492a36 Mon Sep 17 00:00:00 2001 From: Yasien Mac Mini Date: Mon, 17 Mar 2025 14:04:11 +0200 Subject: [PATCH 03/17] pointmto new patient profile and add profile --- .../pat_profile/add_or_view_patient.dart | 95 +++++++++++++++++++ 1 file changed, 95 insertions(+) create mode 100644 Frontend/lib/mih_packages/patient_profile/pat_profile/add_or_view_patient.dart diff --git a/Frontend/lib/mih_packages/patient_profile/pat_profile/add_or_view_patient.dart b/Frontend/lib/mih_packages/patient_profile/pat_profile/add_or_view_patient.dart new file mode 100644 index 00000000..456b7418 --- /dev/null +++ b/Frontend/lib/mih_packages/patient_profile/pat_profile/add_or_view_patient.dart @@ -0,0 +1,95 @@ +import 'dart:convert'; + +import 'package:Mzansi_Innovation_Hub/main.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/arguments.dart'; +import 'package:Mzansi_Innovation_Hub/mih_objects/patients.dart'; +import 'package:Mzansi_Innovation_Hub/mih_packages/patient_profile/pat_profile/patient_add.dart'; +import 'package:Mzansi_Innovation_Hub/mih_packages/patient_profile/pat_profile/patient_profile.dart'; +import 'package:flutter/material.dart'; +import 'package:supertokens_flutter/http.dart' as http; + +class AddOrViewPatient extends StatefulWidget { + //final AppUser signedInUser; + final PatientViewArguments arguments; + const AddOrViewPatient({ + super.key, + required this.arguments, + }); + + @override + State createState() => _AddOrViewPatientState(); +} + +class _AddOrViewPatientState extends State { + late double width; + late double height; + late Widget loading; + + Future fetchPatient() async { + //print("Patien manager page: $endpoint"); + final response = await http.get(Uri.parse( + "${AppEnviroment.baseApiUrl}/patients/${widget.arguments.signedInUser.app_id}")); + // print("Here"); + // print("Body: ${response.body}"); + // print("Code: ${response.statusCode}"); + // var errorCode = response.statusCode.toString(); + // var errorBody = response.body; + + if (response.statusCode == 200) { + // print("Here1"); + var decodedData = jsonDecode(response.body); + // print("Here2"); + Patient patients = Patient.fromJson(decodedData as Map); + // print("Here3"); + // print(patients); + return patients; + } + return null; + } + + @override + void dispose() { + // TODO: implement dispose + super.dispose(); + } + + @override + Widget build(BuildContext context) { + var size = MediaQuery.of(context).size; + setState(() { + width = size.width; + height = size.height; + }); + return FutureBuilder( + future: fetchPatient(), + builder: (ctx, snapshot) { + if (snapshot.connectionState == ConnectionState.done && + snapshot.hasData) { + // Extracting data from snapshot object + //final data = snapshot.data as String; + return PatientProfile( + arguments: PatientViewArguments( + widget.arguments.signedInUser, + snapshot.requireData, + null, + null, + widget.arguments.type, + )); + } else if (snapshot.connectionState == ConnectionState.waiting) { + loading = Container( + width: width, + height: height, + color: MzanziInnovationHub.of(context)!.theme.primaryColor(), + child: const Mihloadingcircle(), + ); + + return loading; + } else { + return AddPatient(signedInUser: widget.arguments.signedInUser); + } + }, + ); + } +} From 73561e1a99386c5985304d1dec6b5e0a2e49e14c Mon Sep 17 00:00:00 2001 From: Yasien Mac Mini Date: Mon, 17 Mar 2025 14:04:40 +0200 Subject: [PATCH 04/17] move edit and delete into new package --- .../patient_profile/add_or_view_patient.dart | 96 --- .../pat_profile/patient_add.dart | 444 +++++++++++ .../pat_profile/patient_edit.dart | 718 ++++++++++++++++++ 3 files changed, 1162 insertions(+), 96 deletions(-) delete mode 100644 Frontend/lib/mih_packages/patient_profile/add_or_view_patient.dart create mode 100644 Frontend/lib/mih_packages/patient_profile/pat_profile/patient_add.dart create mode 100644 Frontend/lib/mih_packages/patient_profile/pat_profile/patient_edit.dart diff --git a/Frontend/lib/mih_packages/patient_profile/add_or_view_patient.dart b/Frontend/lib/mih_packages/patient_profile/add_or_view_patient.dart deleted file mode 100644 index ca6f5630..00000000 --- a/Frontend/lib/mih_packages/patient_profile/add_or_view_patient.dart +++ /dev/null @@ -1,96 +0,0 @@ -import 'dart:convert'; - -import 'package:flutter/material.dart'; -import '../../main.dart'; -import 'package:supertokens_flutter/http.dart' as http; - -import '../../mih_components/mih_pop_up_messages/mih_loading_circle.dart'; -import '../../mih_env/env.dart'; -import '../../mih_objects/arguments.dart'; -import '../../mih_objects/patients.dart'; -import 'patient_add.dart'; -import 'patient_view.dart'; - -class AddOrViewPatient extends StatefulWidget { - //final AppUser signedInUser; - final PatientViewArguments arguments; - const AddOrViewPatient({ - super.key, - required this.arguments, - }); - - @override - State createState() => _AddOrViewPatientState(); -} - -class _AddOrViewPatientState extends State { - late double width; - late double height; - late Widget loading; - - Future fetchPatient() async { - //print("Patien manager page: $endpoint"); - final response = await http.get(Uri.parse( - "${AppEnviroment.baseApiUrl}/patients/${widget.arguments.signedInUser.app_id}")); - // print("Here"); - // print("Body: ${response.body}"); - // print("Code: ${response.statusCode}"); - // var errorCode = response.statusCode.toString(); - // var errorBody = response.body; - - if (response.statusCode == 200) { - // print("Here1"); - var decodedData = jsonDecode(response.body); - // print("Here2"); - Patient patients = Patient.fromJson(decodedData as Map); - // print("Here3"); - // print(patients); - return patients; - } - return null; - } - - @override - void dispose() { - // TODO: implement dispose - super.dispose(); - } - - @override - Widget build(BuildContext context) { - var size = MediaQuery.of(context).size; - setState(() { - width = size.width; - height = size.height; - }); - return FutureBuilder( - future: fetchPatient(), - builder: (ctx, snapshot) { - if (snapshot.connectionState == ConnectionState.done && - snapshot.hasData) { - // Extracting data from snapshot object - //final data = snapshot.data as String; - return PatientView( - arguments: PatientViewArguments( - widget.arguments.signedInUser, - snapshot.requireData, - null, - null, - widget.arguments.type, - )); - } else if (snapshot.connectionState == ConnectionState.waiting) { - loading = Container( - width: width, - height: height, - color: MzanziInnovationHub.of(context)!.theme.primaryColor(), - child: const Mihloadingcircle(), - ); - - return loading; - } else { - return AddPatient(signedInUser: widget.arguments.signedInUser); - } - }, - ); - } -} 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 new file mode 100644 index 00000000..95d677c1 --- /dev/null +++ b/Frontend/lib/mih_packages/patient_profile/pat_profile/patient_add.dart @@ -0,0 +1,444 @@ +import 'dart:convert'; + +import 'package:Mzansi_Innovation_Hub/main.dart'; +import 'package:Mzansi_Innovation_Hub/mih_components/mih_inputs_and_buttons/mih_button.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_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'; +import 'package:Mzansi_Innovation_Hub/mih_objects/app_user.dart'; +import 'package:Mzansi_Innovation_Hub/mih_objects/arguments.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:supertokens_flutter/http.dart' as http; + +class AddPatient extends StatefulWidget { + final AppUser signedInUser; + + const AddPatient({ + super.key, + required this.signedInUser, + }); + + @override + State createState() => _AddPatientState(); +} + +class _AddPatientState extends State { + final idController = TextEditingController(); + final fnameController = TextEditingController(); + final lnameController = TextEditingController(); + final cellController = TextEditingController(); + final emailController = TextEditingController(); + final medNoController = TextEditingController(); + final medNameController = TextEditingController(); + final medSchemeController = TextEditingController(); + final addressController = TextEditingController(); + final medAidController = TextEditingController(); + final medMainMemController = TextEditingController(); + final medAidCodeController = TextEditingController(); + + final baseAPI = AppEnviroment.baseApiUrl; + late int futureDocOfficeId; + //late bool medRequired; + final ValueNotifier medRequired = ValueNotifier(false); + final FocusNode _focusNode = FocusNode(); + + bool isFieldsFilled() { + if (medRequired.value) { + if (idController.text.isEmpty || + fnameController.text.isEmpty || + lnameController.text.isEmpty || + cellController.text.isEmpty || + emailController.text.isEmpty || + medNoController.text.isEmpty || + medNameController.text.isEmpty || + medSchemeController.text.isEmpty || + addressController.text.isEmpty || + medAidController.text.isEmpty || + medMainMemController.text.isEmpty || + medAidCodeController.text.isEmpty) { + return false; + } else { + return true; + } + } else { + if (idController.text.isEmpty || + fnameController.text.isEmpty || + lnameController.text.isEmpty || + cellController.text.isEmpty || + emailController.text.isEmpty || + addressController.text.isEmpty || + medAidController.text.isEmpty) { + return false; + } else { + return true; + } + } + } + + Future addPatientAPICall() async { + var response = await http.post( + Uri.parse("$baseAPI/patients/insert/"), + headers: { + "Content-Type": "application/json; charset=UTF-8" + }, + body: jsonEncode({ + "id_no": idController.text, + "first_name": fnameController.text, + "last_name": lnameController.text, + "email": emailController.text, + "cell_no": cellController.text, + "medical_aid": medAidController.text, + "medical_aid_main_member": medMainMemController.text, + "medical_aid_no": medNoController.text, + "medical_aid_code": medAidCodeController.text, + "medical_aid_name": medNameController.text, + "medical_aid_scheme": medSchemeController.text, + "address": addressController.text, + "app_id": widget.signedInUser.app_id, + }), + ); + if (response.statusCode == 201) { + Navigator.of(context).popAndPushNamed('/patient-profile', + arguments: PatientViewArguments( + widget.signedInUser, null, null, null, "personal")); + String message = + "${fnameController.text} ${lnameController.text} patient profiole has been successfully added!\n"; + successPopUp(message); + } else { + internetConnectionPopUp(); + } + } + + void internetConnectionPopUp() { + showDialog( + context: context, + builder: (context) { + return const MIHErrorMessage(errorType: "Internet Connection"); + }, + ); + } + + void messagePopUp(error) { + showDialog( + context: context, + builder: (context) { + return AlertDialog( + title: Text(error), + ); + }, + ); + } + + void successPopUp(String message) { + showDialog( + context: context, + builder: (context) { + return MIHSuccessMessage( + successType: "Success", + successMessage: message, + ); + }, + ); + } + + void isRequired() { + //print("listerner triggered"); + if (medAidController.text == "Yes") { + medRequired.value = true; + } else { + medRequired.value = false; + } + } + + Widget displayForm() { + return 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"], + ), + 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 Scheme", + editable: value, + required: value, + ), + ], + ), + ); + }, + ), + const SizedBox(height: 30.0), + SizedBox( + width: 450.0, + height: 50.0, + child: MIHButton( + onTap: () { + submitForm(); + }, + buttonText: "Add", + buttonColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + textColor: MzanziInnovationHub.of(context)!.theme.primaryColor(), + ), + ), + ], + ); + } + + void submitForm() { + if (isFieldsFilled()) { + addPatientAPICall(); + } else { + showDialog( + context: context, + builder: (context) { + return const MIHErrorMessage(errorType: "Input Error"); + }, + ); + } + } + + MIHAction getActionButton() { + return MIHAction( + icon: const Icon(Icons.arrow_back), + iconSize: 35, + onTap: () { + Navigator.of(context).pop(); + }, + ); + } + + MIHHeader getHeader() { + return const MIHHeader( + headerAlignment: MainAxisAlignment.center, + headerItems: [ + Text( + "Add Patient Details", + style: TextStyle( + fontWeight: FontWeight.bold, + fontSize: 25, + ), + ), + ], + ); + } + + MIHBody getBody() { + return MIHBody( + borderOn: true, + bodyItems: [ + KeyboardListener( + focusNode: _focusNode, + autofocus: true, + onKeyEvent: (event) async { + if (event is KeyDownEvent && + event.logicalKey == LogicalKeyboardKey.enter) { + submitForm(); + } + }, + child: displayForm(), + ), + ], + ); + } + + @override + void dispose() { + idController.dispose(); + fnameController.dispose(); + lnameController.dispose(); + cellController.dispose(); + emailController.dispose(); + medNoController.dispose(); + medNameController.dispose(); + medSchemeController.dispose(); + addressController.dispose(); + medAidController.dispose(); + medAidCodeController.removeListener(isRequired); + medRequired.dispose(); + medMainMemController.dispose(); + medAidCodeController.dispose(); + _focusNode.dispose(); + super.dispose(); + } + + @override + void initState() { + medAidController.addListener(isRequired); + setState(() { + fnameController.text = widget.signedInUser.fname; + lnameController.text = widget.signedInUser.lname; + emailController.text = widget.signedInUser.email; + medAidController.text = "No"; + }); + super.initState(); + } + + @override + Widget build(BuildContext context) { + return MIHLayoutBuilder( + actionButton: getActionButton(), + header: getHeader(), + secondaryActionButton: null, + body: getBody(), + actionDrawer: null, + secondaryActionDrawer: null, + bottomNavBar: null, + pullDownToRefresh: false, + onPullDown: () async {}, + ); + // return Scaffold( + // // appBar: const MIHAppBar( + // // barTitle: "Add Patient", + // // propicFile: null, + // // ), + // //drawer: MIHAppDrawer(signedInUser: widget.signedInUser), + // 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), + // ), + // ) + // ], + // ), + // ), + // ); + } +} 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 new file mode 100644 index 00000000..ea108318 --- /dev/null +++ b/Frontend/lib/mih_packages/patient_profile/pat_profile/patient_edit.dart @@ -0,0 +1,718 @@ +import 'dart:convert'; + +import 'package:Mzansi_Innovation_Hub/main.dart'; +import 'package:Mzansi_Innovation_Hub/mih_components/mih_inputs_and_buttons/mih_button.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_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'; +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'; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:supertokens_flutter/supertokens.dart'; +import 'package:supertokens_flutter/http.dart' as http; + +class EditPatient extends StatefulWidget { + final Patient selectedPatient; + final AppUser signedInUser; + const EditPatient({ + super.key, + required this.selectedPatient, + required this.signedInUser, + }); + + @override + State createState() => _EditPatientState(); +} + +class _EditPatientState extends State { + var idController = TextEditingController(); + final fnameController = TextEditingController(); + final lnameController = TextEditingController(); + final cellController = TextEditingController(); + final emailController = TextEditingController(); + final medNoController = TextEditingController(); + final medNameController = TextEditingController(); + final medSchemeController = TextEditingController(); + final addressController = TextEditingController(); + final medAidController = TextEditingController(); + final medMainMemController = TextEditingController(); + final medAidCodeController = TextEditingController(); + final baseAPI = AppEnviroment.baseApiUrl; + final docOfficeIdApiUrl = "${AppEnviroment.baseApiUrl}/users/profile/"; + final apiUrlEdit = "${AppEnviroment.baseApiUrl}/patients/update/"; + final apiUrlDelete = "${AppEnviroment.baseApiUrl}/patients/delete/"; + + late int futureDocOfficeId; + late String userEmail; + // bool medRequired = false; + final ValueNotifier medRequired = ValueNotifier(false); + + late double width; + late double height; + + final FocusNode _focusNode = FocusNode(); + + // Future getOfficeIdByUser(String endpoint) async { + // final response = await http.get(Uri.parse(endpoint)); + // if (response.statusCode == 200) { + // String body = response.body; + // var decodedData = jsonDecode(body); + // AppUser u = AppUser.fromJson(decodedData as Map); + // setState(() { + // //futureDocOfficeId = u.docOffice_id; + // //print(futureDocOfficeId); + // }); + // } else { + // internetConnectionPopUp(); + // throw Exception('failed to load patients'); + // } + // } + + Future updatePatientApiCall() async { + //print("Here1"); + //userEmail = getLoginUserEmail() as String; + //print(userEmail); + //print("Here2"); + //await getOfficeIdByUser(docOfficeIdApiUrl + userEmail); + //print(futureDocOfficeId.toString()); + //print("Here3"); + var response = await http.put( + Uri.parse(apiUrlEdit), + headers: { + "Content-Type": "application/json; charset=UTF-8" + }, + body: jsonEncode({ + "id_no": idController.text, + "first_name": fnameController.text, + "last_name": lnameController.text, + "email": emailController.text, + "cell_no": cellController.text, + "medical_aid": medAidController.text, + "medical_aid_main_member": medMainMemController.text, + "medical_aid_no": medNoController.text, + "medical_aid_code": medAidCodeController.text, + "medical_aid_name": medNameController.text, + "medical_aid_scheme": medSchemeController.text, + "address": addressController.text, + "app_id": widget.selectedPatient.app_id, + }), + ); + // print("Here4"); + // print(response.statusCode); + if (response.statusCode == 200) { + Navigator.of(context).pop(); + Navigator.of(context).pop(); + Navigator.of(context).pushNamed('/patient-profile', + arguments: PatientViewArguments( + widget.signedInUser, null, null, null, "personal")); + //Navigator.of(context).pushNamed('/'); + String message = + "${fnameController.text} ${lnameController.text}'s information has been updated successfully! Their medical records and details are now current."; + successPopUp(message); + } else { + internetConnectionPopUp(); + } + } + + Future deletePatientApiCall() async { + //print("Here1"); + //userEmail = getLoginUserEmail() as String; + //print(userEmail); + //print("Here2"); + //await getOfficeIdByUser(docOfficeIdApiUrl + userEmail); + //print("Office ID: ${futureDocOfficeId.toString()}"); + //print("OPatient ID No: ${idController.text}"); + //print("Here3"); + var response = await http.delete( + Uri.parse(apiUrlDelete), + headers: { + "Content-Type": "application/json; charset=UTF-8" + }, + body: jsonEncode( + {"app_id": widget.selectedPatient.app_id}), + ); + //print("Here4"); + //print(response.statusCode); + if (response.statusCode == 200) { + Navigator.of(context).pop(); + Navigator.of(context).pop(); + Navigator.of(context).popAndPushNamed('/patient-profile', + arguments: PatientViewArguments( + widget.signedInUser, null, null, null, "personal")); + String message = + "${fnameController.text} ${lnameController.text}'s record has been deleted successfully. This means it will no longer be visible in patient manager and cannot be used for future appointments."; + successPopUp(message); + } else { + internetConnectionPopUp(); + } + } + + Future getLoginUserEmail() async { + var uid = await SuperTokens.getUserId(); + var response = await http.get(Uri.parse("$baseAPI/user/$uid")); + if (response.statusCode == 200) { + var user = jsonDecode(response.body); + userEmail = user["email"]; + } + } + + void messagePopUp(error) { + showDialog( + context: context, + builder: (context) { + return AlertDialog( + title: Text(error), + ); + }, + ); + } + + void internetConnectionPopUp() { + showDialog( + context: context, + builder: (context) { + return const MIHErrorMessage(errorType: "Internet Connection"); + }, + ); + } + + void deletePatientPopUp() { + showDialog( + context: context, + barrierDismissible: false, + builder: (context) => Dialog( + child: Stack( + children: [ + Container( + padding: const EdgeInsets.all(10.0), + width: 700.0, + height: (height / 3) * 2, + decoration: BoxDecoration( + color: MzanziInnovationHub.of(context)!.theme.primaryColor(), + borderRadius: BorderRadius.circular(25.0), + border: Border.all( + color: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + width: 5.0), + ), + child: SingleChildScrollView( + child: Column( + //mainAxisSize: MainAxisSize.max, + children: [ + Icon( + Icons.warning_amber_rounded, + size: 100, + color: MzanziInnovationHub.of(context)! + .theme + .secondaryColor(), + ), + const SizedBox(height: 15), + Text( + "Are you sure you want to delete this?", + textAlign: TextAlign.center, + style: TextStyle( + color: MzanziInnovationHub.of(context)! + .theme + .secondaryColor(), + fontSize: 25.0, + fontWeight: FontWeight.bold, + ), + ), + const SizedBox(height: 10), + Padding( + padding: const EdgeInsets.symmetric(horizontal: 25.0), + child: Text( + "This action is permanent! Deleting ${fnameController.text} ${lnameController.text} will remove him\\her from your account. You won't be able to recover it once it's gone.", + style: TextStyle( + color: MzanziInnovationHub.of(context)! + .theme + .secondaryColor(), + fontSize: 15.0, + fontWeight: FontWeight.bold, + ), + ), + ), + const SizedBox(height: 15), + Padding( + padding: const EdgeInsets.symmetric(horizontal: 25.0), + child: Text( + "Here's what you'll be deleting:", + style: TextStyle( + color: MzanziInnovationHub.of(context)! + .theme + .secondaryColor(), + fontSize: 20.0, + fontWeight: FontWeight.bold, + ), + ), + ), + const SizedBox(height: 10), + Padding( + padding: const EdgeInsets.symmetric(horizontal: 25.0), + child: SizedBox( + width: 450, + child: Text( + "1) Patient Profile Information.\n2) Patient Notes\n3) Patient Files.", + textAlign: TextAlign.left, + style: TextStyle( + color: MzanziInnovationHub.of(context)! + .theme + .secondaryColor(), + fontSize: 15.0, + fontWeight: FontWeight.bold, + ), + ), + ), + ), + SizedBox( + width: 300, + height: 50, + child: MIHButton( + onTap: deletePatientApiCall, + buttonText: "Delete", + buttonColor: MzanziInnovationHub.of(context)! + .theme + .secondaryColor(), + textColor: MzanziInnovationHub.of(context)! + .theme + .primaryColor(), + )) + ], + ), + ), + ), + Positioned( + top: 5, + right: 5, + width: 50, + height: 50, + child: IconButton( + onPressed: () { + Navigator.pop(context); + }, + icon: Icon( + Icons.close, + color: MzanziInnovationHub.of(context)!.theme.errorColor(), + size: 35, + ), + ), + ), + ], + ), + ), + ); + } + + void successPopUp(String message) { + showDialog( + context: context, + builder: (context) { + return MIHSuccessMessage( + successType: "Success", + successMessage: message, + ); + }, + ); + } + + bool isFieldsFilled() { + if (medRequired.value) { + if (idController.text.isEmpty || + fnameController.text.isEmpty || + lnameController.text.isEmpty || + cellController.text.isEmpty || + emailController.text.isEmpty || + medNoController.text.isEmpty || + medNameController.text.isEmpty || + medSchemeController.text.isEmpty || + addressController.text.isEmpty || + medAidController.text.isEmpty || + medMainMemController.text.isEmpty || + medAidCodeController.text.isEmpty) { + return false; + } else { + return true; + } + } else { + if (idController.text.isEmpty || + fnameController.text.isEmpty || + lnameController.text.isEmpty || + cellController.text.isEmpty || + emailController.text.isEmpty || + addressController.text.isEmpty || + medAidController.text.isEmpty) { + return false; + } else { + return true; + } + } + } + + void isRequired() { + print("listerner triggered"); + if (medAidController.text == "Yes") { + medRequired.value = true; + } else if (medAidController.text == "No") { + medRequired.value = false; + } else { + //print("here"); + } + } + + Widget displayForm() { + return SingleChildScrollView( + child: Column( + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text( + "Personal Details", + textAlign: TextAlign.center, + style: TextStyle( + fontWeight: FontWeight.bold, + fontSize: 22.0, + color: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + ), + ), + IconButton( + icon: const Icon(Icons.delete), + color: MzanziInnovationHub.of(context)!.theme.secondaryColor(), + //alignment: Alignment.topRight, + onPressed: () { + deletePatientPopUp(); + }, + ), + ], + ), + 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 Scheme", + editable: value, + required: value, + ), + ], + ), + ); + }, + ), + const SizedBox(height: 30.0), + SizedBox( + width: 500.0, + height: 50.0, + child: MIHButton( + onTap: () { + submitForm(); + }, + buttonText: "Update", + buttonColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + textColor: MzanziInnovationHub.of(context)!.theme.primaryColor(), + ), + ), + ], + ), + ); + } + + 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"); + }, + ); + } + } + + MIHAction getActionButton() { + return MIHAction( + icon: const Icon(Icons.arrow_back), + iconSize: 35, + onTap: () { + Navigator.of(context).pop(); + }, + ); + } + + MIHHeader getHeader() { + return const MIHHeader( + headerAlignment: MainAxisAlignment.center, + headerItems: [ + Text( + "Edit Patient Details", + style: TextStyle( + fontWeight: FontWeight.bold, + fontSize: 25, + ), + ), + ], + ); + } + + MIHBody getBody() { + return MIHBody( + borderOn: true, + bodyItems: [ + KeyboardListener( + focusNode: _focusNode, + autofocus: true, + onKeyEvent: (event) async { + if (event is KeyDownEvent && + event.logicalKey == LogicalKeyboardKey.enter) { + submitForm(); + } + }, + child: displayForm(), + ), + ], + ); + } + + @override + void dispose() { + idController.dispose(); + fnameController.dispose(); + lnameController.dispose(); + cellController.dispose(); + emailController.dispose(); + medNoController.dispose(); + medNameController.dispose(); + medSchemeController.dispose(); + addressController.dispose(); + medAidController.dispose(); + medAidCodeController.removeListener(isRequired); + medMainMemController.dispose(); + medAidCodeController.dispose(); + medRequired.dispose(); + _focusNode.dispose(); + super.dispose(); + } + + @override + void initState() { + getLoginUserEmail(); + medAidController.addListener(isRequired); + setState(() { + idController.text = widget.selectedPatient.id_no; + fnameController.text = widget.selectedPatient.first_name; + lnameController.text = widget.selectedPatient.last_name; + cellController.text = widget.selectedPatient.cell_no; + emailController.text = widget.selectedPatient.email; + medNameController.text = widget.selectedPatient.medical_aid_name; + medNoController.text = widget.selectedPatient.medical_aid_no; + medSchemeController.text = widget.selectedPatient.medical_aid_scheme; + addressController.text = widget.selectedPatient.address; + medAidController.text = widget.selectedPatient.medical_aid; + medMainMemController.text = + widget.selectedPatient.medical_aid_main_member; + medAidCodeController.text = widget.selectedPatient.medical_aid_code; + }); + + super.initState(); + } + + @override + Widget build(BuildContext context) { + var size = MediaQuery.of(context).size; + setState(() { + width = size.width; + height = size.height; + }); + return MIHLayoutBuilder( + actionButton: getActionButton(), + header: getHeader(), + secondaryActionButton: null, + body: getBody(), + 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 cb42f1f8a14e90b891e764b2b406e08c0c1fd212 Mon Sep 17 00:00:00 2001 From: Yasien Mac Mini Date: Mon, 17 Mar 2025 14:04:57 +0200 Subject: [PATCH 05/17] move full screen to new package --- .../components}/full_screen_file.dart | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) rename Frontend/lib/mih_packages/patient_profile/{ => pat_profile/components}/full_screen_file.dart (96%) diff --git a/Frontend/lib/mih_packages/patient_profile/full_screen_file.dart b/Frontend/lib/mih_packages/patient_profile/pat_profile/components/full_screen_file.dart similarity index 96% rename from Frontend/lib/mih_packages/patient_profile/full_screen_file.dart rename to Frontend/lib/mih_packages/patient_profile/pat_profile/components/full_screen_file.dart index 983a1853..0620f1e4 100644 --- a/Frontend/lib/mih_packages/patient_profile/full_screen_file.dart +++ b/Frontend/lib/mih_packages/patient_profile/pat_profile/components/full_screen_file.dart @@ -2,7 +2,7 @@ import 'dart:async'; import 'package:Mzansi_Innovation_Hub/mih_components/mih_pop_up_messages/mih_loading_circle.dart'; import 'package:flutter/material.dart'; -import '../../main.dart'; +import '../../../../main.dart'; import 'package:syncfusion_flutter_core/theme.dart'; import 'package:syncfusion_flutter_pdfviewer/pdfviewer.dart'; import "package:universal_html/html.dart" as html; @@ -11,11 +11,11 @@ import 'package:http/http.dart' as http; import 'package:printing/printing.dart'; import 'package:fl_downloader/fl_downloader.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'; -import '../../mih_components/mih_layout/mih_layout_builder.dart'; -import '../../mih_objects/arguments.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'; +import '../../../../mih_components/mih_layout/mih_layout_builder.dart'; +import '../../../../mih_objects/arguments.dart'; class FullScreenFileViewer extends StatefulWidget { final FileViewArguments arguments; From d57376da2fa28db7e292113f0910ed73efed9da2 Mon Sep 17 00:00:00 2001 From: Yasien Mac Mini Date: Mon, 17 Mar 2025 14:05:23 +0200 Subject: [PATCH 06/17] new patient profile mih app package --- .../pat_profile/patient_profile.dart | 112 ++++++++++++++++++ 1 file changed, 112 insertions(+) create mode 100644 Frontend/lib/mih_packages/patient_profile/pat_profile/patient_profile.dart diff --git a/Frontend/lib/mih_packages/patient_profile/pat_profile/patient_profile.dart b/Frontend/lib/mih_packages/patient_profile/pat_profile/patient_profile.dart new file mode 100644 index 00000000..872e0994 --- /dev/null +++ b/Frontend/lib/mih_packages/patient_profile/pat_profile/patient_profile.dart @@ -0,0 +1,112 @@ +import 'package:Mzansi_Innovation_Hub/mih_components/mih_package/mih_app.dart'; +import 'package:Mzansi_Innovation_Hub/mih_components/mih_package/mih_app_action.dart'; +import 'package:Mzansi_Innovation_Hub/mih_components/mih_package/mih_app_tools.dart'; +import 'package:Mzansi_Innovation_Hub/mih_objects/arguments.dart'; +import 'package:Mzansi_Innovation_Hub/mih_packages/patient_profile/pat_profile/app_tools/patient_claim_or_statement.dart'; +import 'package:Mzansi_Innovation_Hub/mih_packages/patient_profile/pat_profile/app_tools/patient_consultation.dart'; +import 'package:Mzansi_Innovation_Hub/mih_packages/patient_profile/pat_profile/app_tools/patient_documents.dart'; +import 'package:Mzansi_Innovation_Hub/mih_packages/patient_profile/pat_profile/app_tools/patient_info.dart'; +import 'package:flutter/material.dart'; + +class PatientProfile extends StatefulWidget { + final PatientViewArguments arguments; + const PatientProfile({ + super.key, + required this.arguments, + }); + + @override + State createState() => _PatientProfileState(); +} + +class _PatientProfileState extends State { + int _selcetedIndex = 0; + @override + Widget build(BuildContext context) { + print("Pat Profile: ${widget.arguments.businessUser!.business_id}"); + return MihApp( + appActionButton: getAction(), + appTools: getTools(), + appBody: getToolBody(), + selectedbodyIndex: _selcetedIndex, + onIndexChange: (newValue) { + setState(() { + _selcetedIndex = newValue; + }); + }, + ); + } + + MihAppAction getAction() { + return MihAppAction( + icon: const Icon(Icons.arrow_back), + iconSize: 35, + onTap: () { + Navigator.of(context).pop(); + }, + ); + } + + MihAppTools getTools() { + Map temp = {}; + temp[const Icon(Icons.perm_identity)] = () { + setState(() { + _selcetedIndex = 0; + }); + }; + temp[const Icon(Icons.article_outlined)] = () { + setState(() { + _selcetedIndex = 1; + }); + }; + temp[const Icon(Icons.file_present)] = () { + setState(() { + _selcetedIndex = 2; + }); + }; + temp[const Icon(Icons.file_open_outlined)] = () { + setState(() { + _selcetedIndex = 3; + }); + }; + return MihAppTools( + tools: temp, + selcetedIndex: _selcetedIndex, + ); + } + + List getToolBody() { + List toolBodies = [ + PatientInfo( + signedInUser: widget.arguments.signedInUser, + selectedPatient: widget.arguments.selectedPatient!, + type: widget.arguments.type, + ), + PatientConsultation( + patientAppId: widget.arguments.selectedPatient!.app_id, + selectedPatient: widget.arguments.selectedPatient!, + signedInUser: widget.arguments.signedInUser, + business: widget.arguments.business, + businessUser: widget.arguments.businessUser, + type: widget.arguments.type, + ), + PatientDocuments( + patientIndex: widget.arguments.selectedPatient!.idpatients, + selectedPatient: widget.arguments.selectedPatient!, + signedInUser: widget.arguments.signedInUser, + business: widget.arguments.business, + businessUser: widget.arguments.businessUser, + type: widget.arguments.type, + ), + PatientClaimOrStatement( + patientIndex: widget.arguments.selectedPatient!.idpatients, + selectedPatient: widget.arguments.selectedPatient!, + signedInUser: widget.arguments.signedInUser, + business: widget.arguments.business, + businessUser: widget.arguments.businessUser, + type: widget.arguments.type, + ), + ]; + return toolBodies; + } +} From edbde7e29bc3e391e716fa2531e2f4f7129bc579 Mon Sep 17 00:00:00 2001 From: Yasien Mac Mini Date: Mon, 17 Mar 2025 14:05:38 +0200 Subject: [PATCH 07/17] new app tools --- .../app_tools/patient_consultation.dart | 361 ++++++++++++ .../app_tools/patient_documents.dart | 525 ++++++++++++++++++ .../pat_profile/app_tools/patient_info.dart | 294 ++++++++++ 3 files changed, 1180 insertions(+) create mode 100644 Frontend/lib/mih_packages/patient_profile/pat_profile/app_tools/patient_consultation.dart create mode 100644 Frontend/lib/mih_packages/patient_profile/pat_profile/app_tools/patient_documents.dart create mode 100644 Frontend/lib/mih_packages/patient_profile/pat_profile/app_tools/patient_info.dart diff --git a/Frontend/lib/mih_packages/patient_profile/pat_profile/app_tools/patient_consultation.dart b/Frontend/lib/mih_packages/patient_profile/pat_profile/app_tools/patient_consultation.dart new file mode 100644 index 00000000..f3e0e8aa --- /dev/null +++ b/Frontend/lib/mih_packages/patient_profile/pat_profile/app_tools/patient_consultation.dart @@ -0,0 +1,361 @@ +import 'dart:convert'; +import 'package:Mzansi_Innovation_Hub/main.dart'; +import 'package:Mzansi_Innovation_Hub/mih_components/mih_inputs_and_buttons/mih_button.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_layout/mih_single_child_scroll.dart'; +import 'package:Mzansi_Innovation_Hub/mih_components/mih_layout/mih_window.dart'; +import 'package:Mzansi_Innovation_Hub/mih_components/mih_package/mih-app_tool_body.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'; +import 'package:Mzansi_Innovation_Hub/mih_env/env.dart'; +import 'package:Mzansi_Innovation_Hub/mih_objects/app_user.dart'; +import 'package:Mzansi_Innovation_Hub/mih_objects/business.dart'; +import 'package:Mzansi_Innovation_Hub/mih_objects/business_user.dart'; +import 'package:Mzansi_Innovation_Hub/mih_objects/notes.dart'; +import 'package:Mzansi_Innovation_Hub/mih_objects/patients.dart'; +import 'package:Mzansi_Innovation_Hub/mih_packages/patient_profile/pat_profile/list_builders/build_notes_list.dart'; +import 'package:flutter/material.dart'; +import 'package:supertokens_flutter/http.dart' as http; + +class PatientConsultation extends StatefulWidget { + final String patientAppId; + final Patient selectedPatient; + final AppUser signedInUser; + final Business? business; + final BusinessUser? businessUser; + final String type; + const PatientConsultation({ + super.key, + required this.patientAppId, + required this.selectedPatient, + required this.signedInUser, + required this.business, + required this.businessUser, + required this.type, + }); + + @override + State createState() => _PatientConsultationState(); +} + +class _PatientConsultationState extends State { + late Future> futueNotes; + final titleController = TextEditingController(); + final noteTextController = TextEditingController(); + final officeController = TextEditingController(); + final dateController = TextEditingController(); + final doctorController = TextEditingController(); + final ValueNotifier _counter = ValueNotifier(0); + String endpoint = "${AppEnviroment.baseApiUrl}/notes/patients/"; + + Future> fetchNotes(String endpoint) async { + final response = await http.get(Uri.parse( + "${AppEnviroment.baseApiUrl}/notes/patients/${widget.selectedPatient.app_id}")); + if (response.statusCode == 200) { + Iterable l = jsonDecode(response.body); + List notes = + List.from(l.map((model) => Note.fromJson(model))); + //print("Here notes"); + return notes; + } else { + internetConnectionPopUp(); + throw Exception('failed to load patients'); + } + } + + void addNotePopUp() { + DateTime now = new DateTime.now(); + DateTime date = new DateTime(now.year, now.month, now.day); + var title = ""; + print("Business User: ${widget.businessUser}"); + if (widget.businessUser?.title == "Doctor") { + title = "Dr."; + } + setState(() { + officeController.text = widget.business!.Name; + doctorController.text = + "$title ${widget.signedInUser.fname} ${widget.signedInUser.lname}"; + dateController.text = date.toString().substring(0, 10); + }); + showDialog( + context: context, + barrierDismissible: false, + builder: (context) => MIHWindow( + fullscreen: false, + windowTitle: "Add Note", + windowTools: const [], + onWindowTapClose: () { + Navigator.pop(context); + titleController.clear(); + noteTextController.clear(); + }, + windowBody: [ + 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), + SizedBox( + width: 300, + height: 50, + child: MIHButton( + onTap: () { + if (isFieldsFilled()) { + addPatientNoteAPICall(); + Navigator.pop(context); + } else { + showDialog( + context: context, + builder: (context) { + return const MIHErrorMessage(errorType: "Input Error"); + }, + ); + } + }, + buttonText: "Add Note", + buttonColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + textColor: MzanziInnovationHub.of(context)!.theme.primaryColor(), + ), + ) + ], + ), + ); + } + + Future addPatientNoteAPICall() async { + // String title = ""; + // if (widget.businessUser!.title == "Doctor") { + // title = "Dr."; + // } + var response = await http.post( + Uri.parse("${AppEnviroment.baseApiUrl}/notes/insert/"), + headers: { + "Content-Type": "application/json; charset=UTF-8" + }, + body: jsonEncode({ + "note_name": titleController.text, + "note_text": noteTextController.text, + "doc_office": officeController.text, + "doctor": doctorController.text, + "app_id": widget.selectedPatient.app_id, + }), + ); + if (response.statusCode == 201) { + setState(() { + futueNotes = fetchNotes(endpoint + widget.patientAppId.toString()); + }); + // Navigator.of(context) + // .pushNamed('/patient-manager', arguments: widget.userEmail); + String message = + "Your note has been successfully added to the patients medical record. You can now view it alongside their other important information."; + successPopUp(message); + } else { + internetConnectionPopUp(); + } + } + + bool isFieldsFilled() { + if (titleController.text.isEmpty || + noteTextController.text.isEmpty || + _counter.value >= 512) { + return false; + } else { + return true; + } + } + + Color getNoteDetailLimitColor() { + if (_counter.value <= 512) { + return MzanziInnovationHub.of(context)!.theme.secondaryColor(); + } else { + return MzanziInnovationHub.of(context)!.theme.errorColor(); + } + } + + 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, + builder: (context) { + return MIHSuccessMessage( + successType: "Success", + successMessage: message, + ); + }, + ); + } + + void internetConnectionPopUp() { + showDialog( + context: context, + builder: (context) { + return const MIHErrorMessage(errorType: "Internet Connection"); + }, + ); + } + + @override + void dispose() { + titleController.dispose(); + noteTextController.dispose(); + doctorController.dispose(); + dateController.dispose(); + officeController.dispose(); + super.dispose(); + } + + @override + void initState() { + futueNotes = fetchNotes(endpoint + widget.patientAppId); + noteTextController.addListener(() { + setState(() { + _counter.value = noteTextController.text.characters.length; + }); + }); + super.initState(); + } + + @override + Widget build(BuildContext context) { + return MihAppToolBody( + borderOn: true, + bodyItem: getBody(), + ); + } + + Widget getBody() { + return MihSingleChildScroll( + child: FutureBuilder( + future: futueNotes, + builder: (context, snapshot) { + if (snapshot.connectionState == ConnectionState.waiting) { + return const Center( + child: Mihloadingcircle(), + ); + } else if (snapshot.hasData) { + final notesList = snapshot.data!; + return Column(children: [ + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: setIcons(), + ), + Divider( + color: + MzanziInnovationHub.of(context)!.theme.secondaryColor()), + const SizedBox(height: 10), + BuildNotesList( + notes: notesList, + signedInUser: widget.signedInUser, + selectedPatient: widget.selectedPatient, + business: widget.business, + businessUser: widget.businessUser, + type: widget.type, + ), + ]); + } else { + return const Center( + child: Text("Error Loading Notes"), + ); + } + }, + ), + ); + } +} diff --git a/Frontend/lib/mih_packages/patient_profile/pat_profile/app_tools/patient_documents.dart b/Frontend/lib/mih_packages/patient_profile/pat_profile/app_tools/patient_documents.dart new file mode 100644 index 00000000..1270c3c5 --- /dev/null +++ b/Frontend/lib/mih_packages/patient_profile/pat_profile/app_tools/patient_documents.dart @@ -0,0 +1,525 @@ +import 'dart:convert'; + +import 'package:Mzansi_Innovation_Hub/main.dart'; +import 'package:Mzansi_Innovation_Hub/mih_components/med_cert_input.dart'; +import 'package:Mzansi_Innovation_Hub/mih_components/mih_inputs_and_buttons/mih_button.dart'; +import 'package:Mzansi_Innovation_Hub/mih_components/mih_inputs_and_buttons/mih_file_input.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_window.dart'; +import 'package:Mzansi_Innovation_Hub/mih_components/mih_package/mih-app_tool_body.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'; +import 'package:Mzansi_Innovation_Hub/mih_env/env.dart'; +import 'package:Mzansi_Innovation_Hub/mih_objects/app_user.dart'; +import 'package:Mzansi_Innovation_Hub/mih_objects/business.dart'; +import 'package:Mzansi_Innovation_Hub/mih_objects/business_user.dart'; +import 'package:Mzansi_Innovation_Hub/mih_objects/files.dart'; +import 'package:Mzansi_Innovation_Hub/mih_objects/patients.dart'; +import 'package:Mzansi_Innovation_Hub/mih_packages/patient_profile/pat_profile/components/prescip_input.dart'; +import 'package:Mzansi_Innovation_Hub/mih_packages/patient_profile/pat_profile/list_builders/build_files_list.dart'; +import 'package:file_picker/file_picker.dart'; +import 'package:flutter/material.dart'; +import 'package:supertokens_flutter/supertokens.dart'; +import 'package:supertokens_flutter/http.dart' as http; +import 'package:http/http.dart' as http2; + +class PatientDocuments extends StatefulWidget { + final int patientIndex; + final Patient selectedPatient; + final AppUser signedInUser; + final Business? business; + final BusinessUser? businessUser; + final String type; + const PatientDocuments({ + super.key, + required this.patientIndex, + required this.selectedPatient, + required this.signedInUser, + required this.business, + required this.businessUser, + required this.type, + }); + + @override + State createState() => _PatientDocumentsState(); +} + +class _PatientDocumentsState extends State { + late Future> futueFiles; + final selectedFileController = TextEditingController(); + final startDateController = TextEditingController(); + final endDateTextController = TextEditingController(); + final retDateTextController = TextEditingController(); + final medicineController = TextEditingController(); + final quantityController = TextEditingController(); + final dosageController = TextEditingController(); + final timesDailyController = TextEditingController(); + final noDaysController = TextEditingController(); + final noRepeatsController = TextEditingController(); + final outputController = TextEditingController(); + late PlatformFile selected; + + Future> fetchFiles() async { + final response = await http.get(Uri.parse( + "${AppEnviroment.baseApiUrl}/files/patients/${widget.selectedPatient.app_id}")); + //print(response.statusCode); + //print(response.body); + if (response.statusCode == 200) { + Iterable l = jsonDecode(response.body); + List files = + List.from(l.map((model) => PFile.fromJson(model))); + return files; + } else { + internetConnectionPopUp(); + throw Exception('failed to load patients'); + } + } + + Future uploadSelectedFile(PlatformFile file) async { + //var strem = new http.ByteStream.fromBytes(file.bytes.) + //start loading circle + showDialog( + context: context, + builder: (context) { + return const Mihloadingcircle(); + }, + ); + var token = await SuperTokens.getAccessToken(); + //print(t); + //print("here1"); + var request = http2.MultipartRequest( + 'POST', Uri.parse("${AppEnviroment.baseApiUrl}/minio/upload/file/")); + request.headers['accept'] = 'application/json'; + request.headers['Authorization'] = 'Bearer $token'; + request.headers['Content-Type'] = 'multipart/form-data'; + request.fields['app_id'] = widget.selectedPatient.app_id; + request.fields['folder'] = "patient_files"; + request.files.add(await http2.MultipartFile.fromBytes('file', file.bytes!, + filename: file.name.replaceAll(RegExp(r' '), '-'))); + //print("here2"); + var response1 = await request.send(); + //print("here3"); + //print(response1.statusCode); + //print(response1.toString()); + if (response1.statusCode == 200) { + //print("here3"); + var fname = file.name.replaceAll(RegExp(r' '), '-'); + var filePath = "${widget.selectedPatient.app_id}/patient_files/$fname"; + var response2 = await http.post( + Uri.parse("${AppEnviroment.baseApiUrl}/files/insert/"), + headers: { + "Content-Type": "application/json; charset=UTF-8" + }, + body: jsonEncode({ + "file_path": filePath, + "file_name": fname, + "app_id": widget.selectedPatient.app_id + }), + ); + //print("here5"); + //print(response2.statusCode); + if (response2.statusCode == 201) { + setState(() { + selectedFileController.clear(); + futueFiles = fetchFiles(); + }); + // end loading circle + Navigator.of(context).pop(); + String message = + "The file ${file.name.replaceAll(RegExp(r' '), '-')} has been successfully generated and added to ${widget.selectedPatient.first_name} ${widget.selectedPatient.last_name}'s record. You can now access and download it for their use."; + successPopUp(message); + } else { + internetConnectionPopUp(); + } + } else { + internetConnectionPopUp(); + } + } + + Future generateMedCert() async { + //start loading circle + showDialog( + context: context, + builder: (context) { + return const Mihloadingcircle(); + }, + ); + var response1 = await http.post( + Uri.parse("${AppEnviroment.baseApiUrl}/minio/generate/med-cert/"), + headers: { + "Content-Type": "application/json; charset=UTF-8" + }, + body: jsonEncode({ + "app_id": widget.selectedPatient.app_id, + "fullName": + "${widget.selectedPatient.first_name} ${widget.selectedPatient.last_name}", + "id_no": widget.selectedPatient.id_no, + "docfname": + "DR. ${widget.signedInUser.fname} ${widget.signedInUser.lname}", + "startDate": startDateController.text, + "busName": widget.business!.Name, + "busAddr": "*TO BE ADDED IN THE FUTURE*", + "busNo": widget.business!.contact_no, + "busEmail": widget.business!.bus_email, + "endDate": endDateTextController.text, + "returnDate": retDateTextController.text, + "logo_path": widget.business!.logo_path, + "sig_path": widget.businessUser!.sig_path, + }), + ); + //print(response1.statusCode); + DateTime now = new DateTime.now(); + DateTime date = new DateTime(now.year, now.month, now.day); + String fileName = + "Med-Cert-${widget.selectedPatient.first_name} ${widget.selectedPatient.last_name}-${date.toString().substring(0, 10)}.pdf"; + if (response1.statusCode == 200) { + var response2 = await http.post( + Uri.parse("${AppEnviroment.baseApiUrl}/files/insert/"), + headers: { + "Content-Type": "application/json; charset=UTF-8" + }, + body: jsonEncode({ + "file_path": + "${widget.selectedPatient.app_id}/patient_files/$fileName", + "file_name": fileName, + "app_id": widget.selectedPatient.app_id + }), + ); + //print(response2.statusCode); + if (response2.statusCode == 201) { + setState(() { + startDateController.clear(); + endDateTextController.clear(); + retDateTextController.clear(); + futueFiles = fetchFiles(); + }); + // end loading circle + Navigator.of(context).pop(); + Navigator.of(context).pop(); + String message = + "The medical certificate $fileName has been successfully generated and added to ${widget.selectedPatient.first_name} ${widget.selectedPatient.last_name}'s record. You can now access and download it for their use."; + successPopUp(message); + } else { + internetConnectionPopUp(); + } + } else { + internetConnectionPopUp(); + } + } + + void uploudFilePopUp() { + showDialog( + context: context, + barrierDismissible: false, + builder: (context) => MIHWindow( + fullscreen: false, + windowTitle: "Upload File", + windowTools: const [], + onWindowTapClose: () { + Navigator.pop(context); + }, + windowBody: [ + MIHFileField( + controller: selectedFileController, + hintText: "Select File", + 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(() { + selected = selectedFile; + }); + setState(() { + selectedFileController.text = selectedFile.name; + }); + }, + ), + const SizedBox(height: 15), + SizedBox( + width: 300, + height: 50, + child: MIHButton( + buttonText: "Add File", + buttonColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + textColor: MzanziInnovationHub.of(context)!.theme.primaryColor(), + onTap: () { + if (isFileFieldsFilled()) { + uploadSelectedFile(selected); + Navigator.pop(context); + } else { + showDialog( + context: context, + builder: (context) { + return const MIHErrorMessage(errorType: "Input Error"); + }, + ); + } + }, + ), + ) + ], + ), + ); + } + + void medCertPopUp() { + showDialog( + context: context, + barrierDismissible: false, + builder: (context) => MIHWindow( + fullscreen: false, + windowTitle: "Create Medical Certificate", + windowTools: const [], + onWindowTapClose: () { + Navigator.pop(context); + }, + windowBody: [ + Medcertinput( + startDateController: startDateController, + endDateTextController: endDateTextController, + retDateTextController: retDateTextController, + ), + const SizedBox(height: 15.0), + SizedBox( + width: 300, + height: 50, + child: MIHButton( + buttonText: "Generate", + buttonColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + textColor: MzanziInnovationHub.of(context)!.theme.primaryColor(), + onTap: () async { + if (isMedCertFieldsFilled()) { + await generateMedCert(); + //Navigator.pop(context); + } else { + showDialog( + context: context, + builder: (context) { + return const MIHErrorMessage(errorType: "Input Error"); + }, + ); + } + }, + ), + ) + ], + ), + ); + } + + void prescritionPopUp() { + showDialog( + context: context, + barrierDismissible: false, + builder: (context) => MIHWindow( + fullscreen: false, + windowTitle: "Create Prescription", + windowTools: const [], + onWindowTapClose: () { + medicineController.clear(); + quantityController.clear(); + dosageController.clear(); + timesDailyController.clear(); + noDaysController.clear(); + noRepeatsController.clear(); + Navigator.pop(context); + }, + windowBody: [ + PrescripInput( + medicineController: medicineController, + quantityController: quantityController, + dosageController: dosageController, + timesDailyController: timesDailyController, + noDaysController: noDaysController, + noRepeatsController: noRepeatsController, + outputController: outputController, + selectedPatient: widget.selectedPatient, + signedInUser: widget.signedInUser, + business: widget.business, + businessUser: widget.businessUser, + ), + ], + ), + ); + } + + bool isFileFieldsFilled() { + if (selectedFileController.text.isEmpty) { + return false; + } else { + return true; + } + } + + bool isMedCertFieldsFilled() { + if (startDateController.text.isEmpty || + endDateTextController.text.isEmpty || + retDateTextController.text.isEmpty) { + return false; + } else { + return true; + } + } + + List setIcons() { + if (widget.type == "personal") { + return [ + Text( + "Documents", + textAlign: TextAlign.center, + style: TextStyle( + fontSize: 25, + fontWeight: FontWeight.bold, + color: MzanziInnovationHub.of(context)!.theme.secondaryColor(), + ), + ), + IconButton( + onPressed: () { + uploudFilePopUp(); + }, + icon: Icon( + Icons.add, + color: MzanziInnovationHub.of(context)!.theme.secondaryColor(), + ), + ) + ]; + } else { + return [ + Text( + "Documents", + textAlign: TextAlign.center, + style: TextStyle( + fontSize: 25, + fontWeight: FontWeight.bold, + color: MzanziInnovationHub.of(context)!.theme.secondaryColor(), + ), + ), + IconButton( + onPressed: () { + medCertPopUp(); + }, + icon: Icon( + Icons.sick_outlined, + color: MzanziInnovationHub.of(context)!.theme.secondaryColor(), + ), + ), + IconButton( + onPressed: () { + prescritionPopUp(); + }, + icon: Icon( + Icons.medication_outlined, + color: MzanziInnovationHub.of(context)!.theme.secondaryColor(), + ), + ), + IconButton( + onPressed: () { + uploudFilePopUp(); + }, + icon: Icon( + Icons.add, + color: MzanziInnovationHub.of(context)!.theme.secondaryColor(), + ), + ) + ]; + } + } + + void successPopUp(String message) { + showDialog( + context: context, + builder: (context) { + return MIHSuccessMessage( + successType: "Success", + successMessage: message, + ); + }, + ); + } + + void internetConnectionPopUp() { + showDialog( + context: context, + builder: (context) { + return const MIHErrorMessage(errorType: "Internet Connection"); + }, + ); + } + + @override + void dispose() { + startDateController.dispose(); + endDateTextController.dispose(); + retDateTextController.dispose(); + selectedFileController.dispose(); + medicineController.dispose(); + quantityController.dispose(); + dosageController.dispose(); + timesDailyController.dispose(); + noDaysController.dispose(); + noRepeatsController.dispose(); + outputController.dispose(); + super.dispose(); + } + + @override + void initState() { + futueFiles = fetchFiles(); + super.initState(); + } + + @override + Widget build(BuildContext context) { + return MihAppToolBody( + borderOn: true, + bodyItem: getBody(), + ); + } + + Widget getBody() { + return MihSingleChildScroll( + child: FutureBuilder( + future: futueFiles, + builder: (context, snapshot) { + if (snapshot.connectionState == ConnectionState.waiting) { + return const Center( + child: Mihloadingcircle(), + ); + } else if (snapshot.hasData) { + final filesList = snapshot.data!; + return Column(children: [ + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: setIcons(), + ), + Divider( + color: + MzanziInnovationHub.of(context)!.theme.secondaryColor()), + const SizedBox(height: 10), + BuildFilesList( + files: filesList, + signedInUser: widget.signedInUser, + selectedPatient: widget.selectedPatient, + business: widget.business, + businessUser: widget.businessUser, + type: widget.type, + ), + ]); + } else { + return const Center( + child: Text("Error Loading Notes"), + ); + } + }, + ), + ); + } +} diff --git a/Frontend/lib/mih_packages/patient_profile/pat_profile/app_tools/patient_info.dart b/Frontend/lib/mih_packages/patient_profile/pat_profile/app_tools/patient_info.dart new file mode 100644 index 00000000..5b1f1697 --- /dev/null +++ b/Frontend/lib/mih_packages/patient_profile/pat_profile/app_tools/patient_info.dart @@ -0,0 +1,294 @@ +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/mih-app_tool_body.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'; +import 'package:flutter/material.dart'; + +class PatientInfo extends StatefulWidget { + final AppUser signedInUser; + final Patient selectedPatient; + final String type; + const PatientInfo({ + super.key, + required this.signedInUser, + required this.selectedPatient, + required this.type, + }); + + @override + State createState() => _PatientInfoState(); +} + +class _PatientInfoState extends State { + final idController = TextEditingController(); + final fnameController = TextEditingController(); + final lnameController = TextEditingController(); + final cellController = TextEditingController(); + final emailController = TextEditingController(); + final medNoController = TextEditingController(); + final medNameController = TextEditingController(); + final medSchemeController = TextEditingController(); + final addressController = TextEditingController(); + final medAidController = TextEditingController(); + final medMainMemController = TextEditingController(); + final medAidCodeController = TextEditingController(); + double textFieldWidth = 400.0; + late String medAid; + + Widget getPatientDetailsField() { + return Wrap( + spacing: 15, + runSpacing: 10, + children: [ + SizedBox( + width: textFieldWidth, + child: MIHTextField( + controller: idController, + hintText: "ID No.", + editable: false, + required: false), + ), + SizedBox( + width: textFieldWidth, + child: MIHTextField( + controller: fnameController, + hintText: "Name", + editable: false, + required: false), + ), + SizedBox( + width: textFieldWidth, + child: MIHTextField( + controller: lnameController, + hintText: "Surname", + editable: false, + required: false), + ), + SizedBox( + width: textFieldWidth, + child: MIHTextField( + controller: cellController, + hintText: "Cell No.", + editable: false, + required: false), + ), + SizedBox( + width: textFieldWidth, + child: MIHTextField( + controller: emailController, + hintText: "Email", + editable: false, + required: false), + ), + SizedBox( + width: textFieldWidth, + child: MIHTextField( + controller: addressController, + hintText: "Address", + editable: false, + required: false), + ), + ], + ); + } + + Widget getMedAidDetailsFields() { + List medAidDet = []; + medAidDet.add(SizedBox( + width: textFieldWidth, + child: MIHTextField( + controller: medAidController, + hintText: "Medical Aid", + editable: false, + required: false), + )); + bool req; + if (medAid == "Yes") { + req = true; + } else { + req = false; + } + medAidDet.addAll([ + Visibility( + visible: req, + child: SizedBox( + width: textFieldWidth, + child: MIHTextField( + controller: medMainMemController, + hintText: "Main Member", + editable: false, + required: false), + ), + ), + //const SizedBox(height: 10.0), + Visibility( + visible: req, + child: SizedBox( + width: textFieldWidth, + child: MIHTextField( + controller: medNoController, + hintText: "No.", + editable: false, + required: false), + ), + ), + //const SizedBox(height: 10.0), + Visibility( + visible: req, + child: SizedBox( + width: textFieldWidth, + child: MIHTextField( + controller: medAidCodeController, + hintText: "Code", + editable: false, + required: false), + ), + ), + //const SizedBox(height: 10.0), + Visibility( + visible: req, + child: SizedBox( + width: textFieldWidth, + child: MIHTextField( + controller: medNameController, + hintText: "Name", + editable: false, + required: false), + ), + ), + //const SizedBox(height: 10.0), + Visibility( + visible: req, + child: SizedBox( + width: textFieldWidth, + child: MIHTextField( + controller: medSchemeController, + hintText: "Scheme", + editable: false, + required: false), + ), + ), + //), + ]); + return Wrap( + spacing: 10, + runSpacing: 10, + children: medAidDet, + ); + } + + @override + void dispose() { + idController.dispose(); + fnameController.dispose(); + lnameController.dispose(); + cellController.dispose(); + emailController.dispose(); + medNameController.dispose(); + medNoController.dispose(); + medSchemeController.dispose(); + addressController.dispose(); + medAidController.dispose(); + medMainMemController.dispose(); + medAidCodeController.dispose(); + super.dispose(); + } + + @override + void initState() { + setState(() { + idController.value = TextEditingValue(text: widget.selectedPatient.id_no); + fnameController.value = + TextEditingValue(text: widget.selectedPatient.first_name); + lnameController.value = + TextEditingValue(text: widget.selectedPatient.last_name); + cellController.value = + TextEditingValue(text: widget.selectedPatient.cell_no); + emailController.value = + TextEditingValue(text: widget.selectedPatient.email); + medNameController.value = + TextEditingValue(text: widget.selectedPatient.medical_aid_name); + medNoController.value = + TextEditingValue(text: widget.selectedPatient.medical_aid_no); + medSchemeController.value = + TextEditingValue(text: widget.selectedPatient.medical_aid_scheme); + addressController.value = + TextEditingValue(text: widget.selectedPatient.address); + medAidController.value = + TextEditingValue(text: widget.selectedPatient.medical_aid); + medMainMemController.value = TextEditingValue( + text: widget.selectedPatient.medical_aid_main_member); + medAidCodeController.value = + TextEditingValue(text: widget.selectedPatient.medical_aid_code); + medAid = widget.selectedPatient.medical_aid; + }); + super.initState(); + } + + @override + Widget build(BuildContext context) { + return MihAppToolBody( + borderOn: true, + bodyItem: getBody(), + ); + } + + Widget getBody() { + return MihSingleChildScroll( + child: Column( + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.center, + //crossAxisAlignment: , + children: [ + Text( + "Personal Details", + textAlign: TextAlign.center, + style: TextStyle( + fontSize: 25, + fontWeight: FontWeight.bold, + color: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + ), + ), + Visibility( + visible: widget.type == "personal", + child: IconButton( + icon: const Icon(Icons.edit), + alignment: Alignment.topRight, + color: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + onPressed: () { + Navigator.of(context).pushNamed('/patient-profile/edit', + arguments: PatientEditArguments( + widget.signedInUser, widget.selectedPatient)); + }, + ), + ) + ]), + Divider( + color: MzanziInnovationHub.of(context)!.theme.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(), + ], + ), + ); + } +} From 6c396264ce82d0ef03383c41c741f94119651e73 Mon Sep 17 00:00:00 2001 From: Yasien Mac Mini Date: Mon, 17 Mar 2025 14:05:51 +0200 Subject: [PATCH 08/17] new builders --- .../build_claim_statement_files_list.dart | 227 ++++++++++ .../list_builders/build_file_view.dart | 265 ++++++++++++ .../list_builders/build_files_list.dart | 397 ++++++++++++++++++ .../list_builders/build_notes_list.dart | 396 +++++++++++++++++ 4 files changed, 1285 insertions(+) create mode 100644 Frontend/lib/mih_packages/patient_profile/pat_profile/list_builders/build_claim_statement_files_list.dart create mode 100644 Frontend/lib/mih_packages/patient_profile/pat_profile/list_builders/build_file_view.dart create mode 100644 Frontend/lib/mih_packages/patient_profile/pat_profile/list_builders/build_files_list.dart create mode 100644 Frontend/lib/mih_packages/patient_profile/pat_profile/list_builders/build_notes_list.dart diff --git a/Frontend/lib/mih_packages/patient_profile/pat_profile/list_builders/build_claim_statement_files_list.dart b/Frontend/lib/mih_packages/patient_profile/pat_profile/list_builders/build_claim_statement_files_list.dart new file mode 100644 index 00000000..8456a0ab --- /dev/null +++ b/Frontend/lib/mih_packages/patient_profile/pat_profile/list_builders/build_claim_statement_files_list.dart @@ -0,0 +1,227 @@ +import 'dart:convert'; + +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_components/mih_layout/mih_window.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'; +import 'package:Mzansi_Innovation_Hub/mih_env/env.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/business.dart'; +import 'package:Mzansi_Innovation_Hub/mih_objects/business_user.dart'; +import 'package:Mzansi_Innovation_Hub/mih_objects/claim_statement_file.dart'; +import 'package:Mzansi_Innovation_Hub/mih_objects/patients.dart'; +import 'package:Mzansi_Innovation_Hub/mih_packages/patient_profile/pat_profile/list_builders/build_file_view.dart'; +import 'package:flutter/material.dart'; +import 'package:supertokens_flutter/http.dart' as http; + +class BuildClaimStatementFileList extends StatefulWidget { + final AppUser signedInUser; + final List files; + final Patient selectedPatient; + final Business? business; + final BusinessUser? businessUser; + final String type; + const BuildClaimStatementFileList({ + super.key, + required this.files, + required this.signedInUser, + required this.selectedPatient, + required this.business, + required this.businessUser, + required this.type, + }); + + @override + State createState() => + _BuildClaimStatementFileListState(); +} + +class _BuildClaimStatementFileListState + extends State { + int indexOn = 0; + final baseAPI = AppEnviroment.baseApiUrl; + final basefile = AppEnviroment.baseFileUrl; + String fileUrl = ""; + + Future getFileUrlApiCall(String filePath) async { + var url = "$baseAPI/minio/pull/file/${AppEnviroment.getEnv()}/$filePath"; + //print(url); + var response = await http.get(Uri.parse(url)); + // print("here1"); + //print(response.statusCode); + + if (response.statusCode == 200) { + //print("here2"); + String body = response.body; + //print(body); + //print("here3"); + var decodedData = jsonDecode(body); + //print("Dedoced: ${decodedData['minioURL']}"); + + return decodedData['minioURL']; + //AppUser u = AppUser.fromJson(decodedData); + // print(u.email); + //return "AlometThere"; + } else { + throw Exception("Error: GetUserData status code ${response.statusCode}"); + } + } + + void internetConnectionPopUp() { + showDialog( + context: context, + builder: (context) { + return const MIHErrorMessage(errorType: "Internet Connection"); + }, + ); + } + + void successPopUp(String message) { + showDialog( + context: context, + builder: (context) { + return MIHSuccessMessage( + successType: "Success", + successMessage: message, + ); + }, + ); + } + + void deleteFilePopUp(String filePath, int fileID) { + showDialog( + context: context, + barrierDismissible: false, + builder: (context) => MIHDeleteMessage( + deleteType: "File", + onTap: () async { + //API Call here + await MIHClaimStatementGenerationApi + .deleteClaimStatementFilesByFileID( + PatientViewArguments( + widget.signedInUser, + widget.selectedPatient, + widget.businessUser, + widget.business, + "business", + ), + filePath, + fileID, + context, + ); + }, + ), + ); + } + + void viewFilePopUp(String fileName, String filePath, int fileID, String url) { + bool hasAccessToDelete = false; + if (widget.type == "business") { + hasAccessToDelete = true; + } + showDialog( + context: context, + barrierDismissible: false, + builder: (context) => MIHWindow( + fullscreen: true, + windowTitle: fileName, + windowBody: [ + BuildFileView( + link: url, + path: filePath, + //pdfLink: '${AppEnviroment.baseFileUrl}/mih/$filePath', + ), + const SizedBox( + height: 10, + ) + ], + windowTools: [ + Visibility( + visible: hasAccessToDelete, + child: IconButton( + onPressed: () { + deleteFilePopUp(filePath, fileID); + }, + icon: Icon( + size: 35, + Icons.delete, + color: MzanziInnovationHub.of(context)!.theme.secondaryColor(), + ), + ), + ), + ], + onWindowTapClose: () { + Navigator.pop(context); + }, + ), + ); + } + + @override + void dispose() { + // TODO: implement dispose + super.dispose(); + } + + @override + Widget build(BuildContext context) { + if (widget.files.isNotEmpty) { + return ListView.separated( + shrinkWrap: true, + physics: const NeverScrollableScrollPhysics(), + separatorBuilder: (BuildContext context, int index) { + return Divider( + color: MzanziInnovationHub.of(context)!.theme.secondaryColor(), + ); + }, + itemCount: widget.files.length, + itemBuilder: (context, index) { + return ListTile( + title: Text( + widget.files[index].file_name, + style: TextStyle( + color: MzanziInnovationHub.of(context)!.theme.secondaryColor(), + ), + ), + subtitle: Text( + widget.files[index].insert_date, + style: TextStyle( + color: MzanziInnovationHub.of(context)!.theme.secondaryColor(), + ), + ), + // trailing: Icon( + // Icons.arrow_forward, + // color: MzanziInnovationHub.of(context)!.theme.secondaryColor(), + // ), + onTap: () async { + await getFileUrlApiCall(widget.files[index].file_path) + .then((urlHere) { + //print(url); + setState(() { + fileUrl = urlHere; + }); + }); + + viewFilePopUp( + widget.files[index].file_name, + widget.files[index].file_path, + widget.files[index].idclaim_statement_file, + fileUrl); + }, + ); + }, + ); + } else { + return const Center( + child: Text( + "No Documents Available", + style: TextStyle(fontSize: 25, color: Colors.grey), + textAlign: TextAlign.center, + ), + ); + } + } +} diff --git a/Frontend/lib/mih_packages/patient_profile/pat_profile/list_builders/build_file_view.dart b/Frontend/lib/mih_packages/patient_profile/pat_profile/list_builders/build_file_view.dart new file mode 100644 index 00000000..ba08bc62 --- /dev/null +++ b/Frontend/lib/mih_packages/patient_profile/pat_profile/list_builders/build_file_view.dart @@ -0,0 +1,265 @@ +import 'dart:async'; + +import 'package:Mzansi_Innovation_Hub/main.dart'; +import 'package:Mzansi_Innovation_Hub/mih_components/mih_pop_up_messages/mih_loading_circle.dart'; +import 'package:Mzansi_Innovation_Hub/mih_objects/arguments.dart'; +import 'package:flutter/material.dart'; +import 'package:syncfusion_flutter_core/theme.dart'; +import 'package:syncfusion_flutter_pdfviewer/pdfviewer.dart'; +import "package:universal_html/html.dart" as html; +import 'package:http/http.dart' as http; +import 'package:fl_downloader/fl_downloader.dart'; + +class BuildFileView extends StatefulWidget { + final String link; + final String path; + + const BuildFileView({ + super.key, + required this.link, + required this.path, + }); + + @override + State createState() => _BuildFileViewState(); +} + +class _BuildFileViewState extends State { + late PdfViewerController pdfViewerController = PdfViewerController(); + //late TextEditingController currentPageController = TextEditingController(); + double startZoomLevel = 1; + + int progress = 0; + late StreamSubscription progressStream; + + void mihLoadingPopUp() { + showDialog( + context: context, + builder: (context) { + return const Mihloadingcircle(); + }, + ); + } + + String getExtType(String path) { + //print(pdfLink.split(".")[1]); + return path.split(".").last; + } + + String getFileName(String path) { + //print(pdfLink.split(".")[1]); + return path.split("/").last; + } + + void printDocument() async { + print("Printing ${widget.path.split("/").last}"); + http.Response response = await http.get(Uri.parse(widget.link)); + var pdfData = response.bodyBytes; + Navigator.of(context).pushNamed( + '/file-veiwer/print-preview', + arguments: PrintPreviewArguments( + pdfData, + getFileName( + widget.path, + ), + ), + ); + } + + void nativeFileDownload(String fileLink) async { + var permission = await FlDownloader.requestPermission(); + if (permission == StoragePermissionStatus.granted) { + try { + mihLoadingPopUp(); + await FlDownloader.download(fileLink); + Navigator.of(context).pop(); + } on Exception catch (error) { + Navigator.of(context).pop(); + print(error); + } + } else { + print("denied"); + } + } + + @override + void dispose() { + pdfViewerController.dispose(); + progressStream.cancel(); + super.dispose(); + } + + @override + void initState() { + super.initState(); + FlDownloader.initialize(); + progressStream = FlDownloader.progressStream.listen((event) { + if (event.status == DownloadStatus.successful) { + setState(() { + progress = event.progress; + }); + //Navigator.of(context).pop(); + print("Progress $progress%: Success Downloading"); + FlDownloader.openFile(filePath: event.filePath); + } else if (event.status == DownloadStatus.failed) { + print("Progress $progress%: Error Downloading"); + } else if (event.status == DownloadStatus.running) { + print("Progress $progress%: Download Running"); + } + }); + } + + @override + Widget build(BuildContext context) { + // double width = MediaQuery.sizeOf(context).width; + //double height = MediaQuery.sizeOf(context).height; + debugPrint(widget.link); + if (getExtType(widget.path).toLowerCase() == "pdf") { + return Expanded( + child: Stack( + fit: StackFit.expand, + children: [ + SfPdfViewerTheme( + data: SfPdfViewerThemeData( + backgroundColor: + MzanziInnovationHub.of(context)!.theme.primaryColor(), + ), + child: SfPdfViewer.network( + widget.link, + controller: pdfViewerController, + interactionMode: PdfInteractionMode.pan, + ), + ), + Positioned( + bottom: 10, + right: 10, + width: 50, + height: 50, + child: IconButton.filled( + iconSize: 35, + padding: const EdgeInsets.all(0), + onPressed: () { + printDocument(); + }, + icon: Icon( + Icons.print, + color: MzanziInnovationHub.of(context)!.theme.primaryColor(), + ), + ), + ), + Positioned( + bottom: 10, + left: 10, + width: 50, + height: 50, + child: IconButton.filled( + iconSize: 35, + padding: const EdgeInsets.all(0), + onPressed: () async { + // debugPrint( + // "I'm here ${MzanziInnovationHub.of(context)!.theme.getPlatform()}"); + if (MzanziInnovationHub.of(context)!.theme.getPlatform() == + "Web") { + html.window.open( + widget.link, + // '${AppEnviroment.baseFileUrl}/mih/$filePath', + 'download'); + } else { + // print("Here"); + // var permission = await FlDownloader.requestPermission(); + // if (permission == StoragePermissionStatus.granted) { + // await FlDownloader.download(widget.link); + // } else { + // print("denied"); + // } + nativeFileDownload(widget.link); + } + }, + icon: Icon( + Icons.download, + color: MzanziInnovationHub.of(context)!.theme.primaryColor(), + ), + ), + ), + ], + ), + ); + } else { + return Expanded( + // height: height, + // padding: const EdgeInsets.all(10.0), + child: Stack( + fit: StackFit.expand, + children: [ + InteractiveViewer( + //constrained: true, + //clipBehavior: Clip.antiAlias, + maxScale: 5.0, + //minScale: 0., + child: Image.network(widget.link), + ), + Positioned( + bottom: 10, + right: 10, + width: 50, + height: 50, + child: IconButton.filled( + iconSize: 35, + padding: const EdgeInsets.all(0), + onPressed: () { + //expandImage(width, height); + Navigator.of(context).pushNamed( + '/file-veiwer', + arguments: FileViewArguments( + widget.link, + widget.path, + ), + ); + }, + icon: Icon( + Icons.fullscreen, + color: MzanziInnovationHub.of(context)!.theme.primaryColor(), + ), + ), + ), + Positioned( + bottom: 10, + left: 10, + width: 50, + height: 50, + child: IconButton.filled( + iconSize: 35, + padding: const EdgeInsets.all(0), + onPressed: () async { + // debugPrint("I'm here "); + // debugPrint( + // "I'm here ${MzanziInnovationHub.of(context)!.theme.getPlatform()}"); + if (MzanziInnovationHub.of(context)!.theme.getPlatform() == + "Web") { + html.window.open( + widget.link, + // '${AppEnviroment.baseFileUrl}/mih/$filePath', + 'download'); + } else { + //print("Here"); + // var permission = await FlDownloader.requestPermission(); + // if (permission == StoragePermissionStatus.granted) { + // await FlDownloader.download(widget.link); + // } else { + // print("denied"); + // } + nativeFileDownload(widget.link); + } + }, + icon: Icon( + Icons.download, + color: MzanziInnovationHub.of(context)!.theme.primaryColor(), + ), + ), + ), + ], + ), + ); + } + } +} diff --git a/Frontend/lib/mih_packages/patient_profile/pat_profile/list_builders/build_files_list.dart b/Frontend/lib/mih_packages/patient_profile/pat_profile/list_builders/build_files_list.dart new file mode 100644 index 00000000..7e440891 --- /dev/null +++ b/Frontend/lib/mih_packages/patient_profile/pat_profile/list_builders/build_files_list.dart @@ -0,0 +1,397 @@ +import 'dart:convert'; + +import 'package:Mzansi_Innovation_Hub/main.dart'; +import 'package:Mzansi_Innovation_Hub/mih_components/mih_layout/mih_window.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'; +import 'package:Mzansi_Innovation_Hub/mih_components/mih_pop_up_messages/mih_success_message.dart'; +import 'package:Mzansi_Innovation_Hub/mih_env/env.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/business.dart'; +import 'package:Mzansi_Innovation_Hub/mih_objects/business_user.dart'; +import 'package:Mzansi_Innovation_Hub/mih_objects/files.dart'; +import 'package:Mzansi_Innovation_Hub/mih_objects/patients.dart'; +import 'package:Mzansi_Innovation_Hub/mih_packages/patient_profile/pat_profile/list_builders/build_file_view.dart'; +import 'package:flutter/material.dart'; +import 'package:supertokens_flutter/http.dart' as http; + +class BuildFilesList extends StatefulWidget { + final AppUser signedInUser; + final List files; + final Patient selectedPatient; + final Business? business; + final BusinessUser? businessUser; + final String type; + const BuildFilesList({ + super.key, + required this.files, + required this.signedInUser, + required this.selectedPatient, + required this.business, + required this.businessUser, + required this.type, + }); + + @override + State createState() => _BuildFilesListState(); +} + +class _BuildFilesListState extends State { + int indexOn = 0; + final baseAPI = AppEnviroment.baseApiUrl; + final basefile = AppEnviroment.baseFileUrl; + String fileUrl = ""; + + Future getFileUrlApiCall(String filePath) async { + var url = "$baseAPI/minio/pull/file/${AppEnviroment.getEnv()}/$filePath"; + //print(url); + var response = await http.get(Uri.parse(url)); + // print("here1"); + //print(response.statusCode); + + if (response.statusCode == 200) { + //print("here2"); + String body = response.body; + //print(body); + //print("here3"); + var decodedData = jsonDecode(body); + //print("Dedoced: ${decodedData['minioURL']}"); + + return decodedData['minioURL']; + //AppUser u = AppUser.fromJson(decodedData); + // print(u.email); + //return "AlometThere"; + } else { + throw Exception("Error: GetUserData status code ${response.statusCode}"); + } + + //print(url); + // var response = await http.get(Uri.parse(url)); + // // print("here1"); + // //print(response.statusCode); + + // if (response.statusCode == 200) { + // //print("here2"); + // String body = response.body; + // //print(body); + // //print("here3"); + // var decodedData = jsonDecode(body); + // //print("Dedoced: ${decodedData['minioURL']}"); + + // return decodedData['minioURL']; + // //AppUser u = AppUser.fromJson(decodedData); + // // print(u.email); + // //return "AlometThere"; + // } else { + // throw Exception("Error: GetUserData status code ${response.statusCode}"); + // } + } + + Future deleteFileApiCall(String filePath, int fileID) async { + showDialog( + context: context, + builder: (context) { + return const Mihloadingcircle(); + }, + ); + // delete file from minio + var response = await http.delete( + Uri.parse("$baseAPI/minio/delete/file/"), + headers: { + "Content-Type": "application/json; charset=UTF-8" + }, + body: jsonEncode({"file_path": filePath}), + ); + //print("Here4"); + //print(response.statusCode); + if (response.statusCode == 200) { + //SQL delete + var response2 = await http.delete( + Uri.parse("$baseAPI/files/delete/"), + headers: { + "Content-Type": "application/json; charset=UTF-8" + }, + body: jsonEncode({"idpatient_files": fileID}), + ); + if (response2.statusCode == 200) { + Navigator.of(context).pop(); + Navigator.of(context).pop(); + Navigator.of(context).pop(); + Navigator.of(context).pop(); + //print(widget.business); + if (widget.business == null) { + Navigator.of(context).pushNamed('/patient-manager/patient', + arguments: PatientViewArguments( + widget.signedInUser, + widget.selectedPatient, + widget.businessUser, + widget.business, + "personal")); + } else { + Navigator.of(context).pushNamed('/patient-manager/patient', + arguments: PatientViewArguments( + widget.signedInUser, + widget.selectedPatient, + widget.businessUser, + widget.business, + "business")); + } + + // Navigator.of(context) + // .pushNamed('/patient-profile', arguments: widget.signedInUser); + // setState(() {}); + String message = + "The File has been deleted successfully. This means it will no longer be visible on your and cannot be used for future appointments."; + successPopUp(message); + } else { + internetConnectionPopUp(); + } + } else { + internetConnectionPopUp(); + } + } + + void internetConnectionPopUp() { + showDialog( + context: context, + builder: (context) { + return const MIHErrorMessage(errorType: "Internet Connection"); + }, + ); + } + + void successPopUp(String message) { + showDialog( + context: context, + builder: (context) { + return MIHSuccessMessage( + successType: "Success", + successMessage: message, + ); + }, + ); + } + + void deleteFilePopUp(String filePath, int fileID) { + showDialog( + context: context, + barrierDismissible: false, + builder: (context) => MIHDeleteMessage( + deleteType: "File", + onTap: () async { + await deleteFileApiCall(filePath, fileID); + }, + ), + ); + } + + void viewFilePopUp(String fileName, String filePath, int fileID, String url) { + bool hasAccessToDelete = false; + if (widget.type == "business") { + hasAccessToDelete = true; + } + showDialog( + context: context, + barrierDismissible: false, + builder: (context) => MIHWindow( + fullscreen: true, + windowTitle: fileName, + windowBody: [ + BuildFileView( + link: url, + path: filePath, + //pdfLink: '${AppEnviroment.baseFileUrl}/mih/$filePath', + ), + const SizedBox( + height: 10, + ) + ], + windowTools: [ + Visibility( + visible: hasAccessToDelete, + child: IconButton( + onPressed: () { + deleteFilePopUp(filePath, fileID); + }, + icon: Icon( + size: 35, + Icons.delete, + color: MzanziInnovationHub.of(context)!.theme.secondaryColor(), + ), + ), + ), + ], + onWindowTapClose: () { + Navigator.pop(context); + }, + ), + ); + // showDialog( + // context: context, + // barrierDismissible: false, + // builder: (context) => Dialog( + // child: Stack( + // children: [ + // Container( + // padding: const EdgeInsets.all(10.0), + // width: 800.0, + // //height: 475.0, + // decoration: BoxDecoration( + // color: MzanziInnovationHub.of(context)!.theme.primaryColor(), + // borderRadius: BorderRadius.circular(25.0), + // border: Border.all( + // color: + // MzanziInnovationHub.of(context)!.theme.secondaryColor(), + // width: 5.0), + // ), + // child: Column( + // mainAxisSize: MainAxisSize.min, + // children: [ + // const SizedBox( + // height: 25, + // ), + // Text( + // fileName, + // textAlign: TextAlign.center, + // style: TextStyle( + // color: MzanziInnovationHub.of(context)! + // .theme + // .secondaryColor(), + // fontSize: 35.0, + // fontWeight: FontWeight.bold, + // ), + // ), + // const SizedBox(height: 25.0), + // Expanded( + // child: BuildFileView( + // link: url, + // path: filePath, + // //pdfLink: '${AppEnviroment.baseFileUrl}/mih/$filePath', + // )), + // const SizedBox(height: 30.0), + // SizedBox( + // width: 300, + // height: 50, + // child: MIHButton( + // onTap: () { + // html.window.open( + // url, + // // '${AppEnviroment.baseFileUrl}/mih/$filePath', + // 'download'); + // }, + // buttonText: "Dowload", + // buttonColor: MzanziInnovationHub.of(context)! + // .theme + // .secondaryColor(), + // textColor: + // MzanziInnovationHub.of(context)!.theme.primaryColor(), + // ), + // ) + // ], + // ), + // ), + // Positioned( + // top: 5, + // right: 5, + // width: 50, + // height: 50, + // child: IconButton( + // onPressed: () { + // Navigator.pop(context); + // }, + // icon: Icon( + // Icons.close, + // color: MzanziInnovationHub.of(context)!.theme.errorColor(), + // size: 35, + // ), + // ), + // ), + // Positioned( + // top: 5, + // left: 5, + // width: 50, + // height: 50, + // child: IconButton( + // onPressed: () { + // deleteFilePopUp(filePath, fileID); + // }, + // icon: Icon( + // Icons.delete, + // color: + // MzanziInnovationHub.of(context)!.theme.secondaryColor(), + // ), + // ), + // ), + // ], + // ), + // ), + // ); + } + + @override + void dispose() { + // TODO: implement dispose + super.dispose(); + } + + @override + Widget build(BuildContext context) { + if (widget.files.isNotEmpty) { + return ListView.separated( + shrinkWrap: true, + physics: const NeverScrollableScrollPhysics(), + separatorBuilder: (BuildContext context, int index) { + return Divider( + color: MzanziInnovationHub.of(context)!.theme.secondaryColor(), + ); + }, + itemCount: widget.files.length, + itemBuilder: (context, index) { + return ListTile( + title: Text( + widget.files[index].file_name, + style: TextStyle( + color: MzanziInnovationHub.of(context)!.theme.secondaryColor(), + ), + ), + subtitle: Text( + widget.files[index].insert_date, + style: TextStyle( + color: MzanziInnovationHub.of(context)!.theme.secondaryColor(), + ), + ), + // trailing: Icon( + // Icons.arrow_forward, + // color: MzanziInnovationHub.of(context)!.theme.secondaryColor(), + // ), + onTap: () async { + await getFileUrlApiCall(widget.files[index].file_path) + .then((urlHere) { + //print(url); + setState(() { + fileUrl = urlHere; + }); + }); + + viewFilePopUp( + widget.files[index].file_name, + widget.files[index].file_path, + widget.files[index].idpatient_files, + fileUrl); + }, + ); + }, + ); + } else { + return const Center( + child: Text( + "No Documents Available", + style: TextStyle(fontSize: 25, color: Colors.grey), + textAlign: TextAlign.center, + ), + ); + } + } +} 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 new file mode 100644 index 00000000..66f28cc3 --- /dev/null +++ b/Frontend/lib/mih_packages/patient_profile/pat_profile/list_builders/build_notes_list.dart @@ -0,0 +1,396 @@ +import 'dart:convert'; + +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_layout/mih_window.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'; +import 'package:Mzansi_Innovation_Hub/mih_env/env.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/business.dart'; +import 'package:Mzansi_Innovation_Hub/mih_objects/business_user.dart'; +import 'package:Mzansi_Innovation_Hub/mih_objects/notes.dart'; +import 'package:Mzansi_Innovation_Hub/mih_objects/patients.dart'; +import 'package:flutter/material.dart'; +import 'package:supertokens_flutter/http.dart' as http; + +class BuildNotesList extends StatefulWidget { + final AppUser signedInUser; + final List notes; + final Patient selectedPatient; + final Business? business; + final BusinessUser? businessUser; + final String type; + const BuildNotesList({ + super.key, + required this.notes, + required this.signedInUser, + required this.selectedPatient, + required this.business, + required this.businessUser, + required this.type, + }); + + @override + State createState() => _BuildNotesListState(); +} + +class _BuildNotesListState extends State { + final noteTitleController = TextEditingController(); + final noteTextController = TextEditingController(); + final businessNameController = TextEditingController(); + final userNameController = TextEditingController(); + final dateController = TextEditingController(); + int indexOn = 0; + final baseAPI = AppEnviroment.baseApiUrl; + + Future deleteNoteApiCall(int NoteId) async { + var response = await http.delete( + Uri.parse("$baseAPI/notes/delete/"), + headers: { + "Content-Type": "application/json; charset=UTF-8" + }, + body: jsonEncode({"idpatient_notes": NoteId}), + ); + //print("Here4"); + //print(response.statusCode); + if (response.statusCode == 200) { + Navigator.of(context).pop(); + Navigator.of(context).pop(); + if (widget.business == null) { + Navigator.of(context).pushNamed('/patient-manager/patient', + arguments: PatientViewArguments( + widget.signedInUser, + widget.selectedPatient, + widget.businessUser, + widget.business, + "personal")); + } else { + Navigator.of(context).pushNamed('/patient-manager/patient', + arguments: PatientViewArguments( + widget.signedInUser, + widget.selectedPatient, + widget.businessUser, + widget.business, + "business")); + } + setState(() {}); + String message = + "The note has been deleted successfully. This means it will no longer be visible on your and cannot be used for future appointments."; + successPopUp(message); + } else { + internetConnectionPopUp(); + } + } + + void internetConnectionPopUp() { + showDialog( + context: context, + builder: (context) { + return const MIHErrorMessage(errorType: "Internet Connection"); + }, + ); + } + + void successPopUp(String message) { + showDialog( + context: context, + builder: (context) { + return MIHSuccessMessage( + successType: "Success", + successMessage: message, + ); + }, + ); + } + + void deletePatientPopUp(int NoteId) { + showDialog( + context: context, + barrierDismissible: false, + builder: (context) => MIHDeleteMessage( + deleteType: "Note", + onTap: () { + deleteNoteApiCall(NoteId); + }, + ), + ); + } + + void viewNotePopUp(Note selectednote) { + setState(() { + noteTitleController.text = selectednote.note_name; + noteTextController.text = selectednote.note_text; + businessNameController.text = selectednote.doc_office; + userNameController.text = selectednote.doctor; + dateController.text = selectednote.insert_date; + }); + bool hasAccessToDelete = false; + if (widget.type == "business" && + selectednote.doc_office == widget.business!.Name) { + hasAccessToDelete = true; + } + showDialog( + context: context, + barrierDismissible: false, + builder: (context) => MIHWindow( + fullscreen: true, + windowTitle: selectednote.note_name, + windowTools: [ + Visibility( + visible: hasAccessToDelete, + child: IconButton( + onPressed: () { + deletePatientPopUp(selectednote.idpatient_notes); + }, + icon: Icon( + Icons.delete, + color: MzanziInnovationHub.of(context)!.theme.secondaryColor(), + ), + ), + ), + ], + onWindowTapClose: () { + Navigator.pop(context); + }, + windowBody: [ + MIHTextField( + controller: businessNameController, + hintText: "Office", + editable: false, + required: false, + ), + const SizedBox(height: 10.0), + MIHTextField( + controller: userNameController, + hintText: "Created By", + editable: false, + required: false, + ), + const SizedBox(height: 10.0), + MIHTextField( + controller: dateController, + hintText: "Created Date", + editable: false, + required: false, + ), + const SizedBox(height: 10.0), + MIHTextField( + controller: noteTitleController, + hintText: "Note Title", + editable: false, + required: false, + ), + const SizedBox(height: 10.0), + Expanded( + child: MIHMLTextField( + controller: noteTextController, + hintText: "Note Details", + editable: false, + required: false, + ), + ), + ], + ), + ); + // showDialog( + // context: context, + // barrierDismissible: false, + // builder: (context) => Dialog( + // child: Stack( + // children: [ + // Container( + // padding: const EdgeInsets.all(15.0), + // width: 700.0, + // //height: 475.0, + // decoration: BoxDecoration( + // color: MzanziInnovationHub.of(context)!.theme.primaryColor(), + // borderRadius: BorderRadius.circular(25.0), + // border: Border.all( + // color: + // MzanziInnovationHub.of(context)!.theme.secondaryColor(), + // width: 5.0), + // ), + // child: Column( + // mainAxisSize: MainAxisSize.max, + // children: [ + // const SizedBox( + // height: 25, + // ), + // Text( + // selectednote.note_name, + // textAlign: TextAlign.center, + // style: TextStyle( + // color: MzanziInnovationHub.of(context)! + // .theme + // .secondaryColor(), + // fontSize: 35.0, + // fontWeight: FontWeight.bold, + // ), + // ), + // const SizedBox(height: 25.0), + // SizedBox( + // width: 700, + // child: MIHTextField( + // controller: businessNameController, + // hintText: "Office", + // editable: false, + // required: false, + // ), + // ), + // const SizedBox(height: 10.0), + // SizedBox( + // width: 700, + // child: MIHTextField( + // controller: userNameController, + // hintText: "Created By", + // editable: false, + // required: false, + // ), + // ), + // const SizedBox(height: 10.0), + // SizedBox( + // width: 700, + // child: MIHTextField( + // controller: dateController, + // hintText: "Created Date", + // editable: false, + // required: false, + // ), + // ), + // const SizedBox(height: 10.0), + // SizedBox( + // width: 700, + // child: MIHTextField( + // controller: noteTitleController, + // hintText: "Note Title", + // editable: false, + // required: false, + // ), + // ), + // const SizedBox(height: 10.0), + // Expanded( + // child: MIHMLTextField( + // controller: noteTextController, + // hintText: "Note Details", + // editable: false, + // required: false, + // ), + // ), + // //const SizedBox(height: 25.0), + // // SizedBox( + // // width: 300, + // // height: 100, + // // child: MIHButton( + // // onTap: () { + // // Navigator.pop(context); + // // }, + // // buttonText: "Close", + // // buttonColor: Colors.blueAccent, + // // textColor: Colors.white, + // // ), + // // ) + // ], + // ), + // ), + // Positioned( + // top: 5, + // right: 5, + // width: 50, + // height: 50, + // child: IconButton( + // onPressed: () { + // Navigator.pop(context); + // }, + // icon: Icon( + // Icons.close, + // color: MzanziInnovationHub.of(context)!.theme.errorColor(), + // size: 35, + // ), + // ), + // ), + // Positioned( + // top: 5, + // left: 5, + // width: 50, + // height: 50, + // child: IconButton( + // onPressed: () { + // deletePatientPopUp(selectednote.idpatient_notes); + // }, + // icon: Icon( + // Icons.delete, + // color: + // MzanziInnovationHub.of(context)!.theme.secondaryColor(), + // ), + // ), + // ), + // ], + // ), + // ), + // ); + } + + @override + void dispose() { + noteTextController.dispose(); + businessNameController.dispose(); + userNameController.dispose(); + dateController.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + if (widget.notes.isNotEmpty) { + return ListView.separated( + shrinkWrap: true, + physics: const NeverScrollableScrollPhysics(), + separatorBuilder: (BuildContext context, int index) { + return Divider( + color: MzanziInnovationHub.of(context)!.theme.secondaryColor(), + ); + }, + itemCount: widget.notes.length, + itemBuilder: (context, index) { + String notePreview = widget.notes[index].note_text; + if (notePreview.length > 30) { + notePreview = "${notePreview.substring(0, 30)} ..."; + } + return ListTile( + title: Text( + "${widget.notes[index].note_name}\n${widget.notes[index].doc_office} - ${widget.notes[index].doctor}", + style: TextStyle( + color: MzanziInnovationHub.of(context)!.theme.secondaryColor(), + ), + ), + subtitle: Text( + "${widget.notes[index].insert_date}:\n$notePreview", + style: TextStyle( + color: MzanziInnovationHub.of(context)!.theme.secondaryColor(), + ), + ), //Text(widget.notes[index].note_text), + trailing: Icon( + Icons.arrow_forward, + color: MzanziInnovationHub.of(context)!.theme.secondaryColor(), + ), + onTap: () { + viewNotePopUp(widget.notes[index]); + }, + ); + }, + ); + } else { + return const Center( + child: Text( + "No Notes Available", + style: TextStyle(fontSize: 25, color: Colors.grey), + textAlign: TextAlign.center, + ), + ); + } + } +} From 920a070d6f4e5b67def6fadab382b12a1c2b4761 Mon Sep 17 00:00:00 2001 From: Yasien Mac Mini Date: Mon, 17 Mar 2025 14:06:10 +0200 Subject: [PATCH 09/17] new components --- .../app_tools/patient_claim_or_statement.dart | 151 +++++ .../components/Claim_Statement_Window.dart | 511 ++++++++++++++++ .../pat_profile/components/prescip_input.dart | 573 ++++++++++++++++++ 3 files changed, 1235 insertions(+) create mode 100644 Frontend/lib/mih_packages/patient_profile/pat_profile/app_tools/patient_claim_or_statement.dart create mode 100644 Frontend/lib/mih_packages/patient_profile/pat_profile/components/Claim_Statement_Window.dart create mode 100644 Frontend/lib/mih_packages/patient_profile/pat_profile/components/prescip_input.dart diff --git a/Frontend/lib/mih_packages/patient_profile/pat_profile/app_tools/patient_claim_or_statement.dart b/Frontend/lib/mih_packages/patient_profile/pat_profile/app_tools/patient_claim_or_statement.dart new file mode 100644 index 00000000..6f96351a --- /dev/null +++ b/Frontend/lib/mih_packages/patient_profile/pat_profile/app_tools/patient_claim_or_statement.dart @@ -0,0 +1,151 @@ +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_components/mih_package/mih-app_tool_body.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'; +import 'package:Mzansi_Innovation_Hub/mih_objects/business.dart'; +import 'package:Mzansi_Innovation_Hub/mih_objects/business_user.dart'; +import 'package:Mzansi_Innovation_Hub/mih_objects/claim_statement_file.dart'; +import 'package:Mzansi_Innovation_Hub/mih_objects/patients.dart'; +import 'package:Mzansi_Innovation_Hub/mih_packages/patient_profile/pat_profile/components/Claim_Statement_Window.dart'; +import 'package:Mzansi_Innovation_Hub/mih_packages/patient_profile/pat_profile/list_builders/build_claim_statement_files_list.dart'; +import 'package:flutter/material.dart'; + +class PatientClaimOrStatement extends StatefulWidget { + final int patientIndex; + final Patient selectedPatient; + final AppUser signedInUser; + final Business? business; + final BusinessUser? businessUser; + final String type; + const PatientClaimOrStatement({ + super.key, + required this.patientIndex, + required this.selectedPatient, + required this.signedInUser, + required this.business, + required this.businessUser, + required this.type, + }); + + @override + State createState() => + _PatientClaimOrStatementState(); +} + +class _PatientClaimOrStatementState extends State { + late Future> futueFiles; + + void claimOrStatementWindow() { + showDialog( + context: context, + barrierDismissible: false, + builder: (context) => ClaimStatementWindow( + selectedPatient: widget.selectedPatient, + signedInUser: widget.signedInUser, + business: widget.business, + businessUser: widget.businessUser, + ), + ); + } + + List setIcons() { + if (widget.type == "personal") { + return [ + Text( + "Claims/ Statements", + textAlign: TextAlign.center, + style: TextStyle( + fontSize: 25, + fontWeight: FontWeight.bold, + color: MzanziInnovationHub.of(context)!.theme.secondaryColor(), + ), + ), + ]; + } else { + return [ + Text( + "Claims/ Statements", + textAlign: TextAlign.center, + style: TextStyle( + fontSize: 25, + fontWeight: FontWeight.bold, + color: MzanziInnovationHub.of(context)!.theme.secondaryColor(), + ), + ), + IconButton( + onPressed: () { + // new window to input fields for claim/ statements + claimOrStatementWindow(); + }, + icon: Icon( + Icons.add, + color: MzanziInnovationHub.of(context)!.theme.secondaryColor(), + ), + ) + ]; + } + } + + @override + void initState() { + if (widget.business == null) { + futueFiles = + MIHClaimStatementGenerationApi.getClaimStatementFilesByPatient( + widget.signedInUser.app_id); + } else { + futueFiles = + MIHClaimStatementGenerationApi.getClaimStatementFilesByBusiness( + widget.business!.business_id); + } + super.initState(); + } + + @override + Widget build(BuildContext context) { + return MihAppToolBody( + borderOn: true, + bodyItem: getBody(), + ); + } + + Widget getBody() { + return FutureBuilder( + future: futueFiles, + builder: (context, snapshot) { + if (snapshot.connectionState == ConnectionState.waiting) { + return const Center( + child: Mihloadingcircle(), + ); + } else if (snapshot.hasData) { + final filesList = snapshot.data!; + return Column( + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: setIcons(), + ), + Divider( + color: + MzanziInnovationHub.of(context)!.theme.secondaryColor()), + const SizedBox(height: 10), + //const Placeholder(), + BuildClaimStatementFileList( + files: filesList, + signedInUser: widget.signedInUser, + selectedPatient: widget.selectedPatient, + business: widget.business, + businessUser: widget.businessUser, + type: widget.type, + ), + ], + ); + } else { + return const Center( + child: Text("Error Loading Notes"), + ); + } + }, + ); + } +} 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 new file mode 100644 index 00000000..3c0b0970 --- /dev/null +++ b/Frontend/lib/mih_packages/patient_profile/pat_profile/components/Claim_Statement_Window.dart @@ -0,0 +1,511 @@ +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_components/mih_inputs_and_buttons/mih_button.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_search_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_window.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'; +import 'package:Mzansi_Innovation_Hub/mih_objects/business.dart'; +import 'package:Mzansi_Innovation_Hub/mih_objects/business_user.dart'; +import 'package:Mzansi_Innovation_Hub/mih_objects/icd10_code.dart.dart'; +import 'package:Mzansi_Innovation_Hub/mih_objects/patients.dart'; +import 'package:Mzansi_Innovation_Hub/mih_packages/patient_profile/icd10_search_window.dart'; +import 'package:flutter/material.dart'; +import 'package:intl/intl.dart'; + +class ClaimStatementWindow extends StatefulWidget { + final Patient selectedPatient; + final AppUser signedInUser; + final Business? business; + final BusinessUser? businessUser; + const ClaimStatementWindow({ + super.key, + required this.selectedPatient, + required this.signedInUser, + required this.business, + required this.businessUser, + }); + + @override + State createState() => _ClaimStatementWindowState(); +} + +class _ClaimStatementWindowState extends State { + final TextEditingController _docTypeController = TextEditingController(); + final TextEditingController _fullNameController = TextEditingController(); + final TextEditingController _idController = TextEditingController(); + final TextEditingController _medAidController = TextEditingController(); + final TextEditingController _medAidNoController = TextEditingController(); + final TextEditingController _medAidCodeController = TextEditingController(); + final TextEditingController _medAidNameController = TextEditingController(); + final TextEditingController _medAidSchemeController = TextEditingController(); + final TextEditingController _providerNameController = TextEditingController(); + final TextEditingController _practiceNoController = TextEditingController(); + final TextEditingController _vatNoController = TextEditingController(); + final TextEditingController _serviceDateController = TextEditingController(); + final TextEditingController _serviceDescController = TextEditingController(); + final TextEditingController _serviceDescOptionsController = + TextEditingController(); + final TextEditingController _prcedureNameController = TextEditingController(); + // final TextEditingController _procedureDateController = + // TextEditingController(); + final TextEditingController _proceedureAdditionalInfoController = + TextEditingController(); + final TextEditingController _icd10CodeController = TextEditingController(); + final TextEditingController _amountController = TextEditingController(); + final TextEditingController _preauthNoController = TextEditingController(); + final ValueNotifier serviceDesc = ValueNotifier(""); + final ValueNotifier medAid = ValueNotifier(""); + List icd10codeList = []; + + void icd10SearchWindow(List codeList) { + showDialog( + context: context, + barrierDismissible: false, + builder: (context) => ICD10SearchWindow( + icd10CodeController: _icd10CodeController, + icd10codeList: codeList, + ), + ); + } + + 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( + // "Patient 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), + // MIHTextField( + // controller: _fullNameController, + // hintText: "Full Name", + // editable: false, + // required: true, + // ), + // const SizedBox(height: 10), + // MIHTextField( + // controller: _idController, + // hintText: "ID No.", + // editable: false, + // required: true, + // ), + // const SizedBox(height: 10), + // MIHTextField( + // controller: _medAidController, + // hintText: "Has Medical Aid", + // editable: false, + // required: true, + // ), + // const SizedBox(height: 10), + // ValueListenableBuilder( + // valueListenable: serviceDesc, + // builder: (BuildContext context, String value, Widget? child) { + // return Visibility( + // visible: value == "Yes", + // child: Column( + // children: [ + // MIHTextField( + // controller: _medAidNoController, + // hintText: "Medical Aid No.", + // editable: false, + // required: true, + // ), + // const SizedBox(height: 10), + // MIHTextField( + // controller: _medAidCodeController, + // hintText: "Medical Aid Code", + // editable: false, + // required: true, + // ), + // const SizedBox(height: 10), + // MIHTextField( + // controller: _medAidNameController, + // hintText: "Medical Aid Name", + // editable: false, + // required: true, + // ), + // const SizedBox(height: 10), + // MIHTextField( + // controller: _medAidSchemeController, + // hintText: "Medical Aid Scheme", + // editable: false, + // required: true, + // ), + // const SizedBox(height: 10), + // ], + // ), + // ); + // }, + // ), + // Text( + // "Provider 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), + // MIHTextField( + // controller: _providerNameController, + // hintText: "Provider Name", + // editable: false, + // required: true, + // ), + // const SizedBox(height: 10), + // MIHTextField( + // controller: _practiceNoController, + // hintText: "Practice No.", + // editable: false, + // required: true, + // ), + // const SizedBox(height: 10), + // MIHTextField( + // controller: _vatNoController, + // hintText: "VAT No.", + // editable: false, + // required: true, + // ), + // 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), + MIHSearchField( + controller: _icd10CodeController, + hintText: "ICD-10 Code & Description", + required: true, + editable: true, + onTap: () { + //api + MIHIcd10CodeApis.getIcd10Codes(_icd10CodeController.text, context) + .then((result) { + icd10SearchWindow(result); + }); + }, + ), + 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), + SizedBox( + width: 500, + height: 50, + child: MIHButton( + onTap: () { + //generate document and uploud it + 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", + ), + context); + } else { + showDialog( + context: context, + builder: (context) { + return const MIHErrorMessage(errorType: "Input Error"); + }, + ); + } + }, + buttonText: "Generate", + buttonColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + textColor: MzanziInnovationHub.of(context)!.theme.primaryColor(), + ), + ) + ], + ); + } + + void serviceDescriptionSelected() { + if (_serviceDescController.text.isNotEmpty) { + serviceDesc.value = _serviceDescController.text; + } else { + serviceDesc.value = ""; + } + } + + void hasMedAid() { + if (_medAidController.text.isNotEmpty) { + medAid.value = _medAidController.text; + } else { + medAid.value = ""; + } + } + + 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; + } + } + } + + String getUserTitle() { + if (widget.businessUser!.title == "Doctor") { + return "Dr."; + } else { + return widget.businessUser!.title; + } + } + + String getTodayDate() { + DateTime today = DateTime.now(); + return DateFormat('yyyy-MM-dd').format(today); + } + + @override + void dispose() { + _docTypeController.dispose(); + _fullNameController.dispose(); + _idController.dispose(); + _medAidController.dispose(); + _medAidNoController.dispose(); + _medAidCodeController.dispose(); + _medAidNameController.dispose(); + _medAidSchemeController.dispose(); + _providerNameController.dispose(); + _practiceNoController.dispose(); + _vatNoController.dispose(); + _serviceDateController.dispose(); + _serviceDescController.dispose(); + _serviceDescOptionsController.dispose(); + _prcedureNameController.dispose(); + // _procedureDateController.dispose(); + _proceedureAdditionalInfoController.dispose(); + _icd10CodeController.dispose(); + _preauthNoController.dispose(); + super.dispose(); + } + + @override + void initState() { + _serviceDescController.addListener(serviceDescriptionSelected); + _medAidController.addListener(hasMedAid); + _fullNameController.text = + "${widget.selectedPatient.first_name} ${widget.selectedPatient.last_name}"; + _idController.text = widget.selectedPatient.id_no; + _medAidController.text = widget.selectedPatient.medical_aid; + _medAidNameController.text = widget.selectedPatient.medical_aid_name; + _medAidCodeController.text = widget.selectedPatient.medical_aid_code; + _medAidNoController.text = widget.selectedPatient.medical_aid_no; + _medAidSchemeController.text = widget.selectedPatient.medical_aid_scheme; + _serviceDateController.text = getTodayDate(); + _providerNameController.text = + "${getUserTitle()} ${widget.signedInUser.fname} ${widget.signedInUser.lname}"; + _practiceNoController.text = widget.business!.practice_no; + _vatNoController.text = widget.business!.vat_no; + super.initState(); + } + + @override + Widget build(BuildContext context) { + return MIHWindow( + fullscreen: false, + windowTitle: "Generate Claim/ Statement Document", + windowTools: const [], + onWindowTapClose: () { + // medicineController.clear(); + // quantityController.clear(); + // dosageController.clear(); + // timesDailyController.clear(); + // noDaysController.clear(); + // noRepeatsController.clear(); + Navigator.pop(context); + }, + windowBody: [ + getWindowBody(), + ], + ); + } +} diff --git a/Frontend/lib/mih_packages/patient_profile/pat_profile/components/prescip_input.dart b/Frontend/lib/mih_packages/patient_profile/pat_profile/components/prescip_input.dart new file mode 100644 index 00000000..411fcaff --- /dev/null +++ b/Frontend/lib/mih_packages/patient_profile/pat_profile/components/prescip_input.dart @@ -0,0 +1,573 @@ +import 'dart:convert'; + +import 'package:Mzansi_Innovation_Hub/main.dart'; +import 'package:Mzansi_Innovation_Hub/mih_components/medicine_search.dart'; +import 'package:Mzansi_Innovation_Hub/mih_components/mih_inputs_and_buttons/mih_button.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_search_input.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'; +import 'package:Mzansi_Innovation_Hub/mih_env/env.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/business.dart'; +import 'package:Mzansi_Innovation_Hub/mih_objects/business_user.dart'; +import 'package:Mzansi_Innovation_Hub/mih_objects/patients.dart'; +import 'package:Mzansi_Innovation_Hub/mih_objects/perscription.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:supertokens_flutter/http.dart' as http; + +class PrescripInput extends StatefulWidget { + final TextEditingController medicineController; + final TextEditingController quantityController; + final TextEditingController dosageController; + final TextEditingController timesDailyController; + final TextEditingController noDaysController; + final TextEditingController noRepeatsController; + final TextEditingController outputController; + final Patient selectedPatient; + final AppUser signedInUser; + final Business? business; + final BusinessUser? businessUser; + const PrescripInput({ + super.key, + required this.medicineController, + required this.quantityController, + required this.dosageController, + required this.timesDailyController, + required this.noDaysController, + required this.noRepeatsController, + required this.outputController, + required this.selectedPatient, + required this.signedInUser, + required this.business, + required this.businessUser, + }); + + @override + State createState() => _PrescripInputState(); +} + +class _PrescripInputState extends State { + final FocusNode _focusNode = FocusNode(); + List perscriptionObjOutput = []; + late double width; + late double height; + + final numberOptions = [ + "0", + "1", + "2", + "3", + "4", + "5", + "6", + "7", + "8", + "9", + "10", + "11", + "12", + "13", + "14", + "15", + "16", + "17", + "18", + "19", + "20", + "21", + "22", + "23", + "24", + "25", + "26", + "27", + "28", + "29", + "30" + ]; + + Future generatePerscription() async { + //start loading circle + showDialog( + context: context, + builder: (context) { + return const Mihloadingcircle(); + }, + ); + + var response1 = await http.post( + Uri.parse("${AppEnviroment.baseApiUrl}/minio/generate/perscription/"), + headers: { + "Content-Type": "application/json; charset=UTF-8" + }, + body: jsonEncode({ + "app_id": widget.selectedPatient.app_id, + "fullName": + "${widget.selectedPatient.first_name} ${widget.selectedPatient.last_name}", + "id_no": widget.selectedPatient.id_no, + "docfname": + "DR. ${widget.signedInUser.fname} ${widget.signedInUser.lname}", + "busName": widget.business!.Name, + "busAddr": "*TO BE ADDED IN THE FUTURE*", + "busNo": widget.business!.contact_no, + "busEmail": widget.business!.bus_email, + "logo_path": widget.business!.logo_path, + "sig_path": widget.businessUser!.sig_path, + "data": perscriptionObjOutput, + }), + ); + //print(response1.statusCode); + DateTime now = new DateTime.now(); + DateTime date = new DateTime(now.year, now.month, now.day); + String fileName = + "Perscription-${widget.selectedPatient.first_name} ${widget.selectedPatient.last_name}-${date.toString().substring(0, 10)}.pdf"; + if (response1.statusCode == 200) { + var response2 = await http.post( + Uri.parse("${AppEnviroment.baseApiUrl}/files/insert/"), + headers: { + "Content-Type": "application/json; charset=UTF-8" + }, + body: jsonEncode({ + "file_path": + "${widget.selectedPatient.app_id}/patient_files/$fileName", + "file_name": fileName, + "app_id": widget.selectedPatient.app_id + }), + ); + //print(response2.statusCode); + if (response2.statusCode == 201) { + setState(() { + //To do + widget.medicineController.clear(); + widget.dosageController.clear(); + widget.timesDailyController.clear(); + widget.noDaysController.clear(); + widget.timesDailyController.clear(); + widget.noRepeatsController.clear(); + widget.quantityController.clear(); + widget.outputController.clear(); + // futueFiles = fetchFiles(); + }); + // end loading circle + Navigator.of(context).pop(); + Navigator.of(context).pop(); + Navigator.of(context).pushNamed('/patient-manager/patient', + arguments: PatientViewArguments( + widget.signedInUser, + widget.selectedPatient, + widget.businessUser, + widget.business, + "business", + )); + String message = + "The perscription $fileName has been successfully generated and added to ${widget.selectedPatient.first_name} ${widget.selectedPatient.last_name}'s record. You can now access and download it for their use."; + successPopUp(message); + } else { + internetConnectionPopUp(); + } + } else { + internetConnectionPopUp(); + } + } + + void internetConnectionPopUp() { + showDialog( + context: context, + builder: (context) { + return const MIHErrorMessage(errorType: "Internet Connection"); + }, + ); + } + + void successPopUp(String message) { + showDialog( + context: context, + builder: (context) { + return MIHSuccessMessage( + successType: "Success", + successMessage: message, + ); + }, + ); + } + + void getMedsPopUp(TextEditingController medSearch) { + showDialog( + context: context, + builder: (context) { + return MedicineSearch( + searchVlaue: medSearch, + ); + }, + ); + } + + bool isFieldsFilled() { + if (widget.medicineController.text.isEmpty || + // widget.quantityController.text.isEmpty || + widget.dosageController.text.isEmpty || + widget.timesDailyController.text.isEmpty || + widget.noDaysController.text.isEmpty || + widget.noRepeatsController.text.isEmpty) { + return false; + } else { + return true; + } + } + + void updatePerscriptionList() { + String name; + String unit; + String form; + List medNameList = widget.medicineController.text.split("%t"); + if (medNameList.length == 1) { + name = medNameList[0]; + unit = ""; + form = ""; + } else { + name = medNameList[0]; + unit = medNameList[1]; + form = medNameList[2]; + } + int quantityCalc = calcQuantity( + widget.dosageController.text, + widget.timesDailyController.text, + widget.noDaysController.text, + medNameList[2].toLowerCase()); + Perscription tempObj = Perscription( + name: name, + unit: unit, + form: form, + fullForm: getFullDoagesForm(form), + quantity: "$quantityCalc", + dosage: widget.dosageController.text, + times: widget.timesDailyController.text, + days: widget.noDaysController.text, + repeats: widget.noRepeatsController.text, + ); + perscriptionObjOutput.add(tempObj); + } + + String getPerscTitle(int index) { + return "${perscriptionObjOutput[index].name} - ${perscriptionObjOutput[index].form}"; + } + + String getPerscSubtitle(int index) { + if (perscriptionObjOutput[index].form.toLowerCase() == "syr") { + String unit = perscriptionObjOutput[index].unit.toLowerCase(); + if (perscriptionObjOutput[index].unit.toLowerCase().contains("ml")) { + unit = "ml"; + } + return "${perscriptionObjOutput[index].dosage} $unit, ${perscriptionObjOutput[index].times} time(s) daily, for ${perscriptionObjOutput[index].days} day(s)\nQuantity: ${perscriptionObjOutput[index].quantity}\nNo. of repeats: ${perscriptionObjOutput[index].repeats}"; + } else { + return "${perscriptionObjOutput[index].dosage} ${perscriptionObjOutput[index].fullForm}(s), ${perscriptionObjOutput[index].times} time(s) daily, for ${perscriptionObjOutput[index].days} day(s)\nQuantity: ${perscriptionObjOutput[index].quantity}\nNo. of repeats: ${perscriptionObjOutput[index].repeats}"; + } + } + + String getFullDoagesForm(String abr) { + var dosageFormList = { + "liq": "liquid", + "tab": "tablet", + "cap": "capsule", + "cps": "capsule", + "oin": "ointment", + "lit": "lotion", + "lot": "lotion", + "inj": "injection", + "syr": "syrup", + "dsp": "effervescent tablet", + "eft": "effervescent tablet", + "ear": "drops", + "drp": "drops", + "opd": "drops", + "udv": "vial", + "sus": "suspension", + "susp": "suspension", + "cal": "calasthetic", + "sol": "solution", + "sln": "solution", + "neb": "nebuliser", + "inh": "inhaler", + "spo": "inhaler", + "inf": "infusion", + "chg": "chewing Gum", + "vac": "vacutainer", + "vag": "vaginal gel", + "jel": "gel", + "eyo": "eye ointment", + "vat": "vaginal cream", + "poi": "injection", + "ped": "powder", + "pow": "powder", + "por": "powder", + "sac": "sachet", + "sup": "suppository", + "cre": "cream", + "ptd": "patch", + "ect": "tablet", + "nas": "spray", + }; + String form; + if (dosageFormList[abr.toLowerCase()] == null) { + form = abr; + } else { + form = dosageFormList[abr.toLowerCase()]!; + } + return form; + } + + int calcQuantity(String dosage, String times, String days, String form) { + var dosageFormList = [ + "tab", + "cap", + "cps", + "dsp", + "eft", + "udv", + "chg", + "sac", + "sup", + "ptd", + "ect", + ]; + if (dosageFormList.contains(form)) { + return int.parse(dosage) * int.parse(times) * int.parse(days); + } else { + return 1; + } + } + + Widget displayMedInput() { + return Column( + children: [ + //const SizedBox(height: 25.0), + + KeyboardListener( + focusNode: _focusNode, + autofocus: true, + onKeyEvent: (event) async { + if (event is KeyDownEvent && + event.logicalKey == LogicalKeyboardKey.enter) { + getMedsPopUp(widget.medicineController); + } + }, + child: MIHSearchField( + controller: widget.medicineController, + hintText: "Medicine", + required: true, + editable: true, + onTap: () { + getMedsPopUp(widget.medicineController); + }, + ), + ), + const SizedBox(height: 10.0), + // SizedBox( + // width: 300, + // child: MIHDropdownField( + // controller: widget.quantityController, + // hintText: "Quantity", + // dropdownOptions: numberOptions, + // required: true, + // editable: true, + // ), + // ), + // const SizedBox(height: 10.0), + MIHDropdownField( + controller: widget.dosageController, + hintText: "Dosage", + dropdownOptions: numberOptions, + required: true, + editable: true, + enableSearch: false, + ), + const SizedBox(height: 10.0), + MIHDropdownField( + controller: widget.timesDailyController, + hintText: "Times Daily", + dropdownOptions: numberOptions, + required: true, + editable: true, + enableSearch: false, + ), + const SizedBox(height: 10.0), + MIHDropdownField( + controller: widget.noDaysController, + hintText: "No. Days", + dropdownOptions: numberOptions, + required: true, + editable: true, + enableSearch: false, + ), + const SizedBox(height: 10.0), + MIHDropdownField( + controller: widget.noRepeatsController, + hintText: "No. Repeats", + dropdownOptions: numberOptions, + required: true, + editable: true, + enableSearch: false, + ), + const SizedBox(height: 15.0), + SizedBox( + width: 300, + height: 50, + child: MIHButton( + buttonText: "Add", + buttonColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + textColor: MzanziInnovationHub.of(context)!.theme.primaryColor(), + onTap: () { + if (isFieldsFilled()) { + // int quantity; + // int.parse(widget.dosageController.text) * + // int.parse(widget.timesDailyController.text) * + // int.parse(widget.noDaysController.text); + setState(() { + //widget.quantityController.text = "$quantity"; + updatePerscriptionList(); + widget.medicineController.clear(); + widget.quantityController.clear(); + widget.dosageController.clear(); + widget.timesDailyController.clear(); + widget.noDaysController.clear(); + widget.noRepeatsController.clear(); + }); + + //addPatientAPICall(); + } else { + showDialog( + context: context, + builder: (context) { + return const MIHErrorMessage(errorType: "Input Error"); + }, + ); + } + }, + ), + ) + ], + ); + } + + Widget displayPerscList() { + return Column( + children: [ + Container( + width: 550, + height: 325, + decoration: BoxDecoration( + color: MzanziInnovationHub.of(context)!.theme.primaryColor(), + borderRadius: BorderRadius.circular(25.0), + border: Border.all( + color: MzanziInnovationHub.of(context)!.theme.secondaryColor(), + width: 3.0), + ), + child: ListView.separated( + separatorBuilder: (BuildContext context, int index) { + return const Padding( + padding: EdgeInsets.symmetric(horizontal: 10.0), + child: Divider(), + ); + }, + itemCount: perscriptionObjOutput.length, + itemBuilder: (context, index) { + //final patient = widget.patients[index].id_no.contains(widget.searchString); + return ListTile( + title: Text( + getPerscTitle(index), + style: TextStyle( + color: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + ), + ), + subtitle: Text( + getPerscSubtitle(index), + style: TextStyle( + color: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + ), + ), + //onTap: () {}, + trailing: IconButton( + icon: Icon( + Icons.delete_forever_outlined, + color: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + ), + onPressed: () { + setState(() { + perscriptionObjOutput.removeAt(index); + }); + }, + ), + ); + }, + ), + ), + const SizedBox(height: 15.0), + SizedBox( + width: 300, + height: 50, + child: MIHButton( + onTap: () async { + if (perscriptionObjOutput.isNotEmpty) { + //print(jsonEncode(perscriptionObjOutput)); + await generatePerscription(); + Navigator.pop(context); + } else { + showDialog( + context: context, + builder: (context) { + return const MIHErrorMessage(errorType: "Input Error"); + }, + ); + } + }, + buttonText: "Generate", + buttonColor: MzanziInnovationHub.of(context)!.theme.successColor(), + textColor: MzanziInnovationHub.of(context)!.theme.primaryColor(), + ), + ) + ], + ); + } + + @override + void dispose() { + _focusNode.dispose(); + super.dispose(); + } + + @override + void initState() { + //futueMeds = getMedList(endpointMeds); + super.initState(); + } + + @override + Widget build(BuildContext context) { + var size = MediaQuery.of(context).size; + setState(() { + width = size.width; + height = size.height; + }); + return Wrap( + direction: Axis.horizontal, + alignment: WrapAlignment.center, + spacing: 10, + runSpacing: 10, + // mainAxisAlignment: MainAxisAlignment.center, + // mainAxisSize: MainAxisSize.max, + // crossAxisAlignment: CrossAxisAlignment.center, + children: [ + SizedBox(width: 500, child: displayMedInput()), + displayPerscList(), + ], + ); + } +} From bb0796f1d478f28720f0c8451771c3dc47aab065 Mon Sep 17 00:00:00 2001 From: Yasien Mac Mini Date: Mon, 17 Mar 2025 14:12:48 +0200 Subject: [PATCH 10/17] remove legacy files --- .../Claim_Statement_Window.dart | 511 ----------- .../build_claim_statement_files_list.dart | 228 ----- .../builder/build_file_view.dart | 266 ------ .../builder/build_files_list.dart | 398 --------- .../builder/build_icd10_code_list.dart | 76 -- .../builder/build_med_list.dart | 70 -- .../builder/build_notes_list.dart | 397 -------- .../builder/build_patient_access_list.dart | 468 ---------- .../builder/build_patient_list.dart | 694 -------------- .../builder/build_patient_queue_list.dart | 845 ------------------ .../patient_profile/icd10_search_window.dart | 58 -- .../patient_profile/patient_add.dart | 445 --------- .../patient_claims_statements.dart | 272 ------ .../patient_profile/patient_details.dart | 298 ------ .../patient_profile/patient_edit.dart | 719 --------------- .../patient_profile/patient_files.dart | 543 ----------- .../patient_profile/patient_manager.dart | 734 --------------- .../patient_profile/patient_notes.dart | 366 -------- .../patient_profile/patient_view.dart | 318 ------- .../patient_profile/prescip_input.dart | 574 ------------ 20 files changed, 8280 deletions(-) delete mode 100644 Frontend/lib/mih_packages/patient_profile/Claim_Statement_Window.dart delete mode 100644 Frontend/lib/mih_packages/patient_profile/builder/build_claim_statement_files_list.dart delete mode 100644 Frontend/lib/mih_packages/patient_profile/builder/build_file_view.dart delete mode 100644 Frontend/lib/mih_packages/patient_profile/builder/build_files_list.dart delete mode 100644 Frontend/lib/mih_packages/patient_profile/builder/build_icd10_code_list.dart delete mode 100644 Frontend/lib/mih_packages/patient_profile/builder/build_med_list.dart delete mode 100644 Frontend/lib/mih_packages/patient_profile/builder/build_notes_list.dart delete mode 100644 Frontend/lib/mih_packages/patient_profile/builder/build_patient_access_list.dart delete mode 100644 Frontend/lib/mih_packages/patient_profile/builder/build_patient_list.dart delete mode 100644 Frontend/lib/mih_packages/patient_profile/builder/build_patient_queue_list.dart delete mode 100644 Frontend/lib/mih_packages/patient_profile/icd10_search_window.dart delete mode 100644 Frontend/lib/mih_packages/patient_profile/patient_add.dart delete mode 100644 Frontend/lib/mih_packages/patient_profile/patient_claims_statements.dart delete mode 100644 Frontend/lib/mih_packages/patient_profile/patient_details.dart delete mode 100644 Frontend/lib/mih_packages/patient_profile/patient_edit.dart delete mode 100644 Frontend/lib/mih_packages/patient_profile/patient_files.dart delete mode 100644 Frontend/lib/mih_packages/patient_profile/patient_manager.dart delete mode 100644 Frontend/lib/mih_packages/patient_profile/patient_notes.dart delete mode 100644 Frontend/lib/mih_packages/patient_profile/patient_view.dart delete mode 100644 Frontend/lib/mih_packages/patient_profile/prescip_input.dart diff --git a/Frontend/lib/mih_packages/patient_profile/Claim_Statement_Window.dart b/Frontend/lib/mih_packages/patient_profile/Claim_Statement_Window.dart deleted file mode 100644 index 3c0b0970..00000000 --- a/Frontend/lib/mih_packages/patient_profile/Claim_Statement_Window.dart +++ /dev/null @@ -1,511 +0,0 @@ -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_components/mih_inputs_and_buttons/mih_button.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_search_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_window.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'; -import 'package:Mzansi_Innovation_Hub/mih_objects/business.dart'; -import 'package:Mzansi_Innovation_Hub/mih_objects/business_user.dart'; -import 'package:Mzansi_Innovation_Hub/mih_objects/icd10_code.dart.dart'; -import 'package:Mzansi_Innovation_Hub/mih_objects/patients.dart'; -import 'package:Mzansi_Innovation_Hub/mih_packages/patient_profile/icd10_search_window.dart'; -import 'package:flutter/material.dart'; -import 'package:intl/intl.dart'; - -class ClaimStatementWindow extends StatefulWidget { - final Patient selectedPatient; - final AppUser signedInUser; - final Business? business; - final BusinessUser? businessUser; - const ClaimStatementWindow({ - super.key, - required this.selectedPatient, - required this.signedInUser, - required this.business, - required this.businessUser, - }); - - @override - State createState() => _ClaimStatementWindowState(); -} - -class _ClaimStatementWindowState extends State { - final TextEditingController _docTypeController = TextEditingController(); - final TextEditingController _fullNameController = TextEditingController(); - final TextEditingController _idController = TextEditingController(); - final TextEditingController _medAidController = TextEditingController(); - final TextEditingController _medAidNoController = TextEditingController(); - final TextEditingController _medAidCodeController = TextEditingController(); - final TextEditingController _medAidNameController = TextEditingController(); - final TextEditingController _medAidSchemeController = TextEditingController(); - final TextEditingController _providerNameController = TextEditingController(); - final TextEditingController _practiceNoController = TextEditingController(); - final TextEditingController _vatNoController = TextEditingController(); - final TextEditingController _serviceDateController = TextEditingController(); - final TextEditingController _serviceDescController = TextEditingController(); - final TextEditingController _serviceDescOptionsController = - TextEditingController(); - final TextEditingController _prcedureNameController = TextEditingController(); - // final TextEditingController _procedureDateController = - // TextEditingController(); - final TextEditingController _proceedureAdditionalInfoController = - TextEditingController(); - final TextEditingController _icd10CodeController = TextEditingController(); - final TextEditingController _amountController = TextEditingController(); - final TextEditingController _preauthNoController = TextEditingController(); - final ValueNotifier serviceDesc = ValueNotifier(""); - final ValueNotifier medAid = ValueNotifier(""); - List icd10codeList = []; - - void icd10SearchWindow(List codeList) { - showDialog( - context: context, - barrierDismissible: false, - builder: (context) => ICD10SearchWindow( - icd10CodeController: _icd10CodeController, - icd10codeList: codeList, - ), - ); - } - - 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( - // "Patient 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), - // MIHTextField( - // controller: _fullNameController, - // hintText: "Full Name", - // editable: false, - // required: true, - // ), - // const SizedBox(height: 10), - // MIHTextField( - // controller: _idController, - // hintText: "ID No.", - // editable: false, - // required: true, - // ), - // const SizedBox(height: 10), - // MIHTextField( - // controller: _medAidController, - // hintText: "Has Medical Aid", - // editable: false, - // required: true, - // ), - // const SizedBox(height: 10), - // ValueListenableBuilder( - // valueListenable: serviceDesc, - // builder: (BuildContext context, String value, Widget? child) { - // return Visibility( - // visible: value == "Yes", - // child: Column( - // children: [ - // MIHTextField( - // controller: _medAidNoController, - // hintText: "Medical Aid No.", - // editable: false, - // required: true, - // ), - // const SizedBox(height: 10), - // MIHTextField( - // controller: _medAidCodeController, - // hintText: "Medical Aid Code", - // editable: false, - // required: true, - // ), - // const SizedBox(height: 10), - // MIHTextField( - // controller: _medAidNameController, - // hintText: "Medical Aid Name", - // editable: false, - // required: true, - // ), - // const SizedBox(height: 10), - // MIHTextField( - // controller: _medAidSchemeController, - // hintText: "Medical Aid Scheme", - // editable: false, - // required: true, - // ), - // const SizedBox(height: 10), - // ], - // ), - // ); - // }, - // ), - // Text( - // "Provider 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), - // MIHTextField( - // controller: _providerNameController, - // hintText: "Provider Name", - // editable: false, - // required: true, - // ), - // const SizedBox(height: 10), - // MIHTextField( - // controller: _practiceNoController, - // hintText: "Practice No.", - // editable: false, - // required: true, - // ), - // const SizedBox(height: 10), - // MIHTextField( - // controller: _vatNoController, - // hintText: "VAT No.", - // editable: false, - // required: true, - // ), - // 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), - MIHSearchField( - controller: _icd10CodeController, - hintText: "ICD-10 Code & Description", - required: true, - editable: true, - onTap: () { - //api - MIHIcd10CodeApis.getIcd10Codes(_icd10CodeController.text, context) - .then((result) { - icd10SearchWindow(result); - }); - }, - ), - 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), - SizedBox( - width: 500, - height: 50, - child: MIHButton( - onTap: () { - //generate document and uploud it - 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", - ), - context); - } else { - showDialog( - context: context, - builder: (context) { - return const MIHErrorMessage(errorType: "Input Error"); - }, - ); - } - }, - buttonText: "Generate", - buttonColor: - MzanziInnovationHub.of(context)!.theme.secondaryColor(), - textColor: MzanziInnovationHub.of(context)!.theme.primaryColor(), - ), - ) - ], - ); - } - - void serviceDescriptionSelected() { - if (_serviceDescController.text.isNotEmpty) { - serviceDesc.value = _serviceDescController.text; - } else { - serviceDesc.value = ""; - } - } - - void hasMedAid() { - if (_medAidController.text.isNotEmpty) { - medAid.value = _medAidController.text; - } else { - medAid.value = ""; - } - } - - 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; - } - } - } - - String getUserTitle() { - if (widget.businessUser!.title == "Doctor") { - return "Dr."; - } else { - return widget.businessUser!.title; - } - } - - String getTodayDate() { - DateTime today = DateTime.now(); - return DateFormat('yyyy-MM-dd').format(today); - } - - @override - void dispose() { - _docTypeController.dispose(); - _fullNameController.dispose(); - _idController.dispose(); - _medAidController.dispose(); - _medAidNoController.dispose(); - _medAidCodeController.dispose(); - _medAidNameController.dispose(); - _medAidSchemeController.dispose(); - _providerNameController.dispose(); - _practiceNoController.dispose(); - _vatNoController.dispose(); - _serviceDateController.dispose(); - _serviceDescController.dispose(); - _serviceDescOptionsController.dispose(); - _prcedureNameController.dispose(); - // _procedureDateController.dispose(); - _proceedureAdditionalInfoController.dispose(); - _icd10CodeController.dispose(); - _preauthNoController.dispose(); - super.dispose(); - } - - @override - void initState() { - _serviceDescController.addListener(serviceDescriptionSelected); - _medAidController.addListener(hasMedAid); - _fullNameController.text = - "${widget.selectedPatient.first_name} ${widget.selectedPatient.last_name}"; - _idController.text = widget.selectedPatient.id_no; - _medAidController.text = widget.selectedPatient.medical_aid; - _medAidNameController.text = widget.selectedPatient.medical_aid_name; - _medAidCodeController.text = widget.selectedPatient.medical_aid_code; - _medAidNoController.text = widget.selectedPatient.medical_aid_no; - _medAidSchemeController.text = widget.selectedPatient.medical_aid_scheme; - _serviceDateController.text = getTodayDate(); - _providerNameController.text = - "${getUserTitle()} ${widget.signedInUser.fname} ${widget.signedInUser.lname}"; - _practiceNoController.text = widget.business!.practice_no; - _vatNoController.text = widget.business!.vat_no; - super.initState(); - } - - @override - Widget build(BuildContext context) { - return MIHWindow( - fullscreen: false, - windowTitle: "Generate Claim/ Statement Document", - windowTools: const [], - onWindowTapClose: () { - // medicineController.clear(); - // quantityController.clear(); - // dosageController.clear(); - // timesDailyController.clear(); - // noDaysController.clear(); - // noRepeatsController.clear(); - Navigator.pop(context); - }, - windowBody: [ - getWindowBody(), - ], - ); - } -} diff --git a/Frontend/lib/mih_packages/patient_profile/builder/build_claim_statement_files_list.dart b/Frontend/lib/mih_packages/patient_profile/builder/build_claim_statement_files_list.dart deleted file mode 100644 index ee548458..00000000 --- a/Frontend/lib/mih_packages/patient_profile/builder/build_claim_statement_files_list.dart +++ /dev/null @@ -1,228 +0,0 @@ -import 'dart:convert'; - -import 'package:Mzansi_Innovation_Hub/mih_apis/mih_claim_statement_generation_api.dart'; -import 'package:Mzansi_Innovation_Hub/mih_objects/arguments.dart'; -import 'package:Mzansi_Innovation_Hub/mih_objects/claim_statement_file.dart'; -import 'package:flutter/material.dart'; -import 'package:supertokens_flutter/http.dart' as http; - -import '../../../main.dart'; -import '../../../mih_components/mih_layout/mih_window.dart'; -import '../../../mih_components/mih_pop_up_messages/mih_delete_message.dart'; -import '../../../mih_components/mih_pop_up_messages/mih_error_message.dart'; -import '../../../mih_components/mih_pop_up_messages/mih_success_message.dart'; -import '../../../mih_env/env.dart'; -import '../../../mih_objects/app_user.dart'; -import '../../../mih_objects/business.dart'; -import '../../../mih_objects/business_user.dart'; -import '../../../mih_objects/patients.dart'; -import 'build_file_view.dart'; - -class BuildClaimStatementFileList extends StatefulWidget { - final AppUser signedInUser; - final List files; - final Patient selectedPatient; - final Business? business; - final BusinessUser? businessUser; - final String type; - const BuildClaimStatementFileList({ - super.key, - required this.files, - required this.signedInUser, - required this.selectedPatient, - required this.business, - required this.businessUser, - required this.type, - }); - - @override - State createState() => - _BuildClaimStatementFileListState(); -} - -class _BuildClaimStatementFileListState - extends State { - int indexOn = 0; - final baseAPI = AppEnviroment.baseApiUrl; - final basefile = AppEnviroment.baseFileUrl; - String fileUrl = ""; - - Future getFileUrlApiCall(String filePath) async { - var url = "$baseAPI/minio/pull/file/${AppEnviroment.getEnv()}/$filePath"; - //print(url); - var response = await http.get(Uri.parse(url)); - // print("here1"); - //print(response.statusCode); - - if (response.statusCode == 200) { - //print("here2"); - String body = response.body; - //print(body); - //print("here3"); - var decodedData = jsonDecode(body); - //print("Dedoced: ${decodedData['minioURL']}"); - - return decodedData['minioURL']; - //AppUser u = AppUser.fromJson(decodedData); - // print(u.email); - //return "AlometThere"; - } else { - throw Exception("Error: GetUserData status code ${response.statusCode}"); - } - } - - void internetConnectionPopUp() { - showDialog( - context: context, - builder: (context) { - return const MIHErrorMessage(errorType: "Internet Connection"); - }, - ); - } - - void successPopUp(String message) { - showDialog( - context: context, - builder: (context) { - return MIHSuccessMessage( - successType: "Success", - successMessage: message, - ); - }, - ); - } - - void deleteFilePopUp(String filePath, int fileID) { - showDialog( - context: context, - barrierDismissible: false, - builder: (context) => MIHDeleteMessage( - deleteType: "File", - onTap: () async { - //API Call here - await MIHClaimStatementGenerationApi - .deleteClaimStatementFilesByFileID( - PatientViewArguments( - widget.signedInUser, - widget.selectedPatient, - widget.businessUser, - widget.business, - "business", - ), - filePath, - fileID, - context, - ); - }, - ), - ); - } - - void viewFilePopUp(String fileName, String filePath, int fileID, String url) { - bool hasAccessToDelete = false; - if (widget.type == "business") { - hasAccessToDelete = true; - } - showDialog( - context: context, - barrierDismissible: false, - builder: (context) => MIHWindow( - fullscreen: true, - windowTitle: fileName, - windowBody: [ - BuildFileView( - link: url, - path: filePath, - //pdfLink: '${AppEnviroment.baseFileUrl}/mih/$filePath', - ), - const SizedBox( - height: 10, - ) - ], - windowTools: [ - Visibility( - visible: hasAccessToDelete, - child: IconButton( - onPressed: () { - deleteFilePopUp(filePath, fileID); - }, - icon: Icon( - size: 35, - Icons.delete, - color: MzanziInnovationHub.of(context)!.theme.secondaryColor(), - ), - ), - ), - ], - onWindowTapClose: () { - Navigator.pop(context); - }, - ), - ); - } - - @override - void dispose() { - // TODO: implement dispose - super.dispose(); - } - - @override - Widget build(BuildContext context) { - if (widget.files.isNotEmpty) { - return ListView.separated( - shrinkWrap: true, - physics: const NeverScrollableScrollPhysics(), - separatorBuilder: (BuildContext context, int index) { - return Divider( - color: MzanziInnovationHub.of(context)!.theme.secondaryColor(), - ); - }, - itemCount: widget.files.length, - itemBuilder: (context, index) { - return ListTile( - title: Text( - widget.files[index].file_name, - style: TextStyle( - color: MzanziInnovationHub.of(context)!.theme.secondaryColor(), - ), - ), - subtitle: Text( - widget.files[index].insert_date, - style: TextStyle( - color: MzanziInnovationHub.of(context)!.theme.secondaryColor(), - ), - ), - // trailing: Icon( - // Icons.arrow_forward, - // color: MzanziInnovationHub.of(context)!.theme.secondaryColor(), - // ), - onTap: () async { - await getFileUrlApiCall(widget.files[index].file_path) - .then((urlHere) { - //print(url); - setState(() { - fileUrl = urlHere; - }); - }); - - viewFilePopUp( - widget.files[index].file_name, - widget.files[index].file_path, - widget.files[index].idclaim_statement_file, - fileUrl); - }, - ); - }, - ); - } else { - return const Center( - child: Text( - "No Documents Available", - style: TextStyle(fontSize: 25, color: Colors.grey), - textAlign: TextAlign.center, - ), - ); - } - } -} diff --git a/Frontend/lib/mih_packages/patient_profile/builder/build_file_view.dart b/Frontend/lib/mih_packages/patient_profile/builder/build_file_view.dart deleted file mode 100644 index 3500e9bf..00000000 --- a/Frontend/lib/mih_packages/patient_profile/builder/build_file_view.dart +++ /dev/null @@ -1,266 +0,0 @@ -import 'dart:async'; - -import 'package:Mzansi_Innovation_Hub/main.dart'; -import 'package:Mzansi_Innovation_Hub/mih_components/mih_pop_up_messages/mih_loading_circle.dart'; -import 'package:flutter/material.dart'; -import 'package:syncfusion_flutter_core/theme.dart'; -import 'package:syncfusion_flutter_pdfviewer/pdfviewer.dart'; -import "package:universal_html/html.dart" as html; -import 'package:http/http.dart' as http; -import 'package:fl_downloader/fl_downloader.dart'; - -import '../../../mih_objects/arguments.dart'; - -class BuildFileView extends StatefulWidget { - final String link; - final String path; - - const BuildFileView({ - super.key, - required this.link, - required this.path, - }); - - @override - State createState() => _BuildFileViewState(); -} - -class _BuildFileViewState extends State { - late PdfViewerController pdfViewerController = PdfViewerController(); - //late TextEditingController currentPageController = TextEditingController(); - double startZoomLevel = 1; - - int progress = 0; - late StreamSubscription progressStream; - - void mihLoadingPopUp() { - showDialog( - context: context, - builder: (context) { - return const Mihloadingcircle(); - }, - ); - } - - String getExtType(String path) { - //print(pdfLink.split(".")[1]); - return path.split(".").last; - } - - String getFileName(String path) { - //print(pdfLink.split(".")[1]); - return path.split("/").last; - } - - void printDocument() async { - print("Printing ${widget.path.split("/").last}"); - http.Response response = await http.get(Uri.parse(widget.link)); - var pdfData = response.bodyBytes; - Navigator.of(context).pushNamed( - '/file-veiwer/print-preview', - arguments: PrintPreviewArguments( - pdfData, - getFileName( - widget.path, - ), - ), - ); - } - - void nativeFileDownload(String fileLink) async { - var permission = await FlDownloader.requestPermission(); - if (permission == StoragePermissionStatus.granted) { - try { - mihLoadingPopUp(); - await FlDownloader.download(fileLink); - Navigator.of(context).pop(); - } on Exception catch (error) { - Navigator.of(context).pop(); - print(error); - } - } else { - print("denied"); - } - } - - @override - void dispose() { - pdfViewerController.dispose(); - progressStream.cancel(); - super.dispose(); - } - - @override - void initState() { - super.initState(); - FlDownloader.initialize(); - progressStream = FlDownloader.progressStream.listen((event) { - if (event.status == DownloadStatus.successful) { - setState(() { - progress = event.progress; - }); - //Navigator.of(context).pop(); - print("Progress $progress%: Success Downloading"); - FlDownloader.openFile(filePath: event.filePath); - } else if (event.status == DownloadStatus.failed) { - print("Progress $progress%: Error Downloading"); - } else if (event.status == DownloadStatus.running) { - print("Progress $progress%: Download Running"); - } - }); - } - - @override - Widget build(BuildContext context) { - // double width = MediaQuery.sizeOf(context).width; - //double height = MediaQuery.sizeOf(context).height; - debugPrint(widget.link); - if (getExtType(widget.path).toLowerCase() == "pdf") { - return Expanded( - child: Stack( - fit: StackFit.expand, - children: [ - SfPdfViewerTheme( - data: SfPdfViewerThemeData( - backgroundColor: - MzanziInnovationHub.of(context)!.theme.primaryColor(), - ), - child: SfPdfViewer.network( - widget.link, - controller: pdfViewerController, - interactionMode: PdfInteractionMode.pan, - ), - ), - Positioned( - bottom: 10, - right: 10, - width: 50, - height: 50, - child: IconButton.filled( - iconSize: 35, - padding: const EdgeInsets.all(0), - onPressed: () { - printDocument(); - }, - icon: Icon( - Icons.print, - color: MzanziInnovationHub.of(context)!.theme.primaryColor(), - ), - ), - ), - Positioned( - bottom: 10, - left: 10, - width: 50, - height: 50, - child: IconButton.filled( - iconSize: 35, - padding: const EdgeInsets.all(0), - onPressed: () async { - // debugPrint( - // "I'm here ${MzanziInnovationHub.of(context)!.theme.getPlatform()}"); - if (MzanziInnovationHub.of(context)!.theme.getPlatform() == - "Web") { - html.window.open( - widget.link, - // '${AppEnviroment.baseFileUrl}/mih/$filePath', - 'download'); - } else { - // print("Here"); - // var permission = await FlDownloader.requestPermission(); - // if (permission == StoragePermissionStatus.granted) { - // await FlDownloader.download(widget.link); - // } else { - // print("denied"); - // } - nativeFileDownload(widget.link); - } - }, - icon: Icon( - Icons.download, - color: MzanziInnovationHub.of(context)!.theme.primaryColor(), - ), - ), - ), - ], - ), - ); - } else { - return Expanded( - // height: height, - // padding: const EdgeInsets.all(10.0), - child: Stack( - fit: StackFit.expand, - children: [ - InteractiveViewer( - //constrained: true, - //clipBehavior: Clip.antiAlias, - maxScale: 5.0, - //minScale: 0., - child: Image.network(widget.link), - ), - Positioned( - bottom: 10, - right: 10, - width: 50, - height: 50, - child: IconButton.filled( - iconSize: 35, - padding: const EdgeInsets.all(0), - onPressed: () { - //expandImage(width, height); - Navigator.of(context).pushNamed( - '/file-veiwer', - arguments: FileViewArguments( - widget.link, - widget.path, - ), - ); - }, - icon: Icon( - Icons.fullscreen, - color: MzanziInnovationHub.of(context)!.theme.primaryColor(), - ), - ), - ), - Positioned( - bottom: 10, - left: 10, - width: 50, - height: 50, - child: IconButton.filled( - iconSize: 35, - padding: const EdgeInsets.all(0), - onPressed: () async { - // debugPrint("I'm here "); - // debugPrint( - // "I'm here ${MzanziInnovationHub.of(context)!.theme.getPlatform()}"); - if (MzanziInnovationHub.of(context)!.theme.getPlatform() == - "Web") { - html.window.open( - widget.link, - // '${AppEnviroment.baseFileUrl}/mih/$filePath', - 'download'); - } else { - //print("Here"); - // var permission = await FlDownloader.requestPermission(); - // if (permission == StoragePermissionStatus.granted) { - // await FlDownloader.download(widget.link); - // } else { - // print("denied"); - // } - nativeFileDownload(widget.link); - } - }, - icon: Icon( - Icons.download, - color: MzanziInnovationHub.of(context)!.theme.primaryColor(), - ), - ), - ), - ], - ), - ); - } - } -} diff --git a/Frontend/lib/mih_packages/patient_profile/builder/build_files_list.dart b/Frontend/lib/mih_packages/patient_profile/builder/build_files_list.dart deleted file mode 100644 index 42aebb42..00000000 --- a/Frontend/lib/mih_packages/patient_profile/builder/build_files_list.dart +++ /dev/null @@ -1,398 +0,0 @@ -import 'dart:convert'; - -import 'package:flutter/material.dart'; -import 'package:supertokens_flutter/http.dart' as http; - -import '../../../main.dart'; -import '../../../mih_components/mih_layout/mih_window.dart'; -import '../../../mih_components/mih_pop_up_messages/mih_delete_message.dart'; -import '../../../mih_components/mih_pop_up_messages/mih_error_message.dart'; -import '../../../mih_components/mih_pop_up_messages/mih_loading_circle.dart'; -import '../../../mih_components/mih_pop_up_messages/mih_success_message.dart'; -import '../../../mih_env/env.dart'; -import '../../../mih_objects/app_user.dart'; -import '../../../mih_objects/arguments.dart'; -import '../../../mih_objects/business.dart'; -import '../../../mih_objects/business_user.dart'; -import '../../../mih_objects/files.dart'; -import '../../../mih_objects/patients.dart'; -import 'build_file_view.dart'; - -class BuildFilesList extends StatefulWidget { - final AppUser signedInUser; - final List files; - final Patient selectedPatient; - final Business? business; - final BusinessUser? businessUser; - final String type; - const BuildFilesList({ - super.key, - required this.files, - required this.signedInUser, - required this.selectedPatient, - required this.business, - required this.businessUser, - required this.type, - }); - - @override - State createState() => _BuildFilesListState(); -} - -class _BuildFilesListState extends State { - int indexOn = 0; - final baseAPI = AppEnviroment.baseApiUrl; - final basefile = AppEnviroment.baseFileUrl; - String fileUrl = ""; - - Future getFileUrlApiCall(String filePath) async { - var url = "$baseAPI/minio/pull/file/${AppEnviroment.getEnv()}/$filePath"; - //print(url); - var response = await http.get(Uri.parse(url)); - // print("here1"); - //print(response.statusCode); - - if (response.statusCode == 200) { - //print("here2"); - String body = response.body; - //print(body); - //print("here3"); - var decodedData = jsonDecode(body); - //print("Dedoced: ${decodedData['minioURL']}"); - - return decodedData['minioURL']; - //AppUser u = AppUser.fromJson(decodedData); - // print(u.email); - //return "AlometThere"; - } else { - throw Exception("Error: GetUserData status code ${response.statusCode}"); - } - - //print(url); - // var response = await http.get(Uri.parse(url)); - // // print("here1"); - // //print(response.statusCode); - - // if (response.statusCode == 200) { - // //print("here2"); - // String body = response.body; - // //print(body); - // //print("here3"); - // var decodedData = jsonDecode(body); - // //print("Dedoced: ${decodedData['minioURL']}"); - - // return decodedData['minioURL']; - // //AppUser u = AppUser.fromJson(decodedData); - // // print(u.email); - // //return "AlometThere"; - // } else { - // throw Exception("Error: GetUserData status code ${response.statusCode}"); - // } - } - - Future deleteFileApiCall(String filePath, int fileID) async { - showDialog( - context: context, - builder: (context) { - return const Mihloadingcircle(); - }, - ); - // delete file from minio - var response = await http.delete( - Uri.parse("$baseAPI/minio/delete/file/"), - headers: { - "Content-Type": "application/json; charset=UTF-8" - }, - body: jsonEncode({"file_path": filePath}), - ); - //print("Here4"); - //print(response.statusCode); - if (response.statusCode == 200) { - //SQL delete - var response2 = await http.delete( - Uri.parse("$baseAPI/files/delete/"), - headers: { - "Content-Type": "application/json; charset=UTF-8" - }, - body: jsonEncode({"idpatient_files": fileID}), - ); - if (response2.statusCode == 200) { - Navigator.of(context).pop(); - Navigator.of(context).pop(); - Navigator.of(context).pop(); - Navigator.of(context).pop(); - //print(widget.business); - if (widget.business == null) { - Navigator.of(context).pushNamed('/patient-manager/patient', - arguments: PatientViewArguments( - widget.signedInUser, - widget.selectedPatient, - widget.businessUser, - widget.business, - "personal")); - } else { - Navigator.of(context).pushNamed('/patient-manager/patient', - arguments: PatientViewArguments( - widget.signedInUser, - widget.selectedPatient, - widget.businessUser, - widget.business, - "business")); - } - - // Navigator.of(context) - // .pushNamed('/patient-profile', arguments: widget.signedInUser); - // setState(() {}); - String message = - "The File has been deleted successfully. This means it will no longer be visible on your and cannot be used for future appointments."; - successPopUp(message); - } else { - internetConnectionPopUp(); - } - } else { - internetConnectionPopUp(); - } - } - - void internetConnectionPopUp() { - showDialog( - context: context, - builder: (context) { - return const MIHErrorMessage(errorType: "Internet Connection"); - }, - ); - } - - void successPopUp(String message) { - showDialog( - context: context, - builder: (context) { - return MIHSuccessMessage( - successType: "Success", - successMessage: message, - ); - }, - ); - } - - void deleteFilePopUp(String filePath, int fileID) { - showDialog( - context: context, - barrierDismissible: false, - builder: (context) => MIHDeleteMessage( - deleteType: "File", - onTap: () async { - await deleteFileApiCall(filePath, fileID); - }, - ), - ); - } - - void viewFilePopUp(String fileName, String filePath, int fileID, String url) { - bool hasAccessToDelete = false; - if (widget.type == "business") { - hasAccessToDelete = true; - } - showDialog( - context: context, - barrierDismissible: false, - builder: (context) => MIHWindow( - fullscreen: true, - windowTitle: fileName, - windowBody: [ - BuildFileView( - link: url, - path: filePath, - //pdfLink: '${AppEnviroment.baseFileUrl}/mih/$filePath', - ), - const SizedBox( - height: 10, - ) - ], - windowTools: [ - Visibility( - visible: hasAccessToDelete, - child: IconButton( - onPressed: () { - deleteFilePopUp(filePath, fileID); - }, - icon: Icon( - size: 35, - Icons.delete, - color: MzanziInnovationHub.of(context)!.theme.secondaryColor(), - ), - ), - ), - ], - onWindowTapClose: () { - Navigator.pop(context); - }, - ), - ); - // showDialog( - // context: context, - // barrierDismissible: false, - // builder: (context) => Dialog( - // child: Stack( - // children: [ - // Container( - // padding: const EdgeInsets.all(10.0), - // width: 800.0, - // //height: 475.0, - // decoration: BoxDecoration( - // color: MzanziInnovationHub.of(context)!.theme.primaryColor(), - // borderRadius: BorderRadius.circular(25.0), - // border: Border.all( - // color: - // MzanziInnovationHub.of(context)!.theme.secondaryColor(), - // width: 5.0), - // ), - // child: Column( - // mainAxisSize: MainAxisSize.min, - // children: [ - // const SizedBox( - // height: 25, - // ), - // Text( - // fileName, - // textAlign: TextAlign.center, - // style: TextStyle( - // color: MzanziInnovationHub.of(context)! - // .theme - // .secondaryColor(), - // fontSize: 35.0, - // fontWeight: FontWeight.bold, - // ), - // ), - // const SizedBox(height: 25.0), - // Expanded( - // child: BuildFileView( - // link: url, - // path: filePath, - // //pdfLink: '${AppEnviroment.baseFileUrl}/mih/$filePath', - // )), - // const SizedBox(height: 30.0), - // SizedBox( - // width: 300, - // height: 50, - // child: MIHButton( - // onTap: () { - // html.window.open( - // url, - // // '${AppEnviroment.baseFileUrl}/mih/$filePath', - // 'download'); - // }, - // buttonText: "Dowload", - // buttonColor: MzanziInnovationHub.of(context)! - // .theme - // .secondaryColor(), - // textColor: - // MzanziInnovationHub.of(context)!.theme.primaryColor(), - // ), - // ) - // ], - // ), - // ), - // Positioned( - // top: 5, - // right: 5, - // width: 50, - // height: 50, - // child: IconButton( - // onPressed: () { - // Navigator.pop(context); - // }, - // icon: Icon( - // Icons.close, - // color: MzanziInnovationHub.of(context)!.theme.errorColor(), - // size: 35, - // ), - // ), - // ), - // Positioned( - // top: 5, - // left: 5, - // width: 50, - // height: 50, - // child: IconButton( - // onPressed: () { - // deleteFilePopUp(filePath, fileID); - // }, - // icon: Icon( - // Icons.delete, - // color: - // MzanziInnovationHub.of(context)!.theme.secondaryColor(), - // ), - // ), - // ), - // ], - // ), - // ), - // ); - } - - @override - void dispose() { - // TODO: implement dispose - super.dispose(); - } - - @override - Widget build(BuildContext context) { - if (widget.files.isNotEmpty) { - return ListView.separated( - shrinkWrap: true, - physics: const NeverScrollableScrollPhysics(), - separatorBuilder: (BuildContext context, int index) { - return Divider( - color: MzanziInnovationHub.of(context)!.theme.secondaryColor(), - ); - }, - itemCount: widget.files.length, - itemBuilder: (context, index) { - return ListTile( - title: Text( - widget.files[index].file_name, - style: TextStyle( - color: MzanziInnovationHub.of(context)!.theme.secondaryColor(), - ), - ), - subtitle: Text( - widget.files[index].insert_date, - style: TextStyle( - color: MzanziInnovationHub.of(context)!.theme.secondaryColor(), - ), - ), - // trailing: Icon( - // Icons.arrow_forward, - // color: MzanziInnovationHub.of(context)!.theme.secondaryColor(), - // ), - onTap: () async { - await getFileUrlApiCall(widget.files[index].file_path) - .then((urlHere) { - //print(url); - setState(() { - fileUrl = urlHere; - }); - }); - - viewFilePopUp( - widget.files[index].file_name, - widget.files[index].file_path, - widget.files[index].idpatient_files, - fileUrl); - }, - ); - }, - ); - } else { - return const Center( - child: Text( - "No Documents Available", - style: TextStyle(fontSize: 25, color: Colors.grey), - textAlign: TextAlign.center, - ), - ); - } - } -} diff --git a/Frontend/lib/mih_packages/patient_profile/builder/build_icd10_code_list.dart b/Frontend/lib/mih_packages/patient_profile/builder/build_icd10_code_list.dart deleted file mode 100644 index 7bce328c..00000000 --- a/Frontend/lib/mih_packages/patient_profile/builder/build_icd10_code_list.dart +++ /dev/null @@ -1,76 +0,0 @@ -import 'package:Mzansi_Innovation_Hub/mih_objects/icd10_code.dart.dart'; -import 'package:flutter/material.dart'; - -import '../../../main.dart'; -import '../../../mih_env/env.dart'; - -class BuildICD10CodeList extends StatefulWidget { - final TextEditingController icd10CodeController; - final List icd10codeList; - - const BuildICD10CodeList({ - super.key, - required this.icd10CodeController, - required this.icd10codeList, - }); - - @override - State createState() => _BuildPatientsListState(); -} - -class _BuildPatientsListState extends State { - String baseAPI = AppEnviroment.baseApiUrl; - int counter = 0; - - Widget displayCode(int index) { - String title = "ICD-10 Code: ${widget.icd10codeList[index].icd10}"; - String description = - "Description: ${widget.icd10codeList[index].description}"; - return ListTile( - title: Text( - title, - style: TextStyle( - color: MzanziInnovationHub.of(context)!.theme.secondaryColor(), - ), - ), - subtitle: RichText( - text: TextSpan( - text: description, - style: DefaultTextStyle.of(context).style, - ), - ), - onTap: () { - //select code - setState(() { - widget.icd10CodeController.text = - "${widget.icd10codeList[index].icd10} - ${widget.icd10codeList[index].description}"; - }); - Navigator.of(context).pop(); - }, - ); - } - - @override - void dispose() { - super.dispose(); - } - - @override - Widget build(BuildContext context) { - return ListView.separated( - physics: const NeverScrollableScrollPhysics(), - shrinkWrap: true, - separatorBuilder: (BuildContext context, index) { - return Divider( - color: MzanziInnovationHub.of(context)!.theme.secondaryColor(), - ); - }, - itemCount: widget.icd10codeList.length, - itemBuilder: (context, index) { - //final patient = widget.patients[index].id_no.contains(widget.searchString); - //print(index); - return displayCode(index); - }, - ); - } -} diff --git a/Frontend/lib/mih_packages/patient_profile/builder/build_med_list.dart b/Frontend/lib/mih_packages/patient_profile/builder/build_med_list.dart deleted file mode 100644 index 70ab9d0e..00000000 --- a/Frontend/lib/mih_packages/patient_profile/builder/build_med_list.dart +++ /dev/null @@ -1,70 +0,0 @@ -import 'package:flutter/material.dart'; - -import '../../../main.dart'; -import '../../../mih_objects/medicine.dart'; - -class BuildMedicinesList extends StatefulWidget { - final TextEditingController contoller; - final List medicines; - //final searchString; - - const BuildMedicinesList({ - super.key, - required this.contoller, - required this.medicines, - //required this.searchString, - }); - - @override - State createState() => _BuildMedicinesListState(); -} - -class _BuildMedicinesListState extends State { - int indexOn = 0; - - @override - void dispose() { - // TODO: implement dispose - super.dispose(); - } - - @override - Widget build(BuildContext context) { - return ListView.separated( - separatorBuilder: (BuildContext context, int index) { - return Divider( - color: MzanziInnovationHub.of(context)!.theme.secondaryColor(), - ); - }, - itemCount: widget.medicines.length, - itemBuilder: (context, index) { - //final patient = widget.patients[index].id_no.contains(widget.searchString); - return ListTile( - title: Text( - widget.medicines[index].name, - style: TextStyle( - color: MzanziInnovationHub.of(context)!.theme.secondaryColor(), - ), - ), - subtitle: Text( - "${widget.medicines[index].unit} - ${widget.medicines[index].form}", - style: TextStyle( - color: MzanziInnovationHub.of(context)!.theme.secondaryColor(), - ), - ), - onTap: () { - setState(() { - widget.contoller.text = - "${widget.medicines[index].name}%t${widget.medicines[index].unit}%t${widget.medicines[index].form}"; - Navigator.of(context).pop(); - }); - }, - trailing: Icon( - Icons.arrow_forward, - color: MzanziInnovationHub.of(context)!.theme.secondaryColor(), - ), - ); - }, - ); - } -} diff --git a/Frontend/lib/mih_packages/patient_profile/builder/build_notes_list.dart b/Frontend/lib/mih_packages/patient_profile/builder/build_notes_list.dart deleted file mode 100644 index c48f15bb..00000000 --- a/Frontend/lib/mih_packages/patient_profile/builder/build_notes_list.dart +++ /dev/null @@ -1,397 +0,0 @@ -import 'dart:convert'; - -import 'package:flutter/material.dart'; -import 'package:supertokens_flutter/http.dart' as http; - -import '../../../main.dart'; -import '../../../mih_components/mih_inputs_and_buttons/mih_multiline_text_input.dart'; -import '../../../mih_components/mih_inputs_and_buttons/mih_text_input.dart'; -import '../../../mih_components/mih_layout/mih_window.dart'; -import '../../../mih_components/mih_pop_up_messages/mih_delete_message.dart'; -import '../../../mih_components/mih_pop_up_messages/mih_error_message.dart'; -import '../../../mih_components/mih_pop_up_messages/mih_success_message.dart'; -import '../../../mih_env/env.dart'; -import '../../../mih_objects/app_user.dart'; -import '../../../mih_objects/arguments.dart'; -import '../../../mih_objects/business.dart'; -import '../../../mih_objects/business_user.dart'; -import '../../../mih_objects/notes.dart'; -import '../../../mih_objects/patients.dart'; - -class BuildNotesList extends StatefulWidget { - final AppUser signedInUser; - final List notes; - final Patient selectedPatient; - final Business? business; - final BusinessUser? businessUser; - final String type; - const BuildNotesList({ - super.key, - required this.notes, - required this.signedInUser, - required this.selectedPatient, - required this.business, - required this.businessUser, - required this.type, - }); - - @override - State createState() => _BuildNotesListState(); -} - -class _BuildNotesListState extends State { - final noteTitleController = TextEditingController(); - final noteTextController = TextEditingController(); - final businessNameController = TextEditingController(); - final userNameController = TextEditingController(); - final dateController = TextEditingController(); - int indexOn = 0; - final baseAPI = AppEnviroment.baseApiUrl; - - Future deleteNoteApiCall(int NoteId) async { - var response = await http.delete( - Uri.parse("$baseAPI/notes/delete/"), - headers: { - "Content-Type": "application/json; charset=UTF-8" - }, - body: jsonEncode({"idpatient_notes": NoteId}), - ); - //print("Here4"); - //print(response.statusCode); - if (response.statusCode == 200) { - Navigator.of(context).pop(); - Navigator.of(context).pop(); - if (widget.business == null) { - Navigator.of(context).pushNamed('/patient-manager/patient', - arguments: PatientViewArguments( - widget.signedInUser, - widget.selectedPatient, - widget.businessUser, - widget.business, - "personal")); - } else { - Navigator.of(context).pushNamed('/patient-manager/patient', - arguments: PatientViewArguments( - widget.signedInUser, - widget.selectedPatient, - widget.businessUser, - widget.business, - "business")); - } - setState(() {}); - String message = - "The note has been deleted successfully. This means it will no longer be visible on your and cannot be used for future appointments."; - successPopUp(message); - } else { - internetConnectionPopUp(); - } - } - - void internetConnectionPopUp() { - showDialog( - context: context, - builder: (context) { - return const MIHErrorMessage(errorType: "Internet Connection"); - }, - ); - } - - void successPopUp(String message) { - showDialog( - context: context, - builder: (context) { - return MIHSuccessMessage( - successType: "Success", - successMessage: message, - ); - }, - ); - } - - void deletePatientPopUp(int NoteId) { - showDialog( - context: context, - barrierDismissible: false, - builder: (context) => MIHDeleteMessage( - deleteType: "Note", - onTap: () { - deleteNoteApiCall(NoteId); - }, - ), - ); - } - - void viewNotePopUp(Note selectednote) { - setState(() { - noteTitleController.text = selectednote.note_name; - noteTextController.text = selectednote.note_text; - businessNameController.text = selectednote.doc_office; - userNameController.text = selectednote.doctor; - dateController.text = selectednote.insert_date; - }); - bool hasAccessToDelete = false; - if (widget.type == "business" && - selectednote.doc_office == widget.business!.Name) { - hasAccessToDelete = true; - } - showDialog( - context: context, - barrierDismissible: false, - builder: (context) => MIHWindow( - fullscreen: true, - windowTitle: selectednote.note_name, - windowTools: [ - Visibility( - visible: hasAccessToDelete, - child: IconButton( - onPressed: () { - deletePatientPopUp(selectednote.idpatient_notes); - }, - icon: Icon( - Icons.delete, - color: MzanziInnovationHub.of(context)!.theme.secondaryColor(), - ), - ), - ), - ], - onWindowTapClose: () { - Navigator.pop(context); - }, - windowBody: [ - MIHTextField( - controller: businessNameController, - hintText: "Office", - editable: false, - required: false, - ), - const SizedBox(height: 10.0), - MIHTextField( - controller: userNameController, - hintText: "Created By", - editable: false, - required: false, - ), - const SizedBox(height: 10.0), - MIHTextField( - controller: dateController, - hintText: "Created Date", - editable: false, - required: false, - ), - const SizedBox(height: 10.0), - MIHTextField( - controller: noteTitleController, - hintText: "Note Title", - editable: false, - required: false, - ), - const SizedBox(height: 10.0), - Expanded( - child: MIHMLTextField( - controller: noteTextController, - hintText: "Note Details", - editable: false, - required: false, - ), - ), - ], - ), - ); - // showDialog( - // context: context, - // barrierDismissible: false, - // builder: (context) => Dialog( - // child: Stack( - // children: [ - // Container( - // padding: const EdgeInsets.all(15.0), - // width: 700.0, - // //height: 475.0, - // decoration: BoxDecoration( - // color: MzanziInnovationHub.of(context)!.theme.primaryColor(), - // borderRadius: BorderRadius.circular(25.0), - // border: Border.all( - // color: - // MzanziInnovationHub.of(context)!.theme.secondaryColor(), - // width: 5.0), - // ), - // child: Column( - // mainAxisSize: MainAxisSize.max, - // children: [ - // const SizedBox( - // height: 25, - // ), - // Text( - // selectednote.note_name, - // textAlign: TextAlign.center, - // style: TextStyle( - // color: MzanziInnovationHub.of(context)! - // .theme - // .secondaryColor(), - // fontSize: 35.0, - // fontWeight: FontWeight.bold, - // ), - // ), - // const SizedBox(height: 25.0), - // SizedBox( - // width: 700, - // child: MIHTextField( - // controller: businessNameController, - // hintText: "Office", - // editable: false, - // required: false, - // ), - // ), - // const SizedBox(height: 10.0), - // SizedBox( - // width: 700, - // child: MIHTextField( - // controller: userNameController, - // hintText: "Created By", - // editable: false, - // required: false, - // ), - // ), - // const SizedBox(height: 10.0), - // SizedBox( - // width: 700, - // child: MIHTextField( - // controller: dateController, - // hintText: "Created Date", - // editable: false, - // required: false, - // ), - // ), - // const SizedBox(height: 10.0), - // SizedBox( - // width: 700, - // child: MIHTextField( - // controller: noteTitleController, - // hintText: "Note Title", - // editable: false, - // required: false, - // ), - // ), - // const SizedBox(height: 10.0), - // Expanded( - // child: MIHMLTextField( - // controller: noteTextController, - // hintText: "Note Details", - // editable: false, - // required: false, - // ), - // ), - // //const SizedBox(height: 25.0), - // // SizedBox( - // // width: 300, - // // height: 100, - // // child: MIHButton( - // // onTap: () { - // // Navigator.pop(context); - // // }, - // // buttonText: "Close", - // // buttonColor: Colors.blueAccent, - // // textColor: Colors.white, - // // ), - // // ) - // ], - // ), - // ), - // Positioned( - // top: 5, - // right: 5, - // width: 50, - // height: 50, - // child: IconButton( - // onPressed: () { - // Navigator.pop(context); - // }, - // icon: Icon( - // Icons.close, - // color: MzanziInnovationHub.of(context)!.theme.errorColor(), - // size: 35, - // ), - // ), - // ), - // Positioned( - // top: 5, - // left: 5, - // width: 50, - // height: 50, - // child: IconButton( - // onPressed: () { - // deletePatientPopUp(selectednote.idpatient_notes); - // }, - // icon: Icon( - // Icons.delete, - // color: - // MzanziInnovationHub.of(context)!.theme.secondaryColor(), - // ), - // ), - // ), - // ], - // ), - // ), - // ); - } - - @override - void dispose() { - noteTextController.dispose(); - businessNameController.dispose(); - userNameController.dispose(); - dateController.dispose(); - super.dispose(); - } - - @override - Widget build(BuildContext context) { - if (widget.notes.isNotEmpty) { - return ListView.separated( - shrinkWrap: true, - physics: const NeverScrollableScrollPhysics(), - separatorBuilder: (BuildContext context, int index) { - return Divider( - color: MzanziInnovationHub.of(context)!.theme.secondaryColor(), - ); - }, - itemCount: widget.notes.length, - itemBuilder: (context, index) { - String notePreview = widget.notes[index].note_text; - if (notePreview.length > 30) { - notePreview = "${notePreview.substring(0, 30)} ..."; - } - return ListTile( - title: Text( - "${widget.notes[index].note_name}\n${widget.notes[index].doc_office} - ${widget.notes[index].doctor}", - style: TextStyle( - color: MzanziInnovationHub.of(context)!.theme.secondaryColor(), - ), - ), - subtitle: Text( - "${widget.notes[index].insert_date}:\n$notePreview", - style: TextStyle( - color: MzanziInnovationHub.of(context)!.theme.secondaryColor(), - ), - ), //Text(widget.notes[index].note_text), - trailing: Icon( - Icons.arrow_forward, - color: MzanziInnovationHub.of(context)!.theme.secondaryColor(), - ), - onTap: () { - viewNotePopUp(widget.notes[index]); - }, - ); - }, - ); - } else { - return const Center( - child: Text( - "No Notes Available", - style: TextStyle(fontSize: 25, color: Colors.grey), - textAlign: TextAlign.center, - ), - ); - } - } -} diff --git a/Frontend/lib/mih_packages/patient_profile/builder/build_patient_access_list.dart b/Frontend/lib/mih_packages/patient_profile/builder/build_patient_access_list.dart deleted file mode 100644 index 250839fd..00000000 --- a/Frontend/lib/mih_packages/patient_profile/builder/build_patient_access_list.dart +++ /dev/null @@ -1,468 +0,0 @@ -import 'dart:convert'; - -import 'package:flutter/material.dart'; -import 'package:supertokens_flutter/http.dart' as http; - -import '../../../main.dart'; -import '../../../mih_apis/mih_api_calls.dart'; -import '../../../mih_components/mih_inputs_and_buttons/mih_button.dart'; -import '../../../mih_components/mih_inputs_and_buttons/mih_date_input.dart'; -import '../../../mih_components/mih_inputs_and_buttons/mih_text_input.dart'; -import '../../../mih_components/mih_inputs_and_buttons/mih_time_input.dart'; -import '../../../mih_components/mih_layout/mih_window.dart'; -import '../../../mih_components/mih_pop_up_messages/mih_error_message.dart'; -import '../../../mih_components/mih_pop_up_messages/mih_success_message.dart'; -import '../../../mih_components/mih_pop_up_messages/mih_warning_message.dart'; -import '../../../mih_env/env.dart'; -import '../../../mih_objects/app_user.dart'; -import '../../../mih_objects/arguments.dart'; -import '../../../mih_objects/business.dart'; -import '../../../mih_objects/patient_access.dart'; -import '../../../mih_objects/patients.dart'; - -class BuildPatientAccessList extends StatefulWidget { - final List patientAccesses; - final AppUser signedInUser; - final Business? business; - final BusinessArguments arguments; - - const BuildPatientAccessList({ - super.key, - required this.patientAccesses, - required this.signedInUser, - required this.business, - required this.arguments, - }); - - @override - State createState() => _BuildPatientsListState(); -} - -class _BuildPatientsListState extends State { - TextEditingController dateController = TextEditingController(); - TextEditingController timeController = TextEditingController(); - TextEditingController idController = TextEditingController(); - TextEditingController fnameController = TextEditingController(); - TextEditingController lnameController = TextEditingController(); - - final baseAPI = AppEnviroment.baseApiUrl; - - Future addPatientAppointmentAPICall(int index) async { - var response = await http.post( - Uri.parse("$baseAPI/queue/insert/"), - headers: { - "Content-Type": "application/json; charset=UTF-8" - }, - body: jsonEncode({ - "business_id": widget.business!.business_id, - "app_id": widget.patientAccesses[index].app_id, - "date": dateController.text, - "time": timeController.text, - "access": "pending", - }), - ); - if (response.statusCode == 201) { - // Navigator.pushNamed(context, '/patient-manager/patient', - // arguments: widget.signedInUser); - String message = - "The appointment has been successfully booked!\n\nAn approval request as been sent to the patient.Once the access request has been approved, you will be able to access the patientAccesses profile. ou can check the status of your request in patient queue under the appointment."; - // "${fnameController.text} ${lnameController.text} patient profiole has been successfully added!\n"; - Navigator.pop(context); - Navigator.pop(context); - setState(() { - dateController.text = ""; - timeController.text = ""; - }); - Navigator.of(context).pushNamed( - '/patient-manager', - arguments: BusinessArguments( - widget.arguments.signedInUser, - widget.arguments.businessUser, - widget.arguments.business, - ), - ); - successPopUp(message); - addAccessReviewNotificationAPICall(index); - } else { - internetConnectionPopUp(); - } - } - - Future addAccessReviewNotificationAPICall(int index) async { - var response = await http.post( - Uri.parse("$baseAPI/notifications/insert/"), - headers: { - "Content-Type": "application/json; charset=UTF-8" - }, - body: jsonEncode({ - "app_id": widget.patientAccesses[index].app_id, - "notification_type": "New Appointment Booked", - "notification_message": - "A new Appointment has been booked by ${widget.arguments.business!.Name} for the ${dateController.text} ${timeController.text}. Please approve the Access Review request.", - "action_path": "/mih-access", - }), - ); - if (response.statusCode == 201) { - // Navigator.pushNamed(context, '/patient-manager/patient', - // arguments: widget.signedInUser); - } else { - internetConnectionPopUp(); - } - } - - void internetConnectionPopUp() { - showDialog( - context: context, - builder: (context) { - return const MIHErrorMessage(errorType: "Internet Connection"); - }, - ); - } - - void successPopUp(String message) { - showDialog( - context: context, - builder: (context) { - return MIHSuccessMessage( - successType: "Success", - successMessage: message, - ); - }, - ); - } - - void submitApointment(int index) { - MIHApiCalls.addAppointmentAPICall( - widget.arguments.business!.business_id, - widget.patientAccesses[index].app_id, - false, - dateController.text, - timeController.text, - widget.arguments, - context, - ); - //addPatientAppointmentAPICall(index); - } - - bool isAppointmentFieldsFilled() { - if (dateController.text.isEmpty || timeController.text.isEmpty) { - return false; - } else { - return true; - } - } - - void appointmentPopUp(int index) { - var firstLetterFName = widget.patientAccesses[index].fname; - var firstLetterLName = widget.patientAccesses[index].lname; - - setState(() { - idController.text = widget.patientAccesses[index].id_no; - fnameController.text = firstLetterFName; - lnameController.text = firstLetterLName; - }); - showDialog( - context: context, - barrierDismissible: false, - builder: (context) => MIHWindow( - fullscreen: false, - windowTitle: "Patient Appointment", - windowTools: const [], - onWindowTapClose: () { - Navigator.pop(context); - }, - windowBody: [ - 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), - SizedBox( - width: 300, - height: 50, - child: MIHButton( - buttonText: "Book", - buttonColor: - MzanziInnovationHub.of(context)!.theme.secondaryColor(), - textColor: MzanziInnovationHub.of(context)!.theme.primaryColor(), - onTap: () { - //print("here1"); - bool filled = isAppointmentFieldsFilled(); - //print("fields filled: $filled"); - if (filled) { - //print("here2"); - submitApointment(index); - //print("here3"); - } else { - showDialog( - context: context, - builder: (context) { - return const MIHErrorMessage(errorType: "Input Error"); - }, - ); - } - }, - ), - ) - ], - ), - ); - } - - void noAccessWarning(int index) { - if (widget.patientAccesses[index].status == "pending") { - showDialog( - context: context, - builder: (context) { - return const MIHWarningMessage(warningType: "No Access"); - }, - ); - } else { - showDialog( - context: context, - builder: (context) { - return const MIHWarningMessage(warningType: "Access Declined"); - }, - ); - } - } - - bool hasAccessToProfile(int index) { - var hasAccess = false; - - if (widget.patientAccesses[index].status == "approved") { - hasAccess = true; - } else { - hasAccess = false; - } - return hasAccess; - } - - void patientProfileChoicePopUp(int index, Patient? patientProfile) async { - var firstLetterFName = widget.patientAccesses[index].fname; - var firstLetterLName = widget.patientAccesses[index].lname; - - setState(() { - idController.text = widget.patientAccesses[index].id_no; - fnameController.text = firstLetterFName; - lnameController.text = firstLetterLName; - }); - showDialog( - context: context, - barrierDismissible: false, - builder: (context) => MIHWindow( - fullscreen: false, - windowTitle: "Patient Profile", - windowTools: const [], - onWindowTapClose: () { - Navigator.pop(context); - }, - windowBody: [ - 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: 30.0), - Wrap(runSpacing: 10, spacing: 10, children: [ - SizedBox( - width: 300, - height: 50, - child: MIHButton( - buttonText: "Book Appointment", - buttonColor: - MzanziInnovationHub.of(context)!.theme.secondaryColor(), - textColor: - MzanziInnovationHub.of(context)!.theme.primaryColor(), - onTap: () { - print("Book an Appointment!!!"); - appointmentPopUp(index); - - // //print("here1"); - // bool filled = isAppointmentFieldsFilled(); - // //print("fields filled: $filled"); - // if (filled) { - // //print("here2"); - // submitApointment(index); - // //print("here3"); - // } else { - // showDialog( - // context: context, - // builder: (context) { - // return const MIHErrorMessage(errorType: "Input Error"); - // }, - // ); - // } - }, - ), - ), - SizedBox( - width: 300, - height: 50, - child: MIHButton( - buttonText: "View Patient Profile", - buttonColor: - MzanziInnovationHub.of(context)!.theme.successColor(), - textColor: - MzanziInnovationHub.of(context)!.theme.primaryColor(), - onTap: () { - Navigator.of(context).pop(); - Navigator.of(context).pushNamed('/patient-manager/patient', - arguments: PatientViewArguments( - widget.signedInUser, - patientProfile, - widget.arguments.businessUser, - widget.business, - "business", - )); - }, - ), - ), - ]) - ], - ), - ); - } - - Widget displayAccessTile(int index) { - var firstName = ""; - var lastName = ""; - String access = widget.patientAccesses[index].status.toUpperCase(); - TextSpan accessWithColour; - var hasAccess = false; - hasAccess = hasAccessToProfile(index); - //print(hasAccess); - if (access == "APPROVED") { - firstName = widget.patientAccesses[index].fname; - lastName = widget.patientAccesses[index].lname; - accessWithColour = TextSpan( - text: "$access\n", - style: TextStyle( - color: MzanziInnovationHub.of(context)!.theme.successColor())); - } else if (access == "PENDING") { - firstName = "${widget.patientAccesses[index].fname[0]}********"; - lastName = "${widget.patientAccesses[index].lname[0]}********"; - accessWithColour = TextSpan( - text: "$access\n", - style: TextStyle( - color: - MzanziInnovationHub.of(context)!.theme.messageTextColor())); - } else { - firstName = "${widget.patientAccesses[index].fname[0]}********"; - lastName = "${widget.patientAccesses[index].lname[0]}********"; - accessWithColour = TextSpan( - text: "$access\n", - style: TextStyle( - color: MzanziInnovationHub.of(context)!.theme.errorColor())); - } - - return ListTile( - title: Text( - "$firstName $lastName", - style: TextStyle( - color: MzanziInnovationHub.of(context)!.theme.secondaryColor(), - ), - ), - subtitle: RichText( - text: TextSpan( - text: "ID No.: ${widget.patientAccesses[index].id_no}\n", - style: DefaultTextStyle.of(context).style, - children: [ - const TextSpan(text: "Access: "), - accessWithColour, - ]), - ), - onTap: () async { - Patient? p; - if (hasAccess) { - await MIHApiCalls.fetchPatientByAppId( - widget.patientAccesses[index].app_id) - .then((result) { - setState(() { - p = result; - }); - }); - patientProfileChoicePopUp(index, p); - } else { - noAccessWarning(index); - } - }, - trailing: Icon( - Icons.arrow_forward, - color: MzanziInnovationHub.of(context)!.theme.secondaryColor(), - ), - ); - } - - @override - void dispose() { - dateController.dispose(); - timeController.dispose(); - idController.dispose(); - fnameController.dispose(); - lnameController.dispose(); - super.dispose(); - } - - @override - Widget build(BuildContext context) { - return ListView.separated( - shrinkWrap: true, - physics: const NeverScrollableScrollPhysics(), - separatorBuilder: (BuildContext context, index) { - return Divider( - color: MzanziInnovationHub.of(context)!.theme.secondaryColor(), - ); - }, - itemCount: widget.patientAccesses.length, - itemBuilder: (context, index) { - //final patient = widget.patientAccesses[index].id_no.contains(widget.searchString); - //print(index); - return displayAccessTile(index); - }, - ); - } -} diff --git a/Frontend/lib/mih_packages/patient_profile/builder/build_patient_list.dart b/Frontend/lib/mih_packages/patient_profile/builder/build_patient_list.dart deleted file mode 100644 index 03d3ccb6..00000000 --- a/Frontend/lib/mih_packages/patient_profile/builder/build_patient_list.dart +++ /dev/null @@ -1,694 +0,0 @@ -import 'dart:convert'; - -import 'package:flutter/material.dart'; -import 'package:supertokens_flutter/http.dart' as http; - -import '../../../main.dart'; -import '../../../mih_apis/mih_api_calls.dart'; -import '../../../mih_components/mih_inputs_and_buttons/mih_button.dart'; -import '../../../mih_components/mih_inputs_and_buttons/mih_date_input.dart'; -import '../../../mih_components/mih_inputs_and_buttons/mih_text_input.dart'; -import '../../../mih_components/mih_inputs_and_buttons/mih_time_input.dart'; -import '../../../mih_components/mih_layout/mih_window.dart'; -import '../../../mih_components/mih_pop_up_messages/mih_error_message.dart'; -import '../../../mih_components/mih_pop_up_messages/mih_success_message.dart'; -import '../../../mih_components/mih_pop_up_messages/mih_warning_message.dart'; -import '../../../mih_env/env.dart'; -import '../../../mih_objects/app_user.dart'; -import '../../../mih_objects/arguments.dart'; -import '../../../mih_objects/business.dart'; -import '../../../mih_objects/patients.dart'; - -class BuildPatientsList extends StatefulWidget { - final List patients; - final AppUser signedInUser; - final Business? business; - final BusinessArguments arguments; - - const BuildPatientsList({ - super.key, - required this.patients, - required this.signedInUser, - required this.business, - required this.arguments, - }); - - @override - State createState() => _BuildPatientsListState(); -} - -class _BuildPatientsListState extends State { - TextEditingController dateController = TextEditingController(); - TextEditingController timeController = TextEditingController(); - TextEditingController idController = TextEditingController(); - TextEditingController fnameController = TextEditingController(); - TextEditingController lnameController = TextEditingController(); - TextEditingController accessStatusController = TextEditingController(); - final baseAPI = AppEnviroment.baseApiUrl; - - Future addPatientAppointmentAPICall(int index) async { - var response = await http.post( - Uri.parse("$baseAPI/queue/insert/"), - headers: { - "Content-Type": "application/json; charset=UTF-8" - }, - body: jsonEncode({ - "business_id": widget.business!.business_id, - "app_id": widget.patients[index].app_id, - "date": dateController.text, - "time": timeController.text, - "access": "pending", - }), - ); - if (response.statusCode == 201) { - // Navigator.pushNamed(context, '/patient-manager/patient', - // arguments: widget.signedInUser); - String message = - "The appointment has been successfully booked!\n\nAn approval request as been sent to the patient.Once the access request has been approved, you will be able to access the patients profile. ou can check the status of your request in patient queue under the appointment."; - // "${fnameController.text} ${lnameController.text} patient profiole has been successfully added!\n"; - Navigator.pop(context); - Navigator.pop(context); - setState(() { - dateController.text = ""; - timeController.text = ""; - }); - Navigator.of(context).pushNamed( - '/patient-manager', - arguments: BusinessArguments( - widget.arguments.signedInUser, - widget.arguments.businessUser, - widget.arguments.business, - ), - ); - successPopUp(message); - addAccessReviewNotificationAPICall(index); - } else { - internetConnectionPopUp(); - } - } - - Future addPatientAccessAPICall(int index) async { - var response = await http.post( - Uri.parse("$baseAPI/access-requests/insert/"), - headers: { - "Content-Type": "application/json; charset=UTF-8" - }, - body: jsonEncode({ - "business_id": widget.business!.business_id, - "app_id": widget.patients[index].app_id, - "date": dateController.text, - "time": timeController.text, - "access": "pending", - }), - ); - if (response.statusCode == 201) { - // Navigator.pushNamed(context, '/patient-manager/patient', - // arguments: widget.signedInUser); - String message = - "The appointment has been successfully booked!\n\nAn approval request as been sent to the patient.Once the access request has been approved, you will be able to access the patients profile. ou can check the status of your request in patient queue under the appointment."; - // "${fnameController.text} ${lnameController.text} patient profiole has been successfully added!\n"; - Navigator.pop(context); - Navigator.pop(context); - setState(() { - dateController.text = ""; - timeController.text = ""; - }); - Navigator.of(context).pushNamed( - '/patient-manager', - arguments: BusinessArguments( - widget.arguments.signedInUser, - widget.arguments.businessUser, - widget.arguments.business, - ), - ); - successPopUp(message); - addAccessReviewNotificationAPICall(index); - } else { - internetConnectionPopUp(); - } - } - - Future addAccessReviewNotificationAPICall(int index) async { - var response = await http.post( - Uri.parse("$baseAPI/notifications/insert/"), - headers: { - "Content-Type": "application/json; charset=UTF-8" - }, - body: jsonEncode({ - "app_id": widget.patients[index].app_id, - "notification_type": "New Appointment Booked", - "notification_message": - "A new Appointment has been booked by ${widget.arguments.business!.Name} for the ${dateController.text} ${timeController.text}. Please approve the Access Review request.", - "action_path": "/mih-access", - }), - ); - if (response.statusCode == 201) { - // Navigator.pushNamed(context, '/patient-manager/patient', - // arguments: widget.signedInUser); - } else { - internetConnectionPopUp(); - } - } - - void internetConnectionPopUp() { - showDialog( - context: context, - builder: (context) { - return const MIHErrorMessage(errorType: "Internet Connection"); - }, - ); - } - - void successPopUp(String message) { - showDialog( - context: context, - builder: (context) { - return MIHSuccessMessage( - successType: "Success", - successMessage: message, - ); - }, - ); - } - - void submitApointment(int index) { - MIHApiCalls.addAppointmentAPICall( - widget.arguments.business!.business_id, - widget.patients[index].app_id, - false, - dateController.text, - timeController.text, - widget.arguments, - context, - ); - //addPatientAppointmentAPICall(index); - } - - bool isAppointmentFieldsFilled() { - if (dateController.text.isEmpty || timeController.text.isEmpty) { - return false; - } else { - return true; - } - } - - 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) => MIHWindow( - fullscreen: false, - windowTitle: "Patient Appointment", - windowTools: const [], - onWindowTapClose: () { - Navigator.pop(context); - }, - windowBody: [ - 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), - SizedBox( - width: 300, - height: 50, - child: MIHButton( - buttonText: "Book", - buttonColor: - MzanziInnovationHub.of(context)!.theme.secondaryColor(), - textColor: MzanziInnovationHub.of(context)!.theme.primaryColor(), - onTap: () { - //print("here1"); - bool filled = isAppointmentFieldsFilled(); - //print("fields filled: $filled"); - if (filled) { - //print("here2"); - submitApointment(index); - //print("here3"); - } else { - showDialog( - context: context, - builder: (context) { - return const MIHErrorMessage(errorType: "Input Error"); - }, - ); - } - }, - ), - ) - ], - ), - ); - } - - void noAccessWarning() { - showDialog( - context: context, - builder: (context) { - return const MIHWarningMessage(warningType: "No Access"); - }, - ); - } - - Future hasAccessToProfile(int index) async { - var hasAccess = false; - await MIHApiCalls.checkBusinessAccessToPatient( - widget.business!.business_id, widget.patients[index].app_id) - .then((results) { - if (results.isEmpty) { - setState(() { - hasAccess = false; - }); - } else if (results[0].status == "approved") { - setState(() { - hasAccess = true; - }); - } else { - setState(() { - hasAccess = false; - }); - } - }); - return hasAccess; - } - - Future getAccessStatusOfProfile(int index) async { - var accessStatus = ""; - await MIHApiCalls.checkBusinessAccessToPatient( - widget.business!.business_id, widget.patients[index].app_id) - .then((results) { - if (results.isEmpty) { - setState(() { - accessStatus = ""; - }); - } else { - setState(() { - accessStatus = results[0].status; - }); - } - }); - return accessStatus; - } - - void patientProfileChoicePopUp(int index) async { - var hasAccess = false; - String accessStatus = ""; - await hasAccessToProfile(index).then((result) { - setState(() { - hasAccess = result; - }); - }); - await getAccessStatusOfProfile(index).then((result) { - setState(() { - accessStatus = result; - }); - }); - // print(accessStatus); - // print(hasAccess); - var firstLetterFName = widget.patients[index].first_name[0]; - var firstLetterLName = widget.patients[index].last_name[0]; - var fnameStar = '*' * 8; - var lnameStar = '*' * 8; - if (accessStatus == "") { - accessStatus = "No Access"; - } - setState(() { - idController.text = widget.patients[index].id_no; - fnameController.text = firstLetterFName + fnameStar; - lnameController.text = firstLetterLName + lnameStar; - accessStatusController.text = accessStatus.toUpperCase(); - }); - //print(accessStatus); - showDialog( - context: context, - barrierDismissible: false, - builder: (context) => MIHWindow( - fullscreen: false, - windowTitle: "Patient Profile", - windowTools: const [], - onWindowTapClose: () { - Navigator.pop(context); - }, - windowBody: [ - 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), - MIHTextField( - controller: accessStatusController, - hintText: "Access Status", - editable: false, - required: true, - ), - const SizedBox(height: 20.0), - Visibility( - visible: !hasAccess, - child: Column( - mainAxisSize: MainAxisSize.max, - mainAxisAlignment: MainAxisAlignment.start, - children: [ - Text( - "Important Notice: Requesting Patient Profile Access", - style: TextStyle( - fontWeight: FontWeight.bold, - color: MzanziInnovationHub.of(context)!.theme.errorColor(), - ), - ), - Text( - "You are about to request access to a patient's profile. Please be aware of the following important points:", - style: TextStyle( - fontWeight: FontWeight.normal, - color: MzanziInnovationHub.of(context)!.theme.errorColor(), - ), - ), - SizedBox( - width: 600, - child: Text( - "1. Permanent Access: Once the patient accepts your access request, it will become permanent.", - style: TextStyle( - fontWeight: FontWeight.normal, - color: - MzanziInnovationHub.of(context)!.theme.errorColor(), - ), - ), - ), - SizedBox( - width: 600, - child: Text( - "2. Shared Information: Any updates you make to the patient's profile will be visible to others who have access to the profile.", - style: TextStyle( - fontWeight: FontWeight.normal, - color: - MzanziInnovationHub.of(context)!.theme.errorColor(), - ), - ), - ), - SizedBox( - width: 600, - child: Text( - "3. Irreversible Access: Once granted, you cannot revoke your access to the patient's profile.", - style: TextStyle( - fontWeight: FontWeight.normal, - color: - MzanziInnovationHub.of(context)!.theme.errorColor(), - ), - ), - ), - Text( - "By pressing the \"Request Access\" button you accept the above terms.", - style: TextStyle( - fontWeight: FontWeight.bold, - color: MzanziInnovationHub.of(context)!.theme.errorColor(), - ), - ), - ], - ), - ), - const SizedBox(height: 20.0), - Wrap(runSpacing: 10, spacing: 10, children: [ - Visibility( - visible: hasAccess, - child: SizedBox( - width: 300, - height: 50, - child: MIHButton( - buttonText: "Book Appointment", - buttonColor: - MzanziInnovationHub.of(context)!.theme.secondaryColor(), - textColor: - MzanziInnovationHub.of(context)!.theme.primaryColor(), - onTap: () { - if (hasAccess) { - appointmentPopUp(index); - } else { - noAccessWarning(); - } - }, - ), - ), - ), - Visibility( - visible: hasAccess, - child: SizedBox( - width: 300, - height: 50, - child: MIHButton( - buttonText: "View Patient Profile", - buttonColor: - MzanziInnovationHub.of(context)!.theme.successColor(), - textColor: - MzanziInnovationHub.of(context)!.theme.primaryColor(), - onTap: () { - if (hasAccess) { - Navigator.of(context) - .pushNamed('/patient-manager/patient', - arguments: PatientViewArguments( - widget.signedInUser, - widget.patients[index], - widget.arguments.businessUser, - widget.business, - "business", - )); - } else { - noAccessWarning(); - } - }, - ), - ), - ), - Visibility( - visible: !hasAccess && accessStatus == "No Access", - child: SizedBox( - width: 300, - height: 50, - child: MIHButton( - buttonText: "Request Access", - buttonColor: - MzanziInnovationHub.of(context)!.theme.successColor(), - textColor: - MzanziInnovationHub.of(context)!.theme.primaryColor(), - onTap: () { - //print("Send access Request..."); - // MIHApiCalls.addPatientAccessAPICall( - // widget.business!.business_id, - // widget.patients[index].app_id, - // "patient", - // widget.business!.Name, - // widget.arguments, - // context, - // ); - }, - ), - ), - ), - Visibility( - visible: !hasAccess && accessStatus == "declined", - child: SizedBox( - width: 300, - height: 50, - child: MIHButton( - buttonText: "Re-apply", - buttonColor: - MzanziInnovationHub.of(context)!.theme.successColor(), - textColor: - MzanziInnovationHub.of(context)!.theme.primaryColor(), - onTap: () { - print("Send rewaply access Request..."); - // MIHApiCalls.reapplyPatientAccessAPICall( - // widget.business!.business_id, - // widget.patients[index].app_id, - // widget.arguments, - // context, - // ); - }, - ), - ), - ), - Visibility( - visible: !hasAccess && accessStatus == "pending", - child: const SizedBox( - width: 500, - //height: 50, - child: Text( - "Patient has not approved access to their profile. Once access has been approved you can book and appointment or view their profile."), - ), - ), - ]) - ], - ), - ); - } - - Widget isMainMember(int index) { - //var matchRE = RegExp(r'^[a-z]+$'); - var firstLetterFName = widget.patients[index].first_name[0]; - var firstLetterLName = widget.patients[index].last_name[0]; - var fnameStar = '*' * 8; - var lnameStar = '*' * 8; - - if (widget.patients[index].medical_aid_main_member == "Yes") { - return Row( - mainAxisSize: MainAxisSize.max, - children: [ - Text( - "$firstLetterFName$fnameStar $firstLetterLName$lnameStar", - style: TextStyle( - color: MzanziInnovationHub.of(context)!.theme.secondaryColor(), - ), - ), - const SizedBox( - width: 10, - ), - Icon( - Icons.star_border_rounded, - color: MzanziInnovationHub.of(context)!.theme.secondaryColor(), - ), - ], - ); - } else { - return Text( - "$firstLetterFName$fnameStar $firstLetterLName$lnameStar", - style: TextStyle( - color: MzanziInnovationHub.of(context)!.theme.secondaryColor(), - ), - ); - } - } - - Widget hasMedicalAid(int index) { - var medAidNoStar = '*' * 8; - if (widget.patients[index].medical_aid == "Yes") { - return ListTile( - title: isMainMember(index), - subtitle: Text( - "ID No.: ${widget.patients[index].id_no}\nMedical Aid No.: $medAidNoStar", - style: TextStyle( - color: MzanziInnovationHub.of(context)!.theme.secondaryColor(), - ), - ), - onTap: () { - patientProfileChoicePopUp(index); - // setState(() { - // appointmentPopUp(index); - // // Add popup to add patienmt to queue - // // Navigator.of(context).pushNamed('/patient-manager/patient', - // // arguments: PatientViewArguments( - // // widget.signedInUser, widget.patients[index], "business")); - // }); - }, - trailing: Icon( - Icons.arrow_forward, - color: MzanziInnovationHub.of(context)!.theme.secondaryColor(), - ), - ); - } else { - return ListTile( - title: isMainMember(index), - subtitle: Text( - "ID No.: ${widget.patients[index].id_no}\nMedical Aid No.: $medAidNoStar", - style: TextStyle( - color: MzanziInnovationHub.of(context)!.theme.secondaryColor(), - ), - ), - onTap: () { - patientProfileChoicePopUp(index); - // setState(() { - // appointmentPopUp(index); - // // Navigator.of(context).pushNamed('/patient-manager/patient', - // // arguments: PatientViewArguments( - // // widget.signedInUser, widget.patients[index], "business")); - // }); - }, - trailing: Icon( - Icons.add, - color: MzanziInnovationHub.of(context)!.theme.secondaryColor(), - ), - ); - } - } - - @override - void dispose() { - dateController.dispose(); - timeController.dispose(); - idController.dispose(); - fnameController.dispose(); - lnameController.dispose(); - accessStatusController.dispose(); - super.dispose(); - } - - @override - Widget build(BuildContext context) { - return ListView.separated( - shrinkWrap: true, - physics: const NeverScrollableScrollPhysics(), - separatorBuilder: (BuildContext context, index) { - return Divider( - color: MzanziInnovationHub.of(context)!.theme.secondaryColor(), - ); - }, - itemCount: widget.patients.length, - itemBuilder: (context, index) { - //final patient = widget.patients[index].id_no.contains(widget.searchString); - //print(index); - return hasMedicalAid(index); - }, - ); - } -} diff --git a/Frontend/lib/mih_packages/patient_profile/builder/build_patient_queue_list.dart b/Frontend/lib/mih_packages/patient_profile/builder/build_patient_queue_list.dart deleted file mode 100644 index bdd795bd..00000000 --- a/Frontend/lib/mih_packages/patient_profile/builder/build_patient_queue_list.dart +++ /dev/null @@ -1,845 +0,0 @@ -import 'dart:convert'; - -import 'package:flutter/material.dart'; -import 'package:supertokens_flutter/http.dart' as http; - -import '../../../main.dart'; -import '../../../mih_apis/mih_api_calls.dart'; -import '../../../mih_components/mih_inputs_and_buttons/mih_button.dart'; -import '../../../mih_components/mih_inputs_and_buttons/mih_date_input.dart'; -import '../../../mih_components/mih_inputs_and_buttons/mih_text_input.dart'; -import '../../../mih_components/mih_inputs_and_buttons/mih_time_input.dart'; -import '../../../mih_components/mih_layout/mih_window.dart'; -import '../../../mih_components/mih_pop_up_messages/mih_delete_message.dart'; -import '../../../mih_components/mih_pop_up_messages/mih_error_message.dart'; -import '../../../mih_components/mih_pop_up_messages/mih_success_message.dart'; -import '../../../mih_components/mih_pop_up_messages/mih_warning_message.dart'; -import '../../../mih_env/env.dart'; -import '../../../mih_objects/app_user.dart'; -import '../../../mih_objects/arguments.dart'; -import '../../../mih_objects/business.dart'; -import '../../../mih_objects/business_user.dart'; -import '../../../mih_objects/patient_queue.dart'; -import '../../../mih_objects/patients.dart'; - -class BuildPatientQueueList extends StatefulWidget { - final List patientQueue; - final AppUser signedInUser; - final Business? business; - final BusinessUser? businessUser; - - const BuildPatientQueueList({ - super.key, - required this.patientQueue, - required this.signedInUser, - required this.business, - required this.businessUser, - }); - - @override - State createState() => _BuildPatientsListState(); -} - -class _BuildPatientsListState extends State { - String baseAPI = AppEnviroment.baseApiUrl; - TextEditingController dateController = TextEditingController(); - TextEditingController timeController = TextEditingController(); - TextEditingController idController = TextEditingController(); - TextEditingController fnameController = TextEditingController(); - TextEditingController lnameController = TextEditingController(); - TextEditingController daysExtensionController = TextEditingController(); - int counter = 0; - - Future updateAccessAPICall(int index, String accessType) async { - var response = await http.put( - Uri.parse("$baseAPI/access-requests/update/"), - headers: { - "Content-Type": "application/json; charset=UTF-8" - }, - body: jsonEncode({ - "business_id": widget.business!.business_id, - "app_id": widget.patientQueue[index].app_id, - "date_time": widget.patientQueue[index].date_time, - "access": accessType, - }), - ); - if (response.statusCode == 200) { - //Navigator.of(context).pushNamed('/home'); - addCancelledAppointmentNotificationAPICall(index); - // Navigator.of(context).pop(); - // Navigator.of(context).pop(); - // Navigator.of(context).pushNamed( - // '/patient-manager', - // arguments: BusinessArguments( - // widget.signedInUser, - // widget.businessUser, - // widget.business, - // ), - // ); - // String message = - // "The appointment for ${widget.patientQueue[index].first_name} ${widget.patientQueue[index].last_name} at ${widget.patientQueue[index].date_time} has been successfully canceled."; - - // successPopUp(message); - } else { - internetConnectionPopUp(); - } - } - - // Future extendAccessAPICall(int index, String revokeDate) async { - // var response = await http.put( - // Uri.parse("$baseAPI/access-requests/extension/"), - // headers: { - // "Content-Type": "application/json; charset=UTF-8" - // }, - // body: jsonEncode({ - // "business_id": widget.business!.business_id, - // "app_id": widget.patientQueue[index].app_id, - // "date_time": widget.patientQueue[index].date_time, - // "revoke_date": revokeDate, - // }), - // ); - // if (response.statusCode == 200) { - // addAccessExtensionNotificationAPICall(index, revokeDate); - // //addCancelledAppointmentNotificationAPICall(index); - // } else { - // internetConnectionPopUp(); - // } - // } - - Future updateApointmentAPICall(int index) async { - var response = await http.put( - Uri.parse("$baseAPI/queue/appoointment/update/"), - headers: { - "Content-Type": "application/json; charset=UTF-8" - }, - body: jsonEncode({ - "idpatient_queue": widget.patientQueue[index].idpatient_queue, - "date": dateController.text, - "time": timeController.text, - }), - ); - if (response.statusCode == 200) { - //Navigator.of(context).pushNamed('/home'); - addRescheduledAppointmentNotificationAPICall(index); - // Navigator.of(context).pop(); - // Navigator.of(context).pop(); - // Navigator.of(context).pop(); - // Navigator.of(context).pushNamed( - // '/patient-manager', - // arguments: BusinessArguments( - // widget.signedInUser, - // widget.businessUser, - // widget.business, - // ), - // ); - - // String message = - // "The appointment has been rescheduled for ${dateController.text} ${timeController.text}.\n\nJust a heads up: We've reset your access to the patient's profile and it will have to be approved again."; - - // successPopUp(message); - } else { - internetConnectionPopUp(); - } - } - - Future fetchPatients(String app_id) async { - //print("pat man drawer: " + endpointUserData + widget.userEmail); - - var response = await http.get(Uri.parse("$baseAPI/patients/$app_id")); - - // print(response.statusCode); - // print(response.body); - if (response.statusCode == 200) { - // print("here"); - String body = response.body; - var decodedData = jsonDecode(body); - Patient u = Patient.fromJson(decodedData); - // print(u.email); - //setState(() { - //_widgetOptions = setLayout(u); - //}); - return u; - } else { - throw Exception("Error: GetUserData status code ${response.statusCode}"); - } - } - - void internetConnectionPopUp() { - showDialog( - context: context, - builder: (context) { - return const MIHErrorMessage(errorType: "Internet Connection"); - }, - ); - } - - void deleteFilePopUp(int index) { - showDialog( - context: context, - barrierDismissible: false, - builder: (context) => MIHDeleteMessage( - deleteType: "appointment", - onTap: () async { - await updateAccessAPICall(index, "cancelled"); - }, - ), - ); - } - - void successPopUp(String message) { - showDialog( - context: context, - builder: (context) { - return MIHSuccessMessage( - successType: "Success", - successMessage: message, - ); - }, - ); - } - - void viewConfirmationPopUp(int index) { - String subtitle = - "Appointment: ${widget.patientQueue[index].date_time.substring(0, 16).replaceAll("T", " ")}\n"; - subtitle += "ID No.: ${widget.patientQueue[index].id_no}\n"; - subtitle += - "Patient: ${widget.patientQueue[index].first_name} ${widget.patientQueue[index].last_name}\n"; - // subtitle += - // "Patient: ${widget.patientQueue[index].first_name} ${widget.patientQueue[index].last_name}\n\n"; - //subtitle += "Business Type: ${widget.patientQueue[index].last_name}\n\n"; - subtitle += - "Would you like to view the patient's profile before the appointment or cancel the appointment now?\n"; - //"You are about to approve an access request to your patient profile.\nPlease be aware that once approved, ${widget.accessRequests[index].Name} will have access to your profile information until ${widget.accessRequests[index].revoke_date.substring(0, 16).replaceAll("T", " ")}.\nIf you are unsure about an upcoming appointment with ${widget.accessRequests[index].Name}, please contact ${widget.accessRequests[index].contact_no} for clarification before approving this request.\n"; - showDialog( - context: context, - barrierDismissible: false, - builder: (context) => MIHWindow( - fullscreen: false, - windowTitle: "Appointment Confirmation", - windowBody: [ - const SizedBox( - height: 10, - ), - Padding( - padding: const EdgeInsets.symmetric(horizontal: 10.0), - child: Text( - subtitle, - textAlign: TextAlign.left, - style: TextStyle( - color: - MzanziInnovationHub.of(context)!.theme.secondaryColor(), - fontSize: 15, - //fontWeight: FontWeight.bold, - ), - ), - ), - Wrap( - runSpacing: 10, - spacing: 10, - children: [ - SizedBox( - width: 300, - height: 50, - child: MIHButton( - onTap: () { - //updateAccessAPICall(index, "cancelled"); - var appointmentDateTime = widget - .patientQueue[index].date_time - .substring(0, 16) - .split("T"); - var firstName = ""; - var lastName = ""; - firstName = widget.patientQueue[index].first_name; - lastName = widget.patientQueue[index].last_name; - - setState(() { - idController.text = widget.patientQueue[index].id_no; - fnameController.text = firstName; - lnameController.text = lastName; - dateController.text = appointmentDateTime[0]; - timeController.text = appointmentDateTime[1]; - }); - manageAppointmentPopUp(index); - }, - buttonText: "Manage Appointment", - buttonColor: - MzanziInnovationHub.of(context)!.theme.secondaryColor(), - textColor: - MzanziInnovationHub.of(context)!.theme.primaryColor(), - ), - ), - SizedBox( - width: 300, - height: 50, - child: MIHButton( - onTap: () { - //updateAccessAPICall(index, "approved"); - - Patient selectedPatient; - fetchPatients(widget.patientQueue[index].app_id).then( - (result) { - setState(() { - selectedPatient = result; - Navigator.of(context).pop(); - Navigator.of(context) - .pushNamed('/patient-manager/patient', - arguments: PatientViewArguments( - widget.signedInUser, - selectedPatient, - widget.businessUser, - widget.business, - "business", - )); - }); - }, - ); - }, - buttonText: "View Patient Profile", - buttonColor: - MzanziInnovationHub.of(context)!.theme.successColor(), - textColor: - MzanziInnovationHub.of(context)!.theme.primaryColor(), - ), - ), - ], - ), - const SizedBox( - height: 10, - ), - ], - windowTools: const [], - onWindowTapClose: () { - Navigator.pop(context); - }), - ); - } - - Future addCancelledAppointmentNotificationAPICall(int index) async { - var response = await http.post( - Uri.parse("$baseAPI/notifications/insert/"), - headers: { - "Content-Type": "application/json; charset=UTF-8" - }, - body: jsonEncode({ - "app_id": widget.patientQueue[index].app_id, - "notification_type": "Appointment Cancelled", - "notification_message": - "Your appointment with ${widget.business!.Name} for the ${widget.patientQueue[index].date_time.replaceAll("T", " ")} has been cancelled.", - "action_path": "/mih-access", - }), - ); - if (response.statusCode == 201) { - // Navigator.pushNamed(context, '/patient-manager/patient', - // arguments: widget.signedInUser); - Navigator.of(context).pop(); - Navigator.of(context).pop(); - Navigator.of(context).pushNamed( - '/patient-manager', - arguments: BusinessArguments( - widget.signedInUser, - widget.businessUser, - widget.business, - ), - ); - String message = - "The appointment for ${widget.patientQueue[index].first_name} ${widget.patientQueue[index].last_name} at ${widget.patientQueue[index].date_time} has been successfully canceled."; - - successPopUp(message); - } else { - internetConnectionPopUp(); - } - } - - Future addRescheduledAppointmentNotificationAPICall(int index) async { - var response = await http.post( - Uri.parse("$baseAPI/notifications/insert/"), - headers: { - "Content-Type": "application/json; charset=UTF-8" - }, - body: jsonEncode({ - "app_id": widget.patientQueue[index].app_id, - "notification_type": "Rescheduled Appointment", - "notification_message": - "Your appointment with ${widget.business!.Name} for the ${widget.patientQueue[index].date_time.replaceAll("T", " ").substring(0, widget.patientQueue[index].date_time.length - 3)} has been rescheduled to the ${dateController.text} ${timeController.text}.", - "action_path": "/mih-access", - }), - ); - if (response.statusCode == 201) { - Navigator.of(context).pop(); - Navigator.of(context).pop(); - Navigator.of(context).pop(); - Navigator.of(context).pushNamed( - '/patient-manager', - arguments: BusinessArguments( - widget.signedInUser, - widget.businessUser, - widget.business, - ), - ); - String message = - "The appointment for ${widget.patientQueue[index].first_name} ${widget.patientQueue[index].last_name} at ${widget.patientQueue[index].date_time} has been successfully canceled."; - - successPopUp(message); - } else { - internetConnectionPopUp(); - } - } - - // Future addAccessExtensionNotificationAPICall( - // int index, String revokeDate) async { - // var response = await http.post( - // Uri.parse("$baseAPI/notifications/insert/"), - // headers: { - // "Content-Type": "application/json; charset=UTF-8" - // }, - // body: jsonEncode({ - // "app_id": widget.patientQueue[index].app_id, - // "notification_type": "Access Extension Request", - // "notification_message": - // "${widget.business!.Name} - access expiry date extension for appointment: ${widget.patientQueue[index].date_time.split("T")[0]}. Expiry Date: from ${widget.patientQueue[index].revoke_date.split("T")[0]} to ${revokeDate.split(" ")[0]}.", - // "action_path": "/mih-access", - // }), - // ); - // if (response.statusCode == 201) { - // Navigator.of(context).pop(); - // Navigator.of(context).pop(); - // Navigator.of(context).pushNamed( - // '/patient-manager', - // arguments: BusinessArguments( - // widget.signedInUser, - // widget.businessUser, - // widget.business, - // ), - // ); - // String message = - // "you have successfully requested an extension on the expirey date. The request has been sent tp ${widget.patientQueue[index].first_name} ${widget.patientQueue[index].last_name} to review and approve the request"; - - // successPopUp(message); - // } else { - // internetConnectionPopUp(); - // } - // } - - void manageAppointmentPopUp(int index) { - showDialog( - context: context, - barrierDismissible: false, - builder: (context) => MIHWindow( - fullscreen: false, - windowTitle: "Manage Appointment", - windowBody: [ - 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), - 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), - Wrap( - runSpacing: 10, - spacing: 10, - children: [ - SizedBox( - width: 300, - height: 50, - child: MIHButton( - onTap: () { - //add mihapicall for deleting appointment - MIHApiCalls.deleteApointmentAPICall( - widget.patientQueue[index].idpatient_queue, - widget.patientQueue[index].app_id, - false, - widget.patientQueue[index].date_time, - BusinessArguments( - widget.signedInUser, - widget.businessUser, - widget.business, - ), - context, - ); - //updateAccessAPICall(index, "cancelled"); - }, - buttonText: "Cancel Appointment", - buttonColor: - MzanziInnovationHub.of(context)!.theme.errorColor(), - textColor: - MzanziInnovationHub.of(context)!.theme.primaryColor(), - ), - ), - SizedBox( - width: 300, - height: 50, - child: MIHButton( - onTap: () { - MIHApiCalls.updateApointmentAPICall( - widget.patientQueue[index].idpatient_queue, - widget.patientQueue[index].app_id, - false, - widget.business!.Name, - widget.patientQueue[index].date_time, - dateController.text, - timeController.text, - BusinessArguments( - widget.signedInUser, - widget.businessUser, - widget.business, - ), - context, - ); - }, - buttonText: "Update Appointment", - buttonColor: - MzanziInnovationHub.of(context)!.theme.successColor(), - textColor: - MzanziInnovationHub.of(context)!.theme.primaryColor(), - ), - ), - ], - ), - const SizedBox( - height: 10, - ), - ], - windowTools: const [], - onWindowTapClose: () { - Navigator.pop(context); - }), - ); - } - - Widget displayQueue(int index) { - String title = - widget.patientQueue[index].date_time.split('T')[1].substring(0, 5); - String line234 = ""; - // var nowDate = DateTime.now(); - // var expireyDate = DateTime.parse(widget.patientQueue[index].revoke_date); - - line234 += - "Name: ${widget.patientQueue[index].first_name} ${widget.patientQueue[index].last_name}\nID No.: ${widget.patientQueue[index].id_no}\nMedical Aid No: "; - if (widget.patientQueue[index].medical_aid_no == "") { - line234 += "No Medical Aid"; - } else { - // subtitle += - // "\nMedical Aid No: "; - line234 += widget.patientQueue[index].medical_aid_no; - } - - // String line5 = "\nAccess Request: "; - // String access = ""; - // if (expireyDate.isBefore(nowDate) && - // widget.patientQueue[index].access != "cacelled") { - // access += "EXPIRED"; - // } else { - // access += widget.patientQueue[index].access.toUpperCase(); - // } - // TextSpan accessWithColour; - // if (access == "APPROVED") { - // accessWithColour = TextSpan( - // text: access, - // style: TextStyle( - // color: MzanziInnovationHub.of(context)!.theme.successColor())); - // } else if (access == "PENDING") { - // accessWithColour = TextSpan( - // text: access, - // style: TextStyle( - // color: - // MzanziInnovationHub.of(context)!.theme.messageTextColor())); - // } else { - // accessWithColour = TextSpan( - // text: access, - // style: TextStyle( - // color: MzanziInnovationHub.of(context)!.theme.errorColor())); - // } - // String line6 = ""; - // line6 += - // "\nAccess Expiration date: ${widget.patientQueue[index].revoke_date.substring(0, 16).replaceAll("T", " ")}"; - return ListTile( - title: Text( - "Appointment: $title", - style: TextStyle( - color: MzanziInnovationHub.of(context)!.theme.secondaryColor(), - ), - ), - subtitle: RichText( - text: TextSpan( - text: line234, - style: DefaultTextStyle.of(context).style, - // children: [ - // TextSpan(text: line5), - // accessWithColour, - // TextSpan(text: line6), - // ] - ), - ), - // Text( - // subtitle, - // style: TextStyle( - // color: MzanziInnovationHub.of(context)!.theme.secondaryColor(), - // ), - // ), - onTap: () { - // var todayDate = DateTime.now(); - // var revokeDate = DateTime.parse(widget.patientQueue[index].revoke_date); - // // print( - // // "Todays: $todayDate\nRevoke Date: $revokeDate\nHas revoke date passed: ${revokeDate.isBefore(todayDate)}"); - // if (revokeDate.isBefore(todayDate)) { - // expiredAccessWarning(); - // } else if (widget.patientQueue[index].access == "approved") { - // viewConfirmationPopUp(index); - // // Patient selectedPatient; - // // fetchPatients(widget.patientQueue[index].app_id).then( - // // (result) { - // // setState(() { - // // selectedPatient = result; - // // Navigator.of(context).pushNamed('/patient-manager/patient', - // // arguments: PatientViewArguments( - // // widget.signedInUser, - // // selectedPatient, - // // widget.businessUser, - // // widget.business, - // // "business", - // // )); - // // }); - // // }, - // // ); - // } else if (widget.patientQueue[index].access == "declined") { - // accessDeclinedWarning(); - // } else if (widget.patientQueue[index].access == "cancelled") { - // appointmentCancelledWarning(); - // } else { - viewConfirmationPopUp(index); - //noAccessWarning(); - // } - }, - //leading: getExtendAccessButton(access), - //trailing: getExtendAccessButton(access, index), - // Icon( - // Icons.arrow_forward, - // color: MzanziInnovationHub.of(context)!.theme.secondaryColor(), - // ), - ); - } - - bool isAccessExpired(String accessType) { - if (accessType == "EXPIRED") { - return true; - } else { - return false; - } - } - - // Widget getExtendAccessButton(String accessType, int index) { - // if (isAccessExpired(accessType)) { - // return IconButton( - // icon: const Icon(Icons.cached), - // onPressed: () { - // setState(() { - // daysExtensionController.text = counter.toString(); - // }); - // reapplyForAccess(index); - // }, - // ); - // } else { - // return Icon( - // Icons.arrow_forward, - // color: MzanziInnovationHub.of(context)!.theme.secondaryColor(), - // ); - // } - // } - - // void reapplyForAccess(int index) { - // showDialog( - // context: context, - // barrierDismissible: false, - // builder: (context) => MIHWindow( - // fullscreen: false, - // windowTitle: "Extend Access", - // windowTools: const [], - // onWindowTapClose: () { - // Navigator.pop(context); - // }, - // windowBody: [ - // Text( - // "Current Expiration Date : ${widget.patientQueue[index].revoke_date.replaceAll("T", " ")}", - // style: TextStyle( - // color: MzanziInnovationHub.of(context)!.theme.secondaryColor(), - // fontSize: 15, - // fontWeight: FontWeight.normal, - // ), - // ), - // const SizedBox(height: 5), - // Text( - // "Select the number of days you would like to extend the access by.", - // style: TextStyle( - // color: MzanziInnovationHub.of(context)!.theme.secondaryColor(), - // fontSize: 15, - // fontWeight: FontWeight.normal, - // ), - // ), - // const SizedBox(height: 5), - // Text( - // "Once you click \"Apply\", an access review request will be triggered to the patient.", - // style: TextStyle( - // color: MzanziInnovationHub.of(context)!.theme.secondaryColor(), - // fontSize: 15, - // fontWeight: FontWeight.normal, - // ), - // ), - // const SizedBox(height: 30), - // Row( - // mainAxisAlignment: MainAxisAlignment.center, - // children: [ - // IconButton.filled( - // onPressed: () { - // if (counter > 0) { - // counter--; - // setState(() { - // daysExtensionController.text = counter.toString(); - // }); - // } - // }, - // icon: const Icon(Icons.remove), - // ), - // const SizedBox(width: 15), - // SizedBox( - // width: 100, - // child: MIHTextField( - // controller: daysExtensionController, - // hintText: "Days", - // editable: false, - // required: true, - // ), - // ), - // const SizedBox(width: 15), - // IconButton.filled( - // onPressed: () { - // counter++; - // setState(() { - // daysExtensionController.text = counter.toString(); - // }); - // }, - // icon: const Icon(Icons.add), - // ), - // ], - // ), - // const SizedBox(height: 30), - // SizedBox( - // width: 300, - // height: 50, - // child: MIHButton( - // onTap: () { - // print( - // "Revoke Date (String): ${widget.patientQueue[index].revoke_date}"); - // var revokeDate = DateTime.parse(widget - // .patientQueue[index].revoke_date - // .replaceAll("T", " ")); - // var newRevokeDate = revokeDate.add( - // Duration(days: int.parse(daysExtensionController.text))); - // print("Revoke Date (DateTime): $revokeDate"); - // print("New Revoke Date (DateTime): $newRevokeDate"); - // print( - // "${widget.business!.Name} would like to extend the access expirey date for your appointment on the ${widget.patientQueue[index].date_time}.\nNew Expirey Date: $revokeDate", - // ); - // extendAccessAPICall(index, "$newRevokeDate"); - // }, - // buttonText: "Apply", - // buttonColor: - // MzanziInnovationHub.of(context)!.theme.secondaryColor(), - // textColor: MzanziInnovationHub.of(context)!.theme.primaryColor(), - // ), - // ), - // ], - // ), - // ); - // } - - void noAccessWarning() { - showDialog( - context: context, - builder: (context) { - return const MIHWarningMessage(warningType: "No Access"); - }, - ); - } - - void accessDeclinedWarning() { - showDialog( - context: context, - builder: (context) { - return const MIHWarningMessage(warningType: "Access Declined"); - }, - ); - } - - void appointmentCancelledWarning() { - showDialog( - context: context, - builder: (context) { - return const MIHWarningMessage(warningType: "Appointment Canelled"); - }, - ); - } - - void expiredAccessWarning() { - showDialog( - context: context, - builder: (context) { - return const MIHWarningMessage(warningType: "Expired Access"); - }, - ); - } - - @override - void dispose() { - daysExtensionController.dispose(); - dateController.dispose(); - timeController.dispose(); - super.dispose(); - } - - @override - Widget build(BuildContext context) { - return ListView.separated( - physics: const NeverScrollableScrollPhysics(), - shrinkWrap: true, - separatorBuilder: (BuildContext context, index) { - return Divider( - color: MzanziInnovationHub.of(context)!.theme.secondaryColor(), - ); - }, - itemCount: widget.patientQueue.length, - itemBuilder: (context, index) { - //final patient = widget.patients[index].id_no.contains(widget.searchString); - //print(index); - return displayQueue(index); - }, - ); - } -} diff --git a/Frontend/lib/mih_packages/patient_profile/icd10_search_window.dart b/Frontend/lib/mih_packages/patient_profile/icd10_search_window.dart deleted file mode 100644 index f7613aaa..00000000 --- a/Frontend/lib/mih_packages/patient_profile/icd10_search_window.dart +++ /dev/null @@ -1,58 +0,0 @@ -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_window.dart'; -import 'package:Mzansi_Innovation_Hub/mih_objects/icd10_code.dart.dart'; -import 'package:Mzansi_Innovation_Hub/mih_packages/patient_profile/builder/build_icd10_code_list.dart'; -import 'package:flutter/material.dart'; - -class ICD10SearchWindow extends StatefulWidget { - final TextEditingController icd10CodeController; - final List icd10codeList; - const ICD10SearchWindow({ - super.key, - required this.icd10CodeController, - required this.icd10codeList, - }); - - @override - State createState() => _ICD10SearchWindowState(); -} - -class _ICD10SearchWindowState extends State { - Widget getWindowBody() { - return Column( - children: [ - MIHTextField( - controller: widget.icd10CodeController, - hintText: "Search Text", - editable: false, - required: false, - ), - BuildICD10CodeList( - icd10CodeController: widget.icd10CodeController, - icd10codeList: widget.icd10codeList, - ), - ], - ); - } - - @override - Widget build(BuildContext context) { - return MIHWindow( - fullscreen: false, - windowTitle: "ICD-10 Search", - windowTools: const [], - onWindowTapClose: () { - // medicineController.clear(); - // quantityController.clear(); - // dosageController.clear(); - // timesDailyController.clear(); - // noDaysController.clear(); - // noRepeatsController.clear(); - Navigator.pop(context); - }, - windowBody: [ - getWindowBody(), - ], - ); - } -} diff --git a/Frontend/lib/mih_packages/patient_profile/patient_add.dart b/Frontend/lib/mih_packages/patient_profile/patient_add.dart deleted file mode 100644 index 192cea3f..00000000 --- a/Frontend/lib/mih_packages/patient_profile/patient_add.dart +++ /dev/null @@ -1,445 +0,0 @@ -import 'dart:convert'; - -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_button.dart'; -import '../../mih_components/mih_inputs_and_buttons/mih_dropdown_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'; -import '../../mih_components/mih_layout/mih_layout_builder.dart'; -import '../../mih_components/mih_pop_up_messages/mih_error_message.dart'; -import '../../mih_components/mih_pop_up_messages/mih_success_message.dart'; -import '../../mih_env/env.dart'; -import '../../mih_objects/app_user.dart'; -import '../../mih_objects/arguments.dart'; - -class AddPatient extends StatefulWidget { - final AppUser signedInUser; - - const AddPatient({ - super.key, - required this.signedInUser, - }); - - @override - State createState() => _AddPatientState(); -} - -class _AddPatientState extends State { - final idController = TextEditingController(); - final fnameController = TextEditingController(); - final lnameController = TextEditingController(); - final cellController = TextEditingController(); - final emailController = TextEditingController(); - final medNoController = TextEditingController(); - final medNameController = TextEditingController(); - final medSchemeController = TextEditingController(); - final addressController = TextEditingController(); - final medAidController = TextEditingController(); - final medMainMemController = TextEditingController(); - final medAidCodeController = TextEditingController(); - - final baseAPI = AppEnviroment.baseApiUrl; - late int futureDocOfficeId; - //late bool medRequired; - final ValueNotifier medRequired = ValueNotifier(false); - final FocusNode _focusNode = FocusNode(); - - bool isFieldsFilled() { - if (medRequired.value) { - if (idController.text.isEmpty || - fnameController.text.isEmpty || - lnameController.text.isEmpty || - cellController.text.isEmpty || - emailController.text.isEmpty || - medNoController.text.isEmpty || - medNameController.text.isEmpty || - medSchemeController.text.isEmpty || - addressController.text.isEmpty || - medAidController.text.isEmpty || - medMainMemController.text.isEmpty || - medAidCodeController.text.isEmpty) { - return false; - } else { - return true; - } - } else { - if (idController.text.isEmpty || - fnameController.text.isEmpty || - lnameController.text.isEmpty || - cellController.text.isEmpty || - emailController.text.isEmpty || - addressController.text.isEmpty || - medAidController.text.isEmpty) { - return false; - } else { - return true; - } - } - } - - Future addPatientAPICall() async { - var response = await http.post( - Uri.parse("$baseAPI/patients/insert/"), - headers: { - "Content-Type": "application/json; charset=UTF-8" - }, - body: jsonEncode({ - "id_no": idController.text, - "first_name": fnameController.text, - "last_name": lnameController.text, - "email": emailController.text, - "cell_no": cellController.text, - "medical_aid": medAidController.text, - "medical_aid_main_member": medMainMemController.text, - "medical_aid_no": medNoController.text, - "medical_aid_code": medAidCodeController.text, - "medical_aid_name": medNameController.text, - "medical_aid_scheme": medSchemeController.text, - "address": addressController.text, - "app_id": widget.signedInUser.app_id, - }), - ); - if (response.statusCode == 201) { - Navigator.of(context).popAndPushNamed('/patient-profile', - arguments: PatientViewArguments( - widget.signedInUser, null, null, null, "personal")); - String message = - "${fnameController.text} ${lnameController.text} patient profiole has been successfully added!\n"; - successPopUp(message); - } else { - internetConnectionPopUp(); - } - } - - void internetConnectionPopUp() { - showDialog( - context: context, - builder: (context) { - return const MIHErrorMessage(errorType: "Internet Connection"); - }, - ); - } - - void messagePopUp(error) { - showDialog( - context: context, - builder: (context) { - return AlertDialog( - title: Text(error), - ); - }, - ); - } - - void successPopUp(String message) { - showDialog( - context: context, - builder: (context) { - return MIHSuccessMessage( - successType: "Success", - successMessage: message, - ); - }, - ); - } - - void isRequired() { - //print("listerner triggered"); - if (medAidController.text == "Yes") { - medRequired.value = true; - } else { - medRequired.value = false; - } - } - - Widget displayForm() { - return 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"], - ), - 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 Scheme", - editable: value, - required: value, - ), - ], - ), - ); - }, - ), - const SizedBox(height: 30.0), - SizedBox( - width: 450.0, - height: 50.0, - child: MIHButton( - onTap: () { - submitForm(); - }, - buttonText: "Add", - buttonColor: - MzanziInnovationHub.of(context)!.theme.secondaryColor(), - textColor: MzanziInnovationHub.of(context)!.theme.primaryColor(), - ), - ), - ], - ); - } - - void submitForm() { - if (isFieldsFilled()) { - addPatientAPICall(); - } else { - showDialog( - context: context, - builder: (context) { - return const MIHErrorMessage(errorType: "Input Error"); - }, - ); - } - } - - MIHAction getActionButton() { - return MIHAction( - icon: const Icon(Icons.arrow_back), - iconSize: 35, - onTap: () { - Navigator.of(context).pop(); - }, - ); - } - - MIHHeader getHeader() { - return const MIHHeader( - headerAlignment: MainAxisAlignment.center, - headerItems: [ - Text( - "Add Patient Details", - style: TextStyle( - fontWeight: FontWeight.bold, - fontSize: 25, - ), - ), - ], - ); - } - - MIHBody getBody() { - return MIHBody( - borderOn: true, - bodyItems: [ - KeyboardListener( - focusNode: _focusNode, - autofocus: true, - onKeyEvent: (event) async { - if (event is KeyDownEvent && - event.logicalKey == LogicalKeyboardKey.enter) { - submitForm(); - } - }, - child: displayForm(), - ), - ], - ); - } - - @override - void dispose() { - idController.dispose(); - fnameController.dispose(); - lnameController.dispose(); - cellController.dispose(); - emailController.dispose(); - medNoController.dispose(); - medNameController.dispose(); - medSchemeController.dispose(); - addressController.dispose(); - medAidController.dispose(); - medAidCodeController.removeListener(isRequired); - medRequired.dispose(); - medMainMemController.dispose(); - medAidCodeController.dispose(); - _focusNode.dispose(); - super.dispose(); - } - - @override - void initState() { - medAidController.addListener(isRequired); - setState(() { - fnameController.text = widget.signedInUser.fname; - lnameController.text = widget.signedInUser.lname; - emailController.text = widget.signedInUser.email; - medAidController.text = "No"; - }); - super.initState(); - } - - @override - Widget build(BuildContext context) { - return MIHLayoutBuilder( - actionButton: getActionButton(), - header: getHeader(), - secondaryActionButton: null, - body: getBody(), - actionDrawer: null, - secondaryActionDrawer: null, - bottomNavBar: null, - pullDownToRefresh: false, - onPullDown: () async {}, - ); - // return Scaffold( - // // appBar: const MIHAppBar( - // // barTitle: "Add Patient", - // // propicFile: null, - // // ), - // //drawer: MIHAppDrawer(signedInUser: widget.signedInUser), - // 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), - // ), - // ) - // ], - // ), - // ), - // ); - } -} diff --git a/Frontend/lib/mih_packages/patient_profile/patient_claims_statements.dart b/Frontend/lib/mih_packages/patient_profile/patient_claims_statements.dart deleted file mode 100644 index b168816e..00000000 --- a/Frontend/lib/mih_packages/patient_profile/patient_claims_statements.dart +++ /dev/null @@ -1,272 +0,0 @@ -import 'dart:async'; -import 'dart:convert'; - -import 'package:Mzansi_Innovation_Hub/mih_apis/mih_claim_statement_generation_api.dart'; -import 'package:Mzansi_Innovation_Hub/mih_objects/claim_statement_file.dart'; -import 'package:Mzansi_Innovation_Hub/mih_packages/patient_profile/Claim_Statement_Window.dart'; -import 'package:Mzansi_Innovation_Hub/mih_packages/patient_profile/builder/build_claim_statement_files_list.dart'; -import 'package:file_picker/file_picker.dart'; -import 'package:flutter/material.dart'; -import '../../main.dart'; -import 'package:supertokens_flutter/http.dart' as http; - -import '../../mih_components/mih_pop_up_messages/mih_error_message.dart'; -import '../../mih_components/mih_pop_up_messages/mih_loading_circle.dart'; -import '../../mih_components/mih_pop_up_messages/mih_success_message.dart'; -import '../../mih_env/env.dart'; -import '../../mih_objects/app_user.dart'; -import '../../mih_objects/business.dart'; -import '../../mih_objects/business_user.dart'; -import '../../mih_objects/files.dart'; -import '../../mih_objects/patients.dart'; -// import 'builder/build_files_list.dart'; - -class PatientClaimsOrStatements extends StatefulWidget { - final int patientIndex; - final Patient selectedPatient; - final AppUser signedInUser; - final Business? business; - final BusinessUser? businessUser; - final String type; - - const PatientClaimsOrStatements({ - super.key, - required this.patientIndex, - required this.selectedPatient, - required this.signedInUser, - required this.business, - required this.businessUser, - required this.type, - }); - - @override - State createState() => - _PatientClaimsOrStatementsState(); -} - -class _PatientClaimsOrStatementsState extends State { - String endpointFiles = "${AppEnviroment.baseApiUrl}/files/patients/"; - String endpointUser = "${AppEnviroment.baseApiUrl}/users/profile/"; - String endpointGenFiles = - "${AppEnviroment.baseApiUrl}/files/generate/med-cert/"; - String endpointFileUpload = "${AppEnviroment.baseApiUrl}/files/upload/file/"; - String endpointInsertFiles = "${AppEnviroment.baseApiUrl}/files/insert/"; - - final startDateController = TextEditingController(); - final endDateTextController = TextEditingController(); - final retDateTextController = TextEditingController(); - final selectedFileController = TextEditingController(); - final medicineController = TextEditingController(); - final quantityController = TextEditingController(); - final dosageController = TextEditingController(); - final timesDailyController = TextEditingController(); - final noDaysController = TextEditingController(); - final noRepeatsController = TextEditingController(); - final outputController = TextEditingController(); - - late Future> futueFiles; - late String userEmail = ""; - late PlatformFile selected; - final baseAPI = AppEnviroment.baseApiUrl; - - Future> fetchFiles() async { - final response = await http.get(Uri.parse( - "${AppEnviroment.baseApiUrl}/files/patients/${widget.selectedPatient.app_id}")); - - //print(response.statusCode); - //print(response.body); - if (response.statusCode == 200) { - Iterable l = jsonDecode(response.body); - List files = - List.from(l.map((model) => PFile.fromJson(model))); - return files; - } else { - internetConnectionPopUp(); - throw Exception('failed to load patients'); - } - } - - void successPopUp(String message) { - showDialog( - context: context, - builder: (context) { - return MIHSuccessMessage( - successType: "Success", - successMessage: message, - ); - }, - ); - } - - void messagePopUp(error) { - showDialog( - context: context, - builder: (context) { - return AlertDialog( - title: Text(error), - ); - }, - ); - } - - void claimOrStatementWindow() { - showDialog( - context: context, - barrierDismissible: false, - builder: (context) => ClaimStatementWindow( - selectedPatient: widget.selectedPatient, - signedInUser: widget.signedInUser, - business: widget.business, - businessUser: widget.businessUser, - ), - ); - } - - void internetConnectionPopUp() { - showDialog( - context: context, - builder: (context) { - return const MIHErrorMessage(errorType: "Internet Connection"); - }, - ); - } - - bool isMedCertFieldsFilled() { - if (startDateController.text.isEmpty || - endDateTextController.text.isEmpty || - retDateTextController.text.isEmpty) { - return false; - } else { - return true; - } - } - - bool isFileFieldsFilled() { - if (selectedFileController.text.isEmpty) { - return false; - } else { - return true; - } - } - - List setIcons() { - if (widget.type == "personal") { - return [ - Text( - "Claims/ Statements", - textAlign: TextAlign.center, - style: TextStyle( - fontSize: 25, - fontWeight: FontWeight.bold, - color: MzanziInnovationHub.of(context)!.theme.secondaryColor(), - ), - ), - // IconButton( - // onPressed: () { - // uploudFilePopUp(); - // }, - // icon: Icon( - // Icons.add, - // color: MzanziInnovationHub.of(context)!.theme.secondaryColor(), - // ), - // ) - ]; - } else { - return [ - Text( - "Claims/ Statements", - textAlign: TextAlign.center, - style: TextStyle( - fontSize: 25, - fontWeight: FontWeight.bold, - color: MzanziInnovationHub.of(context)!.theme.secondaryColor(), - ), - ), - IconButton( - onPressed: () { - // new window to input fields for claim/ statements - claimOrStatementWindow(); - }, - icon: Icon( - Icons.add, - color: MzanziInnovationHub.of(context)!.theme.secondaryColor(), - ), - ) - ]; - } - } - - @override - void dispose() { - startDateController.dispose(); - endDateTextController.dispose(); - retDateTextController.dispose(); - selectedFileController.dispose(); - medicineController.dispose(); - quantityController.dispose(); - dosageController.dispose(); - timesDailyController.dispose(); - noDaysController.dispose(); - noRepeatsController.dispose(); - outputController.dispose(); - super.dispose(); - } - - @override - void initState() { - if (widget.business == null) { - futueFiles = - MIHClaimStatementGenerationApi.getClaimStatementFilesByPatient( - widget.signedInUser.app_id); - } else { - futueFiles = - MIHClaimStatementGenerationApi.getClaimStatementFilesByBusiness( - widget.business!.business_id); - } - - //patientDetails = getPatientDetails() as Patient; - //getUserDetails(); - super.initState(); - } - - @override - Widget build(BuildContext context) { - return FutureBuilder( - future: futueFiles, - builder: (context, snapshot) { - if (snapshot.connectionState == ConnectionState.waiting) { - return const Center( - child: Mihloadingcircle(), - ); - } else if (snapshot.hasData) { - final filesList = snapshot.data!; - return Column( - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.center, - children: setIcons(), - ), - Divider( - color: - MzanziInnovationHub.of(context)!.theme.secondaryColor()), - const SizedBox(height: 10), - //const Placeholder(), - BuildClaimStatementFileList( - files: filesList, - signedInUser: widget.signedInUser, - selectedPatient: widget.selectedPatient, - business: widget.business, - businessUser: widget.businessUser, - type: widget.type, - ), - ], - ); - } else { - return const Center( - child: Text("Error Loading Notes"), - ); - } - }, - ); - } -} diff --git a/Frontend/lib/mih_packages/patient_profile/patient_details.dart b/Frontend/lib/mih_packages/patient_profile/patient_details.dart deleted file mode 100644 index 8772de95..00000000 --- a/Frontend/lib/mih_packages/patient_profile/patient_details.dart +++ /dev/null @@ -1,298 +0,0 @@ -import 'package:flutter/material.dart'; -import '../../main.dart'; -import '../../mih_components/mih_inputs_and_buttons/mih_text_input.dart'; -import '../../mih_objects/app_user.dart'; -import '../../mih_objects/arguments.dart'; -import '../../mih_objects/patients.dart'; - -class PatientDetails extends StatefulWidget { - final AppUser signedInUser; - final Patient selectedPatient; - final String type; - const PatientDetails({ - super.key, - required this.signedInUser, - required this.selectedPatient, - required this.type, - }); - - @override - State createState() => _PatientDetailsState(); -} - -class _PatientDetailsState extends State { - final idController = TextEditingController(); - final fnameController = TextEditingController(); - final lnameController = TextEditingController(); - final cellController = TextEditingController(); - final emailController = TextEditingController(); - final medNoController = TextEditingController(); - final medNameController = TextEditingController(); - final medSchemeController = TextEditingController(); - final addressController = TextEditingController(); - final medAidController = TextEditingController(); - final medMainMemController = TextEditingController(); - final medAidCodeController = TextEditingController(); - double? headingFontSize = 35.0; - double? bodyFonstSize = 20.0; - double textFieldWidth = 400.0; - late String medAid; - - Widget getPatientDetailsField() { - return Wrap( - spacing: 15, - runSpacing: 10, - children: [ - SizedBox( - width: textFieldWidth, - child: MIHTextField( - controller: idController, - hintText: "ID No.", - editable: false, - required: false), - ), - SizedBox( - width: textFieldWidth, - child: MIHTextField( - controller: fnameController, - hintText: "Name", - editable: false, - required: false), - ), - SizedBox( - width: textFieldWidth, - child: MIHTextField( - controller: lnameController, - hintText: "Surname", - editable: false, - required: false), - ), - SizedBox( - width: textFieldWidth, - child: MIHTextField( - controller: cellController, - hintText: "Cell No.", - editable: false, - required: false), - ), - SizedBox( - width: textFieldWidth, - child: MIHTextField( - controller: emailController, - hintText: "Email", - editable: false, - required: false), - ), - SizedBox( - width: textFieldWidth, - child: MIHTextField( - controller: addressController, - hintText: "Address", - editable: false, - required: false), - ), - ], - ); - } - - Widget getMedAidDetailsFields() { - List medAidDet = []; - medAidDet.add(SizedBox( - width: textFieldWidth, - child: MIHTextField( - controller: medAidController, - hintText: "Medical Aid", - editable: false, - required: false), - )); - bool req; - if (medAid == "Yes") { - req = true; - } else { - req = false; - } - medAidDet.addAll([ - Visibility( - visible: req, - child: SizedBox( - width: textFieldWidth, - child: MIHTextField( - controller: medMainMemController, - hintText: "Main Member", - editable: false, - required: false), - ), - ), - //const SizedBox(height: 10.0), - Visibility( - visible: req, - child: SizedBox( - width: textFieldWidth, - child: MIHTextField( - controller: medNoController, - hintText: "No.", - editable: false, - required: false), - ), - ), - //const SizedBox(height: 10.0), - Visibility( - visible: req, - child: SizedBox( - width: textFieldWidth, - child: MIHTextField( - controller: medAidCodeController, - hintText: "Code", - editable: false, - required: false), - ), - ), - //const SizedBox(height: 10.0), - Visibility( - visible: req, - child: SizedBox( - width: textFieldWidth, - child: MIHTextField( - controller: medNameController, - hintText: "Name", - editable: false, - required: false), - ), - ), - //const SizedBox(height: 10.0), - Visibility( - visible: req, - child: SizedBox( - width: textFieldWidth, - child: MIHTextField( - controller: medSchemeController, - hintText: "Scheme", - editable: false, - required: false), - ), - ), - //), - ]); - - return Wrap( - spacing: 10, - runSpacing: 10, - children: medAidDet, - ); - } - - List setIcons() { - if (widget.type == "personal") { - return [ - Text( - "Personal Details", - textAlign: TextAlign.center, - style: TextStyle( - fontSize: 25, - fontWeight: FontWeight.bold, - color: MzanziInnovationHub.of(context)!.theme.secondaryColor(), - ), - ), - IconButton( - icon: const Icon(Icons.edit), - alignment: Alignment.topRight, - color: MzanziInnovationHub.of(context)!.theme.secondaryColor(), - onPressed: () { - Navigator.of(context).pushNamed('/patient-profile/edit', - arguments: PatientEditArguments( - widget.signedInUser, widget.selectedPatient)); - }, - ) - ]; - } else { - return [ - Text( - "Patient Details", - textAlign: TextAlign.center, - style: TextStyle( - fontSize: 25, - fontWeight: FontWeight.bold, - color: MzanziInnovationHub.of(context)!.theme.secondaryColor(), - ), - ), - ]; - } - } - - @override - void dispose() { - idController.dispose(); - fnameController.dispose(); - lnameController.dispose(); - cellController.dispose(); - emailController.dispose(); - medNameController.dispose(); - medNoController.dispose(); - medSchemeController.dispose(); - addressController.dispose(); - medAidController.dispose(); - medMainMemController.dispose(); - medAidCodeController.dispose(); - super.dispose(); - } - - @override - void initState() { - setState(() { - idController.value = TextEditingValue(text: widget.selectedPatient.id_no); - fnameController.value = - TextEditingValue(text: widget.selectedPatient.first_name); - lnameController.value = - TextEditingValue(text: widget.selectedPatient.last_name); - cellController.value = - TextEditingValue(text: widget.selectedPatient.cell_no); - emailController.value = - TextEditingValue(text: widget.selectedPatient.email); - medNameController.value = - TextEditingValue(text: widget.selectedPatient.medical_aid_name); - medNoController.value = - TextEditingValue(text: widget.selectedPatient.medical_aid_no); - medSchemeController.value = - TextEditingValue(text: widget.selectedPatient.medical_aid_scheme); - addressController.value = - TextEditingValue(text: widget.selectedPatient.address); - medAidController.value = - TextEditingValue(text: widget.selectedPatient.medical_aid); - medMainMemController.value = TextEditingValue( - text: widget.selectedPatient.medical_aid_main_member); - medAidCodeController.value = - TextEditingValue(text: widget.selectedPatient.medical_aid_code); - medAid = widget.selectedPatient.medical_aid; - }); - super.initState(); - } - - @override - Widget build(BuildContext context) { - return Column( - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.center, - //crossAxisAlignment: , - children: setIcons(), - ), - Divider(color: MzanziInnovationHub.of(context)!.theme.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(), - ], - ); - } -} diff --git a/Frontend/lib/mih_packages/patient_profile/patient_edit.dart b/Frontend/lib/mih_packages/patient_profile/patient_edit.dart deleted file mode 100644 index f913721e..00000000 --- a/Frontend/lib/mih_packages/patient_profile/patient_edit.dart +++ /dev/null @@ -1,719 +0,0 @@ -import 'dart:convert'; - -import 'package:flutter/material.dart'; -import 'package:flutter/services.dart'; -import '../../main.dart'; -import 'package:supertokens_flutter/supertokens.dart'; -import 'package:supertokens_flutter/http.dart' as http; - -import '../../mih_components/mih_inputs_and_buttons/mih_button.dart'; -import '../../mih_components/mih_inputs_and_buttons/mih_dropdown_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'; -import '../../mih_components/mih_layout/mih_layout_builder.dart'; -import '../../mih_components/mih_pop_up_messages/mih_error_message.dart'; -import '../../mih_components/mih_pop_up_messages/mih_success_message.dart'; -import '../../mih_env/env.dart'; -import '../../mih_objects/app_user.dart'; -import '../../mih_objects/arguments.dart'; -import '../../mih_objects/patients.dart'; - -class EditPatient extends StatefulWidget { - final Patient selectedPatient; - final AppUser signedInUser; - const EditPatient({ - super.key, - required this.selectedPatient, - required this.signedInUser, - }); - - @override - State createState() => _EditPatientState(); -} - -class _EditPatientState extends State { - var idController = TextEditingController(); - final fnameController = TextEditingController(); - final lnameController = TextEditingController(); - final cellController = TextEditingController(); - final emailController = TextEditingController(); - final medNoController = TextEditingController(); - final medNameController = TextEditingController(); - final medSchemeController = TextEditingController(); - final addressController = TextEditingController(); - final medAidController = TextEditingController(); - final medMainMemController = TextEditingController(); - final medAidCodeController = TextEditingController(); - final baseAPI = AppEnviroment.baseApiUrl; - final docOfficeIdApiUrl = "${AppEnviroment.baseApiUrl}/users/profile/"; - final apiUrlEdit = "${AppEnviroment.baseApiUrl}/patients/update/"; - final apiUrlDelete = "${AppEnviroment.baseApiUrl}/patients/delete/"; - - late int futureDocOfficeId; - late String userEmail; - // bool medRequired = false; - final ValueNotifier medRequired = ValueNotifier(false); - - late double width; - late double height; - - final FocusNode _focusNode = FocusNode(); - - // Future getOfficeIdByUser(String endpoint) async { - // final response = await http.get(Uri.parse(endpoint)); - // if (response.statusCode == 200) { - // String body = response.body; - // var decodedData = jsonDecode(body); - // AppUser u = AppUser.fromJson(decodedData as Map); - // setState(() { - // //futureDocOfficeId = u.docOffice_id; - // //print(futureDocOfficeId); - // }); - // } else { - // internetConnectionPopUp(); - // throw Exception('failed to load patients'); - // } - // } - - Future updatePatientApiCall() async { - //print("Here1"); - //userEmail = getLoginUserEmail() as String; - //print(userEmail); - //print("Here2"); - //await getOfficeIdByUser(docOfficeIdApiUrl + userEmail); - //print(futureDocOfficeId.toString()); - //print("Here3"); - var response = await http.put( - Uri.parse(apiUrlEdit), - headers: { - "Content-Type": "application/json; charset=UTF-8" - }, - body: jsonEncode({ - "id_no": idController.text, - "first_name": fnameController.text, - "last_name": lnameController.text, - "email": emailController.text, - "cell_no": cellController.text, - "medical_aid": medAidController.text, - "medical_aid_main_member": medMainMemController.text, - "medical_aid_no": medNoController.text, - "medical_aid_code": medAidCodeController.text, - "medical_aid_name": medNameController.text, - "medical_aid_scheme": medSchemeController.text, - "address": addressController.text, - "app_id": widget.selectedPatient.app_id, - }), - ); - // print("Here4"); - // print(response.statusCode); - if (response.statusCode == 200) { - Navigator.of(context).pop(); - Navigator.of(context).pop(); - Navigator.of(context).pushNamed('/patient-profile', - arguments: PatientViewArguments( - widget.signedInUser, null, null, null, "personal")); - //Navigator.of(context).pushNamed('/'); - String message = - "${fnameController.text} ${lnameController.text}'s information has been updated successfully! Their medical records and details are now current."; - successPopUp(message); - } else { - internetConnectionPopUp(); - } - } - - Future deletePatientApiCall() async { - //print("Here1"); - //userEmail = getLoginUserEmail() as String; - //print(userEmail); - //print("Here2"); - //await getOfficeIdByUser(docOfficeIdApiUrl + userEmail); - //print("Office ID: ${futureDocOfficeId.toString()}"); - //print("OPatient ID No: ${idController.text}"); - //print("Here3"); - var response = await http.delete( - Uri.parse(apiUrlDelete), - headers: { - "Content-Type": "application/json; charset=UTF-8" - }, - body: jsonEncode( - {"app_id": widget.selectedPatient.app_id}), - ); - //print("Here4"); - //print(response.statusCode); - if (response.statusCode == 200) { - Navigator.of(context).pop(); - Navigator.of(context).pop(); - Navigator.of(context).popAndPushNamed('/patient-profile', - arguments: PatientViewArguments( - widget.signedInUser, null, null, null, "personal")); - String message = - "${fnameController.text} ${lnameController.text}'s record has been deleted successfully. This means it will no longer be visible in patient manager and cannot be used for future appointments."; - successPopUp(message); - } else { - internetConnectionPopUp(); - } - } - - Future getLoginUserEmail() async { - var uid = await SuperTokens.getUserId(); - var response = await http.get(Uri.parse("$baseAPI/user/$uid")); - if (response.statusCode == 200) { - var user = jsonDecode(response.body); - userEmail = user["email"]; - } - } - - void messagePopUp(error) { - showDialog( - context: context, - builder: (context) { - return AlertDialog( - title: Text(error), - ); - }, - ); - } - - void internetConnectionPopUp() { - showDialog( - context: context, - builder: (context) { - return const MIHErrorMessage(errorType: "Internet Connection"); - }, - ); - } - - void deletePatientPopUp() { - showDialog( - context: context, - barrierDismissible: false, - builder: (context) => Dialog( - child: Stack( - children: [ - Container( - padding: const EdgeInsets.all(10.0), - width: 700.0, - height: (height / 3) * 2, - decoration: BoxDecoration( - color: MzanziInnovationHub.of(context)!.theme.primaryColor(), - borderRadius: BorderRadius.circular(25.0), - border: Border.all( - color: - MzanziInnovationHub.of(context)!.theme.secondaryColor(), - width: 5.0), - ), - child: SingleChildScrollView( - child: Column( - //mainAxisSize: MainAxisSize.max, - children: [ - Icon( - Icons.warning_amber_rounded, - size: 100, - color: MzanziInnovationHub.of(context)! - .theme - .secondaryColor(), - ), - const SizedBox(height: 15), - Text( - "Are you sure you want to delete this?", - textAlign: TextAlign.center, - style: TextStyle( - color: MzanziInnovationHub.of(context)! - .theme - .secondaryColor(), - fontSize: 25.0, - fontWeight: FontWeight.bold, - ), - ), - const SizedBox(height: 10), - Padding( - padding: const EdgeInsets.symmetric(horizontal: 25.0), - child: Text( - "This action is permanent! Deleting ${fnameController.text} ${lnameController.text} will remove him\\her from your account. You won't be able to recover it once it's gone.", - style: TextStyle( - color: MzanziInnovationHub.of(context)! - .theme - .secondaryColor(), - fontSize: 15.0, - fontWeight: FontWeight.bold, - ), - ), - ), - const SizedBox(height: 15), - Padding( - padding: const EdgeInsets.symmetric(horizontal: 25.0), - child: Text( - "Here's what you'll be deleting:", - style: TextStyle( - color: MzanziInnovationHub.of(context)! - .theme - .secondaryColor(), - fontSize: 20.0, - fontWeight: FontWeight.bold, - ), - ), - ), - const SizedBox(height: 10), - Padding( - padding: const EdgeInsets.symmetric(horizontal: 25.0), - child: SizedBox( - width: 450, - child: Text( - "1) Patient Profile Information.\n2) Patient Notes\n3) Patient Files.", - textAlign: TextAlign.left, - style: TextStyle( - color: MzanziInnovationHub.of(context)! - .theme - .secondaryColor(), - fontSize: 15.0, - fontWeight: FontWeight.bold, - ), - ), - ), - ), - SizedBox( - width: 300, - height: 50, - child: MIHButton( - onTap: deletePatientApiCall, - buttonText: "Delete", - buttonColor: MzanziInnovationHub.of(context)! - .theme - .secondaryColor(), - textColor: MzanziInnovationHub.of(context)! - .theme - .primaryColor(), - )) - ], - ), - ), - ), - Positioned( - top: 5, - right: 5, - width: 50, - height: 50, - child: IconButton( - onPressed: () { - Navigator.pop(context); - }, - icon: Icon( - Icons.close, - color: MzanziInnovationHub.of(context)!.theme.errorColor(), - size: 35, - ), - ), - ), - ], - ), - ), - ); - } - - void successPopUp(String message) { - showDialog( - context: context, - builder: (context) { - return MIHSuccessMessage( - successType: "Success", - successMessage: message, - ); - }, - ); - } - - bool isFieldsFilled() { - if (medRequired.value) { - if (idController.text.isEmpty || - fnameController.text.isEmpty || - lnameController.text.isEmpty || - cellController.text.isEmpty || - emailController.text.isEmpty || - medNoController.text.isEmpty || - medNameController.text.isEmpty || - medSchemeController.text.isEmpty || - addressController.text.isEmpty || - medAidController.text.isEmpty || - medMainMemController.text.isEmpty || - medAidCodeController.text.isEmpty) { - return false; - } else { - return true; - } - } else { - if (idController.text.isEmpty || - fnameController.text.isEmpty || - lnameController.text.isEmpty || - cellController.text.isEmpty || - emailController.text.isEmpty || - addressController.text.isEmpty || - medAidController.text.isEmpty) { - return false; - } else { - return true; - } - } - } - - void isRequired() { - print("listerner triggered"); - if (medAidController.text == "Yes") { - medRequired.value = true; - } else if (medAidController.text == "No") { - medRequired.value = false; - } else { - //print("here"); - } - } - - Widget displayForm() { - return SingleChildScrollView( - child: Column( - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Text( - "Personal Details", - textAlign: TextAlign.center, - style: TextStyle( - fontWeight: FontWeight.bold, - fontSize: 22.0, - color: - MzanziInnovationHub.of(context)!.theme.secondaryColor(), - ), - ), - IconButton( - icon: const Icon(Icons.delete), - color: MzanziInnovationHub.of(context)!.theme.secondaryColor(), - //alignment: Alignment.topRight, - onPressed: () { - deletePatientPopUp(); - }, - ), - ], - ), - 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 Scheme", - editable: value, - required: value, - ), - ], - ), - ); - }, - ), - const SizedBox(height: 30.0), - SizedBox( - width: 500.0, - height: 50.0, - child: MIHButton( - onTap: () { - submitForm(); - }, - buttonText: "Update", - buttonColor: - MzanziInnovationHub.of(context)!.theme.secondaryColor(), - textColor: MzanziInnovationHub.of(context)!.theme.primaryColor(), - ), - ), - ], - ), - ); - } - - 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"); - }, - ); - } - } - - MIHAction getActionButton() { - return MIHAction( - icon: const Icon(Icons.arrow_back), - iconSize: 35, - onTap: () { - Navigator.of(context).pop(); - }, - ); - } - - MIHHeader getHeader() { - return const MIHHeader( - headerAlignment: MainAxisAlignment.center, - headerItems: [ - Text( - "Edit Patient Details", - style: TextStyle( - fontWeight: FontWeight.bold, - fontSize: 25, - ), - ), - ], - ); - } - - MIHBody getBody() { - return MIHBody( - borderOn: true, - bodyItems: [ - KeyboardListener( - focusNode: _focusNode, - autofocus: true, - onKeyEvent: (event) async { - if (event is KeyDownEvent && - event.logicalKey == LogicalKeyboardKey.enter) { - submitForm(); - } - }, - child: displayForm(), - ), - ], - ); - } - - @override - void dispose() { - idController.dispose(); - fnameController.dispose(); - lnameController.dispose(); - cellController.dispose(); - emailController.dispose(); - medNoController.dispose(); - medNameController.dispose(); - medSchemeController.dispose(); - addressController.dispose(); - medAidController.dispose(); - medAidCodeController.removeListener(isRequired); - medMainMemController.dispose(); - medAidCodeController.dispose(); - medRequired.dispose(); - _focusNode.dispose(); - super.dispose(); - } - - @override - void initState() { - getLoginUserEmail(); - medAidController.addListener(isRequired); - setState(() { - idController.text = widget.selectedPatient.id_no; - fnameController.text = widget.selectedPatient.first_name; - lnameController.text = widget.selectedPatient.last_name; - cellController.text = widget.selectedPatient.cell_no; - emailController.text = widget.selectedPatient.email; - medNameController.text = widget.selectedPatient.medical_aid_name; - medNoController.text = widget.selectedPatient.medical_aid_no; - medSchemeController.text = widget.selectedPatient.medical_aid_scheme; - addressController.text = widget.selectedPatient.address; - medAidController.text = widget.selectedPatient.medical_aid; - medMainMemController.text = - widget.selectedPatient.medical_aid_main_member; - medAidCodeController.text = widget.selectedPatient.medical_aid_code; - }); - - super.initState(); - } - - @override - Widget build(BuildContext context) { - var size = MediaQuery.of(context).size; - setState(() { - width = size.width; - height = size.height; - }); - return MIHLayoutBuilder( - actionButton: getActionButton(), - header: getHeader(), - secondaryActionButton: null, - body: getBody(), - 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(); - // }, - // )) - // ], - // ), - // ), - // ); - } -} diff --git a/Frontend/lib/mih_packages/patient_profile/patient_files.dart b/Frontend/lib/mih_packages/patient_profile/patient_files.dart deleted file mode 100644 index 32b93acf..00000000 --- a/Frontend/lib/mih_packages/patient_profile/patient_files.dart +++ /dev/null @@ -1,543 +0,0 @@ -import 'dart:async'; -import 'dart:convert'; - -import 'package:file_picker/file_picker.dart'; -import 'package:flutter/material.dart'; -import '../../main.dart'; -import 'package:supertokens_flutter/http.dart' as http; -import 'package:http/http.dart' as http2; -import 'package:supertokens_flutter/supertokens.dart'; - -import '../../mih_components/med_cert_input.dart'; -import '../../mih_components/mih_inputs_and_buttons/mih_button.dart'; -import '../../mih_components/mih_inputs_and_buttons/mih_file_input.dart'; -import '../../mih_components/mih_layout/mih_window.dart'; -import '../../mih_components/mih_pop_up_messages/mih_error_message.dart'; -import '../../mih_components/mih_pop_up_messages/mih_loading_circle.dart'; -import '../../mih_components/mih_pop_up_messages/mih_success_message.dart'; -import '../../mih_env/env.dart'; -import '../../mih_objects/app_user.dart'; -import '../../mih_objects/business.dart'; -import '../../mih_objects/business_user.dart'; -import '../../mih_objects/files.dart'; -import '../../mih_objects/patients.dart'; -import 'builder/build_files_list.dart'; -import 'prescip_input.dart'; - -class PatientFiles extends StatefulWidget { - final int patientIndex; - final Patient selectedPatient; - final AppUser signedInUser; - final Business? business; - final BusinessUser? businessUser; - final String type; - - const PatientFiles({ - super.key, - required this.patientIndex, - required this.selectedPatient, - required this.signedInUser, - required this.business, - required this.businessUser, - required this.type, - }); - - @override - State createState() => _PatientFilesState(); -} - -class _PatientFilesState extends State { - String endpointFiles = "${AppEnviroment.baseApiUrl}/files/patients/"; - String endpointUser = "${AppEnviroment.baseApiUrl}/users/profile/"; - String endpointGenFiles = - "${AppEnviroment.baseApiUrl}/files/generate/med-cert/"; - String endpointFileUpload = "${AppEnviroment.baseApiUrl}/files/upload/file/"; - String endpointInsertFiles = "${AppEnviroment.baseApiUrl}/files/insert/"; - - final startDateController = TextEditingController(); - final endDateTextController = TextEditingController(); - final retDateTextController = TextEditingController(); - final selectedFileController = TextEditingController(); - final medicineController = TextEditingController(); - final quantityController = TextEditingController(); - final dosageController = TextEditingController(); - final timesDailyController = TextEditingController(); - final noDaysController = TextEditingController(); - final noRepeatsController = TextEditingController(); - final outputController = TextEditingController(); - - late Future> futueFiles; - late String userEmail = ""; - late PlatformFile selected; - final baseAPI = AppEnviroment.baseApiUrl; - - Future generateMedCert() async { - //start loading circle - showDialog( - context: context, - builder: (context) { - return const Mihloadingcircle(); - }, - ); - - var response1 = await http.post( - Uri.parse("${AppEnviroment.baseApiUrl}/minio/generate/med-cert/"), - headers: { - "Content-Type": "application/json; charset=UTF-8" - }, - body: jsonEncode({ - "app_id": widget.selectedPatient.app_id, - "fullName": - "${widget.selectedPatient.first_name} ${widget.selectedPatient.last_name}", - "id_no": widget.selectedPatient.id_no, - "docfname": - "DR. ${widget.signedInUser.fname} ${widget.signedInUser.lname}", - "startDate": startDateController.text, - "busName": widget.business!.Name, - "busAddr": "*TO BE ADDED IN THE FUTURE*", - "busNo": widget.business!.contact_no, - "busEmail": widget.business!.bus_email, - "endDate": endDateTextController.text, - "returnDate": retDateTextController.text, - "logo_path": widget.business!.logo_path, - "sig_path": widget.businessUser!.sig_path, - }), - ); - //print(response1.statusCode); - DateTime now = new DateTime.now(); - DateTime date = new DateTime(now.year, now.month, now.day); - String fileName = - "Med-Cert-${widget.selectedPatient.first_name} ${widget.selectedPatient.last_name}-${date.toString().substring(0, 10)}.pdf"; - if (response1.statusCode == 200) { - var response2 = await http.post( - Uri.parse("${AppEnviroment.baseApiUrl}/files/insert/"), - headers: { - "Content-Type": "application/json; charset=UTF-8" - }, - body: jsonEncode({ - "file_path": - "${widget.selectedPatient.app_id}/patient_files/$fileName", - "file_name": fileName, - "app_id": widget.selectedPatient.app_id - }), - ); - //print(response2.statusCode); - if (response2.statusCode == 201) { - setState(() { - startDateController.clear(); - endDateTextController.clear(); - retDateTextController.clear(); - futueFiles = fetchFiles(); - }); - // end loading circle - Navigator.of(context).pop(); - Navigator.of(context).pop(); - String message = - "The medical certificate $fileName has been successfully generated and added to ${widget.selectedPatient.first_name} ${widget.selectedPatient.last_name}'s record. You can now access and download it for their use."; - successPopUp(message); - } else { - internetConnectionPopUp(); - } - } else { - internetConnectionPopUp(); - } - } - - Future uploadSelectedFile(PlatformFile file) async { - //var strem = new http.ByteStream.fromBytes(file.bytes.) - //start loading circle - showDialog( - context: context, - builder: (context) { - return const Mihloadingcircle(); - }, - ); - - var token = await SuperTokens.getAccessToken(); - //print(t); - //print("here1"); - var request = http2.MultipartRequest( - 'POST', Uri.parse("${AppEnviroment.baseApiUrl}/minio/upload/file/")); - request.headers['accept'] = 'application/json'; - request.headers['Authorization'] = 'Bearer $token'; - request.headers['Content-Type'] = 'multipart/form-data'; - request.fields['app_id'] = widget.selectedPatient.app_id; - request.fields['folder'] = "patient_files"; - request.files.add(await http2.MultipartFile.fromBytes('file', file.bytes!, - filename: file.name.replaceAll(RegExp(r' '), '-'))); - //print("here2"); - var response1 = await request.send(); - //print("here3"); - //print(response1.statusCode); - //print(response1.toString()); - if (response1.statusCode == 200) { - //print("here3"); - var fname = file.name.replaceAll(RegExp(r' '), '-'); - var filePath = "${widget.selectedPatient.app_id}/patient_files/$fname"; - var response2 = await http.post( - Uri.parse("${AppEnviroment.baseApiUrl}/files/insert/"), - headers: { - "Content-Type": "application/json; charset=UTF-8" - }, - body: jsonEncode({ - "file_path": filePath, - "file_name": fname, - "app_id": widget.selectedPatient.app_id - }), - ); - //print("here5"); - //print(response2.statusCode); - if (response2.statusCode == 201) { - setState(() { - selectedFileController.clear(); - futueFiles = fetchFiles(); - }); - // end loading circle - Navigator.of(context).pop(); - String message = - "The file ${file.name.replaceAll(RegExp(r' '), '-')} has been successfully generated and added to ${widget.selectedPatient.first_name} ${widget.selectedPatient.last_name}'s record. You can now access and download it for their use."; - successPopUp(message); - } else { - internetConnectionPopUp(); - } - } else { - internetConnectionPopUp(); - } - } - - Future> fetchFiles() async { - final response = await http.get(Uri.parse( - "${AppEnviroment.baseApiUrl}/files/patients/${widget.selectedPatient.app_id}")); - - //print(response.statusCode); - //print(response.body); - if (response.statusCode == 200) { - Iterable l = jsonDecode(response.body); - List files = - List.from(l.map((model) => PFile.fromJson(model))); - return files; - } else { - internetConnectionPopUp(); - throw Exception('failed to load patients'); - } - } - - void successPopUp(String message) { - showDialog( - context: context, - builder: (context) { - return MIHSuccessMessage( - successType: "Success", - successMessage: message, - ); - }, - ); - } - - void messagePopUp(error) { - showDialog( - context: context, - builder: (context) { - return AlertDialog( - title: Text(error), - ); - }, - ); - } - - void medCertPopUp() { - showDialog( - context: context, - barrierDismissible: false, - builder: (context) => MIHWindow( - fullscreen: false, - windowTitle: "Create Medical Certificate", - windowTools: const [], - onWindowTapClose: () { - Navigator.pop(context); - }, - windowBody: [ - Medcertinput( - startDateController: startDateController, - endDateTextController: endDateTextController, - retDateTextController: retDateTextController, - ), - const SizedBox(height: 15.0), - SizedBox( - width: 300, - height: 50, - child: MIHButton( - buttonText: "Generate", - buttonColor: - MzanziInnovationHub.of(context)!.theme.secondaryColor(), - textColor: MzanziInnovationHub.of(context)!.theme.primaryColor(), - onTap: () async { - if (isMedCertFieldsFilled()) { - await generateMedCert(); - //Navigator.pop(context); - } else { - showDialog( - context: context, - builder: (context) { - return const MIHErrorMessage(errorType: "Input Error"); - }, - ); - } - }, - ), - ) - ], - ), - ); - } - - void prescritionPopUp() { - showDialog( - context: context, - barrierDismissible: false, - builder: (context) => MIHWindow( - fullscreen: false, - windowTitle: "Create Prescription", - windowTools: const [], - onWindowTapClose: () { - medicineController.clear(); - quantityController.clear(); - dosageController.clear(); - timesDailyController.clear(); - noDaysController.clear(); - noRepeatsController.clear(); - Navigator.pop(context); - }, - windowBody: [ - PrescripInput( - medicineController: medicineController, - quantityController: quantityController, - dosageController: dosageController, - timesDailyController: timesDailyController, - noDaysController: noDaysController, - noRepeatsController: noRepeatsController, - outputController: outputController, - selectedPatient: widget.selectedPatient, - signedInUser: widget.signedInUser, - business: widget.business, - businessUser: widget.businessUser, - ), - ], - ), - ); - } - - void uploudFilePopUp() { - showDialog( - context: context, - barrierDismissible: false, - builder: (context) => MIHWindow( - fullscreen: false, - windowTitle: "Upload File", - windowTools: const [], - onWindowTapClose: () { - Navigator.pop(context); - }, - windowBody: [ - MIHFileField( - controller: selectedFileController, - hintText: "Select File", - 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(() { - selected = selectedFile; - }); - - setState(() { - selectedFileController.text = selectedFile.name; - }); - }, - ), - const SizedBox(height: 15), - SizedBox( - width: 300, - height: 50, - child: MIHButton( - buttonText: "Add File", - buttonColor: - MzanziInnovationHub.of(context)!.theme.secondaryColor(), - textColor: MzanziInnovationHub.of(context)!.theme.primaryColor(), - onTap: () { - if (isFileFieldsFilled()) { - uploadSelectedFile(selected); - Navigator.pop(context); - } else { - showDialog( - context: context, - builder: (context) { - return const MIHErrorMessage(errorType: "Input Error"); - }, - ); - } - }, - ), - ) - ], - ), - ); - } - - void internetConnectionPopUp() { - showDialog( - context: context, - builder: (context) { - return const MIHErrorMessage(errorType: "Internet Connection"); - }, - ); - } - - bool isMedCertFieldsFilled() { - if (startDateController.text.isEmpty || - endDateTextController.text.isEmpty || - retDateTextController.text.isEmpty) { - return false; - } else { - return true; - } - } - - bool isFileFieldsFilled() { - if (selectedFileController.text.isEmpty) { - return false; - } else { - return true; - } - } - - List setIcons() { - if (widget.type == "personal") { - return [ - Text( - "Documents", - textAlign: TextAlign.center, - style: TextStyle( - fontSize: 25, - fontWeight: FontWeight.bold, - color: MzanziInnovationHub.of(context)!.theme.secondaryColor(), - ), - ), - IconButton( - onPressed: () { - uploudFilePopUp(); - }, - icon: Icon( - Icons.add, - color: MzanziInnovationHub.of(context)!.theme.secondaryColor(), - ), - ) - ]; - } else { - return [ - Text( - "Documents", - textAlign: TextAlign.center, - style: TextStyle( - fontSize: 25, - fontWeight: FontWeight.bold, - color: MzanziInnovationHub.of(context)!.theme.secondaryColor(), - ), - ), - IconButton( - onPressed: () { - medCertPopUp(); - }, - icon: Icon( - Icons.sick_outlined, - color: MzanziInnovationHub.of(context)!.theme.secondaryColor(), - ), - ), - IconButton( - onPressed: () { - prescritionPopUp(); - }, - icon: Icon( - Icons.medication_outlined, - color: MzanziInnovationHub.of(context)!.theme.secondaryColor(), - ), - ), - IconButton( - onPressed: () { - uploudFilePopUp(); - }, - icon: Icon( - Icons.add, - color: MzanziInnovationHub.of(context)!.theme.secondaryColor(), - ), - ) - ]; - } - } - - @override - void dispose() { - startDateController.dispose(); - endDateTextController.dispose(); - retDateTextController.dispose(); - selectedFileController.dispose(); - medicineController.dispose(); - quantityController.dispose(); - dosageController.dispose(); - timesDailyController.dispose(); - noDaysController.dispose(); - noRepeatsController.dispose(); - outputController.dispose(); - super.dispose(); - } - - @override - void initState() { - futueFiles = fetchFiles(); - //patientDetails = getPatientDetails() as Patient; - //getUserDetails(); - super.initState(); - } - - @override - Widget build(BuildContext context) { - return FutureBuilder( - future: futueFiles, - builder: (context, snapshot) { - if (snapshot.connectionState == ConnectionState.waiting) { - return const Center( - child: Mihloadingcircle(), - ); - } else if (snapshot.hasData) { - final filesList = snapshot.data!; - return Column(children: [ - Row( - mainAxisAlignment: MainAxisAlignment.center, - children: setIcons(), - ), - Divider( - color: MzanziInnovationHub.of(context)!.theme.secondaryColor()), - const SizedBox(height: 10), - BuildFilesList( - files: filesList, - signedInUser: widget.signedInUser, - selectedPatient: widget.selectedPatient, - business: widget.business, - businessUser: widget.businessUser, - type: widget.type, - ), - ]); - } else { - return const Center( - child: Text("Error Loading Notes"), - ); - } - }, - ); - } -} diff --git a/Frontend/lib/mih_packages/patient_profile/patient_manager.dart b/Frontend/lib/mih_packages/patient_profile/patient_manager.dart deleted file mode 100644 index 3ab8b7c9..00000000 --- a/Frontend/lib/mih_packages/patient_profile/patient_manager.dart +++ /dev/null @@ -1,734 +0,0 @@ -import 'dart:async'; -import 'package:flutter_swipe_detector/flutter_swipe_detector.dart'; -import 'package:intl/intl.dart'; - -import 'package:flutter/material.dart'; -import 'package:flutter/services.dart'; -import '../../main.dart'; -import '../../mih_apis/mih_api_calls.dart'; -import '../../mih_components/mih_calendar.dart'; -import '../../mih_components/mih_inputs_and_buttons/mih_search_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'; -import '../../mih_components/mih_layout/mih_layout_builder.dart'; -import '../../mih_components/mih_pop_up_messages/mih_loading_circle.dart'; -import '../../mih_env/env.dart'; -import '../../mih_objects/arguments.dart'; -import '../../mih_objects/patient_access.dart'; -import '../../mih_objects/patient_queue.dart'; -import '../../mih_objects/patients.dart'; -import 'builder/build_patient_access_list.dart'; -import 'builder/build_patient_list.dart'; -import 'builder/build_patient_queue_list.dart'; - -class PatientManager extends StatefulWidget { - //final AppUser signedInUser; - final BusinessArguments arguments; - const PatientManager({ - super.key, - required this.arguments, - }); - - @override - State createState() => _PatientManagerState(); -} - -// -class _PatientManagerState extends State { - TextEditingController searchController = TextEditingController(); - TextEditingController accessSearchController = TextEditingController(); - TextEditingController queueDateController = TextEditingController(); - - String baseUrl = AppEnviroment.baseApiUrl; - - final FocusNode _focusNode = FocusNode(); - - String searchString = ""; - String accessSearchString = ""; - var now = DateTime.now(); - var formatter = DateFormat('yyyy-MM-dd'); - late String formattedDate; - bool start = true; - int _selectedIndex = 0; - - late Future> patientSearchResults; - late Future> patientAccessResults; - late Future> patientQueueResults; - - //Waiting Room Widgets/ Functions - List filterQueueResults( - List queueList, String query) { - List templist = []; - //print(query); - for (var item in queueList) { - if (item.date_time.contains(query)) { - //print(item.medical_aid_no); - templist.add(item); - } - } - //print(templist); - return templist; - } - - Widget displayQueueList(List patientQueueList) { - if (patientQueueList.isNotEmpty) { - return Expanded( - child: BuildPatientQueueList( - patientQueue: patientQueueList, - signedInUser: widget.arguments.signedInUser, - business: widget.arguments.business, - businessUser: widget.arguments.businessUser, - ), - ); - } - return Padding( - padding: const EdgeInsets.only(top: 35.0), - child: Center( - child: Text( - "No Appointments for $formattedDate", - style: TextStyle( - fontSize: 25, - color: MzanziInnovationHub.of(context)!.theme.messageTextColor()), - textAlign: TextAlign.center, - ), - ), - ); - } - - Widget patientQueue() { - return Container( - child: Stack( - children: [ - Column( - mainAxisSize: MainAxisSize.max, - children: [ - //const SizedBox(height: 15), - Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - const Text( - "Waiting Room", - style: TextStyle(fontSize: 25, fontWeight: FontWeight.bold), - ), - IconButton( - iconSize: 20, - icon: const Icon( - Icons.refresh, - ), - onPressed: () { - refreshQueue(); - }, - ), - ], - ), - // Divider( - // color: MzanziInnovationHub.of(context)!.theme.secondaryColor()), - MIHCalendar( - calendarWidth: 500, - rowHeight: 35, - setDate: (value) { - setState(() { - queueDateController.text = value; - }); - }), - //spacer - Row( - mainAxisSize: MainAxisSize.max, - children: [ - FutureBuilder( - future: patientQueueResults, - builder: (context, snapshot) { - //print("patient Queue List ${snapshot.hasData}"); - if (snapshot.connectionState == ConnectionState.waiting) { - return const Mihloadingcircle(); - } else if (snapshot.connectionState == - ConnectionState.done) { - List patientQueueList; - // if (searchString == "") { - // patientQueueList = []; - // } else { - patientQueueList = filterQueueResults( - snapshot.requireData, queueDateController.text); - // print(patientQueueList); - // } - - return displayQueueList(patientQueueList); - } else { - return Center( - child: Text( - "Error pulling Patients Data\n$baseUrl/patients/search/$searchString", - style: TextStyle( - fontSize: 25, - color: MzanziInnovationHub.of(context)! - .theme - .errorColor()), - textAlign: TextAlign.center, - ), - ); - } - }, - ), - ], - ), - ], - ), - Positioned( - right: 0, - bottom: 0, - child: Container( - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(50), - color: - MzanziInnovationHub.of(context)!.theme.secondaryColor(), - ), - child: IconButton( - color: MzanziInnovationHub.of(context)!.theme.primaryColor(), - onPressed: () { - // addAppointmentWindow(); - }, - icon: const Icon( - Icons.add, - size: 50, - ), - ), - )) - ], - ), - ); - } - - void refreshQueue() { - setState(() { - start = true; - }); - checkforchange(); - } - - void refreshAccessList() { - setState(() { - patientAccessResults = MIHApiCalls.getPatientAccessListOfBusiness( - widget.arguments.business!.business_id); - }); - } - - void checkforchange() { - if (start == true) { - setState(() { - patientQueueResults = MIHApiCalls.fetchBusinessAppointmentsAPICall( - queueDateController.text, widget.arguments.business!.business_id); - start = false; - }); - } - if (formattedDate != queueDateController.text) { - setState(() { - patientQueueResults = MIHApiCalls.fetchBusinessAppointmentsAPICall( - queueDateController.text, widget.arguments.business!.business_id); - formattedDate = queueDateController.text; - }); - } - } - - //Patient Lookup Widgets/ Functions - - List filterSearchResults(List patList, String query) { - List templist = []; - //print(query); - for (var item in patList) { - if (item.id_no.contains(searchString) || - item.medical_aid_no.contains(searchString)) { - //print(item.medical_aid_no); - templist.add(item); - } - } - return templist; - } - - Widget displayPatientList(List patientsList, String searchString) { - if (patientsList.isNotEmpty) { - return BuildPatientsList( - patients: patientsList, - signedInUser: widget.arguments.signedInUser, - business: widget.arguments.business, - arguments: widget.arguments, - ); - } else if (patientsList.isEmpty && searchString != "") { - return Padding( - padding: const EdgeInsets.only(top: 35.0), - child: Center( - child: Text( - "No ID or Medical Aid No. matches a Patient", - style: TextStyle( - fontSize: 25, - color: - MzanziInnovationHub.of(context)!.theme.messageTextColor()), - textAlign: TextAlign.center, - ), - ), - ); - } else { - return Padding( - padding: const EdgeInsets.only(top: 35.0), - child: Center( - child: Text( - "Enter ID or Medical Aid No. of Patient", - style: TextStyle( - fontSize: 25, - color: - MzanziInnovationHub.of(context)!.theme.messageTextColor()), - textAlign: TextAlign.center, - ), - ), - ); - } - } - - Widget patientSearch() { - return KeyboardListener( - focusNode: _focusNode, - autofocus: true, - onKeyEvent: (event) async { - if (event is KeyDownEvent && - event.logicalKey == LogicalKeyboardKey.enter) { - submitPatientForm(); - } - }, - child: Column(mainAxisSize: MainAxisSize.max, children: [ - const Text( - "Patient Lookup", - style: TextStyle(fontSize: 25, fontWeight: FontWeight.bold), - ), - Divider(color: MzanziInnovationHub.of(context)!.theme.secondaryColor()), - //spacer - const SizedBox(height: 10), - Row( - mainAxisSize: MainAxisSize.min, - children: [ - Flexible( - flex: 1, - child: MIHSearchField( - controller: searchController, - hintText: "ID or Medical Aid No. Search", - required: false, - editable: true, - onTap: () { - submitPatientForm(); - }, - ), - ), - IconButton( - onPressed: () { - setState(() { - searchController.clear(); - searchString = ""; - }); - submitPatientForm(); - }, - icon: const Icon( - Icons.filter_alt_off, - size: 25, - )) - ], - ), - //spacer - const SizedBox(height: 10), - FutureBuilder( - future: patientSearchResults, - builder: (context, snapshot) { - //print("patient Liust ${snapshot.data}"); - if (snapshot.connectionState == ConnectionState.waiting) { - return const Mihloadingcircle(); - } else if (snapshot.connectionState == ConnectionState.done && - snapshot.hasData) { - List patientsList; - if (searchString == "") { - patientsList = []; - } else { - patientsList = - filterSearchResults(snapshot.data!, searchString); - //print(patientsList); - } - return displayPatientList(patientsList, searchString); - } else { - return Center( - child: Text( - "Error pulling Patients Data\n$baseUrl/patients/search/$searchString", - style: TextStyle( - fontSize: 25, - color: - MzanziInnovationHub.of(context)!.theme.errorColor()), - textAlign: TextAlign.center, - ), - ); - } - }, - ), - ]), - ); - } - - void submitPatientForm() { - if (searchController.text != "") { - setState(() { - searchString = searchController.text; - patientSearchResults = MIHApiCalls.fetchPatients(searchString); - }); - } - // else { - // showDialog( - // context: context, - // builder: (context) { - // return const MIHErrorMessage(errorType: "Input Error"); - // }, - // ); - // } - } - - //Patient Access Widgets/ Functions - List filterAccessResults( - List patAccList, String query) { - List templist = []; - //print(query); - for (var item in patAccList) { - if (item.id_no.contains(query)) { - //print(item.medical_aid_no); - templist.add(item); - } - } - return templist; - } - - Widget displayPatientAccessList(List patientsAccessList) { - if (patientsAccessList.isNotEmpty) { - return BuildPatientAccessList( - patientAccesses: patientsAccessList, - signedInUser: widget.arguments.signedInUser, - business: widget.arguments.business, - arguments: widget.arguments, - ); - } - return Padding( - padding: const EdgeInsets.only(top: 35.0), - child: Center( - child: Text( - "No Patients matching search", - style: TextStyle( - fontSize: 25, - color: MzanziInnovationHub.of(context)!.theme.messageTextColor()), - textAlign: TextAlign.center, - ), - ), - ); - } - - Widget patientAccessSearch() { - return KeyboardListener( - focusNode: _focusNode, - autofocus: true, - onKeyEvent: (event) async { - if (event is KeyDownEvent && - event.logicalKey == LogicalKeyboardKey.enter) { - submitPatientAccessForm(); - } - }, - child: Column(mainAxisSize: MainAxisSize.max, children: [ - Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - const Text( - "My Patient List", - style: TextStyle(fontSize: 25, fontWeight: FontWeight.bold), - ), - IconButton( - iconSize: 20, - icon: const Icon( - Icons.refresh, - ), - onPressed: () { - refreshAccessList(); - }, - ), - ], - ), - Divider(color: MzanziInnovationHub.of(context)!.theme.secondaryColor()), - //spacer - const SizedBox(height: 10), - Row( - mainAxisSize: MainAxisSize.min, - children: [ - Flexible( - flex: 1, - child: MIHSearchField( - controller: accessSearchController, - hintText: "ID Search", - required: false, - editable: true, - onTap: () { - submitPatientAccessForm(); - }, - ), - ), - IconButton( - onPressed: () { - setState(() { - accessSearchController.clear(); - accessSearchString = ""; - }); - submitPatientAccessForm(); - }, - icon: const Icon( - Icons.filter_alt_off, - size: 25, - )) - ], - ), - //spacer - const SizedBox(height: 10), - FutureBuilder( - future: patientAccessResults, - builder: (context, snapshot) { - //print("patient Liust ${snapshot.data}"); - if (snapshot.connectionState == ConnectionState.waiting) { - return const Mihloadingcircle(); - } else if (snapshot.connectionState == ConnectionState.done && - snapshot.hasData) { - List patientsAccessList; - if (accessSearchString == "") { - patientsAccessList = snapshot.data!; - } else { - patientsAccessList = - filterAccessResults(snapshot.data!, accessSearchString); - //print(patientsList); - } - return displayPatientAccessList(patientsAccessList); - } else { - return Center( - child: Text( - "Error pulling Patient Access Data\n$baseUrl/access-requests/business/patient/${widget.arguments.business!.business_id}", - style: TextStyle( - fontSize: 25, - color: - MzanziInnovationHub.of(context)!.theme.errorColor()), - textAlign: TextAlign.center, - ), - ); - } - }, - ), - ]), - ); - } - - void submitPatientAccessForm() { - // if (searchController.text != "") { - setState(() { - accessSearchString = accessSearchController.text; - patientAccessResults = MIHApiCalls.getPatientAccessListOfBusiness( - widget.arguments.business!.business_id); - }); - // } else { - // showDialog( - // context: context, - // builder: (context) { - // return const MIHErrorMessage(errorType: "Input Error"); - // }, - // ); - // } - } - - //Layout Widgets/ Functions - - Widget showSelection(int index) { - if (index == 0) { - return SizedBox( - //width: 660, - child: patientQueue(), - ); - } else if (index == 1) { - return SizedBox( - //width: 660, - child: patientAccessSearch(), - ); - } else { - return SizedBox( - //width: 660, - child: patientSearch(), - ); - } - } - - MIHAction getActionButton() { - return MIHAction( - icon: const Icon(Icons.arrow_back), - iconSize: 35, - onTap: () { - Navigator.of(context).pop(); - - Navigator.of(context).popAndPushNamed( - '/', - arguments: AuthArguments(false, false), - ); - }, - ); - } - - MIHHeader getHeader() { - return MIHHeader( - headerAlignment: MainAxisAlignment.end, - headerItems: [ - //============ Waiting Room ================ - Visibility( - visible: _selectedIndex != 0, - child: IconButton( - onPressed: () { - setState(() { - _selectedIndex = 0; - }); - }, - icon: const Icon( - Icons.people, - size: 35, - ), - ), - ), - Visibility( - visible: _selectedIndex == 0, - child: IconButton.filled( - onPressed: () { - setState(() { - _selectedIndex = 0; - }); - }, - icon: const Icon( - Icons.people, - size: 35, - ), - ), - ), - //============ My Patient List ================ - Visibility( - visible: _selectedIndex != 1, - child: IconButton( - onPressed: () { - setState(() { - _selectedIndex = 1; - }); - }, - icon: const Icon( - Icons.check_box_outlined, - size: 35, - ), - ), - ), - Visibility( - visible: _selectedIndex == 1, - child: IconButton.filled( - onPressed: () { - setState(() { - _selectedIndex = 1; - }); - }, - icon: const Icon( - Icons.check_box_outlined, - size: 35, - ), - ), - ), - //============ Patient Lookup ================ - Visibility( - visible: _selectedIndex != 2, - child: IconButton( - onPressed: () { - setState(() { - _selectedIndex = 2; - }); - }, - icon: const Icon( - Icons.search, - size: 35, - ), - ), - ), - Visibility( - visible: _selectedIndex == 2, - child: IconButton.filled( - onPressed: () { - setState(() { - _selectedIndex = 2; - }); - }, - icon: const Icon( - Icons.search, - size: 35, - ), - ), - ), - ], - ); - } - - MIHBody getBody() { - return MIHBody( - borderOn: true, - bodyItems: [ - showSelection(_selectedIndex), - ], - ); - } - - @override - void dispose() { - searchController.dispose(); - accessSearchController.dispose(); - queueDateController.dispose(); - _focusNode.dispose(); - super.dispose(); - } - - @override - void initState() { - patientSearchResults = MIHApiCalls.fetchPatients("abc"); - patientAccessResults = MIHApiCalls.getPatientAccessListOfBusiness( - widget.arguments.business!.business_id); - queueDateController.addListener(checkforchange); - setState(() { - formattedDate = formatter.format(now); - queueDateController.text = formattedDate; - }); - - super.initState(); - } - - @override - Widget build(BuildContext context) { - return SwipeDetector( - onSwipeLeft: (offset) { - if (_selectedIndex < 2) { - setState(() { - _selectedIndex += 1; - }); - } - //print("swipe left"); - }, - onSwipeRight: (offset) { - if (_selectedIndex > 0) { - setState(() { - _selectedIndex -= 1; - }); - } - //print("swipe right"); - }, - child: MIHLayoutBuilder( - actionButton: getActionButton(), - header: getHeader(), - secondaryActionButton: null, - body: getBody(), - actionDrawer: null, - secondaryActionDrawer: null, - bottomNavBar: null, - pullDownToRefresh: false, - onPullDown: () async {}, - ), - ); - } -} diff --git a/Frontend/lib/mih_packages/patient_profile/patient_notes.dart b/Frontend/lib/mih_packages/patient_profile/patient_notes.dart deleted file mode 100644 index 7a604967..00000000 --- a/Frontend/lib/mih_packages/patient_profile/patient_notes.dart +++ /dev/null @@ -1,366 +0,0 @@ -import 'dart:convert'; - -import 'package:flutter/material.dart'; -import '../../main.dart'; -import 'package:supertokens_flutter/http.dart' as http; - -import '../../mih_components/mih_inputs_and_buttons/mih_button.dart'; -import '../../mih_components/mih_inputs_and_buttons/mih_multiline_text_input.dart'; -import '../../mih_components/mih_inputs_and_buttons/mih_text_input.dart'; -import '../../mih_components/mih_layout/mih_window.dart'; -import '../../mih_components/mih_pop_up_messages/mih_error_message.dart'; -import '../../mih_components/mih_pop_up_messages/mih_loading_circle.dart'; -import '../../mih_components/mih_pop_up_messages/mih_success_message.dart'; -import '../../mih_env/env.dart'; -import '../../mih_objects/app_user.dart'; -import '../../mih_objects/business.dart'; -import '../../mih_objects/business_user.dart'; -import '../../mih_objects/notes.dart'; -import '../../mih_objects/patients.dart'; -import 'builder/build_notes_list.dart'; - -class PatientNotes extends StatefulWidget { - final String patientAppId; - final Patient selectedPatient; - final AppUser signedInUser; - final Business? business; - final BusinessUser? businessUser; - final String type; - const PatientNotes({ - super.key, - required this.patientAppId, - required this.selectedPatient, - required this.signedInUser, - required this.business, - required this.businessUser, - required this.type, - }); - - @override - State createState() => _PatientNotesState(); -} - -class _PatientNotesState extends State { - String endpoint = "${AppEnviroment.baseApiUrl}/notes/patients/"; - String apiUrlAddNote = "${AppEnviroment.baseApiUrl}/notes/insert/"; - final titleController = TextEditingController(); - final noteTextController = TextEditingController(); - final officeController = TextEditingController(); - final dateController = TextEditingController(); - final doctorController = TextEditingController(); - late Future> futueNotes; - //int noteDetailCount = 0; - final ValueNotifier _counter = ValueNotifier(0); - - Future> fetchNotes(String endpoint) async { - final response = await http.get(Uri.parse( - "${AppEnviroment.baseApiUrl}/notes/patients/${widget.selectedPatient.app_id}")); - if (response.statusCode == 200) { - Iterable l = jsonDecode(response.body); - List notes = - List.from(l.map((model) => Note.fromJson(model))); - //print("Here notes"); - return notes; - } else { - internetConnectionPopUp(); - throw Exception('failed to load patients'); - } - } - - Future addPatientNoteAPICall() async { - // String title = ""; - // if (widget.businessUser!.title == "Doctor") { - // title = "Dr."; - // } - var response = await http.post( - Uri.parse("${AppEnviroment.baseApiUrl}/notes/insert/"), - headers: { - "Content-Type": "application/json; charset=UTF-8" - }, - body: jsonEncode({ - "note_name": titleController.text, - "note_text": noteTextController.text, - "doc_office": officeController.text, - "doctor": doctorController.text, - "app_id": widget.selectedPatient.app_id, - }), - ); - if (response.statusCode == 201) { - setState(() { - futueNotes = fetchNotes(endpoint + widget.patientAppId.toString()); - }); - // Navigator.of(context) - // .pushNamed('/patient-manager', arguments: widget.userEmail); - String message = - "Your note has been successfully added to the patients medical record. You can now view it alongside their other important information."; - successPopUp(message); - } else { - internetConnectionPopUp(); - } - } - - void successPopUp(String message) { - showDialog( - context: context, - builder: (context) { - return MIHSuccessMessage( - successType: "Success", - successMessage: message, - ); - }, - ); - } - - void internetConnectionPopUp() { - showDialog( - context: context, - builder: (context) { - return const MIHErrorMessage(errorType: "Internet Connection"); - }, - ); - } - - void messagePopUp(error) { - showDialog( - context: context, - builder: (context) { - return AlertDialog( - title: Text(error), - ); - }, - ); - } - - void addNotePopUp() { - DateTime now = new DateTime.now(); - DateTime date = new DateTime(now.year, now.month, now.day); - var title = ""; - if (widget.businessUser!.title == "Doctor") { - title = "Dr."; - } - setState(() { - officeController.text = widget.business!.Name; - doctorController.text = - "$title ${widget.signedInUser.fname} ${widget.signedInUser.lname}"; - dateController.text = date.toString().substring(0, 10); - }); - showDialog( - context: context, - barrierDismissible: false, - builder: (context) => MIHWindow( - fullscreen: false, - windowTitle: "Add Note", - windowTools: const [], - onWindowTapClose: () { - Navigator.pop(context); - titleController.clear(); - noteTextController.clear(); - }, - windowBody: [ - 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), - SizedBox( - width: 300, - height: 50, - child: MIHButton( - onTap: () { - if (isFieldsFilled()) { - addPatientNoteAPICall(); - Navigator.pop(context); - } else { - showDialog( - context: context, - builder: (context) { - return const MIHErrorMessage(errorType: "Input Error"); - }, - ); - } - }, - buttonText: "Add Note", - buttonColor: - MzanziInnovationHub.of(context)!.theme.secondaryColor(), - textColor: MzanziInnovationHub.of(context)!.theme.primaryColor(), - ), - ) - ], - ), - ); - } - - Color getNoteDetailLimitColor() { - if (_counter.value <= 512) { - return MzanziInnovationHub.of(context)!.theme.secondaryColor(); - } else { - return MzanziInnovationHub.of(context)!.theme.errorColor(); - } - } - - bool isFieldsFilled() { - if (titleController.text.isEmpty || - noteTextController.text.isEmpty || - _counter.value >= 512) { - return false; - } else { - return true; - } - } - - List setIcons() { - if (widget.type == "personal") { - return [ - Text( - "Notes", - textAlign: TextAlign.center, - style: TextStyle( - fontSize: 25, - fontWeight: FontWeight.bold, - color: MzanziInnovationHub.of(context)!.theme.secondaryColor()), - ), - ]; - } else { - return [ - Text( - "Notes", - textAlign: TextAlign.center, - style: TextStyle( - fontSize: 25, - fontWeight: FontWeight.bold, - color: MzanziInnovationHub.of(context)!.theme.secondaryColor()), - ), - IconButton( - onPressed: () { - addNotePopUp(); - }, - icon: Icon(Icons.add, - color: MzanziInnovationHub.of(context)!.theme.secondaryColor()), - ) - ]; - } - } - - @override - void dispose() { - titleController.dispose(); - noteTextController.dispose(); - doctorController.dispose(); - dateController.dispose(); - officeController.dispose(); - super.dispose(); - } - - @override - void initState() { - futueNotes = fetchNotes(endpoint + widget.patientAppId); - // setState(() { - // noteDetailCount = noteTextController.text.length; - // }); - noteTextController.addListener(() { - setState(() { - _counter.value = noteTextController.text.characters.length; - }); - print(_counter.value); - }); - super.initState(); - } - - @override - Widget build(BuildContext context) { - return FutureBuilder( - future: futueNotes, - builder: (context, snapshot) { - if (snapshot.connectionState == ConnectionState.waiting) { - return const Center( - child: Mihloadingcircle(), - ); - } else if (snapshot.hasData) { - final notesList = snapshot.data!; - return Column(children: [ - Row( - mainAxisAlignment: MainAxisAlignment.center, - children: setIcons(), - ), - Divider( - color: MzanziInnovationHub.of(context)!.theme.secondaryColor()), - const SizedBox(height: 10), - BuildNotesList( - notes: notesList, - signedInUser: widget.signedInUser, - selectedPatient: widget.selectedPatient, - business: widget.business, - businessUser: widget.businessUser, - type: widget.type, - ), - ]); - } else { - return const Center( - child: Text("Error Loading Notes"), - ); - } - }, - ); - } -} diff --git a/Frontend/lib/mih_packages/patient_profile/patient_view.dart b/Frontend/lib/mih_packages/patient_profile/patient_view.dart deleted file mode 100644 index 8b4f7ffe..00000000 --- a/Frontend/lib/mih_packages/patient_profile/patient_view.dart +++ /dev/null @@ -1,318 +0,0 @@ -import 'dart:convert'; - -import 'package:Mzansi_Innovation_Hub/mih_packages/patient_profile/patient_claims_statements.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter_swipe_detector/flutter_swipe_detector.dart'; -import '../../main.dart'; -import 'package:supertokens_flutter/http.dart' as http; - -import '../../mih_components/mih_layout/mih_action.dart'; -import '../../mih_components/mih_layout/mih_body.dart'; -import '../../mih_components/mih_layout/mih_header.dart'; -import '../../mih_components/mih_layout/mih_layout_builder.dart'; -import '../../mih_env/env.dart'; -import '../../mih_objects/arguments.dart'; -import '../../mih_objects/patients.dart'; -import 'patient_details.dart'; -import 'patient_files.dart'; -import 'patient_notes.dart'; - -class PatientView extends StatefulWidget { - //final AppUser signedInUser; - final PatientViewArguments arguments; - const PatientView({ - super.key, - required this.arguments, - }); - - @override - State createState() => _PatientViewState(); -} - -class _PatientViewState extends State { - int _selectedIndex = 0; - late double popUpWidth; - late double? popUpheight; - late double popUpTitleSize; - late double popUpSubtitleSize; - late double popUpBodySize; - late double popUpIconSize; - late double popUpPaddingSize; - late double width; - late double height; - - Future fetchPatient() async { - //print("Patien manager page: $endpoint"); - var patientAppId = widget.arguments.selectedPatient!.app_id; - - final response = await http - .get(Uri.parse("${AppEnviroment.baseApiUrl}/patients/$patientAppId")); - // print("Here"); - // print("Body: ${response.body}"); - // print("Code: ${response.statusCode}"); - // var errorCode = response.statusCode.toString(); - // var errorBody = response.body; - - if (response.statusCode == 200) { - //print("Here1"); - var decodedData = jsonDecode(response.body); - // print("Here2"); - Patient patients = Patient.fromJson(decodedData as Map); - // print("Here3"); - // print(patients); - return patients; - } - return null; - } - - void checkScreenSize() { - if (MzanziInnovationHub.of(context)!.theme.screenType == "desktop") { - setState(() { - popUpWidth = (width / 4) * 2; - popUpheight = null; - }); - } else { - setState(() { - popUpWidth = width - (width * 0.1); - popUpheight = null; - }); - } - } - - Widget showSelection(int index) { - if (index == 0) { - return PatientDetails( - signedInUser: widget.arguments.signedInUser, - selectedPatient: widget.arguments.selectedPatient!, - type: widget.arguments.type, - ); - } else if (index == 1) { - return PatientNotes( - patientAppId: widget.arguments.selectedPatient!.app_id, - selectedPatient: widget.arguments.selectedPatient!, - signedInUser: widget.arguments.signedInUser, - business: widget.arguments.business, - businessUser: widget.arguments.businessUser, - type: widget.arguments.type, - ); - } else if (index == 2) { - return PatientFiles( - patientIndex: widget.arguments.selectedPatient!.idpatients, - selectedPatient: widget.arguments.selectedPatient!, - signedInUser: widget.arguments.signedInUser, - business: widget.arguments.business, - businessUser: widget.arguments.businessUser, - type: widget.arguments.type, - ); - } else { - return PatientClaimsOrStatements( - patientIndex: widget.arguments.selectedPatient!.idpatients, - selectedPatient: widget.arguments.selectedPatient!, - signedInUser: widget.arguments.signedInUser, - business: widget.arguments.business, - businessUser: widget.arguments.businessUser, - type: widget.arguments.type, - ); - } - } - - MIHAction getActionButton() { - if (widget.arguments.type == "Personal") { - return MIHAction( - icon: const Icon(Icons.arrow_back), - iconSize: 35, - onTap: () { - Navigator.of(context).pop(); - Navigator.of(context).popAndPushNamed( - '/', - arguments: AuthArguments(true, false), - ); - }, - ); - } else { - return MIHAction( - icon: const Icon(Icons.arrow_back), - iconSize: 35, - onTap: () { - Navigator.of(context).pop(); - }, - ); - } - } - - MIHHeader getHeader() { - return MIHHeader( - headerAlignment: MainAxisAlignment.end, - headerItems: [ - //============ Patient Details ================ - Visibility( - visible: _selectedIndex != 0, - child: IconButton( - onPressed: () { - setState(() { - _selectedIndex = 0; - }); - }, - icon: const Icon( - Icons.perm_identity, - size: 35, - ), - ), - ), - Visibility( - visible: _selectedIndex == 0, - child: IconButton.filled( - iconSize: 35, - onPressed: () { - setState(() { - _selectedIndex = 0; - }); - }, - icon: const Icon( - Icons.perm_identity, - ), - ), - ), - //============ Patient Notes ================ - Visibility( - visible: _selectedIndex != 1, - child: IconButton( - onPressed: () { - setState(() { - _selectedIndex = 1; - }); - }, - icon: const Icon( - Icons.article_outlined, - size: 35, - ), - ), - ), - Visibility( - visible: _selectedIndex == 1, - child: IconButton.filled( - onPressed: () { - setState(() { - _selectedIndex = 1; - }); - }, - icon: const Icon( - Icons.article_outlined, - size: 35, - ), - ), - ), - //============ Patient Files ================ - Visibility( - visible: _selectedIndex != 2, - child: IconButton( - onPressed: () { - setState(() { - _selectedIndex = 2; - }); - }, - icon: const Icon( - Icons.file_present, - size: 35, - ), - ), - ), - Visibility( - visible: _selectedIndex == 2, - child: IconButton.filled( - onPressed: () { - setState(() { - _selectedIndex = 2; - }); - }, - icon: const Icon( - Icons.file_present, - size: 35, - ), - ), - ), - //============ Claims/ Statements ================ - Visibility( - visible: _selectedIndex != 3, - child: IconButton( - onPressed: () { - setState(() { - _selectedIndex = 3; - }); - }, - icon: const Icon( - Icons.file_open_outlined, - size: 35, - ), - ), - ), - Visibility( - visible: _selectedIndex == 3, - child: IconButton.filled( - onPressed: () { - setState(() { - _selectedIndex = 3; - }); - }, - icon: const Icon( - Icons.file_open_outlined, - size: 35, - ), - ), - ), - ], - ); - } - - MIHBody getBody() { - return MIHBody( - borderOn: true, - bodyItems: [showSelection(_selectedIndex)], - ); - } - - @override - void dispose() { - // TODO: implement dispose - super.dispose(); - } - - @override - Widget build(BuildContext context) { - var size = MediaQuery.of(context).size; - setState(() { - width = size.width; - height = size.height; - }); - checkScreenSize(); - return SwipeDetector( - onSwipeLeft: (offset) { - if (_selectedIndex < 3) { - setState(() { - _selectedIndex += 1; - }); - } - //print("swipe left"); - }, - onSwipeRight: (offset) { - if (_selectedIndex > 0) { - setState(() { - _selectedIndex -= 1; - }); - } - //print("swipe right"); - }, - child: MIHLayoutBuilder( - actionButton: getActionButton(), - header: getHeader(), - secondaryActionButton: null, - body: getBody(), - actionDrawer: null, - secondaryActionDrawer: null, - bottomNavBar: null, - pullDownToRefresh: false, - onPullDown: () async {}, - ), - ); - } -} diff --git a/Frontend/lib/mih_packages/patient_profile/prescip_input.dart b/Frontend/lib/mih_packages/patient_profile/prescip_input.dart deleted file mode 100644 index 4a85b090..00000000 --- a/Frontend/lib/mih_packages/patient_profile/prescip_input.dart +++ /dev/null @@ -1,574 +0,0 @@ -import 'dart:convert'; - -import 'package:flutter/material.dart'; -import 'package:flutter/services.dart'; -import '../../main.dart'; -import 'package:supertokens_flutter/http.dart' as http; - -import '../../mih_components/medicine_search.dart'; -import '../../mih_components/mih_inputs_and_buttons/mih_button.dart'; -import '../../mih_components/mih_inputs_and_buttons/mih_dropdown_input.dart'; -import '../../mih_components/mih_inputs_and_buttons/mih_search_input.dart'; -import '../../mih_components/mih_pop_up_messages/mih_error_message.dart'; -import '../../mih_components/mih_pop_up_messages/mih_loading_circle.dart'; -import '../../mih_components/mih_pop_up_messages/mih_success_message.dart'; -import '../../mih_env/env.dart'; -import '../../mih_objects/app_user.dart'; -import '../../mih_objects/arguments.dart'; -import '../../mih_objects/business.dart'; -import '../../mih_objects/business_user.dart'; -import '../../mih_objects/patients.dart'; -import '../../mih_objects/perscription.dart'; - -class PrescripInput extends StatefulWidget { - final TextEditingController medicineController; - final TextEditingController quantityController; - final TextEditingController dosageController; - final TextEditingController timesDailyController; - final TextEditingController noDaysController; - final TextEditingController noRepeatsController; - final TextEditingController outputController; - final Patient selectedPatient; - final AppUser signedInUser; - final Business? business; - final BusinessUser? businessUser; - const PrescripInput({ - super.key, - required this.medicineController, - required this.quantityController, - required this.dosageController, - required this.timesDailyController, - required this.noDaysController, - required this.noRepeatsController, - required this.outputController, - required this.selectedPatient, - required this.signedInUser, - required this.business, - required this.businessUser, - }); - - @override - State createState() => _PrescripInputState(); -} - -class _PrescripInputState extends State { - final FocusNode _focusNode = FocusNode(); - List perscriptionObjOutput = []; - late double width; - late double height; - - final numberOptions = [ - "0", - "1", - "2", - "3", - "4", - "5", - "6", - "7", - "8", - "9", - "10", - "11", - "12", - "13", - "14", - "15", - "16", - "17", - "18", - "19", - "20", - "21", - "22", - "23", - "24", - "25", - "26", - "27", - "28", - "29", - "30" - ]; - - Future generatePerscription() async { - //start loading circle - showDialog( - context: context, - builder: (context) { - return const Mihloadingcircle(); - }, - ); - - var response1 = await http.post( - Uri.parse("${AppEnviroment.baseApiUrl}/minio/generate/perscription/"), - headers: { - "Content-Type": "application/json; charset=UTF-8" - }, - body: jsonEncode({ - "app_id": widget.selectedPatient.app_id, - "fullName": - "${widget.selectedPatient.first_name} ${widget.selectedPatient.last_name}", - "id_no": widget.selectedPatient.id_no, - "docfname": - "DR. ${widget.signedInUser.fname} ${widget.signedInUser.lname}", - "busName": widget.business!.Name, - "busAddr": "*TO BE ADDED IN THE FUTURE*", - "busNo": widget.business!.contact_no, - "busEmail": widget.business!.bus_email, - "logo_path": widget.business!.logo_path, - "sig_path": widget.businessUser!.sig_path, - "data": perscriptionObjOutput, - }), - ); - //print(response1.statusCode); - DateTime now = new DateTime.now(); - DateTime date = new DateTime(now.year, now.month, now.day); - String fileName = - "Perscription-${widget.selectedPatient.first_name} ${widget.selectedPatient.last_name}-${date.toString().substring(0, 10)}.pdf"; - if (response1.statusCode == 200) { - var response2 = await http.post( - Uri.parse("${AppEnviroment.baseApiUrl}/files/insert/"), - headers: { - "Content-Type": "application/json; charset=UTF-8" - }, - body: jsonEncode({ - "file_path": - "${widget.selectedPatient.app_id}/patient_files/$fileName", - "file_name": fileName, - "app_id": widget.selectedPatient.app_id - }), - ); - //print(response2.statusCode); - if (response2.statusCode == 201) { - setState(() { - //To do - widget.medicineController.clear(); - widget.dosageController.clear(); - widget.timesDailyController.clear(); - widget.noDaysController.clear(); - widget.timesDailyController.clear(); - widget.noRepeatsController.clear(); - widget.quantityController.clear(); - widget.outputController.clear(); - // futueFiles = fetchFiles(); - }); - // end loading circle - Navigator.of(context).pop(); - Navigator.of(context).pop(); - Navigator.of(context).pushNamed('/patient-manager/patient', - arguments: PatientViewArguments( - widget.signedInUser, - widget.selectedPatient, - widget.businessUser, - widget.business, - "business", - )); - String message = - "The perscription $fileName has been successfully generated and added to ${widget.selectedPatient.first_name} ${widget.selectedPatient.last_name}'s record. You can now access and download it for their use."; - successPopUp(message); - } else { - internetConnectionPopUp(); - } - } else { - internetConnectionPopUp(); - } - } - - void internetConnectionPopUp() { - showDialog( - context: context, - builder: (context) { - return const MIHErrorMessage(errorType: "Internet Connection"); - }, - ); - } - - void successPopUp(String message) { - showDialog( - context: context, - builder: (context) { - return MIHSuccessMessage( - successType: "Success", - successMessage: message, - ); - }, - ); - } - - void getMedsPopUp(TextEditingController medSearch) { - showDialog( - context: context, - builder: (context) { - return MedicineSearch( - searchVlaue: medSearch, - ); - }, - ); - } - - bool isFieldsFilled() { - if (widget.medicineController.text.isEmpty || - // widget.quantityController.text.isEmpty || - widget.dosageController.text.isEmpty || - widget.timesDailyController.text.isEmpty || - widget.noDaysController.text.isEmpty || - widget.noRepeatsController.text.isEmpty) { - return false; - } else { - return true; - } - } - - void updatePerscriptionList() { - String name; - String unit; - String form; - List medNameList = widget.medicineController.text.split("%t"); - if (medNameList.length == 1) { - name = medNameList[0]; - unit = ""; - form = ""; - } else { - name = medNameList[0]; - unit = medNameList[1]; - form = medNameList[2]; - } - int quantityCalc = calcQuantity( - widget.dosageController.text, - widget.timesDailyController.text, - widget.noDaysController.text, - medNameList[2].toLowerCase()); - Perscription tempObj = Perscription( - name: name, - unit: unit, - form: form, - fullForm: getFullDoagesForm(form), - quantity: "$quantityCalc", - dosage: widget.dosageController.text, - times: widget.timesDailyController.text, - days: widget.noDaysController.text, - repeats: widget.noRepeatsController.text, - ); - perscriptionObjOutput.add(tempObj); - } - - String getPerscTitle(int index) { - return "${perscriptionObjOutput[index].name} - ${perscriptionObjOutput[index].form}"; - } - - String getPerscSubtitle(int index) { - if (perscriptionObjOutput[index].form.toLowerCase() == "syr") { - String unit = perscriptionObjOutput[index].unit.toLowerCase(); - if (perscriptionObjOutput[index].unit.toLowerCase().contains("ml")) { - unit = "ml"; - } - return "${perscriptionObjOutput[index].dosage} $unit, ${perscriptionObjOutput[index].times} time(s) daily, for ${perscriptionObjOutput[index].days} day(s)\nQuantity: ${perscriptionObjOutput[index].quantity}\nNo. of repeats: ${perscriptionObjOutput[index].repeats}"; - } else { - return "${perscriptionObjOutput[index].dosage} ${perscriptionObjOutput[index].fullForm}(s), ${perscriptionObjOutput[index].times} time(s) daily, for ${perscriptionObjOutput[index].days} day(s)\nQuantity: ${perscriptionObjOutput[index].quantity}\nNo. of repeats: ${perscriptionObjOutput[index].repeats}"; - } - } - - String getFullDoagesForm(String abr) { - var dosageFormList = { - "liq": "liquid", - "tab": "tablet", - "cap": "capsule", - "cps": "capsule", - "oin": "ointment", - "lit": "lotion", - "lot": "lotion", - "inj": "injection", - "syr": "syrup", - "dsp": "effervescent tablet", - "eft": "effervescent tablet", - "ear": "drops", - "drp": "drops", - "opd": "drops", - "udv": "vial", - "sus": "suspension", - "susp": "suspension", - "cal": "calasthetic", - "sol": "solution", - "sln": "solution", - "neb": "nebuliser", - "inh": "inhaler", - "spo": "inhaler", - "inf": "infusion", - "chg": "chewing Gum", - "vac": "vacutainer", - "vag": "vaginal gel", - "jel": "gel", - "eyo": "eye ointment", - "vat": "vaginal cream", - "poi": "injection", - "ped": "powder", - "pow": "powder", - "por": "powder", - "sac": "sachet", - "sup": "suppository", - "cre": "cream", - "ptd": "patch", - "ect": "tablet", - "nas": "spray", - }; - String form; - if (dosageFormList[abr.toLowerCase()] == null) { - form = abr; - } else { - form = dosageFormList[abr.toLowerCase()]!; - } - return form; - } - - int calcQuantity(String dosage, String times, String days, String form) { - var dosageFormList = [ - "tab", - "cap", - "cps", - "dsp", - "eft", - "udv", - "chg", - "sac", - "sup", - "ptd", - "ect", - ]; - if (dosageFormList.contains(form)) { - return int.parse(dosage) * int.parse(times) * int.parse(days); - } else { - return 1; - } - } - - Widget displayMedInput() { - return Column( - children: [ - //const SizedBox(height: 25.0), - - KeyboardListener( - focusNode: _focusNode, - autofocus: true, - onKeyEvent: (event) async { - if (event is KeyDownEvent && - event.logicalKey == LogicalKeyboardKey.enter) { - getMedsPopUp(widget.medicineController); - } - }, - child: MIHSearchField( - controller: widget.medicineController, - hintText: "Medicine", - required: true, - editable: true, - onTap: () { - getMedsPopUp(widget.medicineController); - }, - ), - ), - const SizedBox(height: 10.0), - // SizedBox( - // width: 300, - // child: MIHDropdownField( - // controller: widget.quantityController, - // hintText: "Quantity", - // dropdownOptions: numberOptions, - // required: true, - // editable: true, - // ), - // ), - // const SizedBox(height: 10.0), - MIHDropdownField( - controller: widget.dosageController, - hintText: "Dosage", - dropdownOptions: numberOptions, - required: true, - editable: true, - enableSearch: false, - ), - const SizedBox(height: 10.0), - MIHDropdownField( - controller: widget.timesDailyController, - hintText: "Times Daily", - dropdownOptions: numberOptions, - required: true, - editable: true, - enableSearch: false, - ), - const SizedBox(height: 10.0), - MIHDropdownField( - controller: widget.noDaysController, - hintText: "No. Days", - dropdownOptions: numberOptions, - required: true, - editable: true, - enableSearch: false, - ), - const SizedBox(height: 10.0), - MIHDropdownField( - controller: widget.noRepeatsController, - hintText: "No. Repeats", - dropdownOptions: numberOptions, - required: true, - editable: true, - enableSearch: false, - ), - const SizedBox(height: 15.0), - SizedBox( - width: 300, - height: 50, - child: MIHButton( - buttonText: "Add", - buttonColor: - MzanziInnovationHub.of(context)!.theme.secondaryColor(), - textColor: MzanziInnovationHub.of(context)!.theme.primaryColor(), - onTap: () { - if (isFieldsFilled()) { - // int quantity; - // int.parse(widget.dosageController.text) * - // int.parse(widget.timesDailyController.text) * - // int.parse(widget.noDaysController.text); - setState(() { - //widget.quantityController.text = "$quantity"; - updatePerscriptionList(); - widget.medicineController.clear(); - widget.quantityController.clear(); - widget.dosageController.clear(); - widget.timesDailyController.clear(); - widget.noDaysController.clear(); - widget.noRepeatsController.clear(); - }); - - //addPatientAPICall(); - } else { - showDialog( - context: context, - builder: (context) { - return const MIHErrorMessage(errorType: "Input Error"); - }, - ); - } - }, - ), - ) - ], - ); - } - - Widget displayPerscList() { - return Column( - children: [ - Container( - width: 550, - height: 325, - decoration: BoxDecoration( - color: MzanziInnovationHub.of(context)!.theme.primaryColor(), - borderRadius: BorderRadius.circular(25.0), - border: Border.all( - color: MzanziInnovationHub.of(context)!.theme.secondaryColor(), - width: 3.0), - ), - child: ListView.separated( - separatorBuilder: (BuildContext context, int index) { - return const Padding( - padding: EdgeInsets.symmetric(horizontal: 10.0), - child: Divider(), - ); - }, - itemCount: perscriptionObjOutput.length, - itemBuilder: (context, index) { - //final patient = widget.patients[index].id_no.contains(widget.searchString); - return ListTile( - title: Text( - getPerscTitle(index), - style: TextStyle( - color: - MzanziInnovationHub.of(context)!.theme.secondaryColor(), - ), - ), - subtitle: Text( - getPerscSubtitle(index), - style: TextStyle( - color: - MzanziInnovationHub.of(context)!.theme.secondaryColor(), - ), - ), - //onTap: () {}, - trailing: IconButton( - icon: Icon( - Icons.delete_forever_outlined, - color: - MzanziInnovationHub.of(context)!.theme.secondaryColor(), - ), - onPressed: () { - setState(() { - perscriptionObjOutput.removeAt(index); - }); - }, - ), - ); - }, - ), - ), - const SizedBox(height: 15.0), - SizedBox( - width: 300, - height: 50, - child: MIHButton( - onTap: () async { - if (perscriptionObjOutput.isNotEmpty) { - //print(jsonEncode(perscriptionObjOutput)); - await generatePerscription(); - Navigator.pop(context); - } else { - showDialog( - context: context, - builder: (context) { - return const MIHErrorMessage(errorType: "Input Error"); - }, - ); - } - }, - buttonText: "Generate", - buttonColor: MzanziInnovationHub.of(context)!.theme.successColor(), - textColor: MzanziInnovationHub.of(context)!.theme.primaryColor(), - ), - ) - ], - ); - } - - @override - void dispose() { - _focusNode.dispose(); - super.dispose(); - } - - @override - void initState() { - //futueMeds = getMedList(endpointMeds); - super.initState(); - } - - @override - Widget build(BuildContext context) { - var size = MediaQuery.of(context).size; - setState(() { - width = size.width; - height = size.height; - }); - return Wrap( - direction: Axis.horizontal, - alignment: WrapAlignment.center, - spacing: 10, - runSpacing: 10, - // mainAxisAlignment: MainAxisAlignment.center, - // mainAxisSize: MainAxisSize.max, - // crossAxisAlignment: CrossAxisAlignment.center, - children: [ - SizedBox(width: 500, child: displayMedInput()), - displayPerscList(), - ], - ); - } -} From 2876be805aca0e764a978d8b729b18b07fa3bfee Mon Sep 17 00:00:00 2001 From: Yasien Mac Mini Date: Mon, 17 Mar 2025 14:13:13 +0200 Subject: [PATCH 11/17] add icd10 compenent --- .../components/icd10_search_window.dart | 58 +++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 Frontend/lib/mih_packages/patient_profile/pat_profile/components/icd10_search_window.dart 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 new file mode 100644 index 00000000..a191d30f --- /dev/null +++ b/Frontend/lib/mih_packages/patient_profile/pat_profile/components/icd10_search_window.dart @@ -0,0 +1,58 @@ +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_window.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'; + +class ICD10SearchWindow extends StatefulWidget { + final TextEditingController icd10CodeController; + final List icd10codeList; + const ICD10SearchWindow({ + super.key, + required this.icd10CodeController, + required this.icd10codeList, + }); + + @override + State createState() => _ICD10SearchWindowState(); +} + +class _ICD10SearchWindowState extends State { + Widget getWindowBody() { + return Column( + children: [ + MIHTextField( + controller: widget.icd10CodeController, + hintText: "Search Text", + editable: false, + required: false, + ), + BuildICD10CodeList( + icd10CodeController: widget.icd10CodeController, + icd10codeList: widget.icd10codeList, + ), + ], + ); + } + + @override + Widget build(BuildContext context) { + return MIHWindow( + fullscreen: false, + windowTitle: "ICD-10 Search", + windowTools: const [], + onWindowTapClose: () { + // medicineController.clear(); + // quantityController.clear(); + // dosageController.clear(); + // timesDailyController.clear(); + // noDaysController.clear(); + // noRepeatsController.clear(); + Navigator.pop(context); + }, + windowBody: [ + getWindowBody(), + ], + ); + } +} From caa1e788dfd2da94926ac8968bb5f0667039af3c Mon Sep 17 00:00:00 2001 From: Yasien Mac Mini Date: Mon, 17 Mar 2025 14:13:42 +0200 Subject: [PATCH 12/17] use new icd10 compenent --- .../components/Claim_Statement_Window.dart | 106 +----------------- 1 file changed, 1 insertion(+), 105 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 3c0b0970..9d93caad 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 @@ -14,7 +14,7 @@ import 'package:Mzansi_Innovation_Hub/mih_objects/business.dart'; import 'package:Mzansi_Innovation_Hub/mih_objects/business_user.dart'; import 'package:Mzansi_Innovation_Hub/mih_objects/icd10_code.dart.dart'; import 'package:Mzansi_Innovation_Hub/mih_objects/patients.dart'; -import 'package:Mzansi_Innovation_Hub/mih_packages/patient_profile/icd10_search_window.dart'; +import 'package:Mzansi_Innovation_Hub/mih_packages/patient_profile/pat_profile/components/icd10_search_window.dart'; import 'package:flutter/material.dart'; import 'package:intl/intl.dart'; @@ -86,110 +86,6 @@ class _ClaimStatementWindowState extends State { enableSearch: false, ), const SizedBox(height: 10), - // Text( - // "Patient 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), - // MIHTextField( - // controller: _fullNameController, - // hintText: "Full Name", - // editable: false, - // required: true, - // ), - // const SizedBox(height: 10), - // MIHTextField( - // controller: _idController, - // hintText: "ID No.", - // editable: false, - // required: true, - // ), - // const SizedBox(height: 10), - // MIHTextField( - // controller: _medAidController, - // hintText: "Has Medical Aid", - // editable: false, - // required: true, - // ), - // const SizedBox(height: 10), - // ValueListenableBuilder( - // valueListenable: serviceDesc, - // builder: (BuildContext context, String value, Widget? child) { - // return Visibility( - // visible: value == "Yes", - // child: Column( - // children: [ - // MIHTextField( - // controller: _medAidNoController, - // hintText: "Medical Aid No.", - // editable: false, - // required: true, - // ), - // const SizedBox(height: 10), - // MIHTextField( - // controller: _medAidCodeController, - // hintText: "Medical Aid Code", - // editable: false, - // required: true, - // ), - // const SizedBox(height: 10), - // MIHTextField( - // controller: _medAidNameController, - // hintText: "Medical Aid Name", - // editable: false, - // required: true, - // ), - // const SizedBox(height: 10), - // MIHTextField( - // controller: _medAidSchemeController, - // hintText: "Medical Aid Scheme", - // editable: false, - // required: true, - // ), - // const SizedBox(height: 10), - // ], - // ), - // ); - // }, - // ), - // Text( - // "Provider 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), - // MIHTextField( - // controller: _providerNameController, - // hintText: "Provider Name", - // editable: false, - // required: true, - // ), - // const SizedBox(height: 10), - // MIHTextField( - // controller: _practiceNoController, - // hintText: "Practice No.", - // editable: false, - // required: true, - // ), - // const SizedBox(height: 10), - // MIHTextField( - // controller: _vatNoController, - // hintText: "VAT No.", - // editable: false, - // required: true, - // ), - // const SizedBox(height: 10), Text( "Service Details", textAlign: TextAlign.center, From 61e7bc10b28f34edf5d98db7435d85d6efb7106e Mon Sep 17 00:00:00 2001 From: Yasien Mac Mini Date: Mon, 17 Mar 2025 14:14:04 +0200 Subject: [PATCH 13/17] move icd10 build to package --- .../list_builders/build_icd10_code_list.dart | 75 +++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 Frontend/lib/mih_packages/patient_profile/pat_profile/list_builders/build_icd10_code_list.dart diff --git a/Frontend/lib/mih_packages/patient_profile/pat_profile/list_builders/build_icd10_code_list.dart b/Frontend/lib/mih_packages/patient_profile/pat_profile/list_builders/build_icd10_code_list.dart new file mode 100644 index 00000000..936ae228 --- /dev/null +++ b/Frontend/lib/mih_packages/patient_profile/pat_profile/list_builders/build_icd10_code_list.dart @@ -0,0 +1,75 @@ +import 'package:Mzansi_Innovation_Hub/main.dart'; +import 'package:Mzansi_Innovation_Hub/mih_env/env.dart'; +import 'package:Mzansi_Innovation_Hub/mih_objects/icd10_code.dart.dart'; +import 'package:flutter/material.dart'; + +class BuildICD10CodeList extends StatefulWidget { + final TextEditingController icd10CodeController; + final List icd10codeList; + + const BuildICD10CodeList({ + super.key, + required this.icd10CodeController, + required this.icd10codeList, + }); + + @override + State createState() => _BuildPatientsListState(); +} + +class _BuildPatientsListState extends State { + String baseAPI = AppEnviroment.baseApiUrl; + int counter = 0; + + Widget displayCode(int index) { + String title = "ICD-10 Code: ${widget.icd10codeList[index].icd10}"; + String description = + "Description: ${widget.icd10codeList[index].description}"; + return ListTile( + title: Text( + title, + style: TextStyle( + color: MzanziInnovationHub.of(context)!.theme.secondaryColor(), + ), + ), + subtitle: RichText( + text: TextSpan( + text: description, + style: DefaultTextStyle.of(context).style, + ), + ), + onTap: () { + //select code + setState(() { + widget.icd10CodeController.text = + "${widget.icd10codeList[index].icd10} - ${widget.icd10codeList[index].description}"; + }); + Navigator.of(context).pop(); + }, + ); + } + + @override + void dispose() { + super.dispose(); + } + + @override + Widget build(BuildContext context) { + return ListView.separated( + physics: const NeverScrollableScrollPhysics(), + shrinkWrap: true, + separatorBuilder: (BuildContext context, index) { + return Divider( + color: MzanziInnovationHub.of(context)!.theme.secondaryColor(), + ); + }, + itemCount: widget.icd10codeList.length, + itemBuilder: (context, index) { + //final patient = widget.patients[index].id_no.contains(widget.searchString); + //print(index); + return displayCode(index); + }, + ); + } +} From 08960fc329d44d9a220d6bab7f6edad0a52e5104 Mon Sep 17 00:00:00 2001 From: Yasien Mac Mini Date: Mon, 17 Mar 2025 14:22:17 +0200 Subject: [PATCH 14/17] move med search into pat pro package components --- .../lib/mih_components/medicine_search.dart | 202 ------------------ .../components/medicine_search.dart | 112 ++++++++++ 2 files changed, 112 insertions(+), 202 deletions(-) delete mode 100644 Frontend/lib/mih_components/medicine_search.dart create mode 100644 Frontend/lib/mih_packages/patient_profile/pat_profile/components/medicine_search.dart diff --git a/Frontend/lib/mih_components/medicine_search.dart b/Frontend/lib/mih_components/medicine_search.dart deleted file mode 100644 index 8db4b912..00000000 --- a/Frontend/lib/mih_components/medicine_search.dart +++ /dev/null @@ -1,202 +0,0 @@ -import 'dart:convert'; - -import 'package:flutter/material.dart'; -import '../mih_components/mih_layout/mih_window.dart'; -import '../mih_packages/patient_profile/builder/build_med_list.dart'; -import '../mih_components/mih_pop_up_messages/mih_loading_circle.dart'; -import '../mih_components/mih_pop_up_messages/mih_error_message.dart'; -import '../mih_env/env.dart'; -import '../mih_objects/medicine.dart'; -import 'package:supertokens_flutter/http.dart' as http; - -class MedicineSearch extends StatefulWidget { - final TextEditingController searchVlaue; - const MedicineSearch({ - super.key, - required this.searchVlaue, - }); - - @override - State createState() => _MedicineSearchState(); -} - -class _MedicineSearchState extends State { - final String endpointMeds = "${AppEnviroment.baseApiUrl}/users/medicine/"; - - //TextEditingController searchController = TextEditingController(); - - late Future> futueMeds; - //String searchString = ""; - - Future> getMedList(String endpoint) async { - final response = await http.get(Uri.parse(endpoint)); - if (response.statusCode == 200) { - Iterable l = jsonDecode(response.body); - List medicines = - List.from(l.map((model) => Medicine.fromJson(model))); - // List meds = []; - // medicines.forEach((element) => meds.add(element.name)); - return medicines; - } else { - internetConnectionPopUp(); - throw Exception('failed to load medicine'); - } - } - - void internetConnectionPopUp() { - showDialog( - context: context, - builder: (context) { - return const MIHErrorMessage(errorType: "Internet Connection"); - }, - ); - } - - @override - void dispose() { - super.dispose(); - } - - @override - void initState() { - futueMeds = getMedList(endpointMeds + widget.searchVlaue.text); - super.initState(); - } - - @override - Widget build(BuildContext context) { - return MIHWindow( - fullscreen: false, - windowTitle: "Select Medicine", - windowTools: [], - onWindowTapClose: () { - Navigator.pop(context); - }, - windowBody: [ - FutureBuilder( - future: futueMeds, - builder: (context, snapshot) { - if (snapshot.connectionState == ConnectionState.waiting) { - return const SizedBox( - height: 400, - child: Mihloadingcircle(), - ); - } else if (snapshot.hasData && snapshot.data!.isNotEmpty) { - final medsList = snapshot.data!; - return SizedBox( - height: 400, - child: BuildMedicinesList( - contoller: widget.searchVlaue, - medicines: medsList, - //searchString: searchString, - ), - ); - } else { - return const SizedBox( - height: 400, - child: Center( - child: Text( - "No Match Found\nPlease close and manually capture medicine", - style: TextStyle(fontSize: 25, color: Colors.grey), - textAlign: TextAlign.center, - ), - ), - ); - } - }, - ), - ], - ); - // return Dialog( - // child: Stack( - // children: [ - // Container( - // padding: const EdgeInsets.all(10.0), - // width: 700.0, - // //height: 475.0, - // decoration: BoxDecoration( - // color: MzanziInnovationHub.of(context)!.theme.primaryColor(), - // borderRadius: BorderRadius.circular(25.0), - // border: Border.all( - // color: - // MzanziInnovationHub.of(context)!.theme.secondaryColor(), - // width: 5.0), - // ), - // child: SingleChildScrollView( - // padding: const EdgeInsets.symmetric(horizontal: 10), - // child: Column( - // crossAxisAlignment: CrossAxisAlignment.center, - // mainAxisAlignment: MainAxisAlignment.center, - // mainAxisSize: MainAxisSize.min, - // children: [ - // Text( - // "Select Medicine", - // textAlign: TextAlign.center, - // style: TextStyle( - // color: MzanziInnovationHub.of(context)! - // .theme - // .secondaryColor(), - // fontSize: 35.0, - // fontWeight: FontWeight.bold, - // ), - // ), - // const SizedBox(height: 25.0), - // FutureBuilder( - // future: futueMeds, - // builder: (context, snapshot) { - // if (snapshot.connectionState == ConnectionState.waiting) { - // return const SizedBox( - // height: 400, - // child: Mihloadingcircle(), - // ); - // } else if (snapshot.hasData && - // snapshot.data!.isNotEmpty) { - // final medsList = snapshot.data!; - // return SizedBox( - // height: 400, - // child: BuildMedicinesList( - // contoller: widget.searchVlaue, - // medicines: medsList, - // //searchString: searchString, - // ), - // ); - // } else { - // return const SizedBox( - // height: 400, - // child: Center( - // child: Text( - // "No Match Found\nPlease close and manually capture medicine", - // style: - // TextStyle(fontSize: 25, color: Colors.grey), - // textAlign: TextAlign.center, - // ), - // ), - // ); - // } - // }, - // ), - // ], - // ), - // ), - // ), - // Positioned( - // top: 5, - // right: 5, - // width: 50, - // height: 50, - // child: IconButton( - // onPressed: () { - // Navigator.pop(context); - // }, - // icon: const Icon( - // Icons.close, - // color: Colors.red, - // size: 35, - // ), - // ), - // ), - // ], - // ), - // ); - } -} diff --git a/Frontend/lib/mih_packages/patient_profile/pat_profile/components/medicine_search.dart b/Frontend/lib/mih_packages/patient_profile/pat_profile/components/medicine_search.dart new file mode 100644 index 00000000..af9c00c6 --- /dev/null +++ b/Frontend/lib/mih_packages/patient_profile/pat_profile/components/medicine_search.dart @@ -0,0 +1,112 @@ +import 'dart:convert'; + +import 'package:Mzansi_Innovation_Hub/mih_components/mih_layout/mih_window.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'; +import 'package:Mzansi_Innovation_Hub/mih_objects/medicine.dart'; +import 'package:Mzansi_Innovation_Hub/mih_packages/patient_profile/pat_profile/list_builders/build_med_list.dart'; +import 'package:flutter/material.dart'; + +import 'package:supertokens_flutter/http.dart' as http; + +class MedicineSearch extends StatefulWidget { + final TextEditingController searchVlaue; + const MedicineSearch({ + super.key, + required this.searchVlaue, + }); + + @override + State createState() => _MedicineSearchState(); +} + +class _MedicineSearchState extends State { + final String endpointMeds = "${AppEnviroment.baseApiUrl}/users/medicine/"; + + //TextEditingController searchController = TextEditingController(); + + late Future> futueMeds; + //String searchString = ""; + + Future> getMedList(String endpoint) async { + final response = await http.get(Uri.parse(endpoint)); + if (response.statusCode == 200) { + Iterable l = jsonDecode(response.body); + List medicines = + List.from(l.map((model) => Medicine.fromJson(model))); + // List meds = []; + // medicines.forEach((element) => meds.add(element.name)); + return medicines; + } else { + internetConnectionPopUp(); + throw Exception('failed to load medicine'); + } + } + + void internetConnectionPopUp() { + showDialog( + context: context, + builder: (context) { + return const MIHErrorMessage(errorType: "Internet Connection"); + }, + ); + } + + @override + void dispose() { + super.dispose(); + } + + @override + void initState() { + futueMeds = getMedList(endpointMeds + widget.searchVlaue.text); + super.initState(); + } + + @override + Widget build(BuildContext context) { + return MIHWindow( + fullscreen: false, + windowTitle: "Select Medicine", + windowTools: [], + onWindowTapClose: () { + Navigator.pop(context); + }, + windowBody: [ + FutureBuilder( + future: futueMeds, + builder: (context, snapshot) { + if (snapshot.connectionState == ConnectionState.waiting) { + return const SizedBox( + height: 400, + child: Mihloadingcircle(), + ); + } else if (snapshot.hasData && snapshot.data!.isNotEmpty) { + final medsList = snapshot.data!; + return SizedBox( + height: 400, + child: BuildMedicinesList( + contoller: widget.searchVlaue, + medicines: medsList, + //searchString: searchString, + ), + ); + } else { + return const SizedBox( + height: 400, + child: Center( + child: Text( + "No Match Found\nPlease close and manually capture medicine", + style: TextStyle(fontSize: 25, color: Colors.grey), + textAlign: TextAlign.center, + ), + ), + ); + } + }, + ), + ], + ); + } +} From ba2c713ef21d347fe3ec9568a246d5d81529d39b Mon Sep 17 00:00:00 2001 From: Yasien Mac Mini Date: Mon, 17 Mar 2025 14:22:48 +0200 Subject: [PATCH 15/17] add medicin builder topat proo build list --- .../list_builders/build_med_list.dart | 69 +++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 Frontend/lib/mih_packages/patient_profile/pat_profile/list_builders/build_med_list.dart diff --git a/Frontend/lib/mih_packages/patient_profile/pat_profile/list_builders/build_med_list.dart b/Frontend/lib/mih_packages/patient_profile/pat_profile/list_builders/build_med_list.dart new file mode 100644 index 00000000..f43124ae --- /dev/null +++ b/Frontend/lib/mih_packages/patient_profile/pat_profile/list_builders/build_med_list.dart @@ -0,0 +1,69 @@ +import 'package:Mzansi_Innovation_Hub/main.dart'; +import 'package:Mzansi_Innovation_Hub/mih_objects/medicine.dart'; +import 'package:flutter/material.dart'; + +class BuildMedicinesList extends StatefulWidget { + final TextEditingController contoller; + final List medicines; + //final searchString; + + const BuildMedicinesList({ + super.key, + required this.contoller, + required this.medicines, + //required this.searchString, + }); + + @override + State createState() => _BuildMedicinesListState(); +} + +class _BuildMedicinesListState extends State { + int indexOn = 0; + + @override + void dispose() { + // TODO: implement dispose + super.dispose(); + } + + @override + Widget build(BuildContext context) { + return ListView.separated( + separatorBuilder: (BuildContext context, int index) { + return Divider( + color: MzanziInnovationHub.of(context)!.theme.secondaryColor(), + ); + }, + itemCount: widget.medicines.length, + itemBuilder: (context, index) { + //final patient = widget.patients[index].id_no.contains(widget.searchString); + return ListTile( + title: Text( + widget.medicines[index].name, + style: TextStyle( + color: MzanziInnovationHub.of(context)!.theme.secondaryColor(), + ), + ), + subtitle: Text( + "${widget.medicines[index].unit} - ${widget.medicines[index].form}", + style: TextStyle( + color: MzanziInnovationHub.of(context)!.theme.secondaryColor(), + ), + ), + onTap: () { + setState(() { + widget.contoller.text = + "${widget.medicines[index].name}%t${widget.medicines[index].unit}%t${widget.medicines[index].form}"; + Navigator.of(context).pop(); + }); + }, + trailing: Icon( + Icons.arrow_forward, + color: MzanziInnovationHub.of(context)!.theme.secondaryColor(), + ), + ); + }, + ); + } +} From ee808c49de7fac09ada21256b3aa29347fefd548 Mon Sep 17 00:00:00 2001 From: Yasien Mac Mini Date: Mon, 17 Mar 2025 14:31:00 +0200 Subject: [PATCH 16/17] Use new med search component --- .../patient_profile/pat_profile/components/prescip_input.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Frontend/lib/mih_packages/patient_profile/pat_profile/components/prescip_input.dart b/Frontend/lib/mih_packages/patient_profile/pat_profile/components/prescip_input.dart index 411fcaff..19e246ce 100644 --- a/Frontend/lib/mih_packages/patient_profile/pat_profile/components/prescip_input.dart +++ b/Frontend/lib/mih_packages/patient_profile/pat_profile/components/prescip_input.dart @@ -1,7 +1,7 @@ import 'dart:convert'; import 'package:Mzansi_Innovation_Hub/main.dart'; -import 'package:Mzansi_Innovation_Hub/mih_components/medicine_search.dart'; +import 'package:Mzansi_Innovation_Hub/mih_packages/patient_profile/pat_profile/components/medicine_search.dart'; import 'package:Mzansi_Innovation_Hub/mih_components/mih_inputs_and_buttons/mih_button.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_search_input.dart'; From 99f9402a53311c4c038ea10bc4f321540be9ad9a Mon Sep 17 00:00:00 2001 From: Yasien Mac Mini Date: Mon, 17 Mar 2025 14:48:27 +0200 Subject: [PATCH 17/17] remove print --- .../patient_profile/pat_profile/patient_profile.dart | 1 - 1 file changed, 1 deletion(-) diff --git a/Frontend/lib/mih_packages/patient_profile/pat_profile/patient_profile.dart b/Frontend/lib/mih_packages/patient_profile/pat_profile/patient_profile.dart index 872e0994..031b71c5 100644 --- a/Frontend/lib/mih_packages/patient_profile/pat_profile/patient_profile.dart +++ b/Frontend/lib/mih_packages/patient_profile/pat_profile/patient_profile.dart @@ -23,7 +23,6 @@ class _PatientProfileState extends State { int _selcetedIndex = 0; @override Widget build(BuildContext context) { - print("Pat Profile: ${widget.arguments.businessUser!.business_id}"); return MihApp( appActionButton: getAction(), appTools: getTools(),