From 1ee31b46fe32b04d31682cc6a7f78ec57b23f253 Mon Sep 17 00:00:00 2001 From: yaso-meth Date: Mon, 9 Sep 2024 14:07:53 +0200 Subject: [PATCH] add screen to view and update employees --- .../builders/buildEmployeeList.dart | 255 +++++++++++++++++ .../lib/pages/manageBusinessProfile.dart | 262 ++++++++++++++++++ 2 files changed, 517 insertions(+) create mode 100644 Frontend/patient_manager/lib/components/builders/buildEmployeeList.dart create mode 100644 Frontend/patient_manager/lib/pages/manageBusinessProfile.dart diff --git a/Frontend/patient_manager/lib/components/builders/buildEmployeeList.dart b/Frontend/patient_manager/lib/components/builders/buildEmployeeList.dart new file mode 100644 index 00000000..a4667f84 --- /dev/null +++ b/Frontend/patient_manager/lib/components/builders/buildEmployeeList.dart @@ -0,0 +1,255 @@ +import 'dart:convert'; + +import 'package:flutter/material.dart'; +import 'package:patient_manager/components/inputsAndButtons/mihButton.dart'; +import 'package:patient_manager/components/inputsAndButtons/mihDropdownInput.dart'; +import 'package:patient_manager/components/inputsAndButtons/mihTextInput.dart'; +import 'package:patient_manager/components/popUpMessages/mihErrorMessage.dart'; +import 'package:patient_manager/components/popUpMessages/mihLoadingCircle.dart'; +import 'package:patient_manager/components/popUpMessages/mihSuccessMessage.dart'; +import 'package:patient_manager/env/env.dart'; +import 'package:patient_manager/main.dart'; +import 'package:patient_manager/objects/arguments.dart'; +import 'package:patient_manager/objects/businessEmployee.dart'; +import 'package:supertokens_flutter/http.dart' as http; + +class BuildEmployeeList extends StatefulWidget { + final List employees; + final BusinessArguments arguments; + + const BuildEmployeeList({ + super.key, + required this.employees, + required this.arguments, + }); + + @override + State createState() => _BuildEmployeeListState(); +} + +class _BuildEmployeeListState extends State { + TextEditingController accessController = TextEditingController(); + TextEditingController typeController = TextEditingController(); + TextEditingController fnameController = TextEditingController(); + TextEditingController lnameController = TextEditingController(); + + final baseAPI = AppEnviroment.baseApiUrl; + + Future updateEmployeeAPICall(int index) async { + showDialog( + context: context, + builder: (context) { + return const Mihloadingcircle(); + }, + ); + + var response = await http.put( + Uri.parse("$baseAPI/business-user/employees/update/"), + headers: { + "Content-Type": "application/json; charset=UTF-8" + }, + body: jsonEncode({ + "business_id": widget.employees[index].business_id, + "app_id": widget.employees[index].app_id, + "title": typeController.text, + "access": accessController.text, + }), + ); + if (response.statusCode == 200) { + Navigator.of(context).pop(); + Navigator.of(context).pop(); + Navigator.of(context).pop(); + //setState(() {}); + Navigator.of(context).pushNamed( + '/business-profile/manage', + arguments: BusinessArguments( + widget.arguments.signedInUser, + widget.arguments.businessUser, + widget.arguments.business, + ), + ); + String message = "Your employees details have been updated."; + 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 updateEmployeePopUp(int index) { + setState(() { + accessController.text = widget.employees[index].access; + typeController.text = widget.employees[index].title; + fnameController.text = widget.employees[index].fname; + lnameController.text = widget.employees[index].lname; + }); + showDialog( + context: context, + barrierDismissible: false, + builder: (context) => Dialog( + child: Stack( + children: [ + Container( + padding: const EdgeInsets.all(10.0), + width: 700.0, + //height: 475.0, + decoration: BoxDecoration( + color: MzanziInnovationHub.of(context)!.theme.primaryColor(), + borderRadius: BorderRadius.circular(25.0), + border: Border.all( + color: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + width: 5.0), + ), + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 10), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Text( + "Employee Details", + textAlign: TextAlign.center, + style: TextStyle( + color: MzanziInnovationHub.of(context)! + .theme + .secondaryColor(), + fontSize: 35.0, + fontWeight: FontWeight.bold, + ), + ), + const SizedBox(height: 25.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), + MIHDropdownField( + controller: typeController, + hintText: "Title", + dropdownOptions: const ["Doctor", "Assistant"], + required: true, + editable: true, + ), + const SizedBox(height: 10.0), + MIHDropdownField( + controller: accessController, + hintText: "Access", + dropdownOptions: const ["Full", "Partial"], + required: true, + editable: true, + ), + const SizedBox(height: 30.0), + SizedBox( + width: 300, + height: 50, + child: MIHButton( + buttonText: "Update", + buttonColor: MzanziInnovationHub.of(context)! + .theme + .secondaryColor(), + textColor: MzanziInnovationHub.of(context)! + .theme + .primaryColor(), + onTap: () { + updateEmployeeAPICall(index); + }, + ), + ) + ], + ), + ), + ), + 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() { + accessController.dispose(); + typeController.dispose(); + fnameController.dispose(); + lnameController.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + return ListView.separated( + separatorBuilder: (BuildContext context, index) { + return Divider( + color: MzanziInnovationHub.of(context)!.theme.secondaryColor(), + ); + }, + itemCount: widget.employees.length, + itemBuilder: (context, index) { + //final patient = widget.patients[index].id_no.contains(widget.searchString); + //print(index); + var isMe = ""; + if (widget.arguments.signedInUser.app_id == + widget.employees[index].app_id) { + isMe = "(You)"; + } + return ListTile( + title: Text( + "${widget.employees[index].fname} ${widget.employees[index].lname} - ${widget.employees[index].title} $isMe"), + subtitle: Text( + "${widget.employees[index].username}\n${widget.employees[index].email}\nAccess: ${widget.employees[index].access}", + style: TextStyle( + color: MzanziInnovationHub.of(context)!.theme.secondaryColor(), + ), + ), + onTap: () { + updateEmployeePopUp(index); + }, + ); + }, + ); + } +} diff --git a/Frontend/patient_manager/lib/pages/manageBusinessProfile.dart b/Frontend/patient_manager/lib/pages/manageBusinessProfile.dart new file mode 100644 index 00000000..5f68216a --- /dev/null +++ b/Frontend/patient_manager/lib/pages/manageBusinessProfile.dart @@ -0,0 +1,262 @@ +import 'dart:convert'; + +import 'package:flutter/material.dart'; +import 'package:patient_manager/components/builders/buildEmployeeList.dart'; +import 'package:patient_manager/components/popUpMessages/mihLoadingCircle.dart'; +import 'package:patient_manager/components/popUpMessages/mihErrorMessage.dart'; +import 'package:patient_manager/components/popUpMessages/mihSuccessMessage.dart'; +import 'package:patient_manager/env/env.dart'; +import 'package:patient_manager/main.dart'; +import 'package:patient_manager/objects/arguments.dart'; +import 'package:patient_manager/objects/businessEmployee.dart'; +import 'package:supertokens_flutter/http.dart' as http; + +class ManageBusinessProfile extends StatefulWidget { + final BusinessArguments arguments; + const ManageBusinessProfile({ + super.key, + required this.arguments, + }); + + @override + State createState() => _ManageBusinessProfileState(); +} + +class BusinessUserScreenArguments {} + +class _ManageBusinessProfileState extends State { + final FocusNode _focusNode = FocusNode(); + final baseAPI = AppEnviroment.baseApiUrl; + final TextEditingController searchController = TextEditingController(); + + String userSearch = ""; + String errorCode = ""; + String errorBody = ""; + + late Future> employeeList; + + Future> fetchEmployees() async { + //print("Patien manager page: $endpoint"); + final response = await http.get(Uri.parse( + "${AppEnviroment.baseApiUrl}/business-user/employees/${widget.arguments.businessUser!.business_id}")); + errorCode = response.statusCode.toString(); + errorBody = response.body; + + if (response.statusCode == 200) { + //print("Here1"); + Iterable l = jsonDecode(response.body); + //print("Here2"); + List patientQueue = List.from( + l.map((model) => BusinessEmployee.fromJson(model))); + //print("Here3"); + //print(patientQueue); + return patientQueue; + } else { + throw Exception('failed to load employees'); + } + } + + Widget employeesview(double w, double h) { + return SizedBox( + width: w, + height: h - 157, + child: Column(mainAxisSize: MainAxisSize.max, children: [ + //const SizedBox(height: 15), + FutureBuilder( + future: employeeList, + 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 employeeListResults; + // if (searchString == "") { + // patientQueueList = []; + // } else { + + // print(patientQueueList); + // } + + return Expanded( + child: displayEmployeeList(snapshot.requireData), + ); + } else { + 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: Center( + child: Text( + "$errorCode: Error pulling Patients Data\n${AppEnviroment.baseApiUrl}/business-user/users/${widget.arguments.businessUser!.business_id}\n$errorBody", + style: TextStyle( + fontSize: 25, + color: MzanziInnovationHub.of(context)! + .theme + .errorColor()), + textAlign: TextAlign.center, + ), + ), + ), + ); + } + }, + ), + ]), + ); + } + + Widget displayEmployeeList(List employeeList) { + if (employeeList.isNotEmpty) { + return 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: BuildEmployeeList( + employees: employeeList, + arguments: widget.arguments, + ), + ); + } + return 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: Center( + child: Text( + "", + style: TextStyle( + fontSize: 25, + color: MzanziInnovationHub.of(context)!.theme.messageTextColor()), + textAlign: TextAlign.center, + ), + ), + ); + } + + 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 emailError() { + showDialog( + context: context, + builder: (context) { + return const MIHErrorMessage(errorType: "Invalid Email"); + }, + ); + } + + @override + void dispose() { + searchController.dispose(); + _focusNode.dispose(); + super.dispose(); + } + + @override + void initState() { + employeeList = fetchEmployees(); + super.initState(); + } + + @override + Widget build(BuildContext context) { + final screenWidth = MediaQuery.of(context).size.width; + final screenHeight = MediaQuery.of(context).size.height; + return Scaffold( + // appBar: const MIHAppBar( + // barTitle: "Business Profile", + // propicFile: null, + // ), + //drawer: MIHAppDrawer(signedInUser: widget.arguments.signedInUser), + body: SafeArea( + child: Stack( + children: [ + SingleChildScrollView( + padding: const EdgeInsets.all(15), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + mainAxisSize: MainAxisSize.max, + children: [ + const Text( + "Business Team", + style: TextStyle( + fontWeight: FontWeight.bold, + fontSize: 25, + ), + ), + const SizedBox(height: 20), + employeesview(screenWidth, screenHeight), + ], + ), + ), + Positioned( + top: 10, + left: 5, + width: 50, + height: 50, + child: IconButton( + onPressed: () { + Navigator.of(context).pop(); + }, + icon: const Icon(Icons.arrow_back), + ), + ) + ], + ), + ), + ); + } +}