From ff858c7de06e6fc68728f3bc5386fcf97a70dd28 Mon Sep 17 00:00:00 2001 From: Yasien Mac Mini Date: Wed, 26 Feb 2025 11:41:27 +0200 Subject: [PATCH 1/8] Business profile and Manage patient tile name change --- Frontend/lib/mih_packages/mih_home/mih_home.dart | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Frontend/lib/mih_packages/mih_home/mih_home.dart b/Frontend/lib/mih_packages/mih_home/mih_home.dart index 1b6d6e76..fec179d6 100644 --- a/Frontend/lib/mih_packages/mih_home/mih_home.dart +++ b/Frontend/lib/mih_packages/mih_home/mih_home.dart @@ -363,7 +363,7 @@ class _MIHHomeState extends State { ), ); }, - tileName: "Business Profile", + tileName: "Biz Profile", tileIcon: Center( child: FaIcon( FontAwesomeIcons.buildingUser, @@ -407,7 +407,7 @@ class _MIHHomeState extends State { ), ); }, - tileName: "Manage Patient", + tileName: "Pat Manager", tileIcon: Center( child: FaIcon( FontAwesomeIcons.bookMedical, @@ -1118,8 +1118,8 @@ class _MIHHomeState extends State { physics: const NeverScrollableScrollPhysics(), shrinkWrap: true, padding: EdgeInsets.only( - left: width / 10, - right: width / 10, + left: width / 13, + right: width / 13, bottom: height / 15, //top: 20, ), From 10a276ceb5685e7a393ef9ddf284a149f3c2a01a Mon Sep 17 00:00:00 2001 From: Yasien Mac Mini Date: Tue, 4 Mar 2025 09:04:18 +0200 Subject: [PATCH 2/8] update pat man route args --- Frontend/lib/mih_router/routeGenerator.dart | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/Frontend/lib/mih_router/routeGenerator.dart b/Frontend/lib/mih_router/routeGenerator.dart index fc055de1..b26bfbc5 100644 --- a/Frontend/lib/mih_router/routeGenerator.dart +++ b/Frontend/lib/mih_router/routeGenerator.dart @@ -6,6 +6,7 @@ import 'package:Mzansi_Innovation_Hub/mih_packages/mih_policy_tos/mih_terms_of_s import 'package:Mzansi_Innovation_Hub/mih_packages/mzansi_ai/mzansi_ai.dart'; import 'package:Mzansi_Innovation_Hub/mih_packages/mzansi_wallet/mih_barcode_scanner.dart'; import 'package:Mzansi_Innovation_Hub/mih_packages/mzansi_wallet/mzansi_wallet.dart'; +import 'package:Mzansi_Innovation_Hub/mih_packages/patient_profile/pat_manager/pat_manager.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'; @@ -13,7 +14,7 @@ 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_packages/patient_profile/patient_manager.dart'; +// import '../mih_packages/patient_profile/patient_manager.dart'; import '../mih_objects/app_user.dart'; import '../mih_objects/arguments.dart'; import '../mih_packages/about_mih/mih_about.dart'; @@ -244,13 +245,16 @@ class RouteGenerator { //Patient Manager Pages case '/patient-manager': - if (args is BusinessArguments) { + if (args is PatManagerArguments) { //print("route generator: $args"); return MaterialPageRoute( settings: settings, - builder: (_) => PatientManager( + builder: (_) => PatManager( arguments: args, ), + // PatientManager( + // arguments: args, + // ), ); } return _errorRoute(); From b56100ccb15693ca84489e68f7877a22796e6ab6 Mon Sep 17 00:00:00 2001 From: Yasien Mac Mini Date: Tue, 4 Mar 2025 09:04:56 +0200 Subject: [PATCH 3/8] remove notification APIs for its own file --- Frontend/lib/mih_apis/mih_api_calls.dart | 263 +--------------- .../lib/mih_apis/mih_notification_apis.dart | 295 ++++++++++++++++++ 2 files changed, 311 insertions(+), 247 deletions(-) create mode 100644 Frontend/lib/mih_apis/mih_notification_apis.dart diff --git a/Frontend/lib/mih_apis/mih_api_calls.dart b/Frontend/lib/mih_apis/mih_api_calls.dart index 6c26ebc3..e8020fce 100644 --- a/Frontend/lib/mih_apis/mih_api_calls.dart +++ b/Frontend/lib/mih_apis/mih_api_calls.dart @@ -1,5 +1,6 @@ import 'dart:convert'; +import 'package:Mzansi_Innovation_Hub/mih_apis/mih_notification_apis.dart'; import 'package:flutter/material.dart'; // import '../mih_components/mih_pop_up_messages/mih_error_message.dart'; // import '../mih_components/mih_pop_up_messages/mih_success_message.dart'; @@ -317,6 +318,7 @@ class MIHApiCalls { static Future reapplyPatientAccessAPICall( String business_id, String app_id, + bool personalSelected, BusinessArguments args, BuildContext context, ) async { @@ -335,7 +337,8 @@ class MIHApiCalls { }), ); if (response.statusCode == 200) { - reapplyAccessRequestNotificationAPICall(app_id, args, context); + MihNotificationApis.reapplyAccessRequestNotificationAPICall( + app_id, personalSelected, args, context); //notification here } else { internetConnectionPopUp(context); @@ -357,6 +360,7 @@ class MIHApiCalls { String app_id, String type, String requested_by, + bool personalSelected, BusinessArguments args, BuildContext context, ) async { @@ -377,7 +381,8 @@ class MIHApiCalls { }), ); if (response.statusCode == 201) { - addAccessRequestNotificationAPICall(app_id, requested_by, args, context); + MihNotificationApis.addAccessRequestNotificationAPICall( + app_id, requested_by, personalSelected, args, context); } else { internetConnectionPopUp(context); } @@ -431,248 +436,6 @@ class MIHApiCalls { } } - //================== Notifications ========================================================================== - - /// This function is used to create notification to patient for access reviews - /// - /// Patameters:- - /// String app_id, - /// String business_name, - /// BuildContext context, - /// - /// Returns void. (ON SUCCESS 201 , NAVIGATE TO /patient-manager) - static Future addAccessRequestNotificationAPICall( - String app_id, - String business_name, - BusinessArguments args, - BuildContext context, - ) async { - var response = await http.post( - Uri.parse("${AppEnviroment.baseApiUrl}/notifications/insert/"), - headers: { - "Content-Type": "application/json; charset=UTF-8" - }, - body: jsonEncode({ - "app_id": app_id, - "notification_type": "Forever Access Request", - "notification_message": - "A new Forever Access Request has been sent by $business_name in order to access your Patient Profile. Please review request.", - "action_path": "/access-review", - }), - ); - if (response.statusCode == 201) { - String message = - "A request has been sent to the patient advising that you have requested access to their profile. Only once access has been granted will you be able to book an appointment."; - Navigator.of(context).pop(); - Navigator.of(context).pop(); - Navigator.of(context).pushNamed( - '/patient-manager', - arguments: BusinessArguments( - args.signedInUser, - args.businessUser, - args.business, - ), - ); - successPopUp(message, context); - } else { - internetConnectionPopUp(context); - } - } - - /// This function is used to create notification to patient for access reviews - /// - /// Patameters:- - /// String app_id, - /// String business_name, - /// BuildContext context, - /// - /// Returns void. (ON SUCCESS 201 , NAVIGATE TO /patient-manager) - static Future reapplyAccessRequestNotificationAPICall( - String app_id, - BusinessArguments args, - BuildContext context, - ) async { - var response = await http.post( - Uri.parse("${AppEnviroment.baseApiUrl}/notifications/insert/"), - headers: { - "Content-Type": "application/json; charset=UTF-8" - }, - body: jsonEncode({ - "app_id": app_id, - "notification_type": "Re-applying for Access", - "notification_message": - "${args.business!.Name} is re-applying for access to your Patient Profile. Please review request.", - "action_path": "/access-review", - }), - ); - if (response.statusCode == 201) { - String message = - "A request has been sent to the patient advising that you have re-applied for access to their profile. Only once access has been granted will you be able to book an appointment."; - Navigator.of(context).pop(); - Navigator.of(context).pop(); - Navigator.of(context).pushNamed( - '/patient-manager', - arguments: args, - ); - successPopUp(message, context); - } else { - internetConnectionPopUp(context); - } - } - - /// This function is used to create notification to patient for access reviews - /// - /// Patameters:- - /// String app_id, - /// String business_name, - /// String origDate_time, - /// String date, - /// String time, - /// BusinessArguments args, - /// BuildContext context, - /// - /// Returns void. (ON SUCCESS 201 , NAVIGATE TO /patient-manager) - static Future addRescheduledAppointmentNotificationAPICall( - String app_id, - String business_name, - String origDate_time, - String date, - String time, - BusinessArguments args, - BuildContext context, - ) async { - var response = await http.post( - Uri.parse("${AppEnviroment.baseApiUrl}/notifications/insert/"), - headers: { - "Content-Type": "application/json; charset=UTF-8" - }, - body: jsonEncode({ - "app_id": app_id, - "notification_type": "Appointment Rescheduled", - "notification_message": - "Your appointment with $business_name for the ${origDate_time.replaceAll("T", " ").substring(0, origDate_time.length - 3)} has been rescheduled to the ${date} ${time}.", - "action_path": "/appointments", - }), - ); - if (response.statusCode == 201) { - Navigator.of(context).pop(); - Navigator.of(context).pop(); - Navigator.of(context).pop(); - Navigator.of(context).pushNamed( - '/patient-manager', - arguments: BusinessArguments( - args.signedInUser, - args.businessUser, - args.business, - ), - ); - String message = "The appointment has been successfully rescheduled."; - - successPopUp(message, context); - } else { - internetConnectionPopUp(context); - } - } - - /// This function is used to create notification to patient for access reviews - /// - /// Patameters:- - /// String app_id, - /// String business_name, - /// String origDate_time, - /// String date, - /// String time, - /// BusinessArguments args, - /// BuildContext context, - /// - /// Returns void. (ON SUCCESS 201 , NAVIGATE TO /patient-manager) - static Future addCancelledAppointmentNotificationAPICall( - String app_id, - String date_time, - BusinessArguments args, - BuildContext context, - ) async { - var response = await http.post( - Uri.parse("${AppEnviroment.baseApiUrl}/notifications/insert/"), - headers: { - "Content-Type": "application/json; charset=UTF-8" - }, - body: jsonEncode({ - "app_id": app_id, - "notification_type": "Appointment Cancelled", - "notification_message": - "Your appointment with ${args.business!.Name} for the ${date_time.replaceAll("T", " ")} has been cancelled.", - "action_path": "/appointments", - }), - ); - if (response.statusCode == 201) { - Navigator.of(context).pop(); - Navigator.of(context).pop(); - Navigator.of(context).pop(); - Navigator.of(context).pushNamed( - '/patient-manager', - arguments: BusinessArguments( - args.signedInUser, - args.businessUser, - args.business, - ), - ); - String message = - "The appointment has been cancelled successfully. This means it will no longer be visible in your waiting room and calender."; - successPopUp(message, context); - } else { - internetConnectionPopUp(context); - } - } - - /// This function is used to create notification to patient for access reviews - /// - /// Patameters:- - /// String app_id, - /// String business_name, - /// String origDate_time, - /// String date, - /// String time, - /// BusinessArguments args, - /// BuildContext context, - /// - /// Returns void. (ON SUCCESS 201 , NAVIGATE TO /patient-manager) - static Future addNewAppointmentNotificationAPICall( - String app_id, - String date, - String time, - BusinessArguments args, - BuildContext context, - ) async { - var response = await http.post( - Uri.parse("${AppEnviroment.baseApiUrl}/notifications/insert/"), - headers: { - "Content-Type": "application/json; charset=UTF-8" - }, - body: jsonEncode({ - "app_id": app_id, - "notification_type": "New Appointment Booked", - "notification_message": - "An appointment with ${args.business!.Name} has been booked for the $date $time.", - "action_path": "/appointments", - }), - ); - if (response.statusCode == 201) { - Navigator.of(context).pop(); - Navigator.of(context).pop(); - Navigator.of(context).pop(); - Navigator.of(context).pushNamed( - '/patient-manager', - arguments: args, - ); - String message = - "The appointment was been created successfully. This means it will now be visible in your waiting room and calender."; - successPopUp(message, context); - } else { - internetConnectionPopUp(context); - } - } - //================== APPOINTMENT/ PATIENT QUEUE ========================================================================== /// This function is used to fetch a list of appointments for a doctors office for a date. @@ -755,6 +518,7 @@ class MIHApiCalls { static Future updateApointmentAPICall( int idpatient_queue, String app_id, + bool personalSelected, String business_name, String origDate_time, String date, @@ -774,8 +538,9 @@ class MIHApiCalls { }), ); if (response.statusCode == 200) { - addRescheduledAppointmentNotificationAPICall( + MihNotificationApis.addRescheduledAppointmentNotificationAPICall( app_id, + personalSelected, business_name, origDate_time, date, @@ -799,6 +564,7 @@ class MIHApiCalls { static Future deleteApointmentAPICall( int idpatient_queue, String app_id, + bool personalSelected, String date_time, BusinessArguments args, BuildContext context, @@ -813,8 +579,9 @@ class MIHApiCalls { //print("Here4"); //print(response.statusCode); if (response.statusCode == 200) { - addCancelledAppointmentNotificationAPICall( + MihNotificationApis.addCancelledAppointmentNotificationAPICall( app_id, + personalSelected, date_time, args, context, @@ -840,6 +607,7 @@ class MIHApiCalls { static Future addAppointmentAPICall( String business_id, String app_id, + bool personalSelected, String date, String time, BusinessArguments args, @@ -884,8 +652,9 @@ class MIHApiCalls { // String time, // BusinessArguments args, // BuildContext context, - addNewAppointmentNotificationAPICall( + MihNotificationApis.addNewAppointmentNotificationAPICall( app_id, + personalSelected, date, time, args, diff --git a/Frontend/lib/mih_apis/mih_notification_apis.dart b/Frontend/lib/mih_apis/mih_notification_apis.dart new file mode 100644 index 00000000..ba62292d --- /dev/null +++ b/Frontend/lib/mih_apis/mih_notification_apis.dart @@ -0,0 +1,295 @@ +import 'dart:convert'; + +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/arguments.dart'; +import 'package:flutter/material.dart'; +import 'package:supertokens_flutter/http.dart' as http; + +class MihNotificationApis { + final baseAPI = AppEnviroment.baseApiUrl; +//================== Notifications ========================================================================== + + /// This function is used to create notification to patient for access reviews + /// + /// Patameters:- + /// String app_id, + /// String business_name, + /// BuildContext context, + /// + /// Returns void. (ON SUCCESS 201 , NAVIGATE TO /patient-manager) + static Future addAccessRequestNotificationAPICall( + String app_id, + String business_name, + bool personalSelected, + BusinessArguments args, + BuildContext context, + ) async { + var response = await http.post( + Uri.parse("${AppEnviroment.baseApiUrl}/notifications/insert/"), + headers: { + "Content-Type": "application/json; charset=UTF-8" + }, + body: jsonEncode({ + "app_id": app_id, + "notification_type": "Forever Access Request", + "notification_message": + "A new Forever Access Request has been sent by $business_name in order to access your Patient Profile. Please review request.", + "action_path": "/access-review", + }), + ); + if (response.statusCode == 201) { + String message = + "A request has been sent to the patient advising that you have requested access to their profile. Only once access has been granted will you be able to book an appointment."; + Navigator.of(context).pop(); + Navigator.of(context).pop(); + Navigator.of(context).pushNamed( + '/patient-manager', + arguments: PatManagerArguments( + args.signedInUser, + personalSelected, + args.business, + args.businessUser, + ), + ); + successPopUp(message, context); + } else { + internetConnectionPopUp(context); + } + } + + /// This function is used to create notification to patient for access reviews + /// + /// Patameters:- + /// String app_id, + /// String business_name, + /// BuildContext context, + /// + /// Returns void. (ON SUCCESS 201 , NAVIGATE TO /patient-manager) + static Future reapplyAccessRequestNotificationAPICall( + String app_id, + bool personalSelected, + BusinessArguments args, + BuildContext context, + ) async { + var response = await http.post( + Uri.parse("${AppEnviroment.baseApiUrl}/notifications/insert/"), + headers: { + "Content-Type": "application/json; charset=UTF-8" + }, + body: jsonEncode({ + "app_id": app_id, + "notification_type": "Re-applying for Access", + "notification_message": + "${args.business!.Name} is re-applying for access to your Patient Profile. Please review request.", + "action_path": "/access-review", + }), + ); + if (response.statusCode == 201) { + String message = + "A request has been sent to the patient advising that you have re-applied for access to their profile. Only once access has been granted will you be able to book an appointment."; + Navigator.of(context).pop(); + Navigator.of(context).pop(); + Navigator.of(context).pushNamed( + '/patient-manager', + arguments: PatManagerArguments( + args.signedInUser, + personalSelected, + args.business, + args.businessUser, + ), + ); + successPopUp(message, context); + } else { + internetConnectionPopUp(context); + } + } + + /// This function is used to create notification to patient for access reviews + /// + /// Patameters:- + /// String app_id, + /// String business_name, + /// String origDate_time, + /// String date, + /// String time, + /// BusinessArguments args, + /// BuildContext context, + /// + /// Returns void. (ON SUCCESS 201 , NAVIGATE TO /patient-manager) + static Future addRescheduledAppointmentNotificationAPICall( + String app_id, + bool personalSelected, + String business_name, + String origDate_time, + String date, + String time, + BusinessArguments args, + BuildContext context, + ) async { + var response = await http.post( + Uri.parse("${AppEnviroment.baseApiUrl}/notifications/insert/"), + headers: { + "Content-Type": "application/json; charset=UTF-8" + }, + body: jsonEncode({ + "app_id": app_id, + "notification_type": "Appointment Rescheduled", + "notification_message": + "Your appointment with $business_name for the ${origDate_time.replaceAll("T", " ").substring(0, origDate_time.length - 3)} has been rescheduled to the ${date} ${time}.", + "action_path": "/appointments", + }), + ); + if (response.statusCode == 201) { + Navigator.of(context).pop(); + Navigator.of(context).pop(); + Navigator.of(context).pop(); + Navigator.of(context).pushNamed( + '/patient-manager', + arguments: PatManagerArguments( + args.signedInUser, + personalSelected, + args.business, + args.businessUser, + ), + ); + String message = "The appointment has been successfully rescheduled."; + + successPopUp(message, context); + } else { + internetConnectionPopUp(context); + } + } + + /// This function is used to create notification to patient for access reviews + /// + /// Patameters:- + /// String app_id, + /// String business_name, + /// String origDate_time, + /// String date, + /// String time, + /// BusinessArguments args, + /// BuildContext context, + /// + /// Returns void. (ON SUCCESS 201 , NAVIGATE TO /patient-manager) + static Future addCancelledAppointmentNotificationAPICall( + String app_id, + bool personalSelected, + String date_time, + BusinessArguments args, + BuildContext context, + ) async { + var response = await http.post( + Uri.parse("${AppEnviroment.baseApiUrl}/notifications/insert/"), + headers: { + "Content-Type": "application/json; charset=UTF-8" + }, + body: jsonEncode({ + "app_id": app_id, + "notification_type": "Appointment Cancelled", + "notification_message": + "Your appointment with ${args.business!.Name} for the ${date_time.replaceAll("T", " ")} has been cancelled.", + "action_path": "/appointments", + }), + ); + if (response.statusCode == 201) { + Navigator.of(context).pop(); + Navigator.of(context).pop(); + Navigator.of(context).pop(); + Navigator.of(context).pushNamed( + '/patient-manager', + arguments: PatManagerArguments( + args.signedInUser, + personalSelected, + args.business, + args.businessUser, + ), + ); + String message = + "The appointment has been cancelled successfully. This means it will no longer be visible in your waiting room and calender."; + successPopUp(message, context); + } else { + internetConnectionPopUp(context); + } + } + + /// This function is used to create notification to patient for access reviews + /// + /// Patameters:- + /// String app_id, + /// String business_name, + /// String origDate_time, + /// String date, + /// String time, + /// BusinessArguments args, + /// BuildContext context, + /// + /// Returns void. (ON SUCCESS 201 , NAVIGATE TO /patient-manager) + static Future addNewAppointmentNotificationAPICall( + String app_id, + bool personalSelected, + String date, + String time, + BusinessArguments args, + BuildContext context, + ) async { + var response = await http.post( + Uri.parse("${AppEnviroment.baseApiUrl}/notifications/insert/"), + headers: { + "Content-Type": "application/json; charset=UTF-8" + }, + body: jsonEncode({ + "app_id": app_id, + "notification_type": "New Appointment Booked", + "notification_message": + "An appointment with ${args.business!.Name} has been booked for the $date $time.", + "action_path": "/appointments", + }), + ); + if (response.statusCode == 201) { + Navigator.of(context).pop(); + Navigator.of(context).pop(); + Navigator.of(context).pop(); + Navigator.of(context).pushNamed( + '/patient-manager', + arguments: PatManagerArguments( + args.signedInUser, + personalSelected, + args.business, + args.businessUser, + ), + ); + String message = + "The appointment was been created successfully. This means it will now be visible in your waiting room and calender."; + successPopUp(message, context); + } else { + internetConnectionPopUp(context); + } + } +//================== POP UPS ========================================================================== + + static void internetConnectionPopUp(BuildContext context) { + showDialog( + context: context, + builder: (context) { + return const MIHErrorMessage( + errorType: "Internet Connection", + ); + }, + ); + } + + static void successPopUp(String message, BuildContext context) { + showDialog( + context: context, + builder: (context) { + return MIHSuccessMessage( + successType: "Success", + successMessage: message, + ); + }, + ); + } +} From 54bef54563024ce36ca83e07b59b4843d8090541 Mon Sep 17 00:00:00 2001 From: Yasien Mac Mini Date: Tue, 4 Mar 2025 09:05:18 +0200 Subject: [PATCH 4/8] Create pat Manager argument object --- Frontend/lib/mih_objects/arguments.dart | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/Frontend/lib/mih_objects/arguments.dart b/Frontend/lib/mih_objects/arguments.dart index 40c82875..26dab93b 100644 --- a/Frontend/lib/mih_objects/arguments.dart +++ b/Frontend/lib/mih_objects/arguments.dart @@ -181,3 +181,17 @@ class CalendarArguments { this.business, ); } + +class PatManagerArguments { + final AppUser signedInUser; + final bool personalSelected; + final Business? business; + final BusinessUser? businessUser; + + PatManagerArguments( + this.signedInUser, + this.personalSelected, + this.business, + this.businessUser, + ); +} From 5e11e4522a6fd1e23cd49cfed27d04744613c9d2 Mon Sep 17 00:00:00 2001 From: Yasien Mac Mini Date: Tue, 4 Mar 2025 09:05:51 +0200 Subject: [PATCH 5/8] add create patient appointmnt api call --- .../mih_apis/mih_mzansi_calendar_apis.dart | 74 ++++++++++++++++++- 1 file changed, 72 insertions(+), 2 deletions(-) diff --git a/Frontend/lib/mih_apis/mih_mzansi_calendar_apis.dart b/Frontend/lib/mih_apis/mih_mzansi_calendar_apis.dart index 3f2e58fb..ec92f021 100644 --- a/Frontend/lib/mih_apis/mih_mzansi_calendar_apis.dart +++ b/Frontend/lib/mih_apis/mih_mzansi_calendar_apis.dart @@ -1,5 +1,6 @@ import 'dart:convert'; +import 'package:Mzansi_Innovation_Hub/mih_apis/mih_notification_apis.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/appointment.dart'; @@ -69,6 +70,7 @@ class MihMzansiCalendarApis { /// Returns Future>. static Future> getBusinessAppointments( String business_id, + bool waitingRoom, String date, ) async { //print("Patien manager page: $endpoint"); @@ -88,6 +90,15 @@ class MihMzansiCalendarApis { List.from(l.map((model) => Appointment.fromJson(model))); //print("Here3"); //print(patientQueue); + if (waitingRoom == true) { + businessAppointments = businessAppointments + .where((element) => element.app_id != "") + .toList(); + } else { + businessAppointments = businessAppointments + .where((element) => element.app_id == "") + .toList(); + } return businessAppointments; } else { throw Exception('failed to fatch business appointments'); @@ -248,6 +259,60 @@ class MihMzansiCalendarApis { } } + /// This function is used to add an appointment to users mzansi Calendar. + /// + /// Patameters:- + /// AppUser signedInUser, + /// String app_id, + /// String title, + /// String description, + /// String date, + /// String time, + /// BuildContext context, + /// + /// Returns VOID (TRIGGERS SUCCESS pop up) + static Future addPatientAppointment( + AppUser signedInUser, + bool personalSelected, + String patientAppId, + BusinessArguments businessArgs, + String title, + String description, + String date, + String time, + BuildContext context, + ) async { + loadingPopUp(context); + var response = await http.post( + Uri.parse("${AppEnviroment.baseApiUrl}/appointment/insert/"), + headers: { + "Content-Type": "application/json; charset=UTF-8" + }, + body: jsonEncode({ + "app_id": patientAppId, + "business_id": businessArgs.business?.business_id, + "title": title, + "description": description, + "date": date, + "time": time, + }), + ); + if (response.statusCode == 201) { + MihNotificationApis.addNewAppointmentNotificationAPICall( + patientAppId, + personalSelected, + date, + time, + businessArgs, + context, + ); + // Navigator.pop(context); + } else { + Navigator.pop(context); + internetConnectionPopUp(context); + } + } + /// This function is used to update an appointment to users mzansi Calendar. /// /// Patameters:- @@ -263,6 +328,7 @@ class MihMzansiCalendarApis { /// Returns VOID (TRIGGERS SUCCESS pop up) static Future updatePersonalAppointment( AppUser signedInUser, + Business? business, int idappointments, String title, String description, @@ -285,7 +351,7 @@ class MihMzansiCalendarApis { }), ); if (response.statusCode == 200) { - Navigator.pop(context); + // Navigator.pop(context); Navigator.pop(context); Navigator.pop(context); String message = @@ -294,7 +360,11 @@ class MihMzansiCalendarApis { Navigator.pop(context); Navigator.of(context).pushNamed( '/calendar', - arguments: signedInUser, + arguments: CalendarArguments( + signedInUser, + true, + business, + ), ); successPopUp(message, context); } else { From eff4fae83eb542f0d3bd2f183b1e73a86c41f7ff Mon Sep 17 00:00:00 2001 From: Yasien Mac Mini Date: Tue, 4 Mar 2025 09:06:16 +0200 Subject: [PATCH 6/8] new Pat manager files --- .../mih_packages/calendar/appointments.dart | 56 +- .../builder/build_appointment_list.dart | 145 +++- .../lib/mih_packages/mih_home/mih_home.dart | 5 +- .../builder/build_patient_access_list.dart | 1 + .../builder/build_patient_list.dart | 29 +- .../builder/build_patient_queue_list.dart | 2 + .../app_tools/mih_patient_search.dart | 223 ++++++ .../app_tools/my_patient_list.dart | 202 ++++++ .../pat_manager/app_tools/waiting_room.dart | 348 +++++++++ .../build_mih_patient_search_list.dart | 665 ++++++++++++++++++ .../build_my_patient_list_list.dart | 385 ++++++++++ .../build_waiting_room_list.dart | 15 + .../pat_manager/pat_manager.dart | 101 +++ .../patient_profile/patient_manager.dart | 170 +++-- Frontend/pubspec.lock | 74 +- 15 files changed, 2253 insertions(+), 168 deletions(-) create mode 100644 Frontend/lib/mih_packages/patient_profile/pat_manager/app_tools/mih_patient_search.dart create mode 100644 Frontend/lib/mih_packages/patient_profile/pat_manager/app_tools/my_patient_list.dart create mode 100644 Frontend/lib/mih_packages/patient_profile/pat_manager/app_tools/waiting_room.dart create mode 100644 Frontend/lib/mih_packages/patient_profile/pat_manager/list_builders/build_mih_patient_search_list.dart create mode 100644 Frontend/lib/mih_packages/patient_profile/pat_manager/list_builders/build_my_patient_list_list.dart create mode 100644 Frontend/lib/mih_packages/patient_profile/pat_manager/list_builders/build_waiting_room_list.dart create mode 100644 Frontend/lib/mih_packages/patient_profile/pat_manager/pat_manager.dart diff --git a/Frontend/lib/mih_packages/calendar/appointments.dart b/Frontend/lib/mih_packages/calendar/appointments.dart index 83ecc6a0..74e76eaa 100644 --- a/Frontend/lib/mih_packages/calendar/appointments.dart +++ b/Frontend/lib/mih_packages/calendar/appointments.dart @@ -8,15 +8,12 @@ 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_objects/appointment.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_packages/calendar/builder/build_appointment_list.dart'; import 'package:flutter/material.dart'; import '../../main.dart'; import '../../mih_components/mih_calendar.dart'; -import '../../mih_components/mih_layout/mih_action.dart'; -import '../../mih_components/mih_layout/mih_header.dart'; import '../../mih_components/mih_pop_up_messages/mih_loading_circle.dart'; import '../../mih_env/env.dart'; import '../../mih_objects/app_user.dart'; @@ -38,8 +35,8 @@ class Appointments extends StatefulWidget { } class _PatientAccessRequestState extends State { - TextEditingController filterController = TextEditingController(); - TextEditingController appointmentDateController = TextEditingController(); + TextEditingController selectedAppointmentDateController = + TextEditingController(); final TextEditingController _appointmentTitleController = TextEditingController(); final TextEditingController _appointmentDescriptionIDController = @@ -50,12 +47,6 @@ class _PatientAccessRequestState extends State { TextEditingController(); String baseUrl = AppEnviroment.baseApiUrl; - String errorCode = ""; - String errorBody = ""; - String datefilter = ""; - String accessFilter = ""; - bool forceRefresh = false; - late String selectedDropdown; String selectedDay = DateTime.now().toString().split(" ")[0]; late Future> personalAppointmentResults; @@ -68,8 +59,12 @@ class _PatientAccessRequestState extends State { child: BuildAppointmentList( appointmentList: appointmentList, signedInUser: widget.signedInUser, + business: widget.business, + personalSelected: widget.personalSelected, + inWaitingRoom: false, titleController: _appointmentTitleController, descriptionIDController: _appointmentDescriptionIDController, + patientIdController: null, dateController: _appointmentDateController, timeController: _appointmentTimeController, ), @@ -227,6 +222,7 @@ class _PatientAccessRequestState extends State { if (widget.personalSelected == false) { appointmentResults = MihMzansiCalendarApis.getBusinessAppointments( widget.business!.business_id, + false, selectedDay, ); } else { @@ -238,36 +234,6 @@ class _PatientAccessRequestState extends State { }); } - MIHAction getActionButton() { - return MIHAction( - icon: const Icon(Icons.arrow_back), - iconSize: 35, - onTap: () { - Navigator.of(context).pop(); - - Navigator.of(context).popAndPushNamed( - '/', - arguments: AuthArguments(true, false), - ); - }, - ); - } - - MIHHeader getHeader() { - return const MIHHeader( - headerAlignment: MainAxisAlignment.center, - headerItems: [ - Text( - "Appointments", - style: TextStyle( - fontWeight: FontWeight.bold, - fontSize: 25, - ), - ), - ], - ); - } - Widget getBody() { return Stack( children: [ @@ -286,7 +252,7 @@ class _PatientAccessRequestState extends State { setDate: (value) { setState(() { selectedDay = value; - appointmentDateController.text = selectedDay; + selectedAppointmentDateController.text = selectedDay; }); }), // Divider( @@ -348,8 +314,7 @@ class _PatientAccessRequestState extends State { @override void dispose() { - filterController.dispose(); - appointmentDateController.dispose(); + selectedAppointmentDateController.dispose(); _appointmentDateController.dispose(); _appointmentTimeController.dispose(); _appointmentTitleController.dispose(); @@ -359,11 +324,12 @@ class _PatientAccessRequestState extends State { @override void initState() { - appointmentDateController.addListener(checkforchange); + selectedAppointmentDateController.addListener(checkforchange); setState(() { if (widget.personalSelected == false) { appointmentResults = MihMzansiCalendarApis.getBusinessAppointments( widget.business!.business_id, + false, selectedDay, ); } else { diff --git a/Frontend/lib/mih_packages/calendar/builder/build_appointment_list.dart b/Frontend/lib/mih_packages/calendar/builder/build_appointment_list.dart index 35f98784..5ef3b9d6 100644 --- a/Frontend/lib/mih_packages/calendar/builder/build_appointment_list.dart +++ b/Frontend/lib/mih_packages/calendar/builder/build_appointment_list.dart @@ -11,13 +11,18 @@ import 'package:Mzansi_Innovation_Hub/mih_components/mih_pop_up_messages/mih_err 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/appointment.dart'; +import 'package:Mzansi_Innovation_Hub/mih_objects/business.dart'; import 'package:flutter/material.dart'; class BuildAppointmentList extends StatefulWidget { final List appointmentList; final AppUser signedInUser; + final Business? business; + final bool personalSelected; + final bool inWaitingRoom; final TextEditingController titleController; final TextEditingController descriptionIDController; + final TextEditingController? patientIdController; final TextEditingController dateController; final TextEditingController timeController; @@ -25,8 +30,12 @@ class BuildAppointmentList extends StatefulWidget { super.key, required this.appointmentList, required this.signedInUser, + required this.business, + required this.personalSelected, + required this.inWaitingRoom, required this.titleController, required this.descriptionIDController, + required this.patientIdController, required this.dateController, required this.timeController, }); @@ -37,6 +46,7 @@ class BuildAppointmentList extends StatefulWidget { class _BuildAppointmentListState extends State { String baseAPI = AppEnviroment.baseApiUrl; + TextEditingController patientIdController = TextEditingController(); TextEditingController dateController = TextEditingController(); TextEditingController timeController = TextEditingController(); TextEditingController idController = TextEditingController(); @@ -122,7 +132,11 @@ class _BuildAppointmentListState extends State { .split('T')[1] .substring(0, 5); }); - appointmentDetailsWindow(index); + if (widget.inWaitingRoom == false) { + appointmentDetailsWindow(index); + } else { + waitingRiinAppointmentDetailsWindow(index); + } }, ), ), @@ -233,6 +247,120 @@ class _BuildAppointmentListState extends State { ); } + void waitingRiinAppointmentDetailsWindow(int index) { + showDialog( + context: context, + barrierDismissible: false, + builder: (context) { + return MIHWindow( + fullscreen: false, + windowTitle: "Appointment Details", + windowTools: [ + Visibility( + visible: canEditAppointment(index), + child: IconButton( + onPressed: () { + deleteAppointmentConfirmationWindow(index); + }, + icon: const Icon(Icons.delete), + ), + ), + ], + onWindowTapClose: () { + Navigator.of(context).pop(); + widget.dateController.clear(); + widget.timeController.clear(); + widget.titleController.clear(); + widget.descriptionIDController.clear(); + }, + windowBody: [ + SizedBox( + // width: 500, + child: MIHTextField( + controller: widget.titleController, + hintText: "Title", + editable: false, + required: false, + ), + ), + const SizedBox(height: 10), + SizedBox( + // width: 500, + child: MIHTextField( + controller: widget.titleController, + hintText: "Patient ID Number", + editable: false, + required: false, + ), + ), + const SizedBox(height: 10), + SizedBox( + // width: 500, + child: MIHTextField( + controller: widget.dateController, + hintText: "Date", + editable: false, + required: false, + )), + const SizedBox(height: 10), + SizedBox( + // width: 500, + child: MIHTextField( + controller: widget.timeController, + hintText: "Time", + editable: false, + required: false, + )), + const SizedBox(height: 10), + SizedBox( + // width: 500, + height: 250, + child: MIHMLTextField( + controller: widget.descriptionIDController, + hintText: "Description", + editable: false, + required: false, + ), + ), + const SizedBox(height: 20), + Visibility( + visible: canEditAppointment(index), + child: SizedBox( + width: 500, + height: 50, + child: MIHButton( + onTap: () { + appointmentUpdateWindow(index); + }, + buttonText: "Edit", + buttonColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + textColor: + MzanziInnovationHub.of(context)!.theme.primaryColor(), + ), + ), + ), + // SizedBox( + // width: 500, + // height: 50, + // child: MIHButton( + // onTap: () { + // addAppointmentCall(); + // checkforchange(); + // }, + // buttonText: "Add", + // buttonColor: + // MzanziInnovationHub.of(context)!.theme.successColor(), + // textColor: + // MzanziInnovationHub.of(context)!.theme.primaryColor(), + // ), + // ), + ], + ); + }, + ); + } + void appointmentUpdateWindow(int index) { showDialog( context: context, @@ -379,6 +507,7 @@ class _BuildAppointmentListState extends State { if (isAppointmentInputValid()) { MihMzansiCalendarApis.updatePersonalAppointment( widget.signedInUser, + widget.business, widget.appointmentList[index].idappointments, widget.titleController.text, widget.descriptionIDController.text, @@ -405,7 +534,19 @@ class _BuildAppointmentListState extends State { } bool canEditAppointment(int index) { - if (widget.appointmentList[index].business_id == "") { + if (widget.personalSelected == true && + widget.appointmentList[index].app_id == widget.signedInUser.app_id && + widget.appointmentList[index].business_id == "") { + return true; + } else if (widget.personalSelected == false && + widget.appointmentList[index].business_id == + widget.business!.business_id && + widget.appointmentList[index].app_id.isEmpty) { + return true; + } else if (widget.personalSelected == false && + widget.appointmentList[index].business_id == + widget.business!.business_id && + widget.appointmentList[index].app_id.isNotEmpty) { return true; } else { return false; diff --git a/Frontend/lib/mih_packages/mih_home/mih_home.dart b/Frontend/lib/mih_packages/mih_home/mih_home.dart index fec179d6..3344aecd 100644 --- a/Frontend/lib/mih_packages/mih_home/mih_home.dart +++ b/Frontend/lib/mih_packages/mih_home/mih_home.dart @@ -400,10 +400,11 @@ class _MIHHomeState extends State { onTap: () { Navigator.of(context).pushNamed( '/patient-manager', - arguments: BusinessArguments( + arguments: PatManagerArguments( widget.signedInUser, - widget.businessUser, + widget.personalSelected, widget.business, + widget.businessUser, ), ); }, 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 index 5d78c213..cb87a3d9 100644 --- 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 @@ -135,6 +135,7 @@ class _BuildPatientsListState extends State { MIHApiCalls.addAppointmentAPICall( widget.arguments.business!.business_id, widget.patientAccesses[index].app_id, + false, dateController.text, timeController.text, widget.arguments, 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 index fe9341ef..0631d825 100644 --- a/Frontend/lib/mih_packages/patient_profile/builder/build_patient_list.dart +++ b/Frontend/lib/mih_packages/patient_profile/builder/build_patient_list.dart @@ -175,6 +175,7 @@ class _BuildPatientsListState extends State { MIHApiCalls.addAppointmentAPICall( widget.arguments.business!.business_id, widget.patients[index].app_id, + false, dateController.text, timeController.text, widget.arguments, @@ -523,14 +524,14 @@ class _BuildPatientsListState extends State { 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, - ); + // MIHApiCalls.addPatientAccessAPICall( + // widget.business!.business_id, + // widget.patients[index].app_id, + // "patient", + // widget.business!.Name, + // widget.arguments, + // context, + // ); }, ), ), @@ -548,12 +549,12 @@ class _BuildPatientsListState extends State { 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, - ); + // MIHApiCalls.reapplyPatientAccessAPICall( + // widget.business!.business_id, + // widget.patients[index].app_id, + // widget.arguments, + // context, + // ); }, ), ), 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 index 268db8c3..e3ba97dc 100644 --- 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 @@ -475,6 +475,7 @@ class _BuildPatientsListState extends State { MIHApiCalls.deleteApointmentAPICall( widget.patientQueue[index].idpatient_queue, widget.patientQueue[index].app_id, + false, widget.patientQueue[index].date_time, BusinessArguments( widget.signedInUser, @@ -500,6 +501,7 @@ class _BuildPatientsListState extends State { MIHApiCalls.updateApointmentAPICall( widget.patientQueue[index].idpatient_queue, widget.patientQueue[index].app_id, + false, widget.business!.Name, widget.patientQueue[index].date_time, dateController.text, diff --git a/Frontend/lib/mih_packages/patient_profile/pat_manager/app_tools/mih_patient_search.dart b/Frontend/lib/mih_packages/patient_profile/pat_manager/app_tools/mih_patient_search.dart new file mode 100644 index 00000000..45aa6e24 --- /dev/null +++ b/Frontend/lib/mih_packages/patient_profile/pat_manager/app_tools/mih_patient_search.dart @@ -0,0 +1,223 @@ +import 'package:Mzansi_Innovation_Hub/main.dart'; +import 'package:Mzansi_Innovation_Hub/mih_apis/mih_api_calls.dart'; +import 'package:Mzansi_Innovation_Hub/mih_components/mih_inputs_and_buttons/mih_search_input.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_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/patient_access.dart'; +import 'package:Mzansi_Innovation_Hub/mih_objects/patients.dart'; +import 'package:Mzansi_Innovation_Hub/mih_packages/patient_profile/pat_manager/list_builders/build_mih_patient_search_list.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; + +class MihPatientSearch extends StatefulWidget { + final AppUser signedInUser; + final Business? business; + final BusinessUser? businessUser; + final bool personalSelected; + + const MihPatientSearch({ + super.key, + required this.signedInUser, + required this.business, + required this.businessUser, + required this.personalSelected, + }); + + @override + State createState() => _MihPatientSearchState(); +} + +class _MihPatientSearchState extends State { + TextEditingController _mihPatientSearchController = TextEditingController(); + final FocusNode _focusNode = FocusNode(); + String _mihPatientSearchString = ""; + String baseUrl = AppEnviroment.baseApiUrl; + late Future> _mihPatientSearchResults; + + Widget getPatientSearch() { + return KeyboardListener( + focusNode: _focusNode, + autofocus: true, + onKeyEvent: (event) async { + if (event is KeyDownEvent && + event.logicalKey == LogicalKeyboardKey.enter) { + // submitPatientForm(); + submitPatientSearch(); + //To-Do: Implement the search function + // print("To-Do: Implement the search function"); + } + }, + child: Column(mainAxisSize: MainAxisSize.max, children: [ + const Text( + "MIH 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: _mihPatientSearchController, + hintText: "ID or Medical Aid No. Search", + required: false, + editable: true, + onTap: () { + // submitPatientForm(); + submitPatientSearch(); + //To-Do: Implement the search function + // print("To-Do: Implement the search function"); + }, + ), + ), + IconButton( + onPressed: () { + setState(() { + _mihPatientSearchController.clear(); + _mihPatientSearchString = ""; + }); + submitPatientSearch(); + //To-Do: Implement the search function + // print("To-Do: Implement the search function"); + }, + icon: const Icon( + Icons.filter_alt_off, + size: 25, + )) + ], + ), + //spacer + const SizedBox(height: 10), + FutureBuilder( + future: _mihPatientSearchResults, + 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 (_mihPatientSearchString == "") { + patientsList = []; + } else { + patientsList = filterSearchResults( + snapshot.data!, _mihPatientSearchString); + //print(patientsList); + } + return displayPatientList(patientsList, _mihPatientSearchString); + } else { + return Center( + child: Text( + "Error pulling Patients Data\n$baseUrl/patients/search/$_mihPatientSearchString", + style: TextStyle( + fontSize: 25, + color: + MzanziInnovationHub.of(context)!.theme.errorColor()), + textAlign: TextAlign.center, + ), + ); + } + }, + ), + ]), + ); + } + + List filterSearchResults(List patList, String query) { + List templist = []; + //print(query); + for (var item in patList) { + if (item.id_no.contains(_mihPatientSearchString) || + item.medical_aid_no.contains(_mihPatientSearchString)) { + //print(item.medical_aid_no); + templist.add(item); + } + } + return templist; + } + + Widget displayPatientList(List patientsList, String searchString) { + if (patientsList.isNotEmpty) { + return BuildMihPatientSearchList( + patients: patientsList, + signedInUser: widget.signedInUser, + business: widget.business, + businessUser: widget.businessUser, + personalSelected: widget.personalSelected, + ); + } 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, + ), + ), + ); + } + } + + void submitPatientSearch() { + if (_mihPatientSearchController.text != "") { + setState(() { + _mihPatientSearchString = _mihPatientSearchController.text; + _mihPatientSearchResults = + MIHApiCalls.fetchPatients(_mihPatientSearchString); + }); + } + } + + //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; + } + + @override + void initState() { + super.initState(); + _mihPatientSearchResults = MIHApiCalls.fetchPatients("abc"); + } + + @override + Widget build(BuildContext context) { + return MihAppToolBody( + borderOn: true, + bodyItem: getPatientSearch(), + ); + } +} diff --git a/Frontend/lib/mih_packages/patient_profile/pat_manager/app_tools/my_patient_list.dart b/Frontend/lib/mih_packages/patient_profile/pat_manager/app_tools/my_patient_list.dart new file mode 100644 index 00000000..a3e0ec70 --- /dev/null +++ b/Frontend/lib/mih_packages/patient_profile/pat_manager/app_tools/my_patient_list.dart @@ -0,0 +1,202 @@ +import 'package:Mzansi_Innovation_Hub/main.dart'; +import 'package:Mzansi_Innovation_Hub/mih_apis/mih_api_calls.dart'; +import 'package:Mzansi_Innovation_Hub/mih_components/mih_inputs_and_buttons/mih_search_input.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_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/patient_access.dart'; +import 'package:Mzansi_Innovation_Hub/mih_packages/patient_profile/pat_manager/list_builders/build_my_patient_list_list.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; + +class MyPatientList extends StatefulWidget { + final AppUser signedInUser; + final Business? business; + final BusinessUser? businessUser; + final bool personalSelected; + + const MyPatientList({ + super.key, + required this.signedInUser, + this.business, + this.businessUser, + this.personalSelected = false, + }); + + @override + State createState() => _MyPatientListState(); +} + +class _MyPatientListState extends State { + late Future> _myPatientList; + TextEditingController _myPatientSearchController = TextEditingController(); + String _myPatientIdSearchString = ""; + String baseUrl = AppEnviroment.baseApiUrl; + + final FocusNode _focusNode = FocusNode(); + + Widget myPatientListTool() { + return KeyboardListener( + focusNode: _focusNode, + autofocus: true, + onKeyEvent: (event) async { + if (event is KeyDownEvent && + event.logicalKey == LogicalKeyboardKey.enter) { + setState(() { + _myPatientIdSearchString = _myPatientSearchController.text; + _myPatientList = MIHApiCalls.getPatientAccessListOfBusiness( + widget.business!.business_id); + }); + } + }, + 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: () { + getMyPatientList(); + }, + ), + ], + ), + Divider(color: MzanziInnovationHub.of(context)!.theme.secondaryColor()), + //spacer + const SizedBox(height: 10), + Row( + mainAxisSize: MainAxisSize.min, + children: [ + Flexible( + flex: 1, + child: MIHSearchField( + controller: _myPatientSearchController, + hintText: "Patient ID Search", + required: false, + editable: true, + onTap: () { + setState(() { + _myPatientIdSearchString = _myPatientSearchController.text; + _myPatientList = MIHApiCalls.getPatientAccessListOfBusiness( + widget.business!.business_id); + }); + }, + ), + ), + IconButton( + onPressed: () { + setState(() { + _myPatientSearchController.clear(); + _myPatientIdSearchString = ""; + }); + getMyPatientList(); + }, + icon: const Icon( + Icons.filter_alt_off, + size: 25, + )) + ], + ), + //spacer + const SizedBox(height: 10), + FutureBuilder( + future: _myPatientList, + 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 (_myPatientIdSearchString == "") { + patientsAccessList = snapshot.data!; + } else { + patientsAccessList = filterAccessResults( + snapshot.data!, _myPatientIdSearchString); + //print(patientsList); + } + return displayMyPatientList(patientsAccessList); + } else { + return Center( + child: Text( + "Error pulling Patient Access Data\n$baseUrl/access-requests/business/patient/${widget.business!.business_id}", + style: TextStyle( + fontSize: 25, + color: + MzanziInnovationHub.of(context)!.theme.errorColor()), + textAlign: TextAlign.center, + ), + ); + } + }, + ), + ]), + ); + } + + Widget displayMyPatientList(List patientsAccessList) { + if (patientsAccessList.isNotEmpty) { + return BuildMyPatientListList( + patientAccesses: patientsAccessList, + signedInUser: widget.signedInUser, + business: widget.business, + businessUser: widget.businessUser, + ); + } + 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, + ), + ), + ); + } + + List filterAccessResults( + List patAccList, String query) { + List templist = []; + for (var item in patAccList) { + if (item.id_no.contains(query)) { + templist.add(item); + } + } + return templist; + } + + void getMyPatientList() { + setState(() { + _myPatientList = MIHApiCalls.getPatientAccessListOfBusiness( + widget.business!.business_id); + }); + } + + @override + void initState() { + super.initState(); + _myPatientList = MIHApiCalls.getPatientAccessListOfBusiness( + widget.business!.business_id); + } + + @override + Widget build(BuildContext context) { + return MihAppToolBody( + borderOn: true, + bodyItem: myPatientListTool(), + ); + } +} 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 new file mode 100644 index 00000000..eae5583d --- /dev/null +++ b/Frontend/lib/mih_packages/patient_profile/pat_manager/app_tools/waiting_room.dart @@ -0,0 +1,348 @@ +import 'package:Mzansi_Innovation_Hub/main.dart'; +import 'package:Mzansi_Innovation_Hub/mih_apis/mih_mzansi_calendar_apis.dart'; +import 'package:Mzansi_Innovation_Hub/mih_components/mih_calendar.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_multiline_text_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_inputs_and_buttons/mih_time_input.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_env/env.dart'; +import 'package:Mzansi_Innovation_Hub/mih_objects/app_user.dart'; +import 'package:Mzansi_Innovation_Hub/mih_objects/appointment.dart'; +import 'package:Mzansi_Innovation_Hub/mih_objects/business.dart'; +import 'package:Mzansi_Innovation_Hub/mih_packages/calendar/builder/build_appointment_list.dart'; +import 'package:flutter/material.dart'; + +class WaitingRoom extends StatefulWidget { + final AppUser signedInUser; + final Business? business; + final bool personalSelected; + + const WaitingRoom({ + super.key, + required this.signedInUser, + this.business, + required this.personalSelected, + }); + + @override + State createState() => _WaitingRoomState(); +} + +class _WaitingRoomState extends State { + TextEditingController selectedAppointmentDateController = + TextEditingController(); + final TextEditingController _appointmentTitleController = + TextEditingController(); + final TextEditingController _appointmentDescriptionIDController = + TextEditingController(); + final TextEditingController _appointmentDateController = + TextEditingController(); + final TextEditingController _appointmentTimeController = + TextEditingController(); + final TextEditingController _patientController = TextEditingController(); + String baseUrl = AppEnviroment.baseApiUrl; + + String selectedDay = DateTime.now().toString().split(" ")[0]; + + late Future> businessAppointmentResults; + late Future> appointmentResults; + + // Business Appointment Tool + Widget getBusinessAppointmentsTool() { + return Stack( + children: [ + Column( + children: [ + const Text( + "Waiting Room", + style: const TextStyle( + fontWeight: FontWeight.bold, + fontSize: 25, + ), + ), + MIHCalendar( + calendarWidth: 500, + rowHeight: 35, + setDate: (value) { + setState(() { + selectedDay = value; + selectedAppointmentDateController.text = selectedDay; + }); + }), + // Divider( + // color: MzanziInnovationHub.of(context)!.theme.secondaryColor(), + // ), + Row( + mainAxisSize: MainAxisSize.max, + children: [ + FutureBuilder( + future: appointmentResults, + builder: (context, snapshot) { + if (snapshot.connectionState == ConnectionState.waiting) { + return const Expanded( + child: Center(child: Mihloadingcircle())); + } else if (snapshot.connectionState == + ConnectionState.done && + snapshot.hasData) { + return + // Container(child: const Placeholder()); + displayAppointmentList(snapshot.requireData); + } else { + return Center( + child: Text( + "Error pulling appointments", + 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, + ), + ), + )) + ], + ); + } + + Widget displayAppointmentList(List appointmentList) { + if (appointmentList.isNotEmpty) { + return Expanded( + child: BuildAppointmentList( + appointmentList: appointmentList, + signedInUser: widget.signedInUser, + business: widget.business, + personalSelected: widget.personalSelected, + inWaitingRoom: true, + titleController: _appointmentTitleController, + descriptionIDController: _appointmentDescriptionIDController, + patientIdController: _patientController, + dateController: _appointmentDateController, + timeController: _appointmentTimeController, + ), + ); + } + return Expanded( + child: Padding( + padding: const EdgeInsets.only(top: 35.0), + child: Align( + alignment: Alignment.center, + child: Text( + "No Appointments for $selectedDay", + style: TextStyle( + fontSize: 25, + color: MzanziInnovationHub.of(context)!.theme.messageTextColor(), + ), + textAlign: TextAlign.center, + softWrap: true, + ), + ), + ), + ); + } + + void addAppointmentWindow() { + showDialog( + context: context, + barrierDismissible: false, + builder: (context) { + return MIHWindow( + fullscreen: false, + windowTitle: "Add Appointment", + windowTools: [], + onWindowTapClose: () { + Navigator.of(context).pop(); + _appointmentDateController.clear(); + _appointmentTimeController.clear(); + _appointmentTitleController.clear(); + _appointmentDescriptionIDController.clear(); + _patientController.clear(); + }, + windowBody: [ + SizedBox( + // width: 500, + child: MIHTextField( + controller: _appointmentTitleController, + hintText: "Title", + editable: true, + required: true, + ), + ), + const SizedBox(height: 10), + SizedBox( + child: MIHSearchField( + controller: _patientController, + hintText: "Patient ID Number", + required: false, + editable: true, + onTap: () { + //To-Do: Add search functionality + }, + ), + ), + const SizedBox(height: 10), + SizedBox( + // width: 500, + child: MIHDateField( + controller: _appointmentDateController, + lableText: "Date", + required: true, + ), + ), + const SizedBox(height: 10), + SizedBox( + // width: 500, + child: MIHTimeField( + controller: _appointmentTimeController, + lableText: "Time", + required: true, + ), + ), + const SizedBox(height: 10), + SizedBox( + // width: 500, + height: 250, + child: MIHMLTextField( + controller: _appointmentDescriptionIDController, + hintText: "Description", + editable: true, + required: true, + ), + ), + const SizedBox(height: 20), + SizedBox( + width: 500, + height: 50, + child: MIHButton( + onTap: () { + //To-Do: Add appointment + print("To-Do: Add appointment"); + // addAppointmentCall(); + }, + buttonText: "Add", + buttonColor: + MzanziInnovationHub.of(context)!.theme.successColor(), + textColor: + MzanziInnovationHub.of(context)!.theme.primaryColor(), + ), + ), + ], + ); + }, + ); + } + + void addAppointmentCall() { + if (isAppointmentInputValid()) { + if (widget.personalSelected == false) { + MihMzansiCalendarApis.addBusinessAppointment( + widget.signedInUser, + widget.business!, + _appointmentTitleController.text, + _appointmentDescriptionIDController.text, + _appointmentDateController.text, + _appointmentTimeController.text, + context, + ); + } else { + MihMzansiCalendarApis.addPersonalAppointment( + widget.signedInUser, + _appointmentTitleController.text, + _appointmentDescriptionIDController.text, + _appointmentDateController.text, + _appointmentTimeController.text, + context, + ); + } + } else { + showDialog( + context: context, + builder: (context) { + return const MIHErrorMessage(errorType: "Input Error"); + }, + ); + } + checkforchange(); + } + + bool isAppointmentInputValid() { + if (_appointmentTitleController.text.isEmpty || + _appointmentDescriptionIDController.text.isEmpty || + _appointmentDateController.text.isEmpty || + _appointmentTimeController.text.isEmpty) { + return false; + } else { + return true; + } + } + + void checkforchange() { + setState(() { + appointmentResults = MihMzansiCalendarApis.getBusinessAppointments( + widget.business!.business_id, + true, + selectedDay, + ); + }); + } + + @override + void dispose() { + selectedAppointmentDateController.dispose(); + _appointmentDateController.dispose(); + _appointmentTimeController.dispose(); + _appointmentTitleController.dispose(); + _appointmentDescriptionIDController.dispose(); + super.dispose(); + } + + @override + void initState() { + selectedAppointmentDateController.addListener(checkforchange); + setState(() { + appointmentResults = MihMzansiCalendarApis.getBusinessAppointments( + widget.business!.business_id, + true, + selectedDay, + ); + }); + super.initState(); + } + + @override + Widget build(BuildContext context) { + return MihAppToolBody( + borderOn: true, + bodyItem: getBusinessAppointmentsTool(), + ); + } +} diff --git a/Frontend/lib/mih_packages/patient_profile/pat_manager/list_builders/build_mih_patient_search_list.dart b/Frontend/lib/mih_packages/patient_profile/pat_manager/list_builders/build_mih_patient_search_list.dart new file mode 100644 index 00000000..278c76b4 --- /dev/null +++ b/Frontend/lib/mih_packages/patient_profile/pat_manager/list_builders/build_mih_patient_search_list.dart @@ -0,0 +1,665 @@ +import 'dart:convert'; + +import 'package:Mzansi_Innovation_Hub/main.dart'; +import 'package:Mzansi_Innovation_Hub/mih_apis/mih_api_calls.dart'; +import 'package:Mzansi_Innovation_Hub/mih_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_text_input.dart'; +import 'package:Mzansi_Innovation_Hub/mih_components/mih_inputs_and_buttons/mih_time_input.dart'; +import 'package:Mzansi_Innovation_Hub/mih_components/mih_layout/mih_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_success_message.dart'; +import 'package:Mzansi_Innovation_Hub/mih_components/mih_pop_up_messages/mih_warning_message.dart'; +import 'package:Mzansi_Innovation_Hub/mih_env/env.dart'; +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:flutter/material.dart'; +import 'package:supertokens_flutter/http.dart' as http; + +class BuildMihPatientSearchList extends StatefulWidget { + final List patients; + final AppUser signedInUser; + final Business? business; + final BusinessUser? businessUser; + final bool personalSelected; + + const BuildMihPatientSearchList({ + super.key, + required this.patients, + required this.signedInUser, + required this.business, + required this.businessUser, + required this.personalSelected, + }); + + @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 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.signedInUser, + widget.businessUser, + widget.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.business!.Name} for the ${dateController.text} ${timeController.text}. Please approve the Access Review request.", + "action_path": "/access-review", + }), + ); + 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) { + //To-Do: Implement the appointment submission + print("To-do: Implement the appointment submission"); + // MIHApiCalls.addAppointmentAPICall( + // widget.business!.business_id, + // widget.patients[index].app_id, + // dateController.text, + // timeController.text, + // widget.arguments, + // context, + // ); + } + + bool isAppointmentFieldsFilled() { + if (dateController.text.isEmpty || timeController.text.isEmpty) { + return false; + } else { + return true; + } + } + + void 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.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.personalSelected, + BusinessArguments( + widget.signedInUser, + widget.businessUser, + widget.business, + ), + 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.personalSelected, + BusinessArguments( + widget.signedInUser, + widget.businessUser, + widget.business, + ), + 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/pat_manager/list_builders/build_my_patient_list_list.dart b/Frontend/lib/mih_packages/patient_profile/pat_manager/list_builders/build_my_patient_list_list.dart new file mode 100644 index 00000000..b4d23e1a --- /dev/null +++ b/Frontend/lib/mih_packages/patient_profile/pat_manager/list_builders/build_my_patient_list_list.dart @@ -0,0 +1,385 @@ +import 'package:Mzansi_Innovation_Hub/main.dart'; +import 'package:Mzansi_Innovation_Hub/mih_apis/mih_api_calls.dart'; +import 'package:Mzansi_Innovation_Hub/mih_apis/mih_mzansi_calendar_apis.dart'; +import 'package:Mzansi_Innovation_Hub/mih_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_text_input.dart'; +import 'package:Mzansi_Innovation_Hub/mih_components/mih_inputs_and_buttons/mih_time_input.dart'; +import 'package:Mzansi_Innovation_Hub/mih_components/mih_layout/mih_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_warning_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/patient_access.dart'; +import 'package:Mzansi_Innovation_Hub/mih_objects/patients.dart'; +import 'package:flutter/material.dart'; + +class BuildMyPatientListList extends StatefulWidget { + final List patientAccesses; + final AppUser signedInUser; + final Business? business; + final BusinessUser? businessUser; + + const BuildMyPatientListList({ + super.key, + required this.patientAccesses, + required this.signedInUser, + required this.business, + required this.businessUser, + }); + + @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; + + void submitApointment(int index) { + //To-Do: Add the appointment to the database + // print("To-Do: Add the appointment to the database"); + String description = + "Date: ${dateController.text}\nTime: ${timeController.text}\n"; + description += "Medical Practice: ${widget.business!.Name}\n"; + description += "Contact Number: ${widget.business!.contact_no}"; + MihMzansiCalendarApis.addPatientAppointment( + widget.signedInUser, + false, + widget.patientAccesses[index].app_id, + BusinessArguments( + widget.signedInUser, + widget.businessUser, + widget.business, + ), + "${widget.patientAccesses[index].fname} ${widget.patientAccesses[index].lname} - Doctors Visit", + description, + dateController.text, + timeController.text, + context, + ); + // MIHApiCalls.addAppointmentAPICall( + // widget.business!.business_id, + // widget.patientAccesses[index].app_id, + // dateController.text, + // timeController.text, + // BusinessArguments( + // widget.signedInUser, + // widget.businessUser, + // widget.business, + // ), + // context, + // ); + } + + bool isAppointmentFieldsFilled() { + 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: () { + appointmentPopUp(index); + }, + ), + ), + 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.businessUser, + widget.business, + "business", + )); + }, + ), + ), + ]) + ], + ), + ); + } + + Widget displayMyPatientTile(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) { + return displayMyPatientTile(index); + }, + ); + } +} diff --git a/Frontend/lib/mih_packages/patient_profile/pat_manager/list_builders/build_waiting_room_list.dart b/Frontend/lib/mih_packages/patient_profile/pat_manager/list_builders/build_waiting_room_list.dart new file mode 100644 index 00000000..9fc68a82 --- /dev/null +++ b/Frontend/lib/mih_packages/patient_profile/pat_manager/list_builders/build_waiting_room_list.dart @@ -0,0 +1,15 @@ +import 'package:flutter/material.dart'; + +class BuildWaitingRoomList extends StatefulWidget { + const BuildWaitingRoomList({super.key}); + + @override + State createState() => _BuildWaitingRoomListState(); +} + +class _BuildWaitingRoomListState extends State { + @override + Widget build(BuildContext context) { + return const Placeholder(); + } +} 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 new file mode 100644 index 00000000..f7684fcb --- /dev/null +++ b/Frontend/lib/mih_packages/patient_profile/pat_manager/pat_manager.dart @@ -0,0 +1,101 @@ +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_manager/app_tools/mih_patient_search.dart'; +import 'package:Mzansi_Innovation_Hub/mih_packages/patient_profile/pat_manager/app_tools/my_patient_list.dart'; +import 'package:Mzansi_Innovation_Hub/mih_packages/patient_profile/pat_manager/app_tools/waiting_room.dart'; +import 'package:flutter/material.dart'; + +class PatManager extends StatefulWidget { + final PatManagerArguments arguments; + const PatManager({ + super.key, + required this.arguments, + }); + + @override + State createState() => _PatManagerState(); +} + +class _PatManagerState extends State { + int _selcetedIndex = 0; + @override + Widget build(BuildContext context) { + return MihApp( + appActionButton: getActionButton(), + appTools: getTools(), + appBody: getToolBody(), + selectedbodyIndex: _selcetedIndex, + onIndexChange: (newValue) { + setState(() { + _selcetedIndex = newValue; + }); + print("Index: $_selcetedIndex"); + }, + ); + } + + MihAppAction getActionButton() { + return MihAppAction( + icon: const Icon(Icons.arrow_back), + iconSize: 35, + onTap: () { + Navigator.of(context).pop(); + }, + ); + } + + MihAppTools getTools() { + Map temp = {}; + temp[const Icon(Icons.calendar_month)] = () { + setState(() { + _selcetedIndex = 0; + }); + }; + + temp[const Icon(Icons.check_box_outlined)] = () { + setState(() { + _selcetedIndex = 1; + }); + }; + + temp[const Icon(Icons.search)] = () { + setState(() { + _selcetedIndex = 2; + }); + }; + return MihAppTools( + tools: temp, + selcetedIndex: _selcetedIndex, + ); + } + + List getToolBody() { + List toolBodies = [ + //appointment here + // Appointments( + // signedInUser: widget.arguments.signedInUser, + // business: widget.arguments.business, + // personalSelected: widget.arguments.personalSelected, + // ), + WaitingRoom( + signedInUser: widget.arguments.signedInUser, + business: widget.arguments.business, + personalSelected: widget.arguments.personalSelected, + ), + MyPatientList( + signedInUser: widget.arguments.signedInUser, + business: widget.arguments.business, + personalSelected: widget.arguments.personalSelected, + ), + MihPatientSearch( + signedInUser: widget.arguments.signedInUser, + business: widget.arguments.business, + personalSelected: widget.arguments.personalSelected, + businessUser: widget.arguments.businessUser, + ), + ]; + return toolBodies; + } +} diff --git a/Frontend/lib/mih_packages/patient_profile/patient_manager.dart b/Frontend/lib/mih_packages/patient_profile/patient_manager.dart index 795add30..3ab8b7c9 100644 --- a/Frontend/lib/mih_packages/patient_profile/patient_manager.dart +++ b/Frontend/lib/mih_packages/patient_profile/patient_manager.dart @@ -73,11 +73,13 @@ class _PatientManagerState extends State { Widget displayQueueList(List patientQueueList) { if (patientQueueList.isNotEmpty) { - return BuildPatientQueueList( - patientQueue: patientQueueList, - signedInUser: widget.arguments.signedInUser, - business: widget.arguments.business, - businessUser: widget.arguments.businessUser, + return Expanded( + child: BuildPatientQueueList( + patientQueue: patientQueueList, + signedInUser: widget.arguments.signedInUser, + business: widget.arguments.business, + businessUser: widget.arguments.businessUser, + ), ); } return Padding( @@ -95,67 +97,105 @@ class _PatientManagerState extends State { } Widget patientQueue() { - return Column(mainAxisSize: MainAxisSize.max, children: [ - //const SizedBox(height: 15), - Row( - mainAxisAlignment: MainAxisAlignment.center, + return Container( + child: Stack( children: [ - const Text( - "Waiting Room", - style: TextStyle(fontSize: 25, fontWeight: FontWeight.bold), - ), - IconButton( - iconSize: 20, - icon: const Icon( - Icons.refresh, - ), - onPressed: () { - refreshQueue(); - }, + 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, + ), + ), + )) ], ), - Divider(color: MzanziInnovationHub.of(context)!.theme.secondaryColor()), - MIHCalendar( - calendarWidth: 500, - rowHeight: 35, - setDate: (value) { - setState(() { - queueDateController.text = value; - }); - }), - //spacer - 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, - ), - ); - } - }, - ), - ]); + ); } void refreshQueue() { @@ -259,7 +299,6 @@ class _PatientManagerState extends State { style: TextStyle(fontSize: 25, fontWeight: FontWeight.bold), ), Divider(color: MzanziInnovationHub.of(context)!.theme.secondaryColor()), - //spacer const SizedBox(height: 10), Row( @@ -309,7 +348,6 @@ class _PatientManagerState extends State { filterSearchResults(snapshot.data!, searchString); //print(patientsList); } - return displayPatientList(patientsList, searchString); } else { return Center( @@ -347,7 +385,6 @@ class _PatientManagerState extends State { } //Patient Access Widgets/ Functions - List filterAccessResults( List patAccList, String query) { List templist = []; @@ -414,7 +451,6 @@ class _PatientManagerState extends State { ], ), Divider(color: MzanziInnovationHub.of(context)!.theme.secondaryColor()), - //spacer const SizedBox(height: 10), Row( @@ -446,7 +482,6 @@ class _PatientManagerState extends State { )) ], ), - //spacer const SizedBox(height: 10), FutureBuilder( @@ -465,7 +500,6 @@ class _PatientManagerState extends State { filterAccessResults(snapshot.data!, accessSearchString); //print(patientsList); } - return displayPatientAccessList(patientsAccessList); } else { return Center( diff --git a/Frontend/pubspec.lock b/Frontend/pubspec.lock index 1e829927..c39e76f4 100644 --- a/Frontend/pubspec.lock +++ b/Frontend/pubspec.lock @@ -45,10 +45,10 @@ packages: dependency: transitive description: name: async - sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c" + sha256: d2872f9c19731c2e5f10444b14686eb7cc85c76274bd6c16e1816bff9a3bab63 url: "https://pub.dev" source: hosted - version: "2.11.0" + version: "2.12.0" barcode: dependency: transitive description: @@ -85,10 +85,10 @@ packages: dependency: transitive description: name: boolean_selector - sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66" + sha256: "8aab1771e1243a5063b8b0ff68042d67334e3feab9e95b9490f9a6ebf73b42ea" url: "https://pub.dev" source: hosted - version: "2.1.1" + version: "2.1.2" buffer: dependency: transitive description: @@ -181,10 +181,10 @@ packages: dependency: transitive description: name: characters - sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605" + sha256: f71061c654a3380576a52b451dd5532377954cf9dbd272a78fc8479606670803 url: "https://pub.dev" source: hosted - version: "1.3.0" + version: "1.4.0" charcode: dependency: transitive description: @@ -213,10 +213,10 @@ packages: dependency: transitive description: name: clock - sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf + sha256: fddb70d9b5277016c77a80201021d40a2247104d9f4aa7bab7157b7e3f05b84b url: "https://pub.dev" source: hosted - version: "1.1.1" + version: "1.1.2" code_builder: dependency: transitive description: @@ -229,10 +229,10 @@ packages: dependency: transitive description: name: collection - sha256: a1ace0a119f20aabc852d165077c036cd864315bd99b7eaa10a60100341941bf + sha256: "2f5709ae4d3d59dd8f7cd309b4e023046b57d8a6c82130785d2b0e5868084e76" url: "https://pub.dev" source: hosted - version: "1.19.0" + version: "1.19.1" convert: dependency: transitive description: @@ -333,10 +333,10 @@ packages: dependency: transitive description: name: fake_async - sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78" + sha256: "6a95e56b2449df2273fd8c45a662d6947ce1ebb7aafe80e550a3f68297f3cacc" url: "https://pub.dev" source: hosted - version: "1.3.1" + version: "1.3.2" fetch_api: dependency: transitive description: @@ -676,18 +676,18 @@ packages: dependency: transitive description: name: leak_tracker - sha256: "7bb2830ebd849694d1ec25bf1f44582d6ac531a57a365a803a6034ff751d2d06" + sha256: c35baad643ba394b40aac41080300150a4f08fd0fd6a10378f8f7c6bc161acec url: "https://pub.dev" source: hosted - version: "10.0.7" + version: "10.0.8" leak_tracker_flutter_testing: dependency: transitive description: name: leak_tracker_flutter_testing - sha256: "9491a714cca3667b60b5c420da8217e6de0d1ba7a5ec322fab01758f6998f379" + sha256: f8b613e7e6a13ec79cfdc0e97638fddb3ab848452eff057653abd3edba760573 url: "https://pub.dev" source: hosted - version: "3.0.8" + version: "3.0.9" leak_tracker_testing: dependency: transitive description: @@ -764,10 +764,10 @@ packages: dependency: transitive description: name: matcher - sha256: d2323aa2060500f906aa31a895b4030b6da3ebdcc5619d14ce1aada65cd161cb + sha256: dc58c723c3c24bf8d3e2d3ad3f2f9d7bd9cf43ec6feaa64181775e60190153f2 url: "https://pub.dev" source: hosted - version: "0.12.16+1" + version: "0.12.17" material_color_utilities: dependency: transitive description: @@ -788,10 +788,10 @@ packages: dependency: transitive description: name: meta - sha256: bdb68674043280c3428e9ec998512fb681678676b3c54e773629ffe74419f8c7 + sha256: e3641ec5d63ebf0d9b41bd43201a66e3fc79a65db5f61fc181f04cd27aab950c url: "https://pub.dev" source: hosted - version: "1.15.0" + version: "1.16.0" mime: dependency: transitive description: @@ -852,10 +852,10 @@ packages: dependency: transitive description: name: path - sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af" + sha256: "75cca69d1490965be98c73ceaea117e8a04dd21217b37b292c9ddbec0d955bc5" url: "https://pub.dev" source: hosted - version: "1.9.0" + version: "1.9.1" path_parsing: dependency: transitive description: @@ -1153,10 +1153,10 @@ packages: dependency: transitive description: name: source_span - sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c" + sha256: "254ee5351d6cb365c859e20ee823c3bb479bf4a293c22d17a9f1bf144ce86f7c" url: "https://pub.dev" source: hosted - version: "1.10.0" + version: "1.10.1" sprintf: dependency: transitive description: @@ -1169,18 +1169,18 @@ packages: dependency: transitive description: name: stack_trace - sha256: "9f47fd3630d76be3ab26f0ee06d213679aa425996925ff3feffdec504931c377" + sha256: "8b27215b45d22309b5cddda1aa2b19bdfec9df0e765f2de506401c071d38d1b1" url: "https://pub.dev" source: hosted - version: "1.12.0" + version: "1.12.1" stream_channel: dependency: transitive description: name: stream_channel - sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7 + sha256: "969e04c80b8bcdf826f8f16579c7b14d780458bd97f56d107d3950fdbeef059d" url: "https://pub.dev" source: hosted - version: "2.1.2" + version: "2.1.4" stream_transform: dependency: transitive description: @@ -1193,10 +1193,10 @@ packages: dependency: transitive description: name: string_scanner - sha256: "688af5ed3402a4bde5b3a6c15fd768dbf2621a614950b17f04626c431ab3c4c3" + sha256: "921cd31725b72fe181906c6a94d987c78e3b98c2e205b397ea399d4054872b43" url: "https://pub.dev" source: hosted - version: "1.3.0" + version: "1.4.1" supertokens_flutter: dependency: "direct main" description: @@ -1281,18 +1281,18 @@ packages: dependency: transitive description: name: term_glyph - sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84 + sha256: "7f554798625ea768a7518313e58f83891c7f5024f88e46e7182a4558850a4b8e" url: "https://pub.dev" source: hosted - version: "1.2.1" + version: "1.2.2" test_api: dependency: transitive description: name: test_api - sha256: "664d3a9a64782fcdeb83ce9c6b39e78fd2971d4e37827b9b06c3aa1edc5e760c" + sha256: fb31f383e2ee25fbbfe06b40fe21e1e458d14080e3c67e7ba0acfde4df4e0bbd url: "https://pub.dev" source: hosted - version: "0.7.3" + version: "0.7.4" timing: dependency: transitive description: @@ -1425,10 +1425,10 @@ packages: dependency: transitive description: name: vm_service - sha256: f6be3ed8bd01289b34d679c2b62226f63c0e69f9fd2e50a6b3c1c729a961041b + sha256: "0968250880a6c5fe7edc067ed0a13d4bae1577fe2771dcf3010d52c4a9d3ca14" url: "https://pub.dev" source: hosted - version: "14.3.0" + version: "14.3.1" watcher: dependency: transitive description: @@ -1558,5 +1558,5 @@ packages: source: hosted version: "3.1.1" sdks: - dart: ">=3.6.0 <3.9.0" + dart: ">=3.7.0-0 <3.9.0" flutter: ">=3.27.0" From 23dbe21a2c34241f037a60023e7635326fba88d1 Mon Sep 17 00:00:00 2001 From: yaso Date: Tue, 4 Mar 2025 12:58:37 +0200 Subject: [PATCH 7/8] appointment and waiting room update --- .../mih_apis/mih_mzansi_calendar_apis.dart | 209 ++++++++++++++++-- Frontend/lib/mih_objects/arguments.dart | 2 + .../mih_packages/calendar/appointments.dart | 6 + .../builder/build_appointment_list.dart | 57 ++++- .../calendar/mzansi_calendar.dart | 1 + .../lib/mih_packages/mih_home/mih_home.dart | 11 +- .../pat_manager/app_tools/waiting_room.dart | 113 ++++++++-- .../pat_manager/pat_manager.dart | 9 + Frontend/pubspec.lock | 74 +++---- 9 files changed, 391 insertions(+), 91 deletions(-) diff --git a/Frontend/lib/mih_apis/mih_mzansi_calendar_apis.dart b/Frontend/lib/mih_apis/mih_mzansi_calendar_apis.dart index ec92f021..f5388b96 100644 --- a/Frontend/lib/mih_apis/mih_mzansi_calendar_apis.dart +++ b/Frontend/lib/mih_apis/mih_mzansi_calendar_apis.dart @@ -6,6 +6,7 @@ import 'package:Mzansi_Innovation_Hub/mih_objects/app_user.dart'; import 'package:Mzansi_Innovation_Hub/mih_objects/appointment.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:flutter/material.dart'; // import '../mih_components/mih_pop_up_messages/mih_error_message.dart'; // import '../mih_components/mih_pop_up_messages/mih_success_message.dart'; @@ -90,15 +91,15 @@ class MihMzansiCalendarApis { List.from(l.map((model) => Appointment.fromJson(model))); //print("Here3"); //print(patientQueue); - if (waitingRoom == true) { - businessAppointments = businessAppointments - .where((element) => element.app_id != "") - .toList(); - } else { - businessAppointments = businessAppointments - .where((element) => element.app_id == "") - .toList(); - } + // if (waitingRoom == true) { + // businessAppointments = businessAppointments + // .where((element) => element.app_id != "") + // .toList(); + // } else { + // businessAppointments = businessAppointments + // .where((element) => element.app_id == "") + // .toList(); + // } return businessAppointments; } else { throw Exception('failed to fatch business appointments'); @@ -113,8 +114,12 @@ class MihMzansiCalendarApis { /// BuildContext context, /// /// Returns VOID (TRIGGERS NOTIGICATIOPN ON SUCCESS) - static Future deleteLoyaltyCardAPICall( + static Future deleteAppointmentAPICall( AppUser signedInUser, + bool personalSelected, + Business? business, + BusinessUser? businessUser, + bool inWaitingRoom, int idappointments, BuildContext context, ) async { @@ -130,10 +135,27 @@ class MihMzansiCalendarApis { if (response.statusCode == 200) { Navigator.of(context).pop(); Navigator.of(context).pop(); - Navigator.of(context).pushNamed( - '/calendar', - arguments: signedInUser, - ); + if (inWaitingRoom) { + Navigator.of(context).pushNamed( + '/patient-manager', + arguments: PatManagerArguments( + signedInUser, + false, + business, + businessUser, + ), + ); + } else { + Navigator.of(context).pushNamed( + '/calendar', + arguments: CalendarArguments( + signedInUser, + false, + business, + businessUser, + ), + ); + } String message = "The appointment has been deleted successfully. This means it will no longer be visible in your Calendar."; successPopUp(message, context); @@ -191,6 +213,7 @@ class MihMzansiCalendarApis { signedInUser, true, null, + null, ), ); successPopUp(message, context); @@ -215,6 +238,8 @@ class MihMzansiCalendarApis { static Future addBusinessAppointment( AppUser signedInUser, Business business, + BusinessUser businessUser, + bool inWaitingRoom, String title, String description, String date, @@ -244,14 +269,28 @@ class MihMzansiCalendarApis { "Your appointment \"$title\" for the $date $title has been deleted."; // Navigator.pop(context); - Navigator.of(context).pushNamed( - '/calendar', - arguments: CalendarArguments( - signedInUser, - false, - business, - ), - ); + if (inWaitingRoom) { + Navigator.of(context).pushNamed( + '/patient-manager', + arguments: PatManagerArguments( + signedInUser, + false, + business, + businessUser, + ), + ); + } else { + Navigator.of(context).pushNamed( + '/calendar', + arguments: CalendarArguments( + signedInUser, + false, + business, + businessUser, + ), + ); + } + successPopUp(message, context); } else { Navigator.pop(context); @@ -329,6 +368,7 @@ class MihMzansiCalendarApis { static Future updatePersonalAppointment( AppUser signedInUser, Business? business, + BusinessUser? businessUser, int idappointments, String title, String description, @@ -364,6 +404,131 @@ class MihMzansiCalendarApis { signedInUser, true, business, + businessUser, + ), + ); + successPopUp(message, context); + } else { + Navigator.pop(context); + internetConnectionPopUp(context); + } + } + + /// This function is used to update an appointment to users mzansi Calendar. + /// + /// Patameters:- + /// AppUser signedInUser, + /// String app_id, + /// int idappointments, + /// String title, + /// String description, + /// String date, + /// String time, + /// BuildContext context, + /// + /// Returns VOID (TRIGGERS SUCCESS pop up) + static Future updateBusinessAppointment( + AppUser signedInUser, + Business? business, + BusinessUser? businessUser, + int idappointments, + String title, + String description, + String date, + String time, + BuildContext context, + ) async { + loadingPopUp(context); + var response = await http.put( + Uri.parse("${AppEnviroment.baseApiUrl}/appointment/update/"), + headers: { + "Content-Type": "application/json; charset=UTF-8" + }, + body: jsonEncode({ + "idappointments": idappointments, + "title": title, + "description": description, + "date": date, + "time": time, + }), + ); + if (response.statusCode == 200) { + // Navigator.pop(context); + Navigator.pop(context); + Navigator.pop(context); + String message = + "Your appointment \"$title\" has been updates to the $date $title."; + + Navigator.pop(context); + Navigator.of(context).pushNamed( + '/calendar', + arguments: CalendarArguments( + signedInUser, + false, + business, + businessUser, + ), + ); + successPopUp(message, context); + } else { + Navigator.pop(context); + internetConnectionPopUp(context); + } + } + + /// This function is used to update an appointment to users mzansi Calendar. + /// + /// Patameters:- + /// AppUser signedInUser, + /// String app_id, + /// int idappointments, + /// String title, + /// String description, + /// String date, + /// String time, + /// BuildContext context, + /// + /// Returns VOID (TRIGGERS SUCCESS pop up) + static Future updatePatientAppointment( + AppUser signedInUser, + Business? business, + BusinessUser? businessUser, + int idappointments, + String title, + String description, + String date, + String time, + BuildContext context, + ) async { + loadingPopUp(context); + var response = await http.put( + Uri.parse("${AppEnviroment.baseApiUrl}/appointment/update/"), + headers: { + "Content-Type": "application/json; charset=UTF-8" + }, + body: jsonEncode({ + "idappointments": idappointments, + "title": title, + "description": description, + "date": date, + "time": time, + }), + ); + if (response.statusCode == 200) { + // Navigator.pop(context); + Navigator.pop(context); + Navigator.pop(context); + String message = + "Your appointment \"$title\" has been updates to the $date $title."; + + Navigator.pop(context); + Navigator.of(context).pushNamed( + '/patient-manager', + arguments: PatManagerArguments( + signedInUser, + false, + business, + businessUser, ), ); successPopUp(message, context); diff --git a/Frontend/lib/mih_objects/arguments.dart b/Frontend/lib/mih_objects/arguments.dart index 26dab93b..9ede98d7 100644 --- a/Frontend/lib/mih_objects/arguments.dart +++ b/Frontend/lib/mih_objects/arguments.dart @@ -174,11 +174,13 @@ class CalendarArguments { final AppUser signedInUser; final bool personalSelected; final Business? business; + final BusinessUser? businessUser; CalendarArguments( this.signedInUser, this.personalSelected, this.business, + this.businessUser, ); } diff --git a/Frontend/lib/mih_packages/calendar/appointments.dart b/Frontend/lib/mih_packages/calendar/appointments.dart index 74e76eaa..fe1e09ac 100644 --- a/Frontend/lib/mih_packages/calendar/appointments.dart +++ b/Frontend/lib/mih_packages/calendar/appointments.dart @@ -9,6 +9,7 @@ import 'package:Mzansi_Innovation_Hub/mih_components/mih_package/mih-app_tool_bo import 'package:Mzansi_Innovation_Hub/mih_components/mih_pop_up_messages/mih_error_message.dart'; import 'package:Mzansi_Innovation_Hub/mih_objects/appointment.dart'; import 'package:Mzansi_Innovation_Hub/mih_objects/business.dart'; +import 'package:Mzansi_Innovation_Hub/mih_objects/business_user.dart'; import 'package:Mzansi_Innovation_Hub/mih_packages/calendar/builder/build_appointment_list.dart'; import 'package:flutter/material.dart'; import '../../main.dart'; @@ -21,12 +22,14 @@ import '../../mih_objects/app_user.dart'; class Appointments extends StatefulWidget { final AppUser signedInUser; final Business? business; + final BusinessUser? businessUser; final bool personalSelected; const Appointments({ super.key, required this.signedInUser, required this.business, + required this.businessUser, required this.personalSelected, }); @@ -60,6 +63,7 @@ class _PatientAccessRequestState extends State { appointmentList: appointmentList, signedInUser: widget.signedInUser, business: widget.business, + businessUser: widget.businessUser, personalSelected: widget.personalSelected, inWaitingRoom: false, titleController: _appointmentTitleController, @@ -182,6 +186,8 @@ class _PatientAccessRequestState extends State { MihMzansiCalendarApis.addBusinessAppointment( widget.signedInUser, widget.business!, + widget.businessUser!, + false, _appointmentTitleController.text, _appointmentDescriptionIDController.text, _appointmentDateController.text, diff --git a/Frontend/lib/mih_packages/calendar/builder/build_appointment_list.dart b/Frontend/lib/mih_packages/calendar/builder/build_appointment_list.dart index 5ef3b9d6..8bd78efe 100644 --- a/Frontend/lib/mih_packages/calendar/builder/build_appointment_list.dart +++ b/Frontend/lib/mih_packages/calendar/builder/build_appointment_list.dart @@ -12,12 +12,14 @@ 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/appointment.dart'; import 'package:Mzansi_Innovation_Hub/mih_objects/business.dart'; +import 'package:Mzansi_Innovation_Hub/mih_objects/business_user.dart'; import 'package:flutter/material.dart'; class BuildAppointmentList extends StatefulWidget { final List appointmentList; final AppUser signedInUser; final Business? business; + final BusinessUser? businessUser; final bool personalSelected; final bool inWaitingRoom; final TextEditingController titleController; @@ -31,6 +33,7 @@ class BuildAppointmentList extends StatefulWidget { required this.appointmentList, required this.signedInUser, required this.business, + required this.businessUser, required this.personalSelected, required this.inWaitingRoom, required this.titleController, @@ -505,16 +508,44 @@ class _BuildAppointmentListState extends State { void updateAppointmentCall(int index) { if (isAppointmentInputValid()) { - MihMzansiCalendarApis.updatePersonalAppointment( - widget.signedInUser, - widget.business, - widget.appointmentList[index].idappointments, - widget.titleController.text, - widget.descriptionIDController.text, - widget.dateController.text, - widget.timeController.text, - context, - ); + if (widget.personalSelected == true) { + MihMzansiCalendarApis.updatePersonalAppointment( + widget.signedInUser, + widget.business, + null, + widget.appointmentList[index].idappointments, + widget.titleController.text, + widget.descriptionIDController.text, + widget.dateController.text, + widget.timeController.text, + context, + ); + } else if (widget.personalSelected == false && + widget.inWaitingRoom == false) { + MihMzansiCalendarApis.updateBusinessAppointment( + widget.signedInUser, + widget.business, + widget.businessUser, + widget.appointmentList[index].idappointments, + widget.titleController.text, + widget.descriptionIDController.text, + widget.dateController.text, + widget.timeController.text, + context, + ); + } else { + MihMzansiCalendarApis.updatePatientAppointment( + widget.signedInUser, + widget.business, + widget.businessUser, + widget.appointmentList[index].idappointments, + widget.titleController.text, + widget.descriptionIDController.text, + widget.dateController.text, + widget.timeController.text, + context, + ); + } } else { showDialog( context: context, @@ -526,8 +557,12 @@ class _BuildAppointmentListState extends State { } void deleteAppointmentCall(int index) { - MihMzansiCalendarApis.deleteLoyaltyCardAPICall( + MihMzansiCalendarApis.deleteAppointmentAPICall( widget.signedInUser, + widget.personalSelected, + widget.business, + widget.businessUser, + widget.inWaitingRoom, widget.appointmentList[index].idappointments, context, ); diff --git a/Frontend/lib/mih_packages/calendar/mzansi_calendar.dart b/Frontend/lib/mih_packages/calendar/mzansi_calendar.dart index 0e5a21bc..4485808d 100644 --- a/Frontend/lib/mih_packages/calendar/mzansi_calendar.dart +++ b/Frontend/lib/mih_packages/calendar/mzansi_calendar.dart @@ -69,6 +69,7 @@ class _MzansiCalendarState extends State { Appointments( signedInUser: widget.arguments.signedInUser, business: widget.arguments.business, + businessUser: widget.arguments.businessUser, personalSelected: widget.arguments.personalSelected, ), ]; diff --git a/Frontend/lib/mih_packages/mih_home/mih_home.dart b/Frontend/lib/mih_packages/mih_home/mih_home.dart index 3344aecd..8708ca5a 100644 --- a/Frontend/lib/mih_packages/mih_home/mih_home.dart +++ b/Frontend/lib/mih_packages/mih_home/mih_home.dart @@ -38,6 +38,7 @@ import '../../mih_objects/business_user.dart'; import '../../mih_objects/notification.dart'; import '../test/test.dart'; +// ignore: must_be_immutable class MIHHome extends StatefulWidget { final AppUser signedInUser; final BusinessUser? businessUser; @@ -49,8 +50,8 @@ class MIHHome extends StatefulWidget { final bool isBusinessUser; final bool isBusinessUserNew; final bool isDevActive; - final bool personalSelected; - const MIHHome({ + bool personalSelected; + MIHHome({ super.key, required this.signedInUser, required this.businessUser, @@ -253,6 +254,7 @@ class _MIHHomeState extends State { widget.signedInUser, true, widget.business, + null, ), ); }, @@ -434,6 +436,7 @@ class _MIHHomeState extends State { widget.signedInUser, false, widget.business, + widget.businessUser, ), ); }, @@ -1171,8 +1174,10 @@ class _MIHHomeState extends State { text: "Personal", onPressed: () { setState(() { + widget.personalSelected = true; _selectedIndex = 0; }); + print("personal selected: ${widget.personalSelected}"); }, ), GButton( @@ -1180,8 +1185,10 @@ class _MIHHomeState extends State { text: "Business", onPressed: () { setState(() { + widget.personalSelected = false; _selectedIndex = 1; }); + print("personal selected: ${widget.personalSelected}"); }, ), ], 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 eae5583d..f5a99ba0 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 @@ -4,7 +4,6 @@ import 'package:Mzansi_Innovation_Hub/mih_components/mih_calendar.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_multiline_text_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_inputs_and_buttons/mih_time_input.dart'; import 'package:Mzansi_Innovation_Hub/mih_components/mih_layout/mih_window.dart'; @@ -15,19 +14,23 @@ 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/appointment.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_packages/calendar/builder/build_appointment_list.dart'; import 'package:flutter/material.dart'; class WaitingRoom extends StatefulWidget { final AppUser signedInUser; final Business? business; + final BusinessUser? businessUser; final bool personalSelected; - + final Function(int) onIndexChange; const WaitingRoom({ super.key, required this.signedInUser, - this.business, + required this.business, + required this.businessUser, required this.personalSelected, + required this.onIndexChange, }); @override @@ -52,6 +55,7 @@ class _WaitingRoomState extends State { late Future> businessAppointmentResults; late Future> appointmentResults; + bool inWaitingRoom = true; // Business Appointment Tool Widget getBusinessAppointmentsTool() { @@ -122,7 +126,7 @@ class _WaitingRoomState extends State { child: IconButton( color: MzanziInnovationHub.of(context)!.theme.primaryColor(), onPressed: () { - addAppointmentWindow(); + appointmentTypeSelection(); }, icon: const Icon( Icons.add, @@ -141,6 +145,7 @@ class _WaitingRoomState extends State { appointmentList: appointmentList, signedInUser: widget.signedInUser, business: widget.business, + businessUser: widget.businessUser, personalSelected: widget.personalSelected, inWaitingRoom: true, titleController: _appointmentTitleController, @@ -170,7 +175,89 @@ class _WaitingRoomState extends State { ); } + void appointmentTypeSelection() { + String question = "What type of appointment would you like to add?"; + question += + "\n\nExisting Patient: Add an appointment for an patient your practice has access to."; + question += + "\nExisting MIH User: Add an appointment for an existing MIH user your practice does not have access to."; + question += + "\nSkeleton Appointment: Add an appointment without a patient linked."; + showDialog( + context: context, + barrierDismissible: false, + builder: (context) { + return MIHWindow( + fullscreen: false, + windowTitle: "Appointment Type", + windowTools: [], + onWindowTapClose: () { + Navigator.of(context).pop(); + }, + windowBody: [ + Text( + question, + style: TextStyle( + fontSize: 20, + color: + MzanziInnovationHub.of(context)!.theme.secondaryColor()), + textAlign: TextAlign.left, + ), + const SizedBox(height: 15), + SizedBox( + width: 500, + height: 50, + child: MIHButton( + onTap: () { + widget.onIndexChange(1); + Navigator.of(context).pop(); + }, + buttonText: "Existing Patient", + buttonColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + textColor: + MzanziInnovationHub.of(context)!.theme.primaryColor(), + ), + ), + const SizedBox(height: 10), + SizedBox( + width: 500, + height: 50, + child: MIHButton( + onTap: () { + widget.onIndexChange(2); + Navigator.of(context).pop(); + }, + buttonText: "Existing MIH User", + buttonColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + textColor: + MzanziInnovationHub.of(context)!.theme.primaryColor(), + ), + ), + const SizedBox(height: 10), + SizedBox( + width: 500, + height: 50, + child: MIHButton( + onTap: () { + addAppointmentWindow(); + }, + buttonText: "Skeleton Appointment", + buttonColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + textColor: + MzanziInnovationHub.of(context)!.theme.primaryColor(), + ), + ), + ], + ); + }, + ); + } + void addAppointmentWindow() { + print(widget.personalSelected); showDialog( context: context, barrierDismissible: false, @@ -198,18 +285,6 @@ class _WaitingRoomState extends State { ), ), const SizedBox(height: 10), - SizedBox( - child: MIHSearchField( - controller: _patientController, - hintText: "Patient ID Number", - required: false, - editable: true, - onTap: () { - //To-Do: Add search functionality - }, - ), - ), - const SizedBox(height: 10), SizedBox( // width: 500, child: MIHDateField( @@ -244,9 +319,7 @@ class _WaitingRoomState extends State { height: 50, child: MIHButton( onTap: () { - //To-Do: Add appointment - print("To-Do: Add appointment"); - // addAppointmentCall(); + addAppointmentCall(); }, buttonText: "Add", buttonColor: @@ -267,6 +340,8 @@ class _WaitingRoomState extends State { MihMzansiCalendarApis.addBusinessAppointment( widget.signedInUser, widget.business!, + widget.businessUser!, + true, _appointmentTitleController.text, _appointmentDescriptionIDController.text, _appointmentDateController.text, 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 f7684fcb..851132a3 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 @@ -20,6 +20,13 @@ class PatManager extends StatefulWidget { class _PatManagerState extends State { int _selcetedIndex = 0; + + void updateIndex(int index) { + setState(() { + _selcetedIndex = index; + }); + } + @override Widget build(BuildContext context) { return MihApp( @@ -82,7 +89,9 @@ class _PatManagerState extends State { WaitingRoom( signedInUser: widget.arguments.signedInUser, business: widget.arguments.business, + businessUser: widget.arguments.businessUser, personalSelected: widget.arguments.personalSelected, + onIndexChange: updateIndex, ), MyPatientList( signedInUser: widget.arguments.signedInUser, diff --git a/Frontend/pubspec.lock b/Frontend/pubspec.lock index c39e76f4..1e829927 100644 --- a/Frontend/pubspec.lock +++ b/Frontend/pubspec.lock @@ -45,10 +45,10 @@ packages: dependency: transitive description: name: async - sha256: d2872f9c19731c2e5f10444b14686eb7cc85c76274bd6c16e1816bff9a3bab63 + sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c" url: "https://pub.dev" source: hosted - version: "2.12.0" + version: "2.11.0" barcode: dependency: transitive description: @@ -85,10 +85,10 @@ packages: dependency: transitive description: name: boolean_selector - sha256: "8aab1771e1243a5063b8b0ff68042d67334e3feab9e95b9490f9a6ebf73b42ea" + sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66" url: "https://pub.dev" source: hosted - version: "2.1.2" + version: "2.1.1" buffer: dependency: transitive description: @@ -181,10 +181,10 @@ packages: dependency: transitive description: name: characters - sha256: f71061c654a3380576a52b451dd5532377954cf9dbd272a78fc8479606670803 + sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605" url: "https://pub.dev" source: hosted - version: "1.4.0" + version: "1.3.0" charcode: dependency: transitive description: @@ -213,10 +213,10 @@ packages: dependency: transitive description: name: clock - sha256: fddb70d9b5277016c77a80201021d40a2247104d9f4aa7bab7157b7e3f05b84b + sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf url: "https://pub.dev" source: hosted - version: "1.1.2" + version: "1.1.1" code_builder: dependency: transitive description: @@ -229,10 +229,10 @@ packages: dependency: transitive description: name: collection - sha256: "2f5709ae4d3d59dd8f7cd309b4e023046b57d8a6c82130785d2b0e5868084e76" + sha256: a1ace0a119f20aabc852d165077c036cd864315bd99b7eaa10a60100341941bf url: "https://pub.dev" source: hosted - version: "1.19.1" + version: "1.19.0" convert: dependency: transitive description: @@ -333,10 +333,10 @@ packages: dependency: transitive description: name: fake_async - sha256: "6a95e56b2449df2273fd8c45a662d6947ce1ebb7aafe80e550a3f68297f3cacc" + sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78" url: "https://pub.dev" source: hosted - version: "1.3.2" + version: "1.3.1" fetch_api: dependency: transitive description: @@ -676,18 +676,18 @@ packages: dependency: transitive description: name: leak_tracker - sha256: c35baad643ba394b40aac41080300150a4f08fd0fd6a10378f8f7c6bc161acec + sha256: "7bb2830ebd849694d1ec25bf1f44582d6ac531a57a365a803a6034ff751d2d06" url: "https://pub.dev" source: hosted - version: "10.0.8" + version: "10.0.7" leak_tracker_flutter_testing: dependency: transitive description: name: leak_tracker_flutter_testing - sha256: f8b613e7e6a13ec79cfdc0e97638fddb3ab848452eff057653abd3edba760573 + sha256: "9491a714cca3667b60b5c420da8217e6de0d1ba7a5ec322fab01758f6998f379" url: "https://pub.dev" source: hosted - version: "3.0.9" + version: "3.0.8" leak_tracker_testing: dependency: transitive description: @@ -764,10 +764,10 @@ packages: dependency: transitive description: name: matcher - sha256: dc58c723c3c24bf8d3e2d3ad3f2f9d7bd9cf43ec6feaa64181775e60190153f2 + sha256: d2323aa2060500f906aa31a895b4030b6da3ebdcc5619d14ce1aada65cd161cb url: "https://pub.dev" source: hosted - version: "0.12.17" + version: "0.12.16+1" material_color_utilities: dependency: transitive description: @@ -788,10 +788,10 @@ packages: dependency: transitive description: name: meta - sha256: e3641ec5d63ebf0d9b41bd43201a66e3fc79a65db5f61fc181f04cd27aab950c + sha256: bdb68674043280c3428e9ec998512fb681678676b3c54e773629ffe74419f8c7 url: "https://pub.dev" source: hosted - version: "1.16.0" + version: "1.15.0" mime: dependency: transitive description: @@ -852,10 +852,10 @@ packages: dependency: transitive description: name: path - sha256: "75cca69d1490965be98c73ceaea117e8a04dd21217b37b292c9ddbec0d955bc5" + sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af" url: "https://pub.dev" source: hosted - version: "1.9.1" + version: "1.9.0" path_parsing: dependency: transitive description: @@ -1153,10 +1153,10 @@ packages: dependency: transitive description: name: source_span - sha256: "254ee5351d6cb365c859e20ee823c3bb479bf4a293c22d17a9f1bf144ce86f7c" + sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c" url: "https://pub.dev" source: hosted - version: "1.10.1" + version: "1.10.0" sprintf: dependency: transitive description: @@ -1169,18 +1169,18 @@ packages: dependency: transitive description: name: stack_trace - sha256: "8b27215b45d22309b5cddda1aa2b19bdfec9df0e765f2de506401c071d38d1b1" + sha256: "9f47fd3630d76be3ab26f0ee06d213679aa425996925ff3feffdec504931c377" url: "https://pub.dev" source: hosted - version: "1.12.1" + version: "1.12.0" stream_channel: dependency: transitive description: name: stream_channel - sha256: "969e04c80b8bcdf826f8f16579c7b14d780458bd97f56d107d3950fdbeef059d" + sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7 url: "https://pub.dev" source: hosted - version: "2.1.4" + version: "2.1.2" stream_transform: dependency: transitive description: @@ -1193,10 +1193,10 @@ packages: dependency: transitive description: name: string_scanner - sha256: "921cd31725b72fe181906c6a94d987c78e3b98c2e205b397ea399d4054872b43" + sha256: "688af5ed3402a4bde5b3a6c15fd768dbf2621a614950b17f04626c431ab3c4c3" url: "https://pub.dev" source: hosted - version: "1.4.1" + version: "1.3.0" supertokens_flutter: dependency: "direct main" description: @@ -1281,18 +1281,18 @@ packages: dependency: transitive description: name: term_glyph - sha256: "7f554798625ea768a7518313e58f83891c7f5024f88e46e7182a4558850a4b8e" + sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84 url: "https://pub.dev" source: hosted - version: "1.2.2" + version: "1.2.1" test_api: dependency: transitive description: name: test_api - sha256: fb31f383e2ee25fbbfe06b40fe21e1e458d14080e3c67e7ba0acfde4df4e0bbd + sha256: "664d3a9a64782fcdeb83ce9c6b39e78fd2971d4e37827b9b06c3aa1edc5e760c" url: "https://pub.dev" source: hosted - version: "0.7.4" + version: "0.7.3" timing: dependency: transitive description: @@ -1425,10 +1425,10 @@ packages: dependency: transitive description: name: vm_service - sha256: "0968250880a6c5fe7edc067ed0a13d4bae1577fe2771dcf3010d52c4a9d3ca14" + sha256: f6be3ed8bd01289b34d679c2b62226f63c0e69f9fd2e50a6b3c1c729a961041b url: "https://pub.dev" source: hosted - version: "14.3.1" + version: "14.3.0" watcher: dependency: transitive description: @@ -1558,5 +1558,5 @@ packages: source: hosted version: "3.1.1" sdks: - dart: ">=3.7.0-0 <3.9.0" + dart: ">=3.6.0 <3.9.0" flutter: ">=3.27.0" From b051082c9a987e4b252a8d7feeb97a85397b5b1e Mon Sep 17 00:00:00 2001 From: yaso Date: Tue, 4 Mar 2025 13:56:57 +0200 Subject: [PATCH 8/8] testing fix --- .../mih_apis/mih_mzansi_calendar_apis.dart | 15 +++-- .../lib/mih_apis/mih_notification_apis.dart | 1 + .../builder/build_appointment_list.dart | 55 ++++++++++--------- .../build_mih_patient_search_list.dart | 46 ++++++++-------- 4 files changed, 61 insertions(+), 56 deletions(-) diff --git a/Frontend/lib/mih_apis/mih_mzansi_calendar_apis.dart b/Frontend/lib/mih_apis/mih_mzansi_calendar_apis.dart index f5388b96..d71d4e04 100644 --- a/Frontend/lib/mih_apis/mih_mzansi_calendar_apis.dart +++ b/Frontend/lib/mih_apis/mih_mzansi_calendar_apis.dart @@ -135,7 +135,8 @@ class MihMzansiCalendarApis { if (response.statusCode == 200) { Navigator.of(context).pop(); Navigator.of(context).pop(); - if (inWaitingRoom) { + Navigator.of(context).pop(); + if (inWaitingRoom == true && personalSelected == false) { Navigator.of(context).pushNamed( '/patient-manager', arguments: PatManagerArguments( @@ -150,7 +151,7 @@ class MihMzansiCalendarApis { '/calendar', arguments: CalendarArguments( signedInUser, - false, + personalSelected, business, businessUser, ), @@ -265,6 +266,7 @@ class MihMzansiCalendarApis { Navigator.pop(context); Navigator.pop(context); Navigator.pop(context); + Navigator.pop(context); String message = "Your appointment \"$title\" for the $date $title has been deleted."; @@ -391,7 +393,7 @@ class MihMzansiCalendarApis { }), ); if (response.statusCode == 200) { - // Navigator.pop(context); + Navigator.pop(context); Navigator.pop(context); Navigator.pop(context); String message = @@ -453,7 +455,7 @@ class MihMzansiCalendarApis { }), ); if (response.statusCode == 200) { - // Navigator.pop(context); + Navigator.pop(context); Navigator.pop(context); Navigator.pop(context); String message = @@ -515,13 +517,14 @@ class MihMzansiCalendarApis { }), ); if (response.statusCode == 200) { - // Navigator.pop(context); + Navigator.pop(context); + Navigator.pop(context); Navigator.pop(context); Navigator.pop(context); String message = "Your appointment \"$title\" has been updates to the $date $title."; - Navigator.pop(context); + // Navigator.pop(context); Navigator.of(context).pushNamed( '/patient-manager', arguments: PatManagerArguments( diff --git a/Frontend/lib/mih_apis/mih_notification_apis.dart b/Frontend/lib/mih_apis/mih_notification_apis.dart index ba62292d..ab84d871 100644 --- a/Frontend/lib/mih_apis/mih_notification_apis.dart +++ b/Frontend/lib/mih_apis/mih_notification_apis.dart @@ -252,6 +252,7 @@ class MihNotificationApis { Navigator.of(context).pop(); Navigator.of(context).pop(); Navigator.of(context).pop(); + Navigator.of(context).pop(); Navigator.of(context).pushNamed( '/patient-manager', arguments: PatManagerArguments( diff --git a/Frontend/lib/mih_packages/calendar/builder/build_appointment_list.dart b/Frontend/lib/mih_packages/calendar/builder/build_appointment_list.dart index 8bd78efe..a440069b 100644 --- a/Frontend/lib/mih_packages/calendar/builder/build_appointment_list.dart +++ b/Frontend/lib/mih_packages/calendar/builder/build_appointment_list.dart @@ -446,33 +446,33 @@ class _BuildAppointmentListState extends State { MzanziInnovationHub.of(context)!.theme.primaryColor(), ), ), - SizedBox( - width: 500, - height: 50, - child: MIHButton( - onTap: () { - setState(() { - widget.titleController.text = - widget.appointmentList[index].title; - widget.descriptionIDController.text = - widget.appointmentList[index].description; - widget.dateController.text = widget - .appointmentList[index].date_time - .split('T')[0]; - widget.timeController.text = widget - .appointmentList[index].date_time - .split('T')[1] - .substring(0, 5); - }); - Navigator.of(context).pop(); - }, - buttonText: "Cancel", - buttonColor: - MzanziInnovationHub.of(context)!.theme.errorColor(), - textColor: - MzanziInnovationHub.of(context)!.theme.primaryColor(), - ), - ), + // SizedBox( + // width: 500, + // height: 50, + // child: MIHButton( + // onTap: () { + // setState(() { + // widget.titleController.text = + // widget.appointmentList[index].title; + // widget.descriptionIDController.text = + // widget.appointmentList[index].description; + // widget.dateController.text = widget + // .appointmentList[index].date_time + // .split('T')[0]; + // widget.timeController.text = widget + // .appointmentList[index].date_time + // .split('T')[1] + // .substring(0, 5); + // }); + // Navigator.of(context).pop(); + // }, + // buttonText: "Cancel", + // buttonColor: + // MzanziInnovationHub.of(context)!.theme.errorColor(), + // textColor: + // MzanziInnovationHub.of(context)!.theme.primaryColor(), + // ), + // ), ], ) ], @@ -557,6 +557,7 @@ class _BuildAppointmentListState extends State { } void deleteAppointmentCall(int index) { + print("personal selected: ${widget.personalSelected}"); MihMzansiCalendarApis.deleteAppointmentAPICall( widget.signedInUser, widget.personalSelected, diff --git a/Frontend/lib/mih_packages/patient_profile/pat_manager/list_builders/build_mih_patient_search_list.dart b/Frontend/lib/mih_packages/patient_profile/pat_manager/list_builders/build_mih_patient_search_list.dart index 278c76b4..43b54599 100644 --- a/Frontend/lib/mih_packages/patient_profile/pat_manager/list_builders/build_mih_patient_search_list.dart +++ b/Frontend/lib/mih_packages/patient_profile/pat_manager/list_builders/build_mih_patient_search_list.dart @@ -411,7 +411,7 @@ class _BuildPatientsListState extends State { ), ), Text( - "By pressing the \"Request Access\" button you accept the above terms.", + "By pressing the \"Request Access\" button you accept the above terms.\n", style: TextStyle( fontWeight: FontWeight.bold, color: MzanziInnovationHub.of(context)!.theme.errorColor(), @@ -420,29 +420,29 @@ class _BuildPatientsListState extends State { ], ), ), - const SizedBox(height: 20.0), + // const SizedBox(height: 15.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: "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(