Files
mih-project/Frontend/lib/mih_packages/patient_profile/patient_manager.dart

701 lines
20 KiB
Dart

import 'dart:async';
import 'package:flutter_swipe_detector/flutter_swipe_detector.dart';
import 'package:intl/intl.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import '../../main.dart';
import '../../mih_apis/mih_api_calls.dart';
import '../../mih_components/mih_calendar.dart';
import '../../mih_components/mih_inputs_and_buttons/mih_search_input.dart';
import '../../mih_components/mih_layout/mih_action.dart';
import '../../mih_components/mih_layout/mih_body.dart';
import '../../mih_components/mih_layout/mih_header.dart';
import '../../mih_components/mih_layout/mih_layout_builder.dart';
import '../../mih_components/mih_pop_up_messages/mih_loading_circle.dart';
import '../../mih_env/env.dart';
import '../../mih_objects/arguments.dart';
import '../../mih_objects/patient_access.dart';
import '../../mih_objects/patient_queue.dart';
import '../../mih_objects/patients.dart';
import 'builder/build_patient_access_list.dart';
import 'builder/build_patient_list.dart';
import 'builder/build_patient_queue_list.dart';
class PatientManager extends StatefulWidget {
//final AppUser signedInUser;
final BusinessArguments arguments;
const PatientManager({
super.key,
required this.arguments,
});
@override
State<PatientManager> createState() => _PatientManagerState();
}
//
class _PatientManagerState extends State<PatientManager> {
TextEditingController searchController = TextEditingController();
TextEditingController accessSearchController = TextEditingController();
TextEditingController queueDateController = TextEditingController();
String baseUrl = AppEnviroment.baseApiUrl;
final FocusNode _focusNode = FocusNode();
String searchString = "";
String accessSearchString = "";
var now = DateTime.now();
var formatter = DateFormat('yyyy-MM-dd');
late String formattedDate;
bool start = true;
int _selectedIndex = 0;
late Future<List<Patient>> patientSearchResults;
late Future<List<PatientAccess>> patientAccessResults;
late Future<List<PatientQueue>> patientQueueResults;
//Waiting Room Widgets/ Functions
List<PatientQueue> filterQueueResults(
List<PatientQueue> queueList, String query) {
List<PatientQueue> templist = [];
//print(query);
for (var item in queueList) {
if (item.date_time.contains(query)) {
//print(item.medical_aid_no);
templist.add(item);
}
}
//print(templist);
return templist;
}
Widget displayQueueList(List<PatientQueue> patientQueueList) {
if (patientQueueList.isNotEmpty) {
return BuildPatientQueueList(
patientQueue: patientQueueList,
signedInUser: widget.arguments.signedInUser,
business: widget.arguments.business,
businessUser: widget.arguments.businessUser,
);
}
return Padding(
padding: const EdgeInsets.only(top: 35.0),
child: Center(
child: Text(
"No Appointments for $formattedDate",
style: TextStyle(
fontSize: 25,
color: MzanziInnovationHub.of(context)!.theme.messageTextColor()),
textAlign: TextAlign.center,
),
),
);
}
Widget patientQueue() {
return Column(mainAxisSize: MainAxisSize.max, children: [
//const SizedBox(height: 15),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const Text(
"Waiting Room",
style: TextStyle(fontSize: 25, fontWeight: FontWeight.bold),
),
IconButton(
iconSize: 20,
icon: const Icon(
Icons.refresh,
),
onPressed: () {
refreshQueue();
},
),
],
),
Divider(color: MzanziInnovationHub.of(context)!.theme.secondaryColor()),
MIHCalendar(
calendarWidth: 500,
rowHeight: 35,
setDate: (value) {
setState(() {
queueDateController.text = value;
});
}),
//spacer
FutureBuilder(
future: patientQueueResults,
builder: (context, snapshot) {
//print("patient Queue List ${snapshot.hasData}");
if (snapshot.connectionState == ConnectionState.waiting) {
return const Mihloadingcircle();
} else if (snapshot.connectionState == ConnectionState.done) {
List<PatientQueue> patientQueueList;
// if (searchString == "") {
// patientQueueList = [];
// } else {
patientQueueList = filterQueueResults(
snapshot.requireData, queueDateController.text);
// print(patientQueueList);
// }
return displayQueueList(patientQueueList);
} else {
return Center(
child: Text(
"Error pulling Patients Data\n$baseUrl/patients/search/$searchString",
style: TextStyle(
fontSize: 25,
color: MzanziInnovationHub.of(context)!.theme.errorColor()),
textAlign: TextAlign.center,
),
);
}
},
),
]);
}
void refreshQueue() {
setState(() {
start = true;
});
checkforchange();
}
void refreshAccessList() {
setState(() {
patientAccessResults = MIHApiCalls.getPatientAccessListOfBusiness(
widget.arguments.business!.business_id);
});
}
void checkforchange() {
if (start == true) {
setState(() {
patientQueueResults = MIHApiCalls.fetchBusinessAppointmentsAPICall(
queueDateController.text, widget.arguments.business!.business_id);
start = false;
});
}
if (formattedDate != queueDateController.text) {
setState(() {
patientQueueResults = MIHApiCalls.fetchBusinessAppointmentsAPICall(
queueDateController.text, widget.arguments.business!.business_id);
formattedDate = queueDateController.text;
});
}
}
//Patient Lookup Widgets/ Functions
List<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 Padding(
padding: const EdgeInsets.only(top: 35.0),
child: Center(
child: Text(
"No ID or Medical Aid No. matches a Patient",
style: TextStyle(
fontSize: 25,
color:
MzanziInnovationHub.of(context)!.theme.messageTextColor()),
textAlign: TextAlign.center,
),
),
);
} else {
return Padding(
padding: const EdgeInsets.only(top: 35.0),
child: Center(
child: Text(
"Enter ID or Medical Aid No. of Patient",
style: TextStyle(
fontSize: 25,
color:
MzanziInnovationHub.of(context)!.theme.messageTextColor()),
textAlign: TextAlign.center,
),
),
);
}
}
Widget patientSearch() {
return KeyboardListener(
focusNode: _focusNode,
autofocus: true,
onKeyEvent: (event) async {
if (event is KeyDownEvent &&
event.logicalKey == LogicalKeyboardKey.enter) {
submitPatientForm();
}
},
child: Column(mainAxisSize: MainAxisSize.max, children: [
const Text(
"Patient Lookup",
style: TextStyle(fontSize: 25, fontWeight: FontWeight.bold),
),
Divider(color: MzanziInnovationHub.of(context)!.theme.secondaryColor()),
//spacer
const SizedBox(height: 10),
Row(
mainAxisSize: MainAxisSize.min,
children: [
Flexible(
flex: 1,
child: MIHSearchField(
controller: searchController,
hintText: "ID or Medical Aid No. Search",
required: false,
editable: true,
onTap: () {
submitPatientForm();
},
),
),
IconButton(
onPressed: () {
setState(() {
searchController.clear();
searchString = "";
});
submitPatientForm();
},
icon: const Icon(
Icons.filter_alt_off,
size: 25,
))
],
),
//spacer
const SizedBox(height: 10),
FutureBuilder(
future: patientSearchResults,
builder: (context, snapshot) {
//print("patient Liust ${snapshot.data}");
if (snapshot.connectionState == ConnectionState.waiting) {
return const Mihloadingcircle();
} else if (snapshot.connectionState == ConnectionState.done &&
snapshot.hasData) {
List<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 Padding(
padding: const EdgeInsets.only(top: 35.0),
child: Center(
child: Text(
"No Patients matching search",
style: TextStyle(
fontSize: 25,
color: MzanziInnovationHub.of(context)!.theme.messageTextColor()),
textAlign: TextAlign.center,
),
),
);
}
Widget patientAccessSearch() {
return KeyboardListener(
focusNode: _focusNode,
autofocus: true,
onKeyEvent: (event) async {
if (event is KeyDownEvent &&
event.logicalKey == LogicalKeyboardKey.enter) {
submitPatientAccessForm();
}
},
child: Column(mainAxisSize: MainAxisSize.max, children: [
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const Text(
"My Patient List",
style: TextStyle(fontSize: 25, fontWeight: FontWeight.bold),
),
IconButton(
iconSize: 20,
icon: const Icon(
Icons.refresh,
),
onPressed: () {
refreshAccessList();
},
),
],
),
Divider(color: MzanziInnovationHub.of(context)!.theme.secondaryColor()),
//spacer
const SizedBox(height: 10),
Row(
mainAxisSize: MainAxisSize.min,
children: [
Flexible(
flex: 1,
child: MIHSearchField(
controller: accessSearchController,
hintText: "ID Search",
required: false,
editable: true,
onTap: () {
submitPatientAccessForm();
},
),
),
IconButton(
onPressed: () {
setState(() {
accessSearchController.clear();
accessSearchString = "";
});
submitPatientAccessForm();
},
icon: const Icon(
Icons.filter_alt_off,
size: 25,
))
],
),
//spacer
const SizedBox(height: 10),
FutureBuilder(
future: patientAccessResults,
builder: (context, snapshot) {
//print("patient Liust ${snapshot.data}");
if (snapshot.connectionState == ConnectionState.waiting) {
return const Mihloadingcircle();
} else if (snapshot.connectionState == ConnectionState.done &&
snapshot.hasData) {
List<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) {
if (index == 0) {
return SizedBox(
//width: 660,
child: patientQueue(),
);
} else if (index == 1) {
return SizedBox(
//width: 660,
child: patientAccessSearch(),
);
} else {
return SizedBox(
//width: 660,
child: patientSearch(),
);
}
}
MIHAction getActionButton() {
return MIHAction(
icon: const Icon(Icons.arrow_back),
iconSize: 35,
onTap: () {
Navigator.of(context).pop();
Navigator.of(context).popAndPushNamed(
'/',
arguments: AuthArguments(false, false),
);
},
);
}
MIHHeader getHeader() {
return MIHHeader(
headerAlignment: MainAxisAlignment.end,
headerItems: [
//============ Waiting Room ================
Visibility(
visible: _selectedIndex != 0,
child: IconButton(
onPressed: () {
setState(() {
_selectedIndex = 0;
});
},
icon: const Icon(
Icons.people,
size: 35,
),
),
),
Visibility(
visible: _selectedIndex == 0,
child: IconButton.filled(
onPressed: () {
setState(() {
_selectedIndex = 0;
});
},
icon: const Icon(
Icons.people,
size: 35,
),
),
),
//============ My Patient List ================
Visibility(
visible: _selectedIndex != 1,
child: IconButton(
onPressed: () {
setState(() {
_selectedIndex = 1;
});
},
icon: const Icon(
Icons.check_box_outlined,
size: 35,
),
),
),
Visibility(
visible: _selectedIndex == 1,
child: IconButton.filled(
onPressed: () {
setState(() {
_selectedIndex = 1;
});
},
icon: const Icon(
Icons.check_box_outlined,
size: 35,
),
),
),
//============ Patient Lookup ================
Visibility(
visible: _selectedIndex != 2,
child: IconButton(
onPressed: () {
setState(() {
_selectedIndex = 2;
});
},
icon: const Icon(
Icons.search,
size: 35,
),
),
),
Visibility(
visible: _selectedIndex == 2,
child: IconButton.filled(
onPressed: () {
setState(() {
_selectedIndex = 2;
});
},
icon: const Icon(
Icons.search,
size: 35,
),
),
),
],
);
}
MIHBody getBody() {
return MIHBody(
borderOn: true,
bodyItems: [
showSelection(_selectedIndex),
],
);
}
@override
void dispose() {
searchController.dispose();
accessSearchController.dispose();
queueDateController.dispose();
_focusNode.dispose();
super.dispose();
}
@override
void initState() {
patientSearchResults = MIHApiCalls.fetchPatients("abc");
patientAccessResults = MIHApiCalls.getPatientAccessListOfBusiness(
widget.arguments.business!.business_id);
queueDateController.addListener(checkforchange);
setState(() {
formattedDate = formatter.format(now);
queueDateController.text = formattedDate;
});
super.initState();
}
@override
Widget build(BuildContext context) {
return SwipeDetector(
onSwipeLeft: (offset) {
if (_selectedIndex < 2) {
setState(() {
_selectedIndex += 1;
});
}
//print("swipe left");
},
onSwipeRight: (offset) {
if (_selectedIndex > 0) {
setState(() {
_selectedIndex -= 1;
});
}
//print("swipe right");
},
child: MIHLayoutBuilder(
actionButton: getActionButton(),
header: getHeader(),
secondaryActionButton: null,
body: getBody(),
actionDrawer: null,
secondaryActionDrawer: null,
bottomNavBar: null,
pullDownToRefresh: false,
onPullDown: () async {},
),
);
}
}