import 'dart:async'; import 'package:flutter_swipe_detector/flutter_swipe_detector.dart'; import 'package:intl/intl.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import '../../main.dart'; import '../../mih_apis/mih_api_calls.dart'; import '../../mih_components/mih_calendar.dart'; import '../../mih_components/mih_inputs_and_buttons/mih_search_input.dart'; import '../../mih_components/mih_layout/mih_action.dart'; import '../../mih_components/mih_layout/mih_body.dart'; import '../../mih_components/mih_layout/mih_header.dart'; import '../../mih_components/mih_layout/mih_layout_builder.dart'; import '../../mih_components/mih_pop_up_messages/mih_loading_circle.dart'; import '../../mih_env/env.dart'; import '../../mih_objects/arguments.dart'; import '../../mih_objects/patient_access.dart'; import '../../mih_objects/patient_queue.dart'; import '../../mih_objects/patients.dart'; import 'builder/build_patient_access_list.dart'; import 'builder/build_patient_list.dart'; import 'builder/build_patient_queue_list.dart'; class PatientManager extends StatefulWidget { //final AppUser signedInUser; final BusinessArguments arguments; const PatientManager({ super.key, required this.arguments, }); @override State createState() => _PatientManagerState(); } // class _PatientManagerState extends State { TextEditingController searchController = TextEditingController(); TextEditingController accessSearchController = TextEditingController(); TextEditingController queueDateController = TextEditingController(); String baseUrl = AppEnviroment.baseApiUrl; final FocusNode _focusNode = FocusNode(); String searchString = ""; String accessSearchString = ""; var now = DateTime.now(); var formatter = DateFormat('yyyy-MM-dd'); late String formattedDate; bool start = true; int _selectedIndex = 0; late Future> patientSearchResults; late Future> patientAccessResults; late Future> patientQueueResults; //Waiting Room Widgets/ Functions List filterQueueResults( List queueList, String query) { List templist = []; //print(query); for (var item in queueList) { if (item.date_time.contains(query)) { //print(item.medical_aid_no); templist.add(item); } } //print(templist); return templist; } Widget displayQueueList(List patientQueueList) { if (patientQueueList.isNotEmpty) { return 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 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 filterSearchResults(List patList, String query) { List templist = []; //print(query); for (var item in patList) { if (item.id_no.contains(searchString) || item.medical_aid_no.contains(searchString)) { //print(item.medical_aid_no); templist.add(item); } } return templist; } Widget displayPatientList(List patientsList, String searchString) { if (patientsList.isNotEmpty) { return BuildPatientsList( patients: patientsList, signedInUser: widget.arguments.signedInUser, business: widget.arguments.business, arguments: widget.arguments, ); } else if (patientsList.isEmpty && searchString != "") { return Padding( padding: const EdgeInsets.only(top: 35.0), child: Center( child: Text( "No ID or Medical Aid No. matches a Patient", style: TextStyle( fontSize: 25, color: MzanziInnovationHub.of(context)!.theme.messageTextColor()), textAlign: TextAlign.center, ), ), ); } else { return Padding( padding: const EdgeInsets.only(top: 35.0), child: Center( child: Text( "Enter ID or Medical Aid No. of Patient", style: TextStyle( fontSize: 25, color: MzanziInnovationHub.of(context)!.theme.messageTextColor()), textAlign: TextAlign.center, ), ), ); } } Widget patientSearch() { return KeyboardListener( focusNode: _focusNode, autofocus: true, onKeyEvent: (event) async { if (event is KeyDownEvent && event.logicalKey == LogicalKeyboardKey.enter) { submitPatientForm(); } }, child: Column(mainAxisSize: MainAxisSize.max, children: [ const Text( "Patient Lookup", style: TextStyle(fontSize: 25, fontWeight: FontWeight.bold), ), Divider(color: MzanziInnovationHub.of(context)!.theme.secondaryColor()), //spacer const SizedBox(height: 10), Row( mainAxisSize: MainAxisSize.min, children: [ Flexible( flex: 1, child: MIHSearchField( controller: searchController, hintText: "ID or Medical Aid No. Search", required: false, editable: true, onTap: () { submitPatientForm(); }, ), ), IconButton( onPressed: () { setState(() { searchController.clear(); searchString = ""; }); submitPatientForm(); }, icon: const Icon( Icons.filter_alt_off, size: 25, )) ], ), //spacer const SizedBox(height: 10), FutureBuilder( future: patientSearchResults, builder: (context, snapshot) { //print("patient Liust ${snapshot.data}"); if (snapshot.connectionState == ConnectionState.waiting) { return const Mihloadingcircle(); } else if (snapshot.connectionState == ConnectionState.done && snapshot.hasData) { List patientsList; if (searchString == "") { patientsList = []; } else { patientsList = filterSearchResults(snapshot.data!, searchString); //print(patientsList); } return displayPatientList(patientsList, searchString); } else { return Center( child: Text( "Error pulling Patients Data\n$baseUrl/patients/search/$searchString", style: TextStyle( fontSize: 25, color: MzanziInnovationHub.of(context)!.theme.errorColor()), textAlign: TextAlign.center, ), ); } }, ), ]), ); } void submitPatientForm() { if (searchController.text != "") { setState(() { searchString = searchController.text; patientSearchResults = MIHApiCalls.fetchPatients(searchString); }); } // else { // showDialog( // context: context, // builder: (context) { // return const MIHErrorMessage(errorType: "Input Error"); // }, // ); // } } //Patient Access Widgets/ Functions List filterAccessResults( List patAccList, String query) { List templist = []; //print(query); for (var item in patAccList) { if (item.id_no.contains(query)) { //print(item.medical_aid_no); templist.add(item); } } return templist; } Widget displayPatientAccessList(List patientsAccessList) { if (patientsAccessList.isNotEmpty) { return BuildPatientAccessList( patientAccesses: patientsAccessList, signedInUser: widget.arguments.signedInUser, business: widget.arguments.business, arguments: widget.arguments, ); } return Padding( padding: const EdgeInsets.only(top: 35.0), child: Center( child: Text( "No Patients matching search", style: TextStyle( fontSize: 25, color: MzanziInnovationHub.of(context)!.theme.messageTextColor()), textAlign: TextAlign.center, ), ), ); } Widget patientAccessSearch() { return KeyboardListener( focusNode: _focusNode, autofocus: true, onKeyEvent: (event) async { if (event is KeyDownEvent && event.logicalKey == LogicalKeyboardKey.enter) { submitPatientAccessForm(); } }, child: Column(mainAxisSize: MainAxisSize.max, children: [ Row( mainAxisAlignment: MainAxisAlignment.center, children: [ const Text( "My Patient List", style: TextStyle(fontSize: 25, fontWeight: FontWeight.bold), ), IconButton( iconSize: 20, icon: const Icon( Icons.refresh, ), onPressed: () { refreshAccessList(); }, ), ], ), Divider(color: MzanziInnovationHub.of(context)!.theme.secondaryColor()), //spacer const SizedBox(height: 10), Row( mainAxisSize: MainAxisSize.min, children: [ Flexible( flex: 1, child: MIHSearchField( controller: accessSearchController, hintText: "ID Search", required: false, editable: true, onTap: () { submitPatientAccessForm(); }, ), ), IconButton( onPressed: () { setState(() { accessSearchController.clear(); accessSearchString = ""; }); submitPatientAccessForm(); }, icon: const Icon( Icons.filter_alt_off, size: 25, )) ], ), //spacer const SizedBox(height: 10), FutureBuilder( future: patientAccessResults, builder: (context, snapshot) { //print("patient Liust ${snapshot.data}"); if (snapshot.connectionState == ConnectionState.waiting) { return const Mihloadingcircle(); } else if (snapshot.connectionState == ConnectionState.done && snapshot.hasData) { List patientsAccessList; if (accessSearchString == "") { patientsAccessList = snapshot.data!; } else { patientsAccessList = filterAccessResults(snapshot.data!, accessSearchString); //print(patientsList); } return displayPatientAccessList(patientsAccessList); } else { return Center( child: Text( "Error pulling Patient Access Data\n$baseUrl/access-requests/business/patient/${widget.arguments.business!.business_id}", style: TextStyle( fontSize: 25, color: MzanziInnovationHub.of(context)!.theme.errorColor()), textAlign: TextAlign.center, ), ); } }, ), ]), ); } void submitPatientAccessForm() { // if (searchController.text != "") { setState(() { accessSearchString = accessSearchController.text; patientAccessResults = MIHApiCalls.getPatientAccessListOfBusiness( widget.arguments.business!.business_id); }); // } else { // showDialog( // context: context, // builder: (context) { // return const MIHErrorMessage(errorType: "Input Error"); // }, // ); // } } //Layout Widgets/ Functions Widget showSelection(int index) { if (index == 0) { return SizedBox( //width: 660, child: patientQueue(), ); } else if (index == 1) { return SizedBox( //width: 660, child: patientAccessSearch(), ); } else { return SizedBox( //width: 660, child: patientSearch(), ); } } MIHAction getActionButton() { return MIHAction( icon: const Icon(Icons.arrow_back), iconSize: 35, onTap: () { Navigator.of(context).pop(); Navigator.of(context).popAndPushNamed( '/', arguments: 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 {}, ), ); } }