Update patient manager and access flow to cater for forever access.
This commit is contained in:
@@ -0,0 +1,461 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:patient_manager/mih_apis/mih_api_calls.dart';
|
||||||
|
import 'package:patient_manager/mih_components/mih_inputs_and_buttons/mih_button.dart';
|
||||||
|
import 'package:patient_manager/mih_components/mih_layout/mih_window.dart';
|
||||||
|
import 'package:patient_manager/mih_components/mih_pop_up_messages/mih_error_message.dart';
|
||||||
|
import 'package:patient_manager/mih_components/mih_pop_up_messages/mih_success_message.dart';
|
||||||
|
import 'package:patient_manager/mih_components/mih_pop_up_messages/mih_warning_message.dart';
|
||||||
|
import 'package:patient_manager/mih_env/env.dart';
|
||||||
|
import 'package:patient_manager/main.dart';
|
||||||
|
import 'package:patient_manager/mih_objects/app_user.dart';
|
||||||
|
import 'package:patient_manager/mih_objects/patient_access.dart';
|
||||||
|
|
||||||
|
class BuildBusinessAccessList extends StatefulWidget {
|
||||||
|
final List<PatientAccess> patientAccessList;
|
||||||
|
final AppUser signedInUser;
|
||||||
|
|
||||||
|
const BuildBusinessAccessList({
|
||||||
|
super.key,
|
||||||
|
required this.patientAccessList,
|
||||||
|
required this.signedInUser,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<BuildBusinessAccessList> createState() => _BuildPatientsListState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _BuildPatientsListState extends State<BuildBusinessAccessList> {
|
||||||
|
String baseAPI = AppEnviroment.baseApiUrl;
|
||||||
|
late double popUpWidth;
|
||||||
|
late double? popUpheight;
|
||||||
|
late double popUpButtonWidth;
|
||||||
|
late double popUpTitleSize;
|
||||||
|
late double popUpSubtitleSize;
|
||||||
|
late double popUpBodySize;
|
||||||
|
late double popUpIconSize;
|
||||||
|
late double popUpPaddingSize;
|
||||||
|
late double width;
|
||||||
|
late double height;
|
||||||
|
|
||||||
|
// Future<void> updateAccessAPICall(int index, String accessType) async {
|
||||||
|
// var response = await http.put(
|
||||||
|
// Uri.parse("$baseAPI/access-requests/update/"),
|
||||||
|
// headers: <String, String>{
|
||||||
|
// "Content-Type": "application/json; charset=UTF-8"
|
||||||
|
// },
|
||||||
|
// body: jsonEncode(<String, dynamic>{
|
||||||
|
// "business_id": widget.patientAccessList[index].business_id,
|
||||||
|
// "app_id": widget.patientAccessList[index].app_id,
|
||||||
|
// "date_time": widget.patientAccessList[index].date_time,
|
||||||
|
// "access": accessType,
|
||||||
|
// }),
|
||||||
|
// );
|
||||||
|
// if (response.statusCode == 200) {
|
||||||
|
// //Navigator.of(context).pushNamed('/home');
|
||||||
|
// Navigator.of(context).pop();
|
||||||
|
// Navigator.of(context).pop();
|
||||||
|
// Navigator.of(context).pushNamed(
|
||||||
|
// '/patient-access-review',
|
||||||
|
// arguments: widget.signedInUser,
|
||||||
|
// );
|
||||||
|
// String message = "";
|
||||||
|
// if (accessType == "approved") {
|
||||||
|
// message =
|
||||||
|
// "You've successfully approved the access request! ${widget.patientAccessList[index].Name} now has access to your profile until ${widget.patientAccessList[index].revoke_date.substring(0, 16).replaceAll("T", " ")}.";
|
||||||
|
// } else {
|
||||||
|
// message =
|
||||||
|
// "You've declined the access request. ${widget.patientAccessList[index].Name} will not have access to your profile.";
|
||||||
|
// }
|
||||||
|
// successPopUp(message);
|
||||||
|
// } else {
|
||||||
|
// internetConnectionPopUp();
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
void internetConnectionPopUp() {
|
||||||
|
showDialog(
|
||||||
|
context: context,
|
||||||
|
builder: (context) {
|
||||||
|
return const MIHErrorMessage(errorType: "Internet Connection");
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void successPopUp(String message) {
|
||||||
|
showDialog(
|
||||||
|
context: context,
|
||||||
|
builder: (context) {
|
||||||
|
return MIHSuccessMessage(
|
||||||
|
successType: "Success",
|
||||||
|
successMessage: message,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void accessCancelledWarning() {
|
||||||
|
showDialog(
|
||||||
|
context: context,
|
||||||
|
builder: (context) {
|
||||||
|
return const MIHWarningMessage(warningType: "Access Cancelled");
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget displayQueue(int index) {
|
||||||
|
String line1 =
|
||||||
|
"Business Name: ${widget.patientAccessList[index].requested_by}";
|
||||||
|
String line2 = "";
|
||||||
|
line2 +=
|
||||||
|
"Profile Access: ${widget.patientAccessList[index].type.toUpperCase()}\n";
|
||||||
|
line2 +=
|
||||||
|
"Request Date: ${widget.patientAccessList[index].requested_on.substring(0, 16).replaceAll("T", " ")}\n";
|
||||||
|
//subtitle += "Business Type: ${widget.patientAccessList[index].type}\n";
|
||||||
|
String line3 = "Access Status: ";
|
||||||
|
String access = widget.patientAccessList[index].status.toUpperCase();
|
||||||
|
|
||||||
|
TextSpan accessWithColour;
|
||||||
|
if (access == "APPROVED") {
|
||||||
|
accessWithColour = TextSpan(
|
||||||
|
text: "$access\n",
|
||||||
|
style: TextStyle(
|
||||||
|
color: MzanziInnovationHub.of(context)!.theme.successColor()));
|
||||||
|
} else if (access == "PENDING") {
|
||||||
|
accessWithColour = TextSpan(
|
||||||
|
text: "$access\n",
|
||||||
|
style: TextStyle(
|
||||||
|
color:
|
||||||
|
MzanziInnovationHub.of(context)!.theme.messageTextColor()));
|
||||||
|
} else {
|
||||||
|
accessWithColour = TextSpan(
|
||||||
|
text: "$access\n",
|
||||||
|
style: TextStyle(
|
||||||
|
color: MzanziInnovationHub.of(context)!.theme.errorColor()));
|
||||||
|
}
|
||||||
|
|
||||||
|
return ListTile(
|
||||||
|
title: Text(
|
||||||
|
line1,
|
||||||
|
style: TextStyle(
|
||||||
|
color: MzanziInnovationHub.of(context)!.theme.secondaryColor(),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
subtitle: RichText(
|
||||||
|
text: TextSpan(
|
||||||
|
text: line2,
|
||||||
|
style: DefaultTextStyle.of(context).style,
|
||||||
|
children: <TextSpan>[
|
||||||
|
TextSpan(text: line3),
|
||||||
|
accessWithColour,
|
||||||
|
]),
|
||||||
|
),
|
||||||
|
// Text(
|
||||||
|
// subtitle,
|
||||||
|
// style: TextStyle(
|
||||||
|
// color: MzanziInnovationHub.of(context)!.theme.secondaryColor(),
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
onTap: () {
|
||||||
|
viewApprovalPopUp(index);
|
||||||
|
},
|
||||||
|
// trailing: Icon(
|
||||||
|
// Icons.arrow_forward,
|
||||||
|
// color: MzanziInnovationHub.of(context)!.theme.secondaryColor(),
|
||||||
|
// ),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void checkScreenSize() {
|
||||||
|
if (MzanziInnovationHub.of(context)!.theme.screenType == "desktop") {
|
||||||
|
setState(() {
|
||||||
|
popUpWidth = (width / 4) * 2;
|
||||||
|
popUpheight = null;
|
||||||
|
popUpButtonWidth = 300;
|
||||||
|
popUpTitleSize = 25.0;
|
||||||
|
popUpSubtitleSize = 20.0;
|
||||||
|
popUpBodySize = 15;
|
||||||
|
popUpPaddingSize = 25.0;
|
||||||
|
popUpIconSize = 100;
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
setState(() {
|
||||||
|
popUpWidth = width - (width * 0.1);
|
||||||
|
popUpheight = null;
|
||||||
|
popUpButtonWidth = 300;
|
||||||
|
popUpTitleSize = 20.0;
|
||||||
|
popUpSubtitleSize = 18.0;
|
||||||
|
popUpBodySize = 15;
|
||||||
|
popUpPaddingSize = 15.0;
|
||||||
|
popUpIconSize = 100;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void viewApprovalPopUp(int index) {
|
||||||
|
String subtitle =
|
||||||
|
"Business Name: ${widget.patientAccessList[index].requested_by}\n";
|
||||||
|
subtitle +=
|
||||||
|
"Requested Date: ${widget.patientAccessList[index].requested_on.substring(0, 16).replaceAll("T", " ")}\n";
|
||||||
|
subtitle += "Access Status: ${widget.patientAccessList[index].status}\n";
|
||||||
|
subtitle += "Access Profile: ${widget.patientAccessList[index].type}";
|
||||||
|
|
||||||
|
if (widget.patientAccessList[index].status == 'pending') {
|
||||||
|
// "\nYou are about to approve an access request to your patient profile.\nPlease be aware that once approved, ${widget.patientAccessList[index].requested_by} will have access to your profile forever and will be able to contribute to it.\nIf you are unsure about an upcoming appointment with ${widget.patientAccessList[index].requested_by}, please contact *Add Number here* for clarification before approving this request.";
|
||||||
|
} else {
|
||||||
|
subtitle +=
|
||||||
|
"\nApproved By: ${widget.patientAccessList[index].approved_by}\n";
|
||||||
|
subtitle +=
|
||||||
|
"Approved On: ${widget.patientAccessList[index].approved_on.substring(0, 16).replaceAll("T", " ")}";
|
||||||
|
// subtitle +=
|
||||||
|
// "You have approved this access request to your patient profile.\nPlease be aware that once approved, ${widget.patientAccessList[index].requested_by} will have access to your profile forever and will be able to contribute to it.";
|
||||||
|
}
|
||||||
|
showDialog(
|
||||||
|
context: context,
|
||||||
|
barrierDismissible: false,
|
||||||
|
builder: (context) => MIHWindow(
|
||||||
|
fullscreen: false,
|
||||||
|
windowTitle: "Profile Access",
|
||||||
|
windowBody: [
|
||||||
|
const SizedBox(
|
||||||
|
height: 10,
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
width: 1000,
|
||||||
|
child: Text(
|
||||||
|
subtitle,
|
||||||
|
textAlign: TextAlign.left,
|
||||||
|
style: TextStyle(
|
||||||
|
color:
|
||||||
|
MzanziInnovationHub.of(context)!.theme.secondaryColor(),
|
||||||
|
fontSize: popUpBodySize,
|
||||||
|
//fontWeight: FontWeight.bold,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 20.0),
|
||||||
|
Visibility(
|
||||||
|
visible: widget.patientAccessList[index].status == 'pending',
|
||||||
|
child: Column(
|
||||||
|
mainAxisSize: MainAxisSize.max,
|
||||||
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
"Important Notice: Approving Profile Access",
|
||||||
|
style: TextStyle(
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
color:
|
||||||
|
MzanziInnovationHub.of(context)!.theme.errorColor(),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
"You are about to accept access to your patient's profile. Please be aware of the following important points:",
|
||||||
|
style: TextStyle(
|
||||||
|
fontWeight: FontWeight.normal,
|
||||||
|
color:
|
||||||
|
MzanziInnovationHub.of(context)!.theme.errorColor(),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
width: 700,
|
||||||
|
child: Text(
|
||||||
|
"1. Permanent Access: Once you accepts this access request, it will become permanent.",
|
||||||
|
style: TextStyle(
|
||||||
|
fontWeight: FontWeight.normal,
|
||||||
|
color:
|
||||||
|
MzanziInnovationHub.of(context)!.theme.errorColor(),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
width: 700,
|
||||||
|
child: Text(
|
||||||
|
"2. Shared Information: Any updates make to youe patient profile will be visible to all who have access to the profile.",
|
||||||
|
style: TextStyle(
|
||||||
|
fontWeight: FontWeight.normal,
|
||||||
|
color:
|
||||||
|
MzanziInnovationHub.of(context)!.theme.errorColor(),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
width: 700,
|
||||||
|
child: Text(
|
||||||
|
"3. Irreversible Access: Once granted, you cannot revoke access to your patient's profile.",
|
||||||
|
style: TextStyle(
|
||||||
|
fontWeight: FontWeight.normal,
|
||||||
|
color:
|
||||||
|
MzanziInnovationHub.of(context)!.theme.errorColor(),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
"By pressing the \"Approve\" button you accept the above terms.",
|
||||||
|
style: TextStyle(
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
color:
|
||||||
|
MzanziInnovationHub.of(context)!.theme.errorColor(),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Visibility(
|
||||||
|
visible: widget.patientAccessList[index].status == 'approved',
|
||||||
|
child: Column(
|
||||||
|
mainAxisSize: MainAxisSize.max,
|
||||||
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
"Important Notice: Approved Profile Access",
|
||||||
|
style: TextStyle(
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
color:
|
||||||
|
MzanziInnovationHub.of(context)!.theme.errorColor(),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
"You have accepted access to your patient's profile. Please be aware of the following important points:",
|
||||||
|
style: TextStyle(
|
||||||
|
fontWeight: FontWeight.normal,
|
||||||
|
color:
|
||||||
|
MzanziInnovationHub.of(context)!.theme.errorColor(),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
width: 700,
|
||||||
|
child: Text(
|
||||||
|
"1. Permanent Access: This access is permanent.",
|
||||||
|
style: TextStyle(
|
||||||
|
fontWeight: FontWeight.normal,
|
||||||
|
color:
|
||||||
|
MzanziInnovationHub.of(context)!.theme.errorColor(),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
width: 700,
|
||||||
|
child: Text(
|
||||||
|
"2. Shared Information: Any updates make to youe patient profile will be visible to all who have access to the profile.",
|
||||||
|
style: TextStyle(
|
||||||
|
fontWeight: FontWeight.normal,
|
||||||
|
color:
|
||||||
|
MzanziInnovationHub.of(context)!.theme.errorColor(),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
width: 700,
|
||||||
|
child: Text(
|
||||||
|
"3. Irreversible Access: You cannot revoke this access to your patient's profile.",
|
||||||
|
style: TextStyle(
|
||||||
|
fontWeight: FontWeight.normal,
|
||||||
|
color:
|
||||||
|
MzanziInnovationHub.of(context)!.theme.errorColor(),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 20.0),
|
||||||
|
const SizedBox(
|
||||||
|
height: 20,
|
||||||
|
),
|
||||||
|
Visibility(
|
||||||
|
visible: widget.patientAccessList[index].status == 'pending',
|
||||||
|
child: Wrap(
|
||||||
|
runSpacing: 10,
|
||||||
|
spacing: 10,
|
||||||
|
children: [
|
||||||
|
SizedBox(
|
||||||
|
width: popUpButtonWidth,
|
||||||
|
height: 50,
|
||||||
|
child: MIHButton(
|
||||||
|
onTap: () {
|
||||||
|
print("request declined");
|
||||||
|
MIHApiCalls.updatePatientAccessAPICall(
|
||||||
|
widget.patientAccessList[index].business_id,
|
||||||
|
widget.patientAccessList[index].requested_by,
|
||||||
|
widget.patientAccessList[index].app_id,
|
||||||
|
"declined",
|
||||||
|
"${widget.signedInUser.fname} ${widget.signedInUser.lname}",
|
||||||
|
widget.signedInUser,
|
||||||
|
context,
|
||||||
|
);
|
||||||
|
//updateAccessAPICall(index, "declined");
|
||||||
|
},
|
||||||
|
buttonText: "Decline",
|
||||||
|
buttonColor:
|
||||||
|
MzanziInnovationHub.of(context)!.theme.errorColor(),
|
||||||
|
textColor:
|
||||||
|
MzanziInnovationHub.of(context)!.theme.primaryColor(),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
width: popUpButtonWidth,
|
||||||
|
height: 50,
|
||||||
|
child: MIHButton(
|
||||||
|
onTap: () {
|
||||||
|
print("request approved");
|
||||||
|
MIHApiCalls.updatePatientAccessAPICall(
|
||||||
|
widget.patientAccessList[index].business_id,
|
||||||
|
widget.patientAccessList[index].requested_by,
|
||||||
|
widget.patientAccessList[index].app_id,
|
||||||
|
"approved",
|
||||||
|
"${widget.signedInUser.fname} ${widget.signedInUser.lname}",
|
||||||
|
widget.signedInUser,
|
||||||
|
context,
|
||||||
|
);
|
||||||
|
//updateAccessAPICall(index, "approved");
|
||||||
|
},
|
||||||
|
buttonText: "Approve",
|
||||||
|
buttonColor:
|
||||||
|
MzanziInnovationHub.of(context)!.theme.successColor(),
|
||||||
|
textColor:
|
||||||
|
MzanziInnovationHub.of(context)!.theme.primaryColor(),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(
|
||||||
|
height: 10,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
windowTools: const [],
|
||||||
|
onWindowTapClose: () {
|
||||||
|
Navigator.pop(context);
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
var size = MediaQuery.of(context).size;
|
||||||
|
setState(() {
|
||||||
|
width = size.width;
|
||||||
|
height = size.height;
|
||||||
|
});
|
||||||
|
checkScreenSize();
|
||||||
|
return ListView.separated(
|
||||||
|
shrinkWrap: true,
|
||||||
|
physics: const NeverScrollableScrollPhysics(),
|
||||||
|
separatorBuilder: (BuildContext context, index) {
|
||||||
|
return Divider(
|
||||||
|
color: MzanziInnovationHub.of(context)!.theme.secondaryColor(),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
itemCount: widget.patientAccessList.length,
|
||||||
|
itemBuilder: (context, index) {
|
||||||
|
//final patient = widget.patients[index].id_no.contains(widget.searchString);
|
||||||
|
//print(index);
|
||||||
|
return displayQueue(index);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,18 +1,16 @@
|
|||||||
import 'dart:convert';
|
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:patient_manager/mih_apis/mih_api_calls.dart';
|
||||||
import 'package:patient_manager/mih_components/mih_layout/mih_action.dart';
|
import 'package:patient_manager/mih_components/mih_layout/mih_action.dart';
|
||||||
import 'package:patient_manager/mih_components/mih_layout/mih_body.dart';
|
import 'package:patient_manager/mih_components/mih_layout/mih_body.dart';
|
||||||
import 'package:patient_manager/mih_components/mih_layout/mih_header.dart';
|
import 'package:patient_manager/mih_components/mih_layout/mih_header.dart';
|
||||||
import 'package:patient_manager/mih_components/mih_layout/mih_layout_builder.dart';
|
import 'package:patient_manager/mih_components/mih_layout/mih_layout_builder.dart';
|
||||||
import 'package:patient_manager/mih_packages/access_review/builder/build_access_request_list.dart';
|
import 'package:patient_manager/mih_objects/patient_access.dart';
|
||||||
import 'package:patient_manager/mih_components/mih_inputs_and_buttons/mih_dropdown_input.dart';
|
import 'package:patient_manager/mih_components/mih_inputs_and_buttons/mih_dropdown_input.dart';
|
||||||
import 'package:patient_manager/mih_components/mih_pop_up_messages/mih_loading_circle.dart';
|
import 'package:patient_manager/mih_components/mih_pop_up_messages/mih_loading_circle.dart';
|
||||||
import 'package:patient_manager/mih_env/env.dart';
|
import 'package:patient_manager/mih_env/env.dart';
|
||||||
import 'package:patient_manager/main.dart';
|
import 'package:patient_manager/main.dart';
|
||||||
import 'package:patient_manager/mih_objects/access_request.dart';
|
|
||||||
import 'package:patient_manager/mih_objects/app_user.dart';
|
import 'package:patient_manager/mih_objects/app_user.dart';
|
||||||
import 'package:supertokens_flutter/http.dart' as http;
|
import 'package:patient_manager/mih_packages/access_review/builder/build_business_access_list.dart';
|
||||||
|
|
||||||
class PatientAccessRequest extends StatefulWidget {
|
class PatientAccessRequest extends StatefulWidget {
|
||||||
final AppUser signedInUser;
|
final AppUser signedInUser;
|
||||||
@@ -38,43 +36,40 @@ class _PatientAccessRequestState extends State<PatientAccessRequest> {
|
|||||||
bool forceRefresh = false;
|
bool forceRefresh = false;
|
||||||
late String selectedDropdown;
|
late String selectedDropdown;
|
||||||
|
|
||||||
late Future<List<AccessRequest>> accessRequestResults;
|
late Future<List<PatientAccess>> accessList;
|
||||||
|
|
||||||
Future<List<AccessRequest>> fetchAccessRequests() async {
|
// Future<List<AccessRequest>> fetchAccessRequests() async {
|
||||||
//print("Patien manager page: $endpoint");
|
// //print("Patien manager page: $endpoint");
|
||||||
final response = await http.get(
|
// final response = await http.get(
|
||||||
Uri.parse("$baseUrl/access-requests/${widget.signedInUser.app_id}"));
|
// Uri.parse("$baseUrl/access-requests/${widget.signedInUser.app_id}"));
|
||||||
// print("Here");
|
// // print("Here");
|
||||||
// print("Body: ${response.body}");
|
// // print("Body: ${response.body}");
|
||||||
// print("Code: ${response.statusCode}");
|
// // print("Code: ${response.statusCode}");
|
||||||
errorCode = response.statusCode.toString();
|
// errorCode = response.statusCode.toString();
|
||||||
errorBody = response.body;
|
// errorBody = response.body;
|
||||||
|
|
||||||
if (response.statusCode == 200) {
|
// if (response.statusCode == 200) {
|
||||||
//print("Here1");
|
// //print("Here1");
|
||||||
Iterable l = jsonDecode(response.body);
|
// Iterable l = jsonDecode(response.body);
|
||||||
//print("Here2");
|
// //print("Here2");
|
||||||
List<AccessRequest> patientQueue = List<AccessRequest>.from(
|
// List<AccessRequest> patientQueue = List<AccessRequest>.from(
|
||||||
l.map((model) => AccessRequest.fromJson(model)));
|
// l.map((model) => AccessRequest.fromJson(model)));
|
||||||
//print("Here3");
|
// //print("Here3");
|
||||||
//print(patientQueue);
|
// //print(patientQueue);
|
||||||
return patientQueue;
|
// return patientQueue;
|
||||||
} else {
|
// } else {
|
||||||
throw Exception('failed to load patients');
|
// throw Exception('failed to load patients');
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
List<AccessRequest> filterSearchResults(List<AccessRequest> accessList) {
|
List<PatientAccess> filterSearchResults(List<PatientAccess> accessList) {
|
||||||
List<AccessRequest> templist = [];
|
List<PatientAccess> templist = [];
|
||||||
|
|
||||||
for (var item in accessList) {
|
for (var item in accessList) {
|
||||||
if (filterController.text == "All") {
|
if (filterController.text == "All") {
|
||||||
if (item.date_time.contains(datefilter)) {
|
templist.add(item);
|
||||||
templist.add(item);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
if (item.date_time.contains(datefilter) &&
|
if (item.status.contains(filterController.text.toLowerCase())) {
|
||||||
item.access.contains(filterController.text.toLowerCase())) {
|
|
||||||
templist.add(item);
|
templist.add(item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -82,132 +77,17 @@ class _PatientAccessRequestState extends State<PatientAccessRequest> {
|
|||||||
return templist;
|
return templist;
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget displayAccessRequestList(List<AccessRequest> accessRequestList) {
|
|
||||||
if (accessRequestList.isNotEmpty) {
|
|
||||||
return BuildAccessRequestList(
|
|
||||||
signedInUser: widget.signedInUser,
|
|
||||||
accessRequests: accessRequestList,
|
|
||||||
|
|
||||||
// BuildPatientQueueList(
|
|
||||||
// patientQueue: patientQueueList,
|
|
||||||
// signedInUser: widget.signedInUser,
|
|
||||||
// ),
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
return Center(
|
|
||||||
child: Text(
|
|
||||||
"No Request have been made.",
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 25,
|
|
||||||
color: MzanziInnovationHub.of(context)!.theme.messageTextColor()),
|
|
||||||
textAlign: TextAlign.center,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget viewAccessRequest(double w, double h) {
|
|
||||||
return Padding(
|
|
||||||
padding: const EdgeInsets.all(15.0),
|
|
||||||
child: SizedBox(
|
|
||||||
width: w,
|
|
||||||
height: h,
|
|
||||||
child: Column(mainAxisSize: MainAxisSize.max, children: [
|
|
||||||
//const SizedBox(height: 15),
|
|
||||||
const Text(
|
|
||||||
"Access Request",
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 25,
|
|
||||||
fontWeight: FontWeight.bold,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const SizedBox(height: 25),
|
|
||||||
SizedBox(
|
|
||||||
width: 500,
|
|
||||||
child: MIHDropdownField(
|
|
||||||
controller: filterController,
|
|
||||||
hintText: "Access Types",
|
|
||||||
dropdownOptions: const ["All", "Approved", "Pending", "Declined"],
|
|
||||||
required: true,
|
|
||||||
editable: true,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const SizedBox(height: 10),
|
|
||||||
FutureBuilder(
|
|
||||||
future: accessRequestResults,
|
|
||||||
builder: (context, snapshot) {
|
|
||||||
//print("patient Queue List ${snapshot.hasData}");
|
|
||||||
if (snapshot.connectionState == ConnectionState.waiting) {
|
|
||||||
return Expanded(
|
|
||||||
child: Container(
|
|
||||||
//height: 500,
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
color:
|
|
||||||
MzanziInnovationHub.of(context)!.theme.primaryColor(),
|
|
||||||
borderRadius: BorderRadius.circular(25.0),
|
|
||||||
border: Border.all(
|
|
||||||
color: MzanziInnovationHub.of(context)!
|
|
||||||
.theme
|
|
||||||
.secondaryColor(),
|
|
||||||
width: 3.0),
|
|
||||||
),
|
|
||||||
child: const Mihloadingcircle(),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
} else if (snapshot.connectionState == ConnectionState.done) {
|
|
||||||
List<AccessRequest> accessRequestList;
|
|
||||||
accessRequestList = filterSearchResults(snapshot.requireData);
|
|
||||||
if (accessRequestList.isNotEmpty) {
|
|
||||||
return BuildAccessRequestList(
|
|
||||||
signedInUser: widget.signedInUser,
|
|
||||||
accessRequests: accessRequestList,
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
return Center(
|
|
||||||
child: Text(
|
|
||||||
"No Request have been made.",
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 25,
|
|
||||||
color: MzanziInnovationHub.of(context)!
|
|
||||||
.theme
|
|
||||||
.messageTextColor()),
|
|
||||||
textAlign: TextAlign.center,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// return Expanded(
|
|
||||||
// child: displayAccessRequestList(accessRequestList),
|
|
||||||
// );
|
|
||||||
} else {
|
|
||||||
return Center(
|
|
||||||
child: Text(
|
|
||||||
"$errorCode: Error pulling Patients Data\n$baseUrl/queue/patients/\n$errorBody",
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 25,
|
|
||||||
color: MzanziInnovationHub.of(context)!
|
|
||||||
.theme
|
|
||||||
.errorColor()),
|
|
||||||
textAlign: TextAlign.center,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
),
|
|
||||||
]),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
void refreshList() {
|
void refreshList() {
|
||||||
if (forceRefresh == true) {
|
if (forceRefresh == true) {
|
||||||
setState(() {
|
setState(() {
|
||||||
accessRequestResults = fetchAccessRequests();
|
accessList = MIHApiCalls.getBusinessAccessListOfPatient(
|
||||||
|
widget.signedInUser.app_id);
|
||||||
forceRefresh = false;
|
forceRefresh = false;
|
||||||
});
|
});
|
||||||
} else if (selectedDropdown != filterController.text) {
|
} else if (selectedDropdown != filterController.text) {
|
||||||
setState(() {
|
setState(() {
|
||||||
accessRequestResults = fetchAccessRequests();
|
accessList = MIHApiCalls.getBusinessAccessListOfPatient(
|
||||||
|
widget.signedInUser.app_id);
|
||||||
selectedDropdown = filterController.text;
|
selectedDropdown = filterController.text;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -235,7 +115,7 @@ class _PatientAccessRequestState extends State<PatientAccessRequest> {
|
|||||||
headerAlignment: MainAxisAlignment.center,
|
headerAlignment: MainAxisAlignment.center,
|
||||||
headerItems: [
|
headerItems: [
|
||||||
Text(
|
Text(
|
||||||
"Access Reviews",
|
"Forever Access List",
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontWeight: FontWeight.bold,
|
fontWeight: FontWeight.bold,
|
||||||
fontSize: 25,
|
fontSize: 25,
|
||||||
@@ -284,18 +164,18 @@ class _PatientAccessRequestState extends State<PatientAccessRequest> {
|
|||||||
),
|
),
|
||||||
const SizedBox(height: 10),
|
const SizedBox(height: 10),
|
||||||
FutureBuilder(
|
FutureBuilder(
|
||||||
future: accessRequestResults,
|
future: accessList,
|
||||||
builder: (context, snapshot) {
|
builder: (context, snapshot) {
|
||||||
//print("patient Queue List ${snapshot.hasData}");
|
//print("patient Queue List ${snapshot.hasData}");
|
||||||
if (snapshot.connectionState == ConnectionState.waiting) {
|
if (snapshot.connectionState == ConnectionState.waiting) {
|
||||||
return const Mihloadingcircle();
|
return const Mihloadingcircle();
|
||||||
} else if (snapshot.connectionState == ConnectionState.done) {
|
} else if (snapshot.connectionState == ConnectionState.done) {
|
||||||
List<AccessRequest> accessRequestList;
|
List<PatientAccess> accessRequestList;
|
||||||
accessRequestList = filterSearchResults(snapshot.requireData);
|
accessRequestList = filterSearchResults(snapshot.requireData);
|
||||||
if (accessRequestList.isNotEmpty) {
|
if (accessRequestList.isNotEmpty) {
|
||||||
return BuildAccessRequestList(
|
return BuildBusinessAccessList(
|
||||||
signedInUser: widget.signedInUser,
|
signedInUser: widget.signedInUser,
|
||||||
accessRequests: accessRequestList,
|
patientAccessList: accessRequestList,
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
return Center(
|
return Center(
|
||||||
@@ -344,7 +224,8 @@ class _PatientAccessRequestState extends State<PatientAccessRequest> {
|
|||||||
filterController.text = "All";
|
filterController.text = "All";
|
||||||
filterController.addListener(refreshList);
|
filterController.addListener(refreshList);
|
||||||
setState(() {
|
setState(() {
|
||||||
accessRequestResults = fetchAccessRequests();
|
accessList = MIHApiCalls.getBusinessAccessListOfPatient(
|
||||||
|
widget.signedInUser.app_id);
|
||||||
});
|
});
|
||||||
super.initState();
|
super.initState();
|
||||||
}
|
}
|
||||||
@@ -362,48 +243,5 @@ class _PatientAccessRequestState extends State<PatientAccessRequest> {
|
|||||||
pullDownToRefresh: false,
|
pullDownToRefresh: false,
|
||||||
onPullDown: () async {},
|
onPullDown: () async {},
|
||||||
);
|
);
|
||||||
// return Scaffold(
|
|
||||||
// // appBar: const MIHAppBar(
|
|
||||||
// // barTitle: "Access Reviews",
|
|
||||||
// // propicFile: null,
|
|
||||||
// // ),
|
|
||||||
// //drawer: MIHAppDrawer(signedInUser: widget.signedInUser),
|
|
||||||
// body: SafeArea(
|
|
||||||
// child: Stack(
|
|
||||||
// children: [
|
|
||||||
// viewAccessRequest(screenWidth, screenHeight),
|
|
||||||
// Positioned(
|
|
||||||
// top: 10,
|
|
||||||
// left: 5,
|
|
||||||
// width: 50,
|
|
||||||
// height: 50,
|
|
||||||
// child: IconButton(
|
|
||||||
// onPressed: () {
|
|
||||||
// Navigator.of(context).pop();
|
|
||||||
// },
|
|
||||||
// icon: const Icon(Icons.arrow_back),
|
|
||||||
// ),
|
|
||||||
// ),
|
|
||||||
// Positioned(
|
|
||||||
// top: 10,
|
|
||||||
// right: 5,
|
|
||||||
// width: 50,
|
|
||||||
// height: 50,
|
|
||||||
// child: IconButton(
|
|
||||||
// onPressed: () {
|
|
||||||
// setState(() {
|
|
||||||
// forceRefresh = true;
|
|
||||||
// });
|
|
||||||
// refreshList();
|
|
||||||
// },
|
|
||||||
// icon: const Icon(
|
|
||||||
// Icons.refresh,
|
|
||||||
// ),
|
|
||||||
// ),
|
|
||||||
// )
|
|
||||||
// ],
|
|
||||||
// ),
|
|
||||||
// ),
|
|
||||||
// );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,427 @@
|
|||||||
|
import 'dart:convert';
|
||||||
|
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:patient_manager/mih_components/mih_inputs_and_buttons/mih_button.dart';
|
||||||
|
import 'package:patient_manager/mih_components/mih_layout/mih_window.dart';
|
||||||
|
import 'package:patient_manager/mih_components/mih_pop_up_messages/mih_error_message.dart';
|
||||||
|
import 'package:patient_manager/mih_components/mih_pop_up_messages/mih_success_message.dart';
|
||||||
|
import 'package:patient_manager/mih_components/mih_pop_up_messages/mih_warning_message.dart';
|
||||||
|
import 'package:patient_manager/mih_env/env.dart';
|
||||||
|
import 'package:patient_manager/main.dart';
|
||||||
|
import 'package:patient_manager/mih_objects/access_request.dart';
|
||||||
|
import 'package:patient_manager/mih_objects/app_user.dart';
|
||||||
|
import 'package:supertokens_flutter/http.dart' as http;
|
||||||
|
|
||||||
|
class BuildAccessRequestList extends StatefulWidget {
|
||||||
|
final List<AccessRequest> accessRequests;
|
||||||
|
final AppUser signedInUser;
|
||||||
|
|
||||||
|
const BuildAccessRequestList({
|
||||||
|
super.key,
|
||||||
|
required this.accessRequests,
|
||||||
|
required this.signedInUser,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<BuildAccessRequestList> createState() => _BuildPatientsListState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _BuildPatientsListState extends State<BuildAccessRequestList> {
|
||||||
|
String baseAPI = AppEnviroment.baseApiUrl;
|
||||||
|
late double popUpWidth;
|
||||||
|
late double? popUpheight;
|
||||||
|
late double popUpButtonWidth;
|
||||||
|
late double popUpTitleSize;
|
||||||
|
late double popUpSubtitleSize;
|
||||||
|
late double popUpBodySize;
|
||||||
|
late double popUpIconSize;
|
||||||
|
late double popUpPaddingSize;
|
||||||
|
late double width;
|
||||||
|
late double height;
|
||||||
|
|
||||||
|
Future<void> updateAccessAPICall(int index, String accessType) async {
|
||||||
|
var response = await http.put(
|
||||||
|
Uri.parse("$baseAPI/access-requests/update/"),
|
||||||
|
headers: <String, String>{
|
||||||
|
"Content-Type": "application/json; charset=UTF-8"
|
||||||
|
},
|
||||||
|
body: jsonEncode(<String, dynamic>{
|
||||||
|
"business_id": widget.accessRequests[index].business_id,
|
||||||
|
"app_id": widget.accessRequests[index].app_id,
|
||||||
|
"date_time": widget.accessRequests[index].date_time,
|
||||||
|
"access": accessType,
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
if (response.statusCode == 200) {
|
||||||
|
//Navigator.of(context).pushNamed('/home');
|
||||||
|
Navigator.of(context).pop();
|
||||||
|
Navigator.of(context).pop();
|
||||||
|
Navigator.of(context).pushNamed(
|
||||||
|
'/patient-access-review',
|
||||||
|
arguments: widget.signedInUser,
|
||||||
|
);
|
||||||
|
String message = "";
|
||||||
|
if (accessType == "approved") {
|
||||||
|
message =
|
||||||
|
"You've successfully approved the access request! ${widget.accessRequests[index].Name} now has access to your profile until ${widget.accessRequests[index].revoke_date.substring(0, 16).replaceAll("T", " ")}.";
|
||||||
|
} else {
|
||||||
|
message =
|
||||||
|
"You've declined the access request. ${widget.accessRequests[index].Name} will not have access to your profile.";
|
||||||
|
}
|
||||||
|
successPopUp(message);
|
||||||
|
} else {
|
||||||
|
internetConnectionPopUp();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void internetConnectionPopUp() {
|
||||||
|
showDialog(
|
||||||
|
context: context,
|
||||||
|
builder: (context) {
|
||||||
|
return const MIHErrorMessage(errorType: "Internet Connection");
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void successPopUp(String message) {
|
||||||
|
showDialog(
|
||||||
|
context: context,
|
||||||
|
builder: (context) {
|
||||||
|
return MIHSuccessMessage(
|
||||||
|
successType: "Success",
|
||||||
|
successMessage: message,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void accessCancelledWarning() {
|
||||||
|
showDialog(
|
||||||
|
context: context,
|
||||||
|
builder: (context) {
|
||||||
|
return const MIHWarningMessage(warningType: "Access Cancelled");
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget displayQueue(int index) {
|
||||||
|
String line1 =
|
||||||
|
"Appointment: ${widget.accessRequests[index].date_time.substring(0, 16).replaceAll("T", " ")}";
|
||||||
|
String line2 = "";
|
||||||
|
line2 += "Requestor: ${widget.accessRequests[index].Name}\n";
|
||||||
|
//subtitle += "Business Type: ${widget.accessRequests[index].type}\n";
|
||||||
|
String line3 = "Access: ";
|
||||||
|
String access = "";
|
||||||
|
var nowDate = DateTime.now();
|
||||||
|
var expireyDate = DateTime.parse(widget.accessRequests[index].revoke_date);
|
||||||
|
|
||||||
|
if (expireyDate.isBefore(nowDate)) {
|
||||||
|
access += "EXPIRED";
|
||||||
|
} else {
|
||||||
|
access += "${widget.accessRequests[index].access.toUpperCase()}";
|
||||||
|
}
|
||||||
|
String line4 = "";
|
||||||
|
if (widget.accessRequests[index].revoke_date.contains("9999")) {
|
||||||
|
line4 += "Access Expiration date: NOT SET";
|
||||||
|
} else {
|
||||||
|
line4 +=
|
||||||
|
"Access Expiration date: ${widget.accessRequests[index].revoke_date.substring(0, 10)}";
|
||||||
|
}
|
||||||
|
TextSpan accessWithColour;
|
||||||
|
if (access == "APPROVED") {
|
||||||
|
accessWithColour = TextSpan(
|
||||||
|
text: "$access\n",
|
||||||
|
style: TextStyle(
|
||||||
|
color: MzanziInnovationHub.of(context)!.theme.successColor()));
|
||||||
|
} else if (access == "PENDING") {
|
||||||
|
accessWithColour = TextSpan(
|
||||||
|
text: "$access\n",
|
||||||
|
style: TextStyle(
|
||||||
|
color:
|
||||||
|
MzanziInnovationHub.of(context)!.theme.messageTextColor()));
|
||||||
|
} else {
|
||||||
|
accessWithColour = TextSpan(
|
||||||
|
text: "$access\n",
|
||||||
|
style: TextStyle(
|
||||||
|
color: MzanziInnovationHub.of(context)!.theme.errorColor()));
|
||||||
|
}
|
||||||
|
|
||||||
|
return ListTile(
|
||||||
|
title: Text(
|
||||||
|
line1,
|
||||||
|
style: TextStyle(
|
||||||
|
color: MzanziInnovationHub.of(context)!.theme.secondaryColor(),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
subtitle: RichText(
|
||||||
|
text: TextSpan(
|
||||||
|
text: line2,
|
||||||
|
style: DefaultTextStyle.of(context).style,
|
||||||
|
children: <TextSpan>[
|
||||||
|
TextSpan(text: line3),
|
||||||
|
accessWithColour,
|
||||||
|
TextSpan(text: line4),
|
||||||
|
]),
|
||||||
|
),
|
||||||
|
// Text(
|
||||||
|
// subtitle,
|
||||||
|
// style: TextStyle(
|
||||||
|
// color: MzanziInnovationHub.of(context)!.theme.secondaryColor(),
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
onTap: () {
|
||||||
|
if (access == "CANCELLED") {
|
||||||
|
accessCancelledWarning();
|
||||||
|
} else {
|
||||||
|
viewApprovalPopUp(index);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// trailing: Icon(
|
||||||
|
// Icons.arrow_forward,
|
||||||
|
// color: MzanziInnovationHub.of(context)!.theme.secondaryColor(),
|
||||||
|
// ),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void checkScreenSize() {
|
||||||
|
if (MzanziInnovationHub.of(context)!.theme.screenType == "desktop") {
|
||||||
|
setState(() {
|
||||||
|
popUpWidth = (width / 4) * 2;
|
||||||
|
popUpheight = null;
|
||||||
|
popUpButtonWidth = 300;
|
||||||
|
popUpTitleSize = 25.0;
|
||||||
|
popUpSubtitleSize = 20.0;
|
||||||
|
popUpBodySize = 15;
|
||||||
|
popUpPaddingSize = 25.0;
|
||||||
|
popUpIconSize = 100;
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
setState(() {
|
||||||
|
popUpWidth = width - (width * 0.1);
|
||||||
|
popUpheight = null;
|
||||||
|
popUpButtonWidth = 300;
|
||||||
|
popUpTitleSize = 20.0;
|
||||||
|
popUpSubtitleSize = 18.0;
|
||||||
|
popUpBodySize = 15;
|
||||||
|
popUpPaddingSize = 15.0;
|
||||||
|
popUpIconSize = 100;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void viewApprovalPopUp(int index) {
|
||||||
|
String subtitle =
|
||||||
|
"Appointment: ${widget.accessRequests[index].date_time.substring(0, 16).replaceAll("T", " ")}\n";
|
||||||
|
subtitle += "Requestor: ${widget.accessRequests[index].Name}\n";
|
||||||
|
subtitle += "Business Type: ${widget.accessRequests[index].type}\n\n";
|
||||||
|
subtitle +=
|
||||||
|
"You are about to approve an access request to your patient profile.\nPlease be aware that once approved, ${widget.accessRequests[index].Name} will have access to your profile information until ${widget.accessRequests[index].revoke_date.substring(0, 16).replaceAll("T", " ")}.\nIf you are unsure about an upcoming appointment with ${widget.accessRequests[index].Name}, please contact ${widget.accessRequests[index].contact_no} for clarification before approving this request.\n";
|
||||||
|
showDialog(
|
||||||
|
context: context,
|
||||||
|
barrierDismissible: false,
|
||||||
|
builder: (context) => MIHWindow(
|
||||||
|
fullscreen: false,
|
||||||
|
windowTitle: "Update Appointment Access",
|
||||||
|
windowBody: [
|
||||||
|
const SizedBox(
|
||||||
|
height: 10,
|
||||||
|
),
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 10.0),
|
||||||
|
child: Text(
|
||||||
|
subtitle,
|
||||||
|
textAlign: TextAlign.left,
|
||||||
|
style: TextStyle(
|
||||||
|
color:
|
||||||
|
MzanziInnovationHub.of(context)!.theme.secondaryColor(),
|
||||||
|
fontSize: popUpBodySize,
|
||||||
|
//fontWeight: FontWeight.bold,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Wrap(
|
||||||
|
runSpacing: 10,
|
||||||
|
spacing: 10,
|
||||||
|
children: [
|
||||||
|
SizedBox(
|
||||||
|
width: popUpButtonWidth,
|
||||||
|
height: 50,
|
||||||
|
child: MIHButton(
|
||||||
|
onTap: () {
|
||||||
|
updateAccessAPICall(index, "declined");
|
||||||
|
},
|
||||||
|
buttonText: "Decline",
|
||||||
|
buttonColor:
|
||||||
|
MzanziInnovationHub.of(context)!.theme.errorColor(),
|
||||||
|
textColor:
|
||||||
|
MzanziInnovationHub.of(context)!.theme.primaryColor(),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
width: popUpButtonWidth,
|
||||||
|
height: 50,
|
||||||
|
child: MIHButton(
|
||||||
|
onTap: () {
|
||||||
|
updateAccessAPICall(index, "approved");
|
||||||
|
},
|
||||||
|
buttonText: "Approve",
|
||||||
|
buttonColor:
|
||||||
|
MzanziInnovationHub.of(context)!.theme.successColor(),
|
||||||
|
textColor:
|
||||||
|
MzanziInnovationHub.of(context)!.theme.primaryColor(),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
const SizedBox(
|
||||||
|
height: 10,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
windowTools: const [],
|
||||||
|
onWindowTapClose: () {
|
||||||
|
Navigator.pop(context);
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
// showDialog(
|
||||||
|
// context: context,
|
||||||
|
// barrierDismissible: false,
|
||||||
|
// builder: (context) => Dialog(
|
||||||
|
// child: Stack(
|
||||||
|
// children: [
|
||||||
|
// Container(
|
||||||
|
// //padding: const EdgeInsets.all(15.0),
|
||||||
|
// width: popUpWidth,
|
||||||
|
// height: popUpheight,
|
||||||
|
// decoration: BoxDecoration(
|
||||||
|
// color: MzanziInnovationHub.of(context)!.theme.primaryColor(),
|
||||||
|
// borderRadius: BorderRadius.circular(25.0),
|
||||||
|
// border: Border.all(
|
||||||
|
// color:
|
||||||
|
// MzanziInnovationHub.of(context)!.theme.secondaryColor(),
|
||||||
|
// width: 5.0),
|
||||||
|
// ),
|
||||||
|
// child: SingleChildScrollView(
|
||||||
|
// padding: EdgeInsets.all(popUpPaddingSize),
|
||||||
|
// child: Column(
|
||||||
|
// mainAxisSize: MainAxisSize.min,
|
||||||
|
// mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
// crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
|
// children: [
|
||||||
|
// Text(
|
||||||
|
// "Update Appointment Access",
|
||||||
|
// textAlign: TextAlign.center,
|
||||||
|
// style: TextStyle(
|
||||||
|
// color: MzanziInnovationHub.of(context)!
|
||||||
|
// .theme
|
||||||
|
// .secondaryColor(),
|
||||||
|
// fontSize: popUpTitleSize,
|
||||||
|
// fontWeight: FontWeight.bold,
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
// const SizedBox(height: 15.0),
|
||||||
|
// Text(
|
||||||
|
// subtitle,
|
||||||
|
// textAlign: TextAlign.left,
|
||||||
|
// style: TextStyle(
|
||||||
|
// color: MzanziInnovationHub.of(context)!
|
||||||
|
// .theme
|
||||||
|
// .secondaryColor(),
|
||||||
|
// fontSize: popUpBodySize,
|
||||||
|
// //fontWeight: FontWeight.bold,
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
// const SizedBox(height: 10.0),
|
||||||
|
// Wrap(
|
||||||
|
// runSpacing: 10,
|
||||||
|
// spacing: 10,
|
||||||
|
// children: [
|
||||||
|
// SizedBox(
|
||||||
|
// width: popUpButtonWidth,
|
||||||
|
// height: 50,
|
||||||
|
// child: MIHButton(
|
||||||
|
// onTap: () {
|
||||||
|
// updateAccessAPICall(index, "declined");
|
||||||
|
// },
|
||||||
|
// buttonText: "Decline",
|
||||||
|
// buttonColor: MzanziInnovationHub.of(context)!
|
||||||
|
// .theme
|
||||||
|
// .errorColor(),
|
||||||
|
// textColor: MzanziInnovationHub.of(context)!
|
||||||
|
// .theme
|
||||||
|
// .primaryColor(),
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
// SizedBox(
|
||||||
|
// width: popUpButtonWidth,
|
||||||
|
// height: 50,
|
||||||
|
// child: MIHButton(
|
||||||
|
// onTap: () {
|
||||||
|
// updateAccessAPICall(index, "approved");
|
||||||
|
// },
|
||||||
|
// buttonText: "Approve",
|
||||||
|
// buttonColor: MzanziInnovationHub.of(context)!
|
||||||
|
// .theme
|
||||||
|
// .successColor(),
|
||||||
|
// textColor: MzanziInnovationHub.of(context)!
|
||||||
|
// .theme
|
||||||
|
// .primaryColor(),
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
// ],
|
||||||
|
// )
|
||||||
|
// ],
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
// Positioned(
|
||||||
|
// top: 5,
|
||||||
|
// right: 5,
|
||||||
|
// width: 50,
|
||||||
|
// height: 50,
|
||||||
|
// child: IconButton(
|
||||||
|
// onPressed: () {
|
||||||
|
// Navigator.pop(context);
|
||||||
|
// },
|
||||||
|
// icon: Icon(
|
||||||
|
// Icons.close,
|
||||||
|
// color: MzanziInnovationHub.of(context)!.theme.errorColor(),
|
||||||
|
// size: 35,
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
// ],
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
// );
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
var size = MediaQuery.of(context).size;
|
||||||
|
setState(() {
|
||||||
|
width = size.width;
|
||||||
|
height = size.height;
|
||||||
|
});
|
||||||
|
checkScreenSize();
|
||||||
|
return ListView.separated(
|
||||||
|
shrinkWrap: true,
|
||||||
|
physics: const NeverScrollableScrollPhysics(),
|
||||||
|
separatorBuilder: (BuildContext context, index) {
|
||||||
|
return Divider(
|
||||||
|
color: MzanziInnovationHub.of(context)!.theme.secondaryColor(),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
itemCount: widget.accessRequests.length,
|
||||||
|
itemBuilder: (context, index) {
|
||||||
|
//final patient = widget.patients[index].id_no.contains(widget.searchString);
|
||||||
|
//print(index);
|
||||||
|
return displayQueue(index);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,451 @@
|
|||||||
|
import 'dart:convert';
|
||||||
|
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:patient_manager/mih_apis/mih_api_calls.dart';
|
||||||
|
import 'package:patient_manager/mih_components/mih_inputs_and_buttons/mih_date_input.dart';
|
||||||
|
import 'package:patient_manager/mih_components/mih_inputs_and_buttons/mih_text_input.dart';
|
||||||
|
import 'package:patient_manager/mih_components/mih_inputs_and_buttons/mih_time_input.dart';
|
||||||
|
import 'package:patient_manager/mih_components/mih_layout/mih_window.dart';
|
||||||
|
import 'package:patient_manager/mih_components/mih_pop_up_messages/mih_error_message.dart';
|
||||||
|
import 'package:patient_manager/mih_components/mih_inputs_and_buttons/mih_button.dart';
|
||||||
|
import 'package:patient_manager/mih_components/mih_pop_up_messages/mih_success_message.dart';
|
||||||
|
import 'package:patient_manager/mih_components/mih_pop_up_messages/mih_warning_message.dart';
|
||||||
|
import 'package:patient_manager/mih_env/env.dart';
|
||||||
|
import 'package:patient_manager/main.dart';
|
||||||
|
import 'package:patient_manager/mih_objects/app_user.dart';
|
||||||
|
import 'package:patient_manager/mih_objects/arguments.dart';
|
||||||
|
import 'package:patient_manager/mih_objects/business.dart';
|
||||||
|
import 'package:patient_manager/mih_objects/patient_access.dart';
|
||||||
|
import 'package:patient_manager/mih_objects/patients.dart';
|
||||||
|
import 'package:supertokens_flutter/http.dart' as http;
|
||||||
|
|
||||||
|
class BuildPatientAccessList extends StatefulWidget {
|
||||||
|
final List<PatientAccess> patientAccesses;
|
||||||
|
final AppUser signedInUser;
|
||||||
|
final Business? business;
|
||||||
|
final BusinessArguments arguments;
|
||||||
|
|
||||||
|
const BuildPatientAccessList({
|
||||||
|
super.key,
|
||||||
|
required this.patientAccesses,
|
||||||
|
required this.signedInUser,
|
||||||
|
required this.business,
|
||||||
|
required this.arguments,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<BuildPatientAccessList> createState() => _BuildPatientsListState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _BuildPatientsListState extends State<BuildPatientAccessList> {
|
||||||
|
TextEditingController dateController = TextEditingController();
|
||||||
|
TextEditingController timeController = TextEditingController();
|
||||||
|
TextEditingController idController = TextEditingController();
|
||||||
|
TextEditingController fnameController = TextEditingController();
|
||||||
|
TextEditingController lnameController = TextEditingController();
|
||||||
|
|
||||||
|
final baseAPI = AppEnviroment.baseApiUrl;
|
||||||
|
|
||||||
|
Future<void> addPatientAppointmentAPICall(int index) async {
|
||||||
|
var response = await http.post(
|
||||||
|
Uri.parse("$baseAPI/queue/insert/"),
|
||||||
|
headers: <String, String>{
|
||||||
|
"Content-Type": "application/json; charset=UTF-8"
|
||||||
|
},
|
||||||
|
body: jsonEncode(<String, dynamic>{
|
||||||
|
"business_id": widget.business!.business_id,
|
||||||
|
"app_id": widget.patientAccesses[index].app_id,
|
||||||
|
"date": dateController.text,
|
||||||
|
"time": timeController.text,
|
||||||
|
"access": "pending",
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
if (response.statusCode == 201) {
|
||||||
|
// Navigator.pushNamed(context, '/patient-manager/patient',
|
||||||
|
// arguments: widget.signedInUser);
|
||||||
|
String message =
|
||||||
|
"The appointment has been successfully booked!\n\nAn approval request as been sent to the patient.Once the access request has been approved, you will be able to access the patientAccesses profile. ou can check the status of your request in patient queue under the appointment.";
|
||||||
|
// "${fnameController.text} ${lnameController.text} patient profiole has been successfully added!\n";
|
||||||
|
Navigator.pop(context);
|
||||||
|
Navigator.pop(context);
|
||||||
|
setState(() {
|
||||||
|
dateController.text = "";
|
||||||
|
timeController.text = "";
|
||||||
|
});
|
||||||
|
Navigator.of(context).pushNamed(
|
||||||
|
'/patient-manager',
|
||||||
|
arguments: BusinessArguments(
|
||||||
|
widget.arguments.signedInUser,
|
||||||
|
widget.arguments.businessUser,
|
||||||
|
widget.arguments.business,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
successPopUp(message);
|
||||||
|
addAccessReviewNotificationAPICall(index);
|
||||||
|
} else {
|
||||||
|
internetConnectionPopUp();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> addAccessReviewNotificationAPICall(int index) async {
|
||||||
|
var response = await http.post(
|
||||||
|
Uri.parse("$baseAPI/notifications/insert/"),
|
||||||
|
headers: <String, String>{
|
||||||
|
"Content-Type": "application/json; charset=UTF-8"
|
||||||
|
},
|
||||||
|
body: jsonEncode(<String, dynamic>{
|
||||||
|
"app_id": widget.patientAccesses[index].app_id,
|
||||||
|
"notification_type": "New Appointment Booked",
|
||||||
|
"notification_message":
|
||||||
|
"A new Appointment has been booked by ${widget.arguments.business!.Name} for the ${dateController.text} ${timeController.text}. Please approve the Access Review request.",
|
||||||
|
"action_path": "/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) {
|
||||||
|
MIHApiCalls.addAppointmentAPICall(
|
||||||
|
widget.arguments.business!.business_id,
|
||||||
|
widget.patientAccesses[index].app_id,
|
||||||
|
dateController.text,
|
||||||
|
timeController.text,
|
||||||
|
widget.arguments,
|
||||||
|
context,
|
||||||
|
);
|
||||||
|
//addPatientAppointmentAPICall(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isAppointmentFieldsFilled() {
|
||||||
|
if (dateController.text.isEmpty || timeController.text.isEmpty) {
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void appointmentPopUp(int index) {
|
||||||
|
var firstLetterFName = widget.patientAccesses[index].fname;
|
||||||
|
var firstLetterLName = widget.patientAccesses[index].lname;
|
||||||
|
|
||||||
|
setState(() {
|
||||||
|
idController.text = widget.patientAccesses[index].id_no;
|
||||||
|
fnameController.text = firstLetterFName;
|
||||||
|
lnameController.text = firstLetterLName;
|
||||||
|
});
|
||||||
|
showDialog(
|
||||||
|
context: context,
|
||||||
|
barrierDismissible: false,
|
||||||
|
builder: (context) => MIHWindow(
|
||||||
|
fullscreen: false,
|
||||||
|
windowTitle: "Patient Appointment",
|
||||||
|
windowTools: const [],
|
||||||
|
onWindowTapClose: () {
|
||||||
|
Navigator.pop(context);
|
||||||
|
},
|
||||||
|
windowBody: [
|
||||||
|
MIHTextField(
|
||||||
|
controller: idController,
|
||||||
|
hintText: "ID No.",
|
||||||
|
editable: false,
|
||||||
|
required: true,
|
||||||
|
),
|
||||||
|
const SizedBox(height: 10.0),
|
||||||
|
MIHTextField(
|
||||||
|
controller: fnameController,
|
||||||
|
hintText: "First Name",
|
||||||
|
editable: false,
|
||||||
|
required: true,
|
||||||
|
),
|
||||||
|
const SizedBox(height: 10.0),
|
||||||
|
MIHTextField(
|
||||||
|
controller: lnameController,
|
||||||
|
hintText: "Surname",
|
||||||
|
editable: false,
|
||||||
|
required: true,
|
||||||
|
),
|
||||||
|
const SizedBox(height: 10.0),
|
||||||
|
MIHDateField(
|
||||||
|
controller: dateController,
|
||||||
|
lableText: "Date",
|
||||||
|
required: true,
|
||||||
|
),
|
||||||
|
const SizedBox(height: 10.0),
|
||||||
|
MIHTimeField(
|
||||||
|
controller: timeController,
|
||||||
|
lableText: "Time",
|
||||||
|
required: true,
|
||||||
|
),
|
||||||
|
const SizedBox(height: 30.0),
|
||||||
|
SizedBox(
|
||||||
|
width: 300,
|
||||||
|
height: 50,
|
||||||
|
child: MIHButton(
|
||||||
|
buttonText: "Book",
|
||||||
|
buttonColor:
|
||||||
|
MzanziInnovationHub.of(context)!.theme.secondaryColor(),
|
||||||
|
textColor: MzanziInnovationHub.of(context)!.theme.primaryColor(),
|
||||||
|
onTap: () {
|
||||||
|
//print("here1");
|
||||||
|
bool filled = isAppointmentFieldsFilled();
|
||||||
|
//print("fields filled: $filled");
|
||||||
|
if (filled) {
|
||||||
|
//print("here2");
|
||||||
|
submitApointment(index);
|
||||||
|
//print("here3");
|
||||||
|
} else {
|
||||||
|
showDialog(
|
||||||
|
context: context,
|
||||||
|
builder: (context) {
|
||||||
|
return const MIHErrorMessage(errorType: "Input Error");
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void noAccessWarning() {
|
||||||
|
showDialog(
|
||||||
|
context: context,
|
||||||
|
builder: (context) {
|
||||||
|
return const MIHWarningMessage(warningType: "No Access");
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool hasAccessToProfile(int index) {
|
||||||
|
var hasAccess = false;
|
||||||
|
|
||||||
|
if (widget.patientAccesses[index].status == "approved") {
|
||||||
|
hasAccess = true;
|
||||||
|
} else {
|
||||||
|
hasAccess = false;
|
||||||
|
}
|
||||||
|
return hasAccess;
|
||||||
|
}
|
||||||
|
|
||||||
|
void patientProfileChoicePopUp(int index, Patient? patientProfile) async {
|
||||||
|
var firstLetterFName = widget.patientAccesses[index].fname;
|
||||||
|
var firstLetterLName = widget.patientAccesses[index].lname;
|
||||||
|
|
||||||
|
setState(() {
|
||||||
|
idController.text = widget.patientAccesses[index].id_no;
|
||||||
|
fnameController.text = firstLetterFName;
|
||||||
|
lnameController.text = firstLetterLName;
|
||||||
|
});
|
||||||
|
showDialog(
|
||||||
|
context: context,
|
||||||
|
barrierDismissible: false,
|
||||||
|
builder: (context) => MIHWindow(
|
||||||
|
fullscreen: false,
|
||||||
|
windowTitle: "Patient Profile",
|
||||||
|
windowTools: const [],
|
||||||
|
onWindowTapClose: () {
|
||||||
|
Navigator.pop(context);
|
||||||
|
},
|
||||||
|
windowBody: [
|
||||||
|
MIHTextField(
|
||||||
|
controller: idController,
|
||||||
|
hintText: "ID No.",
|
||||||
|
editable: false,
|
||||||
|
required: true,
|
||||||
|
),
|
||||||
|
const SizedBox(height: 10.0),
|
||||||
|
MIHTextField(
|
||||||
|
controller: fnameController,
|
||||||
|
hintText: "First Name",
|
||||||
|
editable: false,
|
||||||
|
required: true,
|
||||||
|
),
|
||||||
|
const SizedBox(height: 10.0),
|
||||||
|
MIHTextField(
|
||||||
|
controller: lnameController,
|
||||||
|
hintText: "Surname",
|
||||||
|
editable: false,
|
||||||
|
required: true,
|
||||||
|
),
|
||||||
|
const SizedBox(height: 30.0),
|
||||||
|
Wrap(runSpacing: 10, spacing: 10, children: [
|
||||||
|
SizedBox(
|
||||||
|
width: 300,
|
||||||
|
height: 50,
|
||||||
|
child: MIHButton(
|
||||||
|
buttonText: "Book Appointment",
|
||||||
|
buttonColor:
|
||||||
|
MzanziInnovationHub.of(context)!.theme.secondaryColor(),
|
||||||
|
textColor:
|
||||||
|
MzanziInnovationHub.of(context)!.theme.primaryColor(),
|
||||||
|
onTap: () {
|
||||||
|
print("Book an Appointment!!!");
|
||||||
|
appointmentPopUp(index);
|
||||||
|
|
||||||
|
// //print("here1");
|
||||||
|
// bool filled = isAppointmentFieldsFilled();
|
||||||
|
// //print("fields filled: $filled");
|
||||||
|
// if (filled) {
|
||||||
|
// //print("here2");
|
||||||
|
// submitApointment(index);
|
||||||
|
// //print("here3");
|
||||||
|
// } else {
|
||||||
|
// showDialog(
|
||||||
|
// context: context,
|
||||||
|
// builder: (context) {
|
||||||
|
// return const MIHErrorMessage(errorType: "Input Error");
|
||||||
|
// },
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
width: 300,
|
||||||
|
height: 50,
|
||||||
|
child: MIHButton(
|
||||||
|
buttonText: "View Patient Profile",
|
||||||
|
buttonColor:
|
||||||
|
MzanziInnovationHub.of(context)!.theme.successColor(),
|
||||||
|
textColor:
|
||||||
|
MzanziInnovationHub.of(context)!.theme.primaryColor(),
|
||||||
|
onTap: () {
|
||||||
|
Navigator.of(context).pop();
|
||||||
|
Navigator.of(context).pushNamed('/patient-manager/patient',
|
||||||
|
arguments: PatientViewArguments(
|
||||||
|
widget.signedInUser,
|
||||||
|
patientProfile,
|
||||||
|
widget.arguments.businessUser,
|
||||||
|
widget.business,
|
||||||
|
"business",
|
||||||
|
));
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
])
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget displayAccessTile(int index) {
|
||||||
|
var firstName = widget.patientAccesses[index].fname;
|
||||||
|
var lastName = widget.patientAccesses[index].lname;
|
||||||
|
String access = widget.patientAccesses[index].status.toUpperCase();
|
||||||
|
TextSpan accessWithColour;
|
||||||
|
var hasAccess = false;
|
||||||
|
hasAccess = hasAccessToProfile(index);
|
||||||
|
//print(hasAccess);
|
||||||
|
if (access == "APPROVED") {
|
||||||
|
accessWithColour = TextSpan(
|
||||||
|
text: "$access\n",
|
||||||
|
style: TextStyle(
|
||||||
|
color: MzanziInnovationHub.of(context)!.theme.successColor()));
|
||||||
|
} else if (access == "PENDING") {
|
||||||
|
accessWithColour = TextSpan(
|
||||||
|
text: "$access\n",
|
||||||
|
style: TextStyle(
|
||||||
|
color:
|
||||||
|
MzanziInnovationHub.of(context)!.theme.messageTextColor()));
|
||||||
|
} else {
|
||||||
|
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: <TextSpan>[
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
trailing: Icon(
|
||||||
|
Icons.arrow_forward,
|
||||||
|
color: MzanziInnovationHub.of(context)!.theme.secondaryColor(),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
dateController.dispose();
|
||||||
|
timeController.dispose();
|
||||||
|
idController.dispose();
|
||||||
|
fnameController.dispose();
|
||||||
|
lnameController.dispose();
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return ListView.separated(
|
||||||
|
shrinkWrap: true,
|
||||||
|
physics: const NeverScrollableScrollPhysics(),
|
||||||
|
separatorBuilder: (BuildContext context, index) {
|
||||||
|
return Divider(
|
||||||
|
color: MzanziInnovationHub.of(context)!.theme.secondaryColor(),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
itemCount: widget.patientAccesses.length,
|
||||||
|
itemBuilder: (context, index) {
|
||||||
|
//final patient = widget.patientAccesses[index].id_no.contains(widget.searchString);
|
||||||
|
//print(index);
|
||||||
|
return displayAccessTile(index);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:patient_manager/mih_apis/mih_api_calls.dart';
|
||||||
import 'package:patient_manager/mih_components/mih_inputs_and_buttons/mih_date_input.dart';
|
import 'package:patient_manager/mih_components/mih_inputs_and_buttons/mih_date_input.dart';
|
||||||
import 'package:patient_manager/mih_components/mih_inputs_and_buttons/mih_text_input.dart';
|
import 'package:patient_manager/mih_components/mih_inputs_and_buttons/mih_text_input.dart';
|
||||||
import 'package:patient_manager/mih_components/mih_inputs_and_buttons/mih_time_input.dart';
|
import 'package:patient_manager/mih_components/mih_inputs_and_buttons/mih_time_input.dart';
|
||||||
@@ -8,6 +9,7 @@ import 'package:patient_manager/mih_components/mih_layout/mih_window.dart';
|
|||||||
import 'package:patient_manager/mih_components/mih_pop_up_messages/mih_error_message.dart';
|
import 'package:patient_manager/mih_components/mih_pop_up_messages/mih_error_message.dart';
|
||||||
import 'package:patient_manager/mih_components/mih_inputs_and_buttons/mih_button.dart';
|
import 'package:patient_manager/mih_components/mih_inputs_and_buttons/mih_button.dart';
|
||||||
import 'package:patient_manager/mih_components/mih_pop_up_messages/mih_success_message.dart';
|
import 'package:patient_manager/mih_components/mih_pop_up_messages/mih_success_message.dart';
|
||||||
|
import 'package:patient_manager/mih_components/mih_pop_up_messages/mih_warning_message.dart';
|
||||||
import 'package:patient_manager/mih_env/env.dart';
|
import 'package:patient_manager/mih_env/env.dart';
|
||||||
import 'package:patient_manager/main.dart';
|
import 'package:patient_manager/main.dart';
|
||||||
import 'package:patient_manager/mih_objects/app_user.dart';
|
import 'package:patient_manager/mih_objects/app_user.dart';
|
||||||
@@ -40,7 +42,7 @@ class _BuildPatientsListState extends State<BuildPatientsList> {
|
|||||||
TextEditingController idController = TextEditingController();
|
TextEditingController idController = TextEditingController();
|
||||||
TextEditingController fnameController = TextEditingController();
|
TextEditingController fnameController = TextEditingController();
|
||||||
TextEditingController lnameController = TextEditingController();
|
TextEditingController lnameController = TextEditingController();
|
||||||
|
TextEditingController accessStatusController = TextEditingController();
|
||||||
final baseAPI = AppEnviroment.baseApiUrl;
|
final baseAPI = AppEnviroment.baseApiUrl;
|
||||||
|
|
||||||
Future<void> addPatientAppointmentAPICall(int index) async {
|
Future<void> addPatientAppointmentAPICall(int index) async {
|
||||||
@@ -84,6 +86,47 @@ class _BuildPatientsListState extends State<BuildPatientsList> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<void> addPatientAccessAPICall(int index) async {
|
||||||
|
var response = await http.post(
|
||||||
|
Uri.parse("$baseAPI/access-requests/insert/"),
|
||||||
|
headers: <String, String>{
|
||||||
|
"Content-Type": "application/json; charset=UTF-8"
|
||||||
|
},
|
||||||
|
body: jsonEncode(<String, dynamic>{
|
||||||
|
"business_id": widget.business!.business_id,
|
||||||
|
"app_id": widget.patients[index].app_id,
|
||||||
|
"date": dateController.text,
|
||||||
|
"time": timeController.text,
|
||||||
|
"access": "pending",
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
if (response.statusCode == 201) {
|
||||||
|
// Navigator.pushNamed(context, '/patient-manager/patient',
|
||||||
|
// arguments: widget.signedInUser);
|
||||||
|
String message =
|
||||||
|
"The appointment has been successfully booked!\n\nAn approval request as been sent to the patient.Once the access request has been approved, you will be able to access the patients profile. ou can check the status of your request in patient queue under the appointment.";
|
||||||
|
// "${fnameController.text} ${lnameController.text} patient profiole has been successfully added!\n";
|
||||||
|
Navigator.pop(context);
|
||||||
|
Navigator.pop(context);
|
||||||
|
setState(() {
|
||||||
|
dateController.text = "";
|
||||||
|
timeController.text = "";
|
||||||
|
});
|
||||||
|
Navigator.of(context).pushNamed(
|
||||||
|
'/patient-manager',
|
||||||
|
arguments: BusinessArguments(
|
||||||
|
widget.arguments.signedInUser,
|
||||||
|
widget.arguments.businessUser,
|
||||||
|
widget.arguments.business,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
successPopUp(message);
|
||||||
|
addAccessReviewNotificationAPICall(index);
|
||||||
|
} else {
|
||||||
|
internetConnectionPopUp();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Future<void> addAccessReviewNotificationAPICall(int index) async {
|
Future<void> addAccessReviewNotificationAPICall(int index) async {
|
||||||
var response = await http.post(
|
var response = await http.post(
|
||||||
Uri.parse("$baseAPI/notifications/insert/"),
|
Uri.parse("$baseAPI/notifications/insert/"),
|
||||||
@@ -128,7 +171,15 @@ class _BuildPatientsListState extends State<BuildPatientsList> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void submitApointment(int index) {
|
void submitApointment(int index) {
|
||||||
addPatientAppointmentAPICall(index);
|
MIHApiCalls.addAppointmentAPICall(
|
||||||
|
widget.arguments.business!.business_id,
|
||||||
|
widget.patients[index].app_id,
|
||||||
|
dateController.text,
|
||||||
|
timeController.text,
|
||||||
|
widget.arguments,
|
||||||
|
context,
|
||||||
|
);
|
||||||
|
//addPatientAppointmentAPICall(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isAppointmentFieldsFilled() {
|
bool isAppointmentFieldsFilled() {
|
||||||
@@ -224,129 +275,278 @@ class _BuildPatientsListState extends State<BuildPatientsList> {
|
|||||||
],
|
],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
// showDialog(
|
}
|
||||||
// context: context,
|
|
||||||
// barrierDismissible: false,
|
void noAccessWarning() {
|
||||||
// builder: (context) => Dialog(
|
showDialog(
|
||||||
// child: Stack(
|
context: context,
|
||||||
// children: [
|
builder: (context) {
|
||||||
// Container(
|
return const MIHWarningMessage(warningType: "No Access");
|
||||||
// padding: const EdgeInsets.all(10.0),
|
},
|
||||||
// width: 700.0,
|
);
|
||||||
// //height: 475.0,
|
}
|
||||||
// decoration: BoxDecoration(
|
|
||||||
// color: MzanziInnovationHub.of(context)!.theme.primaryColor(),
|
Future<bool> hasAccessToProfile(int index) async {
|
||||||
// borderRadius: BorderRadius.circular(25.0),
|
var hasAccess = false;
|
||||||
// border: Border.all(
|
await MIHApiCalls.checkBusinessAccessToPatient(
|
||||||
// color:
|
widget.business!.business_id, widget.patients[index].app_id)
|
||||||
// MzanziInnovationHub.of(context)!.theme.secondaryColor(),
|
.then((results) {
|
||||||
// width: 5.0),
|
if (results.isEmpty) {
|
||||||
// ),
|
setState(() {
|
||||||
// child: SingleChildScrollView(
|
hasAccess = false;
|
||||||
// padding: const EdgeInsets.symmetric(horizontal: 10),
|
});
|
||||||
// child: Column(
|
} else if (results[0].status == "approved") {
|
||||||
// mainAxisSize: MainAxisSize.min,
|
setState(() {
|
||||||
// children: [
|
hasAccess = true;
|
||||||
// Text(
|
});
|
||||||
// "Patient Appointment",
|
} else {
|
||||||
// textAlign: TextAlign.center,
|
setState(() {
|
||||||
// style: TextStyle(
|
hasAccess = false;
|
||||||
// color: MzanziInnovationHub.of(context)!
|
});
|
||||||
// .theme
|
}
|
||||||
// .secondaryColor(),
|
});
|
||||||
// fontSize: 35.0,
|
return hasAccess;
|
||||||
// fontWeight: FontWeight.bold,
|
}
|
||||||
// ),
|
|
||||||
// ),
|
Future<String> getAccessStatusOfProfile(int index) async {
|
||||||
// const SizedBox(height: 25.0),
|
var accessStatus = "";
|
||||||
// MIHTextField(
|
await MIHApiCalls.checkBusinessAccessToPatient(
|
||||||
// controller: idController,
|
widget.business!.business_id, widget.patients[index].app_id)
|
||||||
// hintText: "ID No.",
|
.then((results) {
|
||||||
// editable: false,
|
if (results.isEmpty) {
|
||||||
// required: true,
|
setState(() {
|
||||||
// ),
|
accessStatus = "";
|
||||||
// const SizedBox(height: 10.0),
|
});
|
||||||
// MIHTextField(
|
} else {
|
||||||
// controller: fnameController,
|
setState(() {
|
||||||
// hintText: "First Name",
|
accessStatus = results[0].status;
|
||||||
// editable: false,
|
});
|
||||||
// required: true,
|
}
|
||||||
// ),
|
});
|
||||||
// const SizedBox(height: 10.0),
|
return accessStatus;
|
||||||
// MIHTextField(
|
}
|
||||||
// controller: lnameController,
|
|
||||||
// hintText: "Surname",
|
void patientProfileChoicePopUp(int index) async {
|
||||||
// editable: false,
|
var hasAccess = false;
|
||||||
// required: true,
|
String accessStatus = "";
|
||||||
// ),
|
await hasAccessToProfile(index).then((result) {
|
||||||
// const SizedBox(height: 10.0),
|
setState(() {
|
||||||
// MIHDateField(
|
hasAccess = result;
|
||||||
// controller: dateController,
|
});
|
||||||
// lableText: "Date",
|
});
|
||||||
// required: true,
|
await getAccessStatusOfProfile(index).then((result) {
|
||||||
// ),
|
setState(() {
|
||||||
// const SizedBox(height: 10.0),
|
accessStatus = result;
|
||||||
// MIHTimeField(
|
});
|
||||||
// controller: timeController,
|
});
|
||||||
// lableText: "Time",
|
// print(accessStatus);
|
||||||
// required: true,
|
// print(hasAccess);
|
||||||
// ),
|
var firstLetterFName = widget.patients[index].first_name[0];
|
||||||
// const SizedBox(height: 30.0),
|
var firstLetterLName = widget.patients[index].last_name[0];
|
||||||
// SizedBox(
|
var fnameStar = '*' * 8;
|
||||||
// width: 300,
|
var lnameStar = '*' * 8;
|
||||||
// height: 50,
|
if (accessStatus == "") {
|
||||||
// child: MIHButton(
|
accessStatus = "No Access";
|
||||||
// buttonText: "Book",
|
}
|
||||||
// buttonColor: MzanziInnovationHub.of(context)!
|
setState(() {
|
||||||
// .theme
|
idController.text = widget.patients[index].id_no;
|
||||||
// .secondaryColor(),
|
fnameController.text = firstLetterFName + fnameStar;
|
||||||
// textColor: MzanziInnovationHub.of(context)!
|
lnameController.text = firstLetterLName + lnameStar;
|
||||||
// .theme
|
accessStatusController.text = accessStatus.toUpperCase();
|
||||||
// .primaryColor(),
|
});
|
||||||
// onTap: () {
|
|
||||||
// //print("here1");
|
showDialog(
|
||||||
// bool filled = isAppointmentFieldsFilled();
|
context: context,
|
||||||
// //print("fields filled: $filled");
|
barrierDismissible: false,
|
||||||
// if (filled) {
|
builder: (context) => MIHWindow(
|
||||||
// //print("here2");
|
fullscreen: false,
|
||||||
// submitApointment(index);
|
windowTitle: "Patient Profile",
|
||||||
// //print("here3");
|
windowTools: const [],
|
||||||
// } else {
|
onWindowTapClose: () {
|
||||||
// showDialog(
|
Navigator.pop(context);
|
||||||
// context: context,
|
},
|
||||||
// builder: (context) {
|
windowBody: [
|
||||||
// return const MIHErrorMessage(
|
MIHTextField(
|
||||||
// errorType: "Input Error");
|
controller: idController,
|
||||||
// },
|
hintText: "ID No.",
|
||||||
// );
|
editable: false,
|
||||||
// }
|
required: true,
|
||||||
// },
|
),
|
||||||
// ),
|
const SizedBox(height: 10.0),
|
||||||
// )
|
MIHTextField(
|
||||||
// ],
|
controller: fnameController,
|
||||||
// ),
|
hintText: "First Name",
|
||||||
// ),
|
editable: false,
|
||||||
// ),
|
required: true,
|
||||||
// Positioned(
|
),
|
||||||
// top: 5,
|
const SizedBox(height: 10.0),
|
||||||
// right: 5,
|
MIHTextField(
|
||||||
// width: 50,
|
controller: lnameController,
|
||||||
// height: 50,
|
hintText: "Surname",
|
||||||
// child: IconButton(
|
editable: false,
|
||||||
// onPressed: () {
|
required: true,
|
||||||
// Navigator.pop(context);
|
),
|
||||||
// },
|
const SizedBox(height: 10.0),
|
||||||
// icon: Icon(
|
MIHTextField(
|
||||||
// Icons.close,
|
controller: accessStatusController,
|
||||||
// color: MzanziInnovationHub.of(context)!.theme.errorColor(),
|
hintText: "Access Status",
|
||||||
// size: 35,
|
editable: false,
|
||||||
// ),
|
required: true,
|
||||||
// ),
|
),
|
||||||
// ),
|
const SizedBox(height: 20.0),
|
||||||
// ],
|
Visibility(
|
||||||
// ),
|
visible: !hasAccess,
|
||||||
// ),
|
child: Column(
|
||||||
// );
|
mainAxisSize: MainAxisSize.max,
|
||||||
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
"Important Notice: Requesting Patient Profile Access",
|
||||||
|
style: TextStyle(
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
color: MzanziInnovationHub.of(context)!.theme.errorColor(),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
"You are about to request access to a patient's profile. Please be aware of the following important points:",
|
||||||
|
style: TextStyle(
|
||||||
|
fontWeight: FontWeight.normal,
|
||||||
|
color: MzanziInnovationHub.of(context)!.theme.errorColor(),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
width: 600,
|
||||||
|
child: Text(
|
||||||
|
"1. Permanent Access: Once the patient accepts your access request, it will become permanent.",
|
||||||
|
style: TextStyle(
|
||||||
|
fontWeight: FontWeight.normal,
|
||||||
|
color:
|
||||||
|
MzanziInnovationHub.of(context)!.theme.errorColor(),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
width: 600,
|
||||||
|
child: Text(
|
||||||
|
"2. Shared Information: Any updates you make to the patient's profile will be visible to others who have access to the profile.",
|
||||||
|
style: TextStyle(
|
||||||
|
fontWeight: FontWeight.normal,
|
||||||
|
color:
|
||||||
|
MzanziInnovationHub.of(context)!.theme.errorColor(),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
width: 600,
|
||||||
|
child: Text(
|
||||||
|
"3. Irreversible Access: Once granted, you cannot revoke your access to the patient's profile.",
|
||||||
|
style: TextStyle(
|
||||||
|
fontWeight: FontWeight.normal,
|
||||||
|
color:
|
||||||
|
MzanziInnovationHub.of(context)!.theme.errorColor(),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
"By pressing the \"Request Access\" button you accept the above terms.",
|
||||||
|
style: TextStyle(
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
color: MzanziInnovationHub.of(context)!.theme.errorColor(),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 20.0),
|
||||||
|
Wrap(runSpacing: 10, spacing: 10, children: [
|
||||||
|
Visibility(
|
||||||
|
visible: hasAccess,
|
||||||
|
child: SizedBox(
|
||||||
|
width: 300,
|
||||||
|
height: 50,
|
||||||
|
child: MIHButton(
|
||||||
|
buttonText: "Book Appointment",
|
||||||
|
buttonColor:
|
||||||
|
MzanziInnovationHub.of(context)!.theme.secondaryColor(),
|
||||||
|
textColor:
|
||||||
|
MzanziInnovationHub.of(context)!.theme.primaryColor(),
|
||||||
|
onTap: () {
|
||||||
|
if (hasAccess) {
|
||||||
|
appointmentPopUp(index);
|
||||||
|
} else {
|
||||||
|
noAccessWarning();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Visibility(
|
||||||
|
visible: hasAccess,
|
||||||
|
child: SizedBox(
|
||||||
|
width: 300,
|
||||||
|
height: 50,
|
||||||
|
child: MIHButton(
|
||||||
|
buttonText: "View Patient Profile",
|
||||||
|
buttonColor:
|
||||||
|
MzanziInnovationHub.of(context)!.theme.successColor(),
|
||||||
|
textColor:
|
||||||
|
MzanziInnovationHub.of(context)!.theme.primaryColor(),
|
||||||
|
onTap: () {
|
||||||
|
if (hasAccess) {
|
||||||
|
Navigator.of(context)
|
||||||
|
.pushNamed('/patient-manager/patient',
|
||||||
|
arguments: PatientViewArguments(
|
||||||
|
widget.signedInUser,
|
||||||
|
widget.patients[index],
|
||||||
|
widget.arguments.businessUser,
|
||||||
|
widget.business,
|
||||||
|
"business",
|
||||||
|
));
|
||||||
|
} else {
|
||||||
|
noAccessWarning();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Visibility(
|
||||||
|
visible: !hasAccess && accessStatus != "pending",
|
||||||
|
child: SizedBox(
|
||||||
|
width: 300,
|
||||||
|
height: 50,
|
||||||
|
child: MIHButton(
|
||||||
|
buttonText: "Request Access",
|
||||||
|
buttonColor:
|
||||||
|
MzanziInnovationHub.of(context)!.theme.successColor(),
|
||||||
|
textColor:
|
||||||
|
MzanziInnovationHub.of(context)!.theme.primaryColor(),
|
||||||
|
onTap: () {
|
||||||
|
print("Send access Request...");
|
||||||
|
MIHApiCalls.addPatientAccessAPICall(
|
||||||
|
widget.business!.business_id,
|
||||||
|
widget.patients[index].app_id,
|
||||||
|
"patient",
|
||||||
|
widget.business!.Name,
|
||||||
|
widget.arguments,
|
||||||
|
context,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Visibility(
|
||||||
|
visible: !hasAccess && accessStatus == "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) {
|
Widget isMainMember(int index) {
|
||||||
@@ -397,13 +597,14 @@ class _BuildPatientsListState extends State<BuildPatientsList> {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
onTap: () {
|
onTap: () {
|
||||||
setState(() {
|
patientProfileChoicePopUp(index);
|
||||||
appointmentPopUp(index);
|
// setState(() {
|
||||||
// Add popup to add patienmt to queue
|
// appointmentPopUp(index);
|
||||||
// Navigator.of(context).pushNamed('/patient-manager/patient',
|
// // Add popup to add patienmt to queue
|
||||||
// arguments: PatientViewArguments(
|
// // Navigator.of(context).pushNamed('/patient-manager/patient',
|
||||||
// widget.signedInUser, widget.patients[index], "business"));
|
// // arguments: PatientViewArguments(
|
||||||
});
|
// // widget.signedInUser, widget.patients[index], "business"));
|
||||||
|
// });
|
||||||
},
|
},
|
||||||
trailing: Icon(
|
trailing: Icon(
|
||||||
Icons.arrow_forward,
|
Icons.arrow_forward,
|
||||||
@@ -420,12 +621,13 @@ class _BuildPatientsListState extends State<BuildPatientsList> {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
onTap: () {
|
onTap: () {
|
||||||
setState(() {
|
patientProfileChoicePopUp(index);
|
||||||
appointmentPopUp(index);
|
// setState(() {
|
||||||
// Navigator.of(context).pushNamed('/patient-manager/patient',
|
// appointmentPopUp(index);
|
||||||
// arguments: PatientViewArguments(
|
// // Navigator.of(context).pushNamed('/patient-manager/patient',
|
||||||
// widget.signedInUser, widget.patients[index], "business"));
|
// // arguments: PatientViewArguments(
|
||||||
});
|
// // widget.signedInUser, widget.patients[index], "business"));
|
||||||
|
// });
|
||||||
},
|
},
|
||||||
trailing: Icon(
|
trailing: Icon(
|
||||||
Icons.add,
|
Icons.add,
|
||||||
@@ -442,6 +644,7 @@ class _BuildPatientsListState extends State<BuildPatientsList> {
|
|||||||
idController.dispose();
|
idController.dispose();
|
||||||
fnameController.dispose();
|
fnameController.dispose();
|
||||||
lnameController.dispose();
|
lnameController.dispose();
|
||||||
|
accessStatusController.dispose();
|
||||||
super.dispose();
|
super.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:patient_manager/mih_apis/mih_api_calls.dart';
|
||||||
import 'package:patient_manager/mih_components/mih_inputs_and_buttons/mih_button.dart';
|
import 'package:patient_manager/mih_components/mih_inputs_and_buttons/mih_button.dart';
|
||||||
import 'package:patient_manager/mih_components/mih_inputs_and_buttons/mih_date_input.dart';
|
import 'package:patient_manager/mih_components/mih_inputs_and_buttons/mih_date_input.dart';
|
||||||
import 'package:patient_manager/mih_components/mih_inputs_and_buttons/mih_text_input.dart';
|
import 'package:patient_manager/mih_components/mih_inputs_and_buttons/mih_text_input.dart';
|
||||||
@@ -47,6 +48,7 @@ class _BuildPatientsListState extends State<BuildPatientQueueList> {
|
|||||||
TextEditingController lnameController = TextEditingController();
|
TextEditingController lnameController = TextEditingController();
|
||||||
TextEditingController daysExtensionController = TextEditingController();
|
TextEditingController daysExtensionController = TextEditingController();
|
||||||
int counter = 0;
|
int counter = 0;
|
||||||
|
|
||||||
Future<void> updateAccessAPICall(int index, String accessType) async {
|
Future<void> updateAccessAPICall(int index, String accessType) async {
|
||||||
var response = await http.put(
|
var response = await http.put(
|
||||||
Uri.parse("$baseAPI/access-requests/update/"),
|
Uri.parse("$baseAPI/access-requests/update/"),
|
||||||
@@ -82,30 +84,30 @@ class _BuildPatientsListState extends State<BuildPatientQueueList> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> extendAccessAPICall(int index, String revokeDate) async {
|
// Future<void> extendAccessAPICall(int index, String revokeDate) async {
|
||||||
var response = await http.put(
|
// var response = await http.put(
|
||||||
Uri.parse("$baseAPI/access-requests/extension/"),
|
// Uri.parse("$baseAPI/access-requests/extension/"),
|
||||||
headers: <String, String>{
|
// headers: <String, String>{
|
||||||
"Content-Type": "application/json; charset=UTF-8"
|
// "Content-Type": "application/json; charset=UTF-8"
|
||||||
},
|
// },
|
||||||
body: jsonEncode(<String, dynamic>{
|
// body: jsonEncode(<String, dynamic>{
|
||||||
"business_id": widget.business!.business_id,
|
// "business_id": widget.business!.business_id,
|
||||||
"app_id": widget.patientQueue[index].app_id,
|
// "app_id": widget.patientQueue[index].app_id,
|
||||||
"date_time": widget.patientQueue[index].date_time,
|
// "date_time": widget.patientQueue[index].date_time,
|
||||||
"revoke_date": revokeDate,
|
// "revoke_date": revokeDate,
|
||||||
}),
|
// }),
|
||||||
);
|
// );
|
||||||
if (response.statusCode == 200) {
|
// if (response.statusCode == 200) {
|
||||||
addAccessExtensionNotificationAPICall(index, revokeDate);
|
// addAccessExtensionNotificationAPICall(index, revokeDate);
|
||||||
//addCancelledAppointmentNotificationAPICall(index);
|
// //addCancelledAppointmentNotificationAPICall(index);
|
||||||
} else {
|
// } else {
|
||||||
internetConnectionPopUp();
|
// internetConnectionPopUp();
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
Future<void> updateApointmentAPICall(int index) async {
|
Future<void> updateApointmentAPICall(int index) async {
|
||||||
var response = await http.put(
|
var response = await http.put(
|
||||||
Uri.parse("$baseAPI/queue/update/"),
|
Uri.parse("$baseAPI/queue/appoointment/update/"),
|
||||||
headers: <String, String>{
|
headers: <String, String>{
|
||||||
"Content-Type": "application/json; charset=UTF-8"
|
"Content-Type": "application/json; charset=UTF-8"
|
||||||
},
|
},
|
||||||
@@ -199,13 +201,8 @@ class _BuildPatientsListState extends State<BuildPatientQueueList> {
|
|||||||
String subtitle =
|
String subtitle =
|
||||||
"Appointment: ${widget.patientQueue[index].date_time.substring(0, 16).replaceAll("T", " ")}\n";
|
"Appointment: ${widget.patientQueue[index].date_time.substring(0, 16).replaceAll("T", " ")}\n";
|
||||||
subtitle += "ID No.: ${widget.patientQueue[index].id_no}\n";
|
subtitle += "ID No.: ${widget.patientQueue[index].id_no}\n";
|
||||||
if (widget.patientQueue[index].access == "approved") {
|
subtitle +=
|
||||||
subtitle +=
|
"Patient: ${widget.patientQueue[index].first_name} ${widget.patientQueue[index].last_name}\n";
|
||||||
"Patient: ${widget.patientQueue[index].first_name} ${widget.patientQueue[index].last_name}\n";
|
|
||||||
} else {
|
|
||||||
subtitle +=
|
|
||||||
"Patient: ${widget.patientQueue[index].first_name[0]}******** ${widget.patientQueue[index].last_name[0]}********\n\n";
|
|
||||||
}
|
|
||||||
// subtitle +=
|
// subtitle +=
|
||||||
// "Patient: ${widget.patientQueue[index].first_name} ${widget.patientQueue[index].last_name}\n\n";
|
// "Patient: ${widget.patientQueue[index].first_name} ${widget.patientQueue[index].last_name}\n\n";
|
||||||
//subtitle += "Business Type: ${widget.patientQueue[index].last_name}\n\n";
|
//subtitle += "Business Type: ${widget.patientQueue[index].last_name}\n\n";
|
||||||
@@ -251,15 +248,9 @@ class _BuildPatientsListState extends State<BuildPatientQueueList> {
|
|||||||
.split("T");
|
.split("T");
|
||||||
var firstName = "";
|
var firstName = "";
|
||||||
var lastName = "";
|
var lastName = "";
|
||||||
if (widget.patientQueue[index].access == "approved") {
|
firstName = widget.patientQueue[index].first_name;
|
||||||
firstName = widget.patientQueue[index].first_name;
|
lastName = widget.patientQueue[index].last_name;
|
||||||
lastName = widget.patientQueue[index].last_name;
|
|
||||||
} else {
|
|
||||||
firstName =
|
|
||||||
"${widget.patientQueue[index].first_name[0]}********";
|
|
||||||
lastName =
|
|
||||||
"${widget.patientQueue[index].last_name[0]}********";
|
|
||||||
}
|
|
||||||
setState(() {
|
setState(() {
|
||||||
idController.text = widget.patientQueue[index].id_no;
|
idController.text = widget.patientQueue[index].id_no;
|
||||||
fnameController.text = firstName;
|
fnameController.text = firstName;
|
||||||
@@ -282,27 +273,25 @@ class _BuildPatientsListState extends State<BuildPatientQueueList> {
|
|||||||
child: MIHButton(
|
child: MIHButton(
|
||||||
onTap: () {
|
onTap: () {
|
||||||
//updateAccessAPICall(index, "approved");
|
//updateAccessAPICall(index, "approved");
|
||||||
if (widget.patientQueue[index].access == "approved") {
|
|
||||||
Patient selectedPatient;
|
Patient selectedPatient;
|
||||||
fetchPatients(widget.patientQueue[index].app_id).then(
|
fetchPatients(widget.patientQueue[index].app_id).then(
|
||||||
(result) {
|
(result) {
|
||||||
setState(() {
|
setState(() {
|
||||||
selectedPatient = result;
|
selectedPatient = result;
|
||||||
Navigator.of(context)
|
Navigator.of(context).pop();
|
||||||
.pushNamed('/patient-manager/patient',
|
Navigator.of(context)
|
||||||
arguments: PatientViewArguments(
|
.pushNamed('/patient-manager/patient',
|
||||||
widget.signedInUser,
|
arguments: PatientViewArguments(
|
||||||
selectedPatient,
|
widget.signedInUser,
|
||||||
widget.businessUser,
|
selectedPatient,
|
||||||
widget.business,
|
widget.businessUser,
|
||||||
"business",
|
widget.business,
|
||||||
));
|
"business",
|
||||||
});
|
));
|
||||||
},
|
});
|
||||||
);
|
},
|
||||||
} else {
|
);
|
||||||
noAccessWarning();
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
buttonText: "View Patient Profile",
|
buttonText: "View Patient Profile",
|
||||||
buttonColor:
|
buttonColor:
|
||||||
@@ -395,40 +384,40 @@ class _BuildPatientsListState extends State<BuildPatientQueueList> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> addAccessExtensionNotificationAPICall(
|
// Future<void> addAccessExtensionNotificationAPICall(
|
||||||
int index, String revokeDate) async {
|
// int index, String revokeDate) async {
|
||||||
var response = await http.post(
|
// var response = await http.post(
|
||||||
Uri.parse("$baseAPI/notifications/insert/"),
|
// Uri.parse("$baseAPI/notifications/insert/"),
|
||||||
headers: <String, String>{
|
// headers: <String, String>{
|
||||||
"Content-Type": "application/json; charset=UTF-8"
|
// "Content-Type": "application/json; charset=UTF-8"
|
||||||
},
|
// },
|
||||||
body: jsonEncode(<String, dynamic>{
|
// body: jsonEncode(<String, dynamic>{
|
||||||
"app_id": widget.patientQueue[index].app_id,
|
// "app_id": widget.patientQueue[index].app_id,
|
||||||
"notification_type": "Access Extension Request",
|
// "notification_type": "Access Extension Request",
|
||||||
"notification_message":
|
// "notification_message":
|
||||||
"${widget.business!.Name} - access expiry date extension for appointment: ${widget.patientQueue[index].date_time.split("T")[0]}. Expiry Date: from ${widget.patientQueue[index].revoke_date.split("T")[0]} to ${revokeDate.split(" ")[0]}.",
|
// "${widget.business!.Name} - access expiry date extension for appointment: ${widget.patientQueue[index].date_time.split("T")[0]}. Expiry Date: from ${widget.patientQueue[index].revoke_date.split("T")[0]} to ${revokeDate.split(" ")[0]}.",
|
||||||
"action_path": "/access-review",
|
// "action_path": "/access-review",
|
||||||
}),
|
// }),
|
||||||
);
|
// );
|
||||||
if (response.statusCode == 201) {
|
// if (response.statusCode == 201) {
|
||||||
Navigator.of(context).pop();
|
// Navigator.of(context).pop();
|
||||||
Navigator.of(context).pop();
|
// Navigator.of(context).pop();
|
||||||
Navigator.of(context).pushNamed(
|
// Navigator.of(context).pushNamed(
|
||||||
'/patient-manager',
|
// '/patient-manager',
|
||||||
arguments: BusinessArguments(
|
// arguments: BusinessArguments(
|
||||||
widget.signedInUser,
|
// widget.signedInUser,
|
||||||
widget.businessUser,
|
// widget.businessUser,
|
||||||
widget.business,
|
// widget.business,
|
||||||
),
|
// ),
|
||||||
);
|
// );
|
||||||
String message =
|
// String message =
|
||||||
"you have successfully requested an extension on the expirey date. The request has been sent tp ${widget.patientQueue[index].first_name} ${widget.patientQueue[index].last_name} to review and approve the request";
|
// "you have successfully requested an extension on the expirey date. The request has been sent tp ${widget.patientQueue[index].first_name} ${widget.patientQueue[index].last_name} to review and approve the request";
|
||||||
|
|
||||||
successPopUp(message);
|
// successPopUp(message);
|
||||||
} else {
|
// } else {
|
||||||
internetConnectionPopUp();
|
// internetConnectionPopUp();
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
void manageAppointmentPopUp(int index) {
|
void manageAppointmentPopUp(int index) {
|
||||||
showDialog(
|
showDialog(
|
||||||
@@ -481,7 +470,19 @@ class _BuildPatientsListState extends State<BuildPatientQueueList> {
|
|||||||
height: 50,
|
height: 50,
|
||||||
child: MIHButton(
|
child: MIHButton(
|
||||||
onTap: () {
|
onTap: () {
|
||||||
updateAccessAPICall(index, "cancelled");
|
//add mihapicall for deleting appointment
|
||||||
|
MIHApiCalls.deleteApointmentAPICall(
|
||||||
|
widget.patientQueue[index].idpatient_queue,
|
||||||
|
widget.patientQueue[index].app_id,
|
||||||
|
widget.patientQueue[index].date_time,
|
||||||
|
BusinessArguments(
|
||||||
|
widget.signedInUser,
|
||||||
|
widget.businessUser,
|
||||||
|
widget.business,
|
||||||
|
),
|
||||||
|
context,
|
||||||
|
);
|
||||||
|
//updateAccessAPICall(index, "cancelled");
|
||||||
},
|
},
|
||||||
buttonText: "Cancel Appointment",
|
buttonText: "Cancel Appointment",
|
||||||
buttonColor:
|
buttonColor:
|
||||||
@@ -495,7 +496,20 @@ class _BuildPatientsListState extends State<BuildPatientQueueList> {
|
|||||||
height: 50,
|
height: 50,
|
||||||
child: MIHButton(
|
child: MIHButton(
|
||||||
onTap: () {
|
onTap: () {
|
||||||
updateApointmentAPICall(index);
|
MIHApiCalls.updateApointmentAPICall(
|
||||||
|
widget.patientQueue[index].idpatient_queue,
|
||||||
|
widget.patientQueue[index].app_id,
|
||||||
|
widget.business!.Name,
|
||||||
|
widget.patientQueue[index].date_time,
|
||||||
|
dateController.text,
|
||||||
|
timeController.text,
|
||||||
|
BusinessArguments(
|
||||||
|
widget.signedInUser,
|
||||||
|
widget.businessUser,
|
||||||
|
widget.business,
|
||||||
|
),
|
||||||
|
context,
|
||||||
|
);
|
||||||
},
|
},
|
||||||
buttonText: "Update Appointment",
|
buttonText: "Update Appointment",
|
||||||
buttonColor:
|
buttonColor:
|
||||||
@@ -518,60 +532,51 @@ class _BuildPatientsListState extends State<BuildPatientQueueList> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Widget displayQueue(int index) {
|
Widget displayQueue(int index) {
|
||||||
String fname = widget.patientQueue[index].first_name[0] + "********";
|
|
||||||
String lname = widget.patientQueue[index].last_name[0] + "********";
|
|
||||||
String title =
|
String title =
|
||||||
widget.patientQueue[index].date_time.split('T')[1].substring(0, 5);
|
widget.patientQueue[index].date_time.split('T')[1].substring(0, 5);
|
||||||
String line234 = "";
|
String line234 = "";
|
||||||
var nowDate = DateTime.now();
|
// var nowDate = DateTime.now();
|
||||||
var expireyDate = DateTime.parse(widget.patientQueue[index].revoke_date);
|
// var expireyDate = DateTime.parse(widget.patientQueue[index].revoke_date);
|
||||||
|
|
||||||
if (widget.patientQueue[index].access != "approved" ||
|
line234 +=
|
||||||
expireyDate.isBefore(nowDate)) {
|
"Name: ${widget.patientQueue[index].first_name} ${widget.patientQueue[index].last_name}\nID No.: ${widget.patientQueue[index].id_no}\nMedical Aid No: ";
|
||||||
line234 += "Name: $fname $lname\n";
|
if (widget.patientQueue[index].medical_aid_no == "") {
|
||||||
line234 += "ID No.: ${widget.patientQueue[index].id_no}\n";
|
line234 += "No Medical Aid";
|
||||||
line234 += "Medical Aid No: ********";
|
|
||||||
//subtitle += "********";
|
|
||||||
} else {
|
} else {
|
||||||
line234 +=
|
// subtitle +=
|
||||||
"Name: ${widget.patientQueue[index].first_name} ${widget.patientQueue[index].last_name}\nID No.: ${widget.patientQueue[index].id_no}\nMedical Aid No: ";
|
// "\nMedical Aid No: ";
|
||||||
if (widget.patientQueue[index].medical_aid_no == "") {
|
line234 += widget.patientQueue[index].medical_aid_no;
|
||||||
line234 += "No Medical Aid";
|
|
||||||
} else {
|
|
||||||
// subtitle +=
|
|
||||||
// "\nMedical Aid No: ";
|
|
||||||
line234 += widget.patientQueue[index].medical_aid_no;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
String line5 = "\nAccess Request: ";
|
|
||||||
String access = "";
|
// String line5 = "\nAccess Request: ";
|
||||||
if (expireyDate.isBefore(nowDate) &&
|
// String access = "";
|
||||||
widget.patientQueue[index].access != "cacelled") {
|
// if (expireyDate.isBefore(nowDate) &&
|
||||||
access += "EXPIRED";
|
// widget.patientQueue[index].access != "cacelled") {
|
||||||
} else {
|
// access += "EXPIRED";
|
||||||
access += widget.patientQueue[index].access.toUpperCase();
|
// } else {
|
||||||
}
|
// access += widget.patientQueue[index].access.toUpperCase();
|
||||||
TextSpan accessWithColour;
|
// }
|
||||||
if (access == "APPROVED") {
|
// TextSpan accessWithColour;
|
||||||
accessWithColour = TextSpan(
|
// if (access == "APPROVED") {
|
||||||
text: access,
|
// accessWithColour = TextSpan(
|
||||||
style: TextStyle(
|
// text: access,
|
||||||
color: MzanziInnovationHub.of(context)!.theme.successColor()));
|
// style: TextStyle(
|
||||||
} else if (access == "PENDING") {
|
// color: MzanziInnovationHub.of(context)!.theme.successColor()));
|
||||||
accessWithColour = TextSpan(
|
// } else if (access == "PENDING") {
|
||||||
text: access,
|
// accessWithColour = TextSpan(
|
||||||
style: TextStyle(
|
// text: access,
|
||||||
color:
|
// style: TextStyle(
|
||||||
MzanziInnovationHub.of(context)!.theme.messageTextColor()));
|
// color:
|
||||||
} else {
|
// MzanziInnovationHub.of(context)!.theme.messageTextColor()));
|
||||||
accessWithColour = TextSpan(
|
// } else {
|
||||||
text: access,
|
// accessWithColour = TextSpan(
|
||||||
style: TextStyle(
|
// text: access,
|
||||||
color: MzanziInnovationHub.of(context)!.theme.errorColor()));
|
// style: TextStyle(
|
||||||
}
|
// color: MzanziInnovationHub.of(context)!.theme.errorColor()));
|
||||||
String line6 = "";
|
// }
|
||||||
line6 +=
|
// String line6 = "";
|
||||||
"\nAccess Expiration date: ${widget.patientQueue[index].revoke_date.substring(0, 16).replaceAll("T", " ")}";
|
// line6 +=
|
||||||
|
// "\nAccess Expiration date: ${widget.patientQueue[index].revoke_date.substring(0, 16).replaceAll("T", " ")}";
|
||||||
return ListTile(
|
return ListTile(
|
||||||
title: Text(
|
title: Text(
|
||||||
"Appointment: $title",
|
"Appointment: $title",
|
||||||
@@ -581,13 +586,14 @@ class _BuildPatientsListState extends State<BuildPatientQueueList> {
|
|||||||
),
|
),
|
||||||
subtitle: RichText(
|
subtitle: RichText(
|
||||||
text: TextSpan(
|
text: TextSpan(
|
||||||
text: line234,
|
text: line234,
|
||||||
style: DefaultTextStyle.of(context).style,
|
style: DefaultTextStyle.of(context).style,
|
||||||
children: [
|
// children: [
|
||||||
TextSpan(text: line5),
|
// TextSpan(text: line5),
|
||||||
accessWithColour,
|
// accessWithColour,
|
||||||
TextSpan(text: line6),
|
// TextSpan(text: line6),
|
||||||
]),
|
// ]
|
||||||
|
),
|
||||||
),
|
),
|
||||||
// Text(
|
// Text(
|
||||||
// subtitle,
|
// subtitle,
|
||||||
@@ -596,41 +602,41 @@ class _BuildPatientsListState extends State<BuildPatientQueueList> {
|
|||||||
// ),
|
// ),
|
||||||
// ),
|
// ),
|
||||||
onTap: () {
|
onTap: () {
|
||||||
var todayDate = DateTime.now();
|
// var todayDate = DateTime.now();
|
||||||
var revokeDate = DateTime.parse(widget.patientQueue[index].revoke_date);
|
// var revokeDate = DateTime.parse(widget.patientQueue[index].revoke_date);
|
||||||
// print(
|
// // print(
|
||||||
// "Todays: $todayDate\nRevoke Date: $revokeDate\nHas revoke date passed: ${revokeDate.isBefore(todayDate)}");
|
// // "Todays: $todayDate\nRevoke Date: $revokeDate\nHas revoke date passed: ${revokeDate.isBefore(todayDate)}");
|
||||||
if (revokeDate.isBefore(todayDate)) {
|
// if (revokeDate.isBefore(todayDate)) {
|
||||||
expiredAccessWarning();
|
// expiredAccessWarning();
|
||||||
} else if (widget.patientQueue[index].access == "approved") {
|
// } else if (widget.patientQueue[index].access == "approved") {
|
||||||
viewConfirmationPopUp(index);
|
// viewConfirmationPopUp(index);
|
||||||
// Patient selectedPatient;
|
// // Patient selectedPatient;
|
||||||
// fetchPatients(widget.patientQueue[index].app_id).then(
|
// // fetchPatients(widget.patientQueue[index].app_id).then(
|
||||||
// (result) {
|
// // (result) {
|
||||||
// setState(() {
|
// // setState(() {
|
||||||
// selectedPatient = result;
|
// // selectedPatient = result;
|
||||||
// Navigator.of(context).pushNamed('/patient-manager/patient',
|
// // Navigator.of(context).pushNamed('/patient-manager/patient',
|
||||||
// arguments: PatientViewArguments(
|
// // arguments: PatientViewArguments(
|
||||||
// widget.signedInUser,
|
// // widget.signedInUser,
|
||||||
// selectedPatient,
|
// // selectedPatient,
|
||||||
// widget.businessUser,
|
// // widget.businessUser,
|
||||||
// widget.business,
|
// // widget.business,
|
||||||
// "business",
|
// // "business",
|
||||||
// ));
|
// // ));
|
||||||
// });
|
// // });
|
||||||
// },
|
// // },
|
||||||
// );
|
// // );
|
||||||
} else if (widget.patientQueue[index].access == "declined") {
|
// } else if (widget.patientQueue[index].access == "declined") {
|
||||||
accessDeclinedWarning();
|
// accessDeclinedWarning();
|
||||||
} else if (widget.patientQueue[index].access == "cancelled") {
|
// } else if (widget.patientQueue[index].access == "cancelled") {
|
||||||
appointmentCancelledWarning();
|
// appointmentCancelledWarning();
|
||||||
} else {
|
// } else {
|
||||||
viewConfirmationPopUp(index);
|
viewConfirmationPopUp(index);
|
||||||
//noAccessWarning();
|
//noAccessWarning();
|
||||||
}
|
// }
|
||||||
},
|
},
|
||||||
//leading: getExtendAccessButton(access),
|
//leading: getExtendAccessButton(access),
|
||||||
trailing: getExtendAccessButton(access, index),
|
//trailing: getExtendAccessButton(access, index),
|
||||||
// Icon(
|
// Icon(
|
||||||
// Icons.arrow_forward,
|
// Icons.arrow_forward,
|
||||||
// color: MzanziInnovationHub.of(context)!.theme.secondaryColor(),
|
// color: MzanziInnovationHub.of(context)!.theme.secondaryColor(),
|
||||||
@@ -646,130 +652,130 @@ class _BuildPatientsListState extends State<BuildPatientQueueList> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget getExtendAccessButton(String accessType, int index) {
|
// Widget getExtendAccessButton(String accessType, int index) {
|
||||||
if (isAccessExpired(accessType)) {
|
// if (isAccessExpired(accessType)) {
|
||||||
return IconButton(
|
// return IconButton(
|
||||||
icon: const Icon(Icons.cached),
|
// icon: const Icon(Icons.cached),
|
||||||
onPressed: () {
|
// onPressed: () {
|
||||||
setState(() {
|
// setState(() {
|
||||||
daysExtensionController.text = counter.toString();
|
// daysExtensionController.text = counter.toString();
|
||||||
});
|
// });
|
||||||
reapplyForAccess(index);
|
// reapplyForAccess(index);
|
||||||
},
|
// },
|
||||||
);
|
// );
|
||||||
} else {
|
// } else {
|
||||||
return Icon(
|
// return Icon(
|
||||||
Icons.arrow_forward,
|
// Icons.arrow_forward,
|
||||||
color: MzanziInnovationHub.of(context)!.theme.secondaryColor(),
|
// color: MzanziInnovationHub.of(context)!.theme.secondaryColor(),
|
||||||
);
|
// );
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
void reapplyForAccess(int index) {
|
// void reapplyForAccess(int index) {
|
||||||
showDialog(
|
// showDialog(
|
||||||
context: context,
|
// context: context,
|
||||||
barrierDismissible: false,
|
// barrierDismissible: false,
|
||||||
builder: (context) => MIHWindow(
|
// builder: (context) => MIHWindow(
|
||||||
fullscreen: false,
|
// fullscreen: false,
|
||||||
windowTitle: "Extend Access",
|
// windowTitle: "Extend Access",
|
||||||
windowTools: const [],
|
// windowTools: const [],
|
||||||
onWindowTapClose: () {
|
// onWindowTapClose: () {
|
||||||
Navigator.pop(context);
|
// Navigator.pop(context);
|
||||||
},
|
// },
|
||||||
windowBody: [
|
// windowBody: [
|
||||||
Text(
|
// Text(
|
||||||
"Current Expiration Date : ${widget.patientQueue[index].revoke_date.replaceAll("T", " ")}",
|
// "Current Expiration Date : ${widget.patientQueue[index].revoke_date.replaceAll("T", " ")}",
|
||||||
style: TextStyle(
|
// style: TextStyle(
|
||||||
color: MzanziInnovationHub.of(context)!.theme.secondaryColor(),
|
// color: MzanziInnovationHub.of(context)!.theme.secondaryColor(),
|
||||||
fontSize: 15,
|
// fontSize: 15,
|
||||||
fontWeight: FontWeight.normal,
|
// fontWeight: FontWeight.normal,
|
||||||
),
|
// ),
|
||||||
),
|
// ),
|
||||||
const SizedBox(height: 5),
|
// const SizedBox(height: 5),
|
||||||
Text(
|
// Text(
|
||||||
"Select the number of days you would like to extend the access by.",
|
// "Select the number of days you would like to extend the access by.",
|
||||||
style: TextStyle(
|
// style: TextStyle(
|
||||||
color: MzanziInnovationHub.of(context)!.theme.secondaryColor(),
|
// color: MzanziInnovationHub.of(context)!.theme.secondaryColor(),
|
||||||
fontSize: 15,
|
// fontSize: 15,
|
||||||
fontWeight: FontWeight.normal,
|
// fontWeight: FontWeight.normal,
|
||||||
),
|
// ),
|
||||||
),
|
// ),
|
||||||
const SizedBox(height: 5),
|
// const SizedBox(height: 5),
|
||||||
Text(
|
// Text(
|
||||||
"Once you click \"Apply\", an access review request will be triggered to the patient.",
|
// "Once you click \"Apply\", an access review request will be triggered to the patient.",
|
||||||
style: TextStyle(
|
// style: TextStyle(
|
||||||
color: MzanziInnovationHub.of(context)!.theme.secondaryColor(),
|
// color: MzanziInnovationHub.of(context)!.theme.secondaryColor(),
|
||||||
fontSize: 15,
|
// fontSize: 15,
|
||||||
fontWeight: FontWeight.normal,
|
// fontWeight: FontWeight.normal,
|
||||||
),
|
// ),
|
||||||
),
|
// ),
|
||||||
const SizedBox(height: 30),
|
// const SizedBox(height: 30),
|
||||||
Row(
|
// Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
// mainAxisAlignment: MainAxisAlignment.center,
|
||||||
children: [
|
// children: [
|
||||||
IconButton.filled(
|
// IconButton.filled(
|
||||||
onPressed: () {
|
// onPressed: () {
|
||||||
if (counter > 0) {
|
// if (counter > 0) {
|
||||||
counter--;
|
// counter--;
|
||||||
setState(() {
|
// setState(() {
|
||||||
daysExtensionController.text = counter.toString();
|
// daysExtensionController.text = counter.toString();
|
||||||
});
|
// });
|
||||||
}
|
// }
|
||||||
},
|
// },
|
||||||
icon: const Icon(Icons.remove),
|
// icon: const Icon(Icons.remove),
|
||||||
),
|
// ),
|
||||||
const SizedBox(width: 15),
|
// const SizedBox(width: 15),
|
||||||
SizedBox(
|
// SizedBox(
|
||||||
width: 100,
|
// width: 100,
|
||||||
child: MIHTextField(
|
// child: MIHTextField(
|
||||||
controller: daysExtensionController,
|
// controller: daysExtensionController,
|
||||||
hintText: "Days",
|
// hintText: "Days",
|
||||||
editable: false,
|
// editable: false,
|
||||||
required: true,
|
// required: true,
|
||||||
),
|
// ),
|
||||||
),
|
// ),
|
||||||
const SizedBox(width: 15),
|
// const SizedBox(width: 15),
|
||||||
IconButton.filled(
|
// IconButton.filled(
|
||||||
onPressed: () {
|
// onPressed: () {
|
||||||
counter++;
|
// counter++;
|
||||||
setState(() {
|
// setState(() {
|
||||||
daysExtensionController.text = counter.toString();
|
// daysExtensionController.text = counter.toString();
|
||||||
});
|
// });
|
||||||
},
|
// },
|
||||||
icon: const Icon(Icons.add),
|
// icon: const Icon(Icons.add),
|
||||||
),
|
// ),
|
||||||
],
|
// ],
|
||||||
),
|
// ),
|
||||||
const SizedBox(height: 30),
|
// const SizedBox(height: 30),
|
||||||
SizedBox(
|
// SizedBox(
|
||||||
width: 300,
|
// width: 300,
|
||||||
height: 50,
|
// height: 50,
|
||||||
child: MIHButton(
|
// child: MIHButton(
|
||||||
onTap: () {
|
// onTap: () {
|
||||||
print(
|
// print(
|
||||||
"Revoke Date (String): ${widget.patientQueue[index].revoke_date}");
|
// "Revoke Date (String): ${widget.patientQueue[index].revoke_date}");
|
||||||
var revokeDate = DateTime.parse(widget
|
// var revokeDate = DateTime.parse(widget
|
||||||
.patientQueue[index].revoke_date
|
// .patientQueue[index].revoke_date
|
||||||
.replaceAll("T", " "));
|
// .replaceAll("T", " "));
|
||||||
var newRevokeDate = revokeDate.add(
|
// var newRevokeDate = revokeDate.add(
|
||||||
Duration(days: int.parse(daysExtensionController.text)));
|
// Duration(days: int.parse(daysExtensionController.text)));
|
||||||
print("Revoke Date (DateTime): $revokeDate");
|
// print("Revoke Date (DateTime): $revokeDate");
|
||||||
print("New Revoke Date (DateTime): $newRevokeDate");
|
// print("New Revoke Date (DateTime): $newRevokeDate");
|
||||||
print(
|
// print(
|
||||||
"${widget.business!.Name} would like to extend the access expirey date for your appointment on the ${widget.patientQueue[index].date_time}.\nNew Expirey Date: $revokeDate",
|
// "${widget.business!.Name} would like to extend the access expirey date for your appointment on the ${widget.patientQueue[index].date_time}.\nNew Expirey Date: $revokeDate",
|
||||||
);
|
// );
|
||||||
extendAccessAPICall(index, "$newRevokeDate");
|
// extendAccessAPICall(index, "$newRevokeDate");
|
||||||
},
|
// },
|
||||||
buttonText: "Apply",
|
// buttonText: "Apply",
|
||||||
buttonColor:
|
// buttonColor:
|
||||||
MzanziInnovationHub.of(context)!.theme.secondaryColor(),
|
// MzanziInnovationHub.of(context)!.theme.secondaryColor(),
|
||||||
textColor: MzanziInnovationHub.of(context)!.theme.primaryColor(),
|
// textColor: MzanziInnovationHub.of(context)!.theme.primaryColor(),
|
||||||
),
|
// ),
|
||||||
),
|
// ),
|
||||||
],
|
// ],
|
||||||
),
|
// ),
|
||||||
);
|
// );
|
||||||
}
|
// }
|
||||||
|
|
||||||
void noAccessWarning() {
|
void noAccessWarning() {
|
||||||
showDialog(
|
showDialog(
|
||||||
|
|||||||
@@ -1,21 +1,21 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'dart:convert';
|
|
||||||
import 'package:intl/intl.dart';
|
import 'package:intl/intl.dart';
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
|
import 'package:patient_manager/mih_apis/mih_api_calls.dart';
|
||||||
import 'package:patient_manager/mih_components/mih_layout/mih_action.dart';
|
import 'package:patient_manager/mih_components/mih_layout/mih_action.dart';
|
||||||
import 'package:patient_manager/mih_components/mih_layout/mih_body.dart';
|
import 'package:patient_manager/mih_components/mih_layout/mih_body.dart';
|
||||||
import 'package:patient_manager/mih_components/mih_layout/mih_header.dart';
|
import 'package:patient_manager/mih_components/mih_layout/mih_header.dart';
|
||||||
import 'package:patient_manager/mih_components/mih_layout/mih_layout_builder.dart';
|
import 'package:patient_manager/mih_components/mih_layout/mih_layout_builder.dart';
|
||||||
|
import 'package:patient_manager/mih_objects/patient_access.dart';
|
||||||
|
import 'package:patient_manager/mih_packages/patient_profile/builder/build_patient_access_list.dart';
|
||||||
import 'package:patient_manager/mih_packages/patient_profile/builder/build_patient_list.dart';
|
import 'package:patient_manager/mih_packages/patient_profile/builder/build_patient_list.dart';
|
||||||
import 'package:patient_manager/mih_packages/patient_profile/builder/build_patient_queue_list.dart';
|
import 'package:patient_manager/mih_packages/patient_profile/builder/build_patient_queue_list.dart';
|
||||||
import 'package:patient_manager/mih_components/mih_pop_up_messages/mih_loading_circle.dart';
|
import 'package:patient_manager/mih_components/mih_pop_up_messages/mih_loading_circle.dart';
|
||||||
import 'package:patient_manager/mih_components/mih_inputs_and_buttons/mih_date_input.dart';
|
import 'package:patient_manager/mih_components/mih_inputs_and_buttons/mih_date_input.dart';
|
||||||
import 'package:patient_manager/mih_components/mih_pop_up_messages/mih_error_message.dart';
|
|
||||||
import 'package:patient_manager/mih_objects/arguments.dart';
|
import 'package:patient_manager/mih_objects/arguments.dart';
|
||||||
import 'package:patient_manager/mih_objects/patient_queue.dart';
|
import 'package:patient_manager/mih_objects/patient_queue.dart';
|
||||||
import 'package:supertokens_flutter/http.dart' as http;
|
|
||||||
import 'package:patient_manager/mih_components/mih_inputs_and_buttons/mih_search_input.dart';
|
import 'package:patient_manager/mih_components/mih_inputs_and_buttons/mih_search_input.dart';
|
||||||
import 'package:patient_manager/mih_env/env.dart';
|
import 'package:patient_manager/mih_env/env.dart';
|
||||||
import 'package:patient_manager/main.dart';
|
import 'package:patient_manager/main.dart';
|
||||||
@@ -36,15 +36,15 @@ class PatientManager extends StatefulWidget {
|
|||||||
//
|
//
|
||||||
class _PatientManagerState extends State<PatientManager> {
|
class _PatientManagerState extends State<PatientManager> {
|
||||||
TextEditingController searchController = TextEditingController();
|
TextEditingController searchController = TextEditingController();
|
||||||
|
TextEditingController accessSearchController = TextEditingController();
|
||||||
TextEditingController queueDateController = TextEditingController();
|
TextEditingController queueDateController = TextEditingController();
|
||||||
|
|
||||||
String baseUrl = AppEnviroment.baseApiUrl;
|
String baseUrl = AppEnviroment.baseApiUrl;
|
||||||
|
|
||||||
final FocusNode _focusNode = FocusNode();
|
final FocusNode _focusNode = FocusNode();
|
||||||
String errorCode = "";
|
|
||||||
String errorBody = "";
|
|
||||||
|
|
||||||
String searchString = "";
|
String searchString = "";
|
||||||
|
String accessSearchString = "";
|
||||||
var now = DateTime.now();
|
var now = DateTime.now();
|
||||||
var formatter = DateFormat('yyyy-MM-dd');
|
var formatter = DateFormat('yyyy-MM-dd');
|
||||||
late String formattedDate;
|
late String formattedDate;
|
||||||
@@ -52,32 +52,10 @@ class _PatientManagerState extends State<PatientManager> {
|
|||||||
int _selectedIndex = 0;
|
int _selectedIndex = 0;
|
||||||
|
|
||||||
late Future<List<Patient>> patientSearchResults;
|
late Future<List<Patient>> patientSearchResults;
|
||||||
|
late Future<List<PatientAccess>> patientAccessResults;
|
||||||
late Future<List<PatientQueue>> patientQueueResults;
|
late Future<List<PatientQueue>> patientQueueResults;
|
||||||
|
|
||||||
Future<List<PatientQueue>> fetchPatientQueue(String date) async {
|
//Waiting Room Widgets/ Functions
|
||||||
//print("Patien manager page: $endpoint");
|
|
||||||
final response = await http.get(Uri.parse(
|
|
||||||
"$baseUrl/queue/patients/${widget.arguments.businessUser!.business_id}"));
|
|
||||||
// print("Here");
|
|
||||||
// print("Body: ${response.body}");
|
|
||||||
// print("Code: ${response.statusCode}");
|
|
||||||
errorCode = response.statusCode.toString();
|
|
||||||
errorBody = response.body;
|
|
||||||
|
|
||||||
if (response.statusCode == 200) {
|
|
||||||
//print("Here1");
|
|
||||||
Iterable l = jsonDecode(response.body);
|
|
||||||
//print("Here2");
|
|
||||||
List<PatientQueue> patientQueue = List<PatientQueue>.from(
|
|
||||||
l.map((model) => PatientQueue.fromJson(model)));
|
|
||||||
//print("Here3");
|
|
||||||
//print(patientQueue);
|
|
||||||
return patientQueue;
|
|
||||||
} else {
|
|
||||||
throw Exception('failed to load patients');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
List<PatientQueue> filterQueueResults(
|
List<PatientQueue> filterQueueResults(
|
||||||
List<PatientQueue> queueList, String query) {
|
List<PatientQueue> queueList, String query) {
|
||||||
List<PatientQueue> templist = [];
|
List<PatientQueue> templist = [];
|
||||||
@@ -92,121 +70,6 @@ class _PatientManagerState extends State<PatientManager> {
|
|||||||
return templist;
|
return templist;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<List<Patient>> fetchPatients(String search) async {
|
|
||||||
final response =
|
|
||||||
await http.get(Uri.parse("$baseUrl/patients/search/$search"));
|
|
||||||
errorCode = response.statusCode.toString();
|
|
||||||
errorBody = response.body;
|
|
||||||
|
|
||||||
if (response.statusCode == 200) {
|
|
||||||
Iterable l = jsonDecode(response.body);
|
|
||||||
List<Patient> patients =
|
|
||||||
List<Patient>.from(l.map((model) => Patient.fromJson(model)));
|
|
||||||
return patients;
|
|
||||||
} else {
|
|
||||||
throw Exception('failed to load patients');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
List<Patient> filterSearchResults(List<Patient> patList, String query) {
|
|
||||||
List<Patient> templist = [];
|
|
||||||
//print(query);
|
|
||||||
for (var item in patList) {
|
|
||||||
if (item.id_no.contains(searchString) ||
|
|
||||||
item.medical_aid_no.contains(searchString)) {
|
|
||||||
//print(item.medical_aid_no);
|
|
||||||
templist.add(item);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return templist;
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget displayPatientList(List<Patient> patientsList, String searchString) {
|
|
||||||
if (searchString.isNotEmpty && searchString != "") {
|
|
||||||
return BuildPatientsList(
|
|
||||||
patients: patientsList,
|
|
||||||
signedInUser: widget.arguments.signedInUser,
|
|
||||||
business: widget.arguments.business,
|
|
||||||
arguments: widget.arguments,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return Center(
|
|
||||||
child: Text(
|
|
||||||
"Enter ID or Medical Aid No. of Patient",
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 25,
|
|
||||||
color: MzanziInnovationHub.of(context)!.theme.messageTextColor()),
|
|
||||||
textAlign: TextAlign.center,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget patientSearch() {
|
|
||||||
return KeyboardListener(
|
|
||||||
focusNode: _focusNode,
|
|
||||||
autofocus: true,
|
|
||||||
onKeyEvent: (event) async {
|
|
||||||
if (event is KeyDownEvent &&
|
|
||||||
event.logicalKey == LogicalKeyboardKey.enter) {
|
|
||||||
submitPatientForm();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
child: Column(mainAxisSize: MainAxisSize.max, children: [
|
|
||||||
const Text(
|
|
||||||
"Patient Search",
|
|
||||||
style: TextStyle(fontSize: 25, fontWeight: FontWeight.bold),
|
|
||||||
),
|
|
||||||
Divider(color: MzanziInnovationHub.of(context)!.theme.secondaryColor()),
|
|
||||||
|
|
||||||
//spacer
|
|
||||||
const SizedBox(height: 10),
|
|
||||||
MIHSearchField(
|
|
||||||
controller: searchController,
|
|
||||||
hintText: "ID or Medical Aid No. Search",
|
|
||||||
required: true,
|
|
||||||
editable: true,
|
|
||||||
onTap: () {
|
|
||||||
submitPatientForm();
|
|
||||||
},
|
|
||||||
),
|
|
||||||
//spacer
|
|
||||||
const SizedBox(height: 10),
|
|
||||||
FutureBuilder(
|
|
||||||
future: patientSearchResults,
|
|
||||||
builder: (context, snapshot) {
|
|
||||||
//print("patient Liust ${snapshot.data}");
|
|
||||||
if (snapshot.connectionState == ConnectionState.waiting) {
|
|
||||||
return const Mihloadingcircle();
|
|
||||||
} else if (snapshot.connectionState == ConnectionState.done &&
|
|
||||||
snapshot.hasData) {
|
|
||||||
List<Patient> patientsList;
|
|
||||||
if (searchString == "") {
|
|
||||||
patientsList = [];
|
|
||||||
} else {
|
|
||||||
patientsList =
|
|
||||||
filterSearchResults(snapshot.data!, searchString);
|
|
||||||
//print(patientsList);
|
|
||||||
}
|
|
||||||
|
|
||||||
return displayPatientList(patientsList, searchString);
|
|
||||||
} else {
|
|
||||||
return Center(
|
|
||||||
child: Text(
|
|
||||||
"$errorCode: Error pulling Patients Data\n$baseUrl/patients/search/$searchString\n$errorBody",
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 25,
|
|
||||||
color:
|
|
||||||
MzanziInnovationHub.of(context)!.theme.errorColor()),
|
|
||||||
textAlign: TextAlign.center,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
),
|
|
||||||
]),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget displayQueueList(List<PatientQueue> patientQueueList) {
|
Widget displayQueueList(List<PatientQueue> patientQueueList) {
|
||||||
if (patientQueueList.isNotEmpty) {
|
if (patientQueueList.isNotEmpty) {
|
||||||
return BuildPatientQueueList(
|
return BuildPatientQueueList(
|
||||||
@@ -238,13 +101,13 @@ class _PatientManagerState extends State<PatientManager> {
|
|||||||
style: TextStyle(fontSize: 25, fontWeight: FontWeight.bold),
|
style: TextStyle(fontSize: 25, fontWeight: FontWeight.bold),
|
||||||
),
|
),
|
||||||
IconButton(
|
IconButton(
|
||||||
|
iconSize: 25,
|
||||||
|
icon: const Icon(
|
||||||
|
Icons.refresh,
|
||||||
|
),
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
refreshQueue();
|
refreshQueue();
|
||||||
},
|
},
|
||||||
icon: const Icon(
|
|
||||||
Icons.refresh,
|
|
||||||
size: 25,
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
@@ -277,7 +140,7 @@ class _PatientManagerState extends State<PatientManager> {
|
|||||||
} else {
|
} else {
|
||||||
return Center(
|
return Center(
|
||||||
child: Text(
|
child: Text(
|
||||||
"$errorCode: Error pulling Patients Data\n$baseUrl/patients/search/$searchString\n$errorBody",
|
"Error pulling Patients Data\n$baseUrl/patients/search/$searchString",
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontSize: 25,
|
fontSize: 25,
|
||||||
color: MzanziInnovationHub.of(context)!.theme.errorColor()),
|
color: MzanziInnovationHub.of(context)!.theme.errorColor()),
|
||||||
@@ -297,43 +160,324 @@ class _PatientManagerState extends State<PatientManager> {
|
|||||||
checkforchange();
|
checkforchange();
|
||||||
}
|
}
|
||||||
|
|
||||||
void submitPatientForm() {
|
|
||||||
if (searchController.text != "") {
|
|
||||||
setState(() {
|
|
||||||
searchString = searchController.text;
|
|
||||||
patientSearchResults = fetchPatients(searchString);
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
showDialog(
|
|
||||||
context: context,
|
|
||||||
builder: (context) {
|
|
||||||
return const MIHErrorMessage(errorType: "Input Error");
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void checkforchange() {
|
void checkforchange() {
|
||||||
if (start == true) {
|
if (start == true) {
|
||||||
setState(() {
|
setState(() {
|
||||||
patientQueueResults = fetchPatientQueue(queueDateController.text);
|
patientQueueResults = MIHApiCalls.fetchPatientQueue(
|
||||||
|
queueDateController.text, widget.arguments.business!.business_id);
|
||||||
start = false;
|
start = false;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (formattedDate != queueDateController.text) {
|
if (formattedDate != queueDateController.text) {
|
||||||
setState(() {
|
setState(() {
|
||||||
patientQueueResults = fetchPatientQueue(queueDateController.text);
|
patientQueueResults = MIHApiCalls.fetchPatientQueue(
|
||||||
|
queueDateController.text, widget.arguments.business!.business_id);
|
||||||
formattedDate = queueDateController.text;
|
formattedDate = queueDateController.text;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Patient Lookup Widgets/ Functions
|
||||||
|
|
||||||
|
List<Patient> filterSearchResults(List<Patient> patList, String query) {
|
||||||
|
List<Patient> templist = [];
|
||||||
|
//print(query);
|
||||||
|
for (var item in patList) {
|
||||||
|
if (item.id_no.contains(searchString) ||
|
||||||
|
item.medical_aid_no.contains(searchString)) {
|
||||||
|
//print(item.medical_aid_no);
|
||||||
|
templist.add(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return templist;
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget displayPatientList(List<Patient> patientsList, String searchString) {
|
||||||
|
if (patientsList.isNotEmpty) {
|
||||||
|
return BuildPatientsList(
|
||||||
|
patients: patientsList,
|
||||||
|
signedInUser: widget.arguments.signedInUser,
|
||||||
|
business: widget.arguments.business,
|
||||||
|
arguments: widget.arguments,
|
||||||
|
);
|
||||||
|
} else if (patientsList.isEmpty && searchString != "") {
|
||||||
|
return 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 Center(
|
||||||
|
child: Text(
|
||||||
|
"Enter ID or Medical Aid No. of Patient",
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 25,
|
||||||
|
color: MzanziInnovationHub.of(context)!.theme.messageTextColor()),
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget patientSearch() {
|
||||||
|
return KeyboardListener(
|
||||||
|
focusNode: _focusNode,
|
||||||
|
autofocus: true,
|
||||||
|
onKeyEvent: (event) async {
|
||||||
|
if (event is KeyDownEvent &&
|
||||||
|
event.logicalKey == LogicalKeyboardKey.enter) {
|
||||||
|
submitPatientForm();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
child: Column(mainAxisSize: MainAxisSize.max, children: [
|
||||||
|
const Text(
|
||||||
|
"Patient Lookup",
|
||||||
|
style: TextStyle(fontSize: 25, fontWeight: FontWeight.bold),
|
||||||
|
),
|
||||||
|
Divider(color: MzanziInnovationHub.of(context)!.theme.secondaryColor()),
|
||||||
|
|
||||||
|
//spacer
|
||||||
|
const SizedBox(height: 10),
|
||||||
|
Row(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
Flexible(
|
||||||
|
flex: 1,
|
||||||
|
child: MIHSearchField(
|
||||||
|
controller: searchController,
|
||||||
|
hintText: "ID or Medical Aid No. Search",
|
||||||
|
required: false,
|
||||||
|
editable: true,
|
||||||
|
onTap: () {
|
||||||
|
submitPatientForm();
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
IconButton(
|
||||||
|
onPressed: () {
|
||||||
|
setState(() {
|
||||||
|
searchController.clear();
|
||||||
|
searchString = "";
|
||||||
|
});
|
||||||
|
submitPatientForm();
|
||||||
|
},
|
||||||
|
icon: const Icon(
|
||||||
|
Icons.filter_alt_off,
|
||||||
|
size: 25,
|
||||||
|
))
|
||||||
|
],
|
||||||
|
),
|
||||||
|
//spacer
|
||||||
|
const SizedBox(height: 10),
|
||||||
|
FutureBuilder(
|
||||||
|
future: patientSearchResults,
|
||||||
|
builder: (context, snapshot) {
|
||||||
|
//print("patient Liust ${snapshot.data}");
|
||||||
|
if (snapshot.connectionState == ConnectionState.waiting) {
|
||||||
|
return const Mihloadingcircle();
|
||||||
|
} else if (snapshot.connectionState == ConnectionState.done &&
|
||||||
|
snapshot.hasData) {
|
||||||
|
List<Patient> patientsList;
|
||||||
|
if (searchString == "") {
|
||||||
|
patientsList = [];
|
||||||
|
} else {
|
||||||
|
patientsList =
|
||||||
|
filterSearchResults(snapshot.data!, searchString);
|
||||||
|
//print(patientsList);
|
||||||
|
}
|
||||||
|
|
||||||
|
return displayPatientList(patientsList, searchString);
|
||||||
|
} else {
|
||||||
|
return Center(
|
||||||
|
child: Text(
|
||||||
|
"Error pulling Patients Data\n$baseUrl/patients/search/$searchString",
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 25,
|
||||||
|
color:
|
||||||
|
MzanziInnovationHub.of(context)!.theme.errorColor()),
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
),
|
||||||
|
]),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void submitPatientForm() {
|
||||||
|
if (searchController.text != "") {
|
||||||
|
setState(() {
|
||||||
|
searchString = searchController.text;
|
||||||
|
patientSearchResults = MIHApiCalls.fetchPatients(searchString);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// else {
|
||||||
|
// showDialog(
|
||||||
|
// context: context,
|
||||||
|
// builder: (context) {
|
||||||
|
// return const MIHErrorMessage(errorType: "Input Error");
|
||||||
|
// },
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
//Patient Access Widgets/ Functions
|
||||||
|
|
||||||
|
List<PatientAccess> filterAccessResults(
|
||||||
|
List<PatientAccess> patAccList, String query) {
|
||||||
|
List<PatientAccess> templist = [];
|
||||||
|
//print(query);
|
||||||
|
for (var item in patAccList) {
|
||||||
|
if (item.id_no.contains(query)) {
|
||||||
|
//print(item.medical_aid_no);
|
||||||
|
templist.add(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return templist;
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget displayPatientAccessList(List<PatientAccess> patientsAccessList) {
|
||||||
|
if (patientsAccessList.isNotEmpty) {
|
||||||
|
return BuildPatientAccessList(
|
||||||
|
patientAccesses: patientsAccessList,
|
||||||
|
signedInUser: widget.arguments.signedInUser,
|
||||||
|
business: widget.arguments.business,
|
||||||
|
arguments: widget.arguments,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return Center(
|
||||||
|
child: Text(
|
||||||
|
"No Patients matching search",
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 25,
|
||||||
|
color: MzanziInnovationHub.of(context)!.theme.messageTextColor()),
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget patientAccessSearch() {
|
||||||
|
return KeyboardListener(
|
||||||
|
focusNode: _focusNode,
|
||||||
|
autofocus: true,
|
||||||
|
onKeyEvent: (event) async {
|
||||||
|
if (event is KeyDownEvent &&
|
||||||
|
event.logicalKey == LogicalKeyboardKey.enter) {
|
||||||
|
submitPatientAccessForm();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
child: Column(mainAxisSize: MainAxisSize.max, children: [
|
||||||
|
const Text(
|
||||||
|
"My Patient List",
|
||||||
|
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: accessSearchController,
|
||||||
|
hintText: "ID Search",
|
||||||
|
required: false,
|
||||||
|
editable: true,
|
||||||
|
onTap: () {
|
||||||
|
submitPatientAccessForm();
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
IconButton(
|
||||||
|
onPressed: () {
|
||||||
|
setState(() {
|
||||||
|
accessSearchController.clear();
|
||||||
|
accessSearchString = "";
|
||||||
|
});
|
||||||
|
submitPatientAccessForm();
|
||||||
|
},
|
||||||
|
icon: const Icon(
|
||||||
|
Icons.filter_alt_off,
|
||||||
|
size: 25,
|
||||||
|
))
|
||||||
|
],
|
||||||
|
),
|
||||||
|
|
||||||
|
//spacer
|
||||||
|
const SizedBox(height: 10),
|
||||||
|
FutureBuilder(
|
||||||
|
future: patientAccessResults,
|
||||||
|
builder: (context, snapshot) {
|
||||||
|
//print("patient Liust ${snapshot.data}");
|
||||||
|
if (snapshot.connectionState == ConnectionState.waiting) {
|
||||||
|
return const Mihloadingcircle();
|
||||||
|
} else if (snapshot.connectionState == ConnectionState.done &&
|
||||||
|
snapshot.hasData) {
|
||||||
|
List<PatientAccess> patientsAccessList;
|
||||||
|
if (accessSearchString == "") {
|
||||||
|
patientsAccessList = snapshot.data!;
|
||||||
|
} else {
|
||||||
|
patientsAccessList =
|
||||||
|
filterAccessResults(snapshot.data!, accessSearchString);
|
||||||
|
//print(patientsList);
|
||||||
|
}
|
||||||
|
|
||||||
|
return displayPatientAccessList(patientsAccessList);
|
||||||
|
} else {
|
||||||
|
return Center(
|
||||||
|
child: Text(
|
||||||
|
"Error pulling Patient Access Data\n$baseUrl/access-requests/business/patient/${widget.arguments.business!.business_id}",
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 25,
|
||||||
|
color:
|
||||||
|
MzanziInnovationHub.of(context)!.theme.errorColor()),
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
),
|
||||||
|
]),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void submitPatientAccessForm() {
|
||||||
|
// if (searchController.text != "") {
|
||||||
|
setState(() {
|
||||||
|
accessSearchString = accessSearchController.text;
|
||||||
|
patientAccessResults = MIHApiCalls.getPatientAccessListOfBusiness(
|
||||||
|
widget.arguments.business!.business_id);
|
||||||
|
});
|
||||||
|
// } else {
|
||||||
|
// showDialog(
|
||||||
|
// context: context,
|
||||||
|
// builder: (context) {
|
||||||
|
// return const MIHErrorMessage(errorType: "Input Error");
|
||||||
|
// },
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
//Layout Widgets/ Functions
|
||||||
|
|
||||||
Widget showSelection(int index) {
|
Widget showSelection(int index) {
|
||||||
if (index == 0) {
|
if (index == 0) {
|
||||||
return SizedBox(
|
return SizedBox(
|
||||||
//width: 660,
|
//width: 660,
|
||||||
child: patientQueue(),
|
child: patientQueue(),
|
||||||
);
|
);
|
||||||
|
} else if (index == 1) {
|
||||||
|
return SizedBox(
|
||||||
|
//width: 660,
|
||||||
|
child: patientAccessSearch(),
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
return SizedBox(
|
return SizedBox(
|
||||||
//width: 660,
|
//width: 660,
|
||||||
@@ -377,6 +521,17 @@ class _PatientManagerState extends State<PatientManager> {
|
|||||||
_selectedIndex = 1;
|
_selectedIndex = 1;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
icon: const Icon(
|
||||||
|
Icons.check_box_outlined,
|
||||||
|
size: 35,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
IconButton(
|
||||||
|
onPressed: () {
|
||||||
|
setState(() {
|
||||||
|
_selectedIndex = 2;
|
||||||
|
});
|
||||||
|
},
|
||||||
icon: const Icon(
|
icon: const Icon(
|
||||||
Icons.search,
|
Icons.search,
|
||||||
size: 35,
|
size: 35,
|
||||||
@@ -398,13 +553,17 @@ class _PatientManagerState extends State<PatientManager> {
|
|||||||
@override
|
@override
|
||||||
void dispose() {
|
void dispose() {
|
||||||
searchController.dispose();
|
searchController.dispose();
|
||||||
|
accessSearchController.dispose();
|
||||||
queueDateController.dispose();
|
queueDateController.dispose();
|
||||||
|
_focusNode.dispose();
|
||||||
super.dispose();
|
super.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
patientSearchResults = fetchPatients("abc");
|
patientSearchResults = MIHApiCalls.fetchPatients("abc");
|
||||||
|
patientAccessResults = MIHApiCalls.getPatientAccessListOfBusiness(
|
||||||
|
widget.arguments.business!.business_id);
|
||||||
queueDateController.addListener(checkforchange);
|
queueDateController.addListener(checkforchange);
|
||||||
setState(() {
|
setState(() {
|
||||||
formattedDate = formatter.format(now);
|
formattedDate = formatter.format(now);
|
||||||
@@ -427,75 +586,5 @@ class _PatientManagerState extends State<PatientManager> {
|
|||||||
pullDownToRefresh: false,
|
pullDownToRefresh: false,
|
||||||
onPullDown: () async {},
|
onPullDown: () async {},
|
||||||
);
|
);
|
||||||
// return Scaffold(
|
|
||||||
// // appBar: const MIHAppBar(
|
|
||||||
// // barTitle: "Patient Manager",
|
|
||||||
// // propicFile: null,
|
|
||||||
// // ),
|
|
||||||
// body: Stack(
|
|
||||||
// children: [
|
|
||||||
// Column(
|
|
||||||
// mainAxisAlignment: MainAxisAlignment.start,
|
|
||||||
// crossAxisAlignment: CrossAxisAlignment.center,
|
|
||||||
// children: [
|
|
||||||
// const SizedBox(height: 5),
|
|
||||||
// Row(
|
|
||||||
// crossAxisAlignment: CrossAxisAlignment.end,
|
|
||||||
// mainAxisAlignment: MainAxisAlignment.end,
|
|
||||||
// children: [
|
|
||||||
// IconButton(
|
|
||||||
// onPressed: () {
|
|
||||||
// setState(() {
|
|
||||||
// _selectedIndex = 0;
|
|
||||||
// });
|
|
||||||
// },
|
|
||||||
// icon: const Icon(
|
|
||||||
// Icons.people,
|
|
||||||
// size: 35,
|
|
||||||
// ),
|
|
||||||
// ),
|
|
||||||
// IconButton(
|
|
||||||
// onPressed: () {
|
|
||||||
// setState(() {
|
|
||||||
// _selectedIndex = 1;
|
|
||||||
// });
|
|
||||||
// },
|
|
||||||
// icon: const Icon(
|
|
||||||
// Icons.search,
|
|
||||||
// size: 35,
|
|
||||||
// ),
|
|
||||||
// ),
|
|
||||||
// IconButton(
|
|
||||||
// onPressed: () {
|
|
||||||
// refreshQueue();
|
|
||||||
// },
|
|
||||||
// icon: const Icon(
|
|
||||||
// Icons.refresh,
|
|
||||||
// size: 35,
|
|
||||||
// ),
|
|
||||||
// ),
|
|
||||||
// ],
|
|
||||||
// ),
|
|
||||||
// Padding(
|
|
||||||
// padding: EdgeInsets.symmetric(horizontal: 15),
|
|
||||||
// child: showSelection(_selectedIndex, screenWidth, screenHeight),
|
|
||||||
// ),
|
|
||||||
// ],
|
|
||||||
// ),
|
|
||||||
// Positioned(
|
|
||||||
// top: 5,
|
|
||||||
// left: 5,
|
|
||||||
// width: 50,
|
|
||||||
// height: 50,
|
|
||||||
// child: IconButton(
|
|
||||||
// onPressed: () {
|
|
||||||
// Navigator.of(context).pop();
|
|
||||||
// },
|
|
||||||
// icon: const Icon(Icons.arrow_back),
|
|
||||||
// ),
|
|
||||||
// )
|
|
||||||
// ],
|
|
||||||
// ),
|
|
||||||
// );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -105,17 +105,27 @@ class _PatientViewState extends State<PatientView> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
MIHAction getActionButton() {
|
MIHAction getActionButton() {
|
||||||
return MIHAction(
|
if (widget.arguments.type == "Personal") {
|
||||||
icon: const Icon(Icons.arrow_back),
|
return MIHAction(
|
||||||
iconSize: 35,
|
icon: const Icon(Icons.arrow_back),
|
||||||
onTap: () {
|
iconSize: 35,
|
||||||
Navigator.of(context).pop();
|
onTap: () {
|
||||||
|
Navigator.of(context).pop();
|
||||||
|
|
||||||
Navigator.of(context).popAndPushNamed(
|
Navigator.of(context).popAndPushNamed(
|
||||||
'/',
|
'/',
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
} else {
|
||||||
|
return MIHAction(
|
||||||
|
icon: const Icon(Icons.arrow_back),
|
||||||
|
iconSize: 35,
|
||||||
|
onTap: () {
|
||||||
|
Navigator.of(context).pop();
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MIHHeader getHeader() {
|
MIHHeader getHeader() {
|
||||||
|
|||||||
Reference in New Issue
Block a user