From be5b7c595cab6cd09e7cf8da1916c3237e824c5d Mon Sep 17 00:00:00 2001 From: marykilewe Date: Fri, 21 Jun 2024 13:16:17 +0300 Subject: [PATCH 1/4] updated update page --- src/constants/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/constants/index.js b/src/constants/index.js index 769d962..ab0e589 100644 --- a/src/constants/index.js +++ b/src/constants/index.js @@ -2,4 +2,4 @@ export const API_URL = process.env.REACT_APP_BACKEND_URL + "/facilities"; export const EMAIL_URL = process.env.REACT_APP_BACKEND_URL; -export const BASE_URL = window.location.protocol + '//' + window.location.host; \ No newline at end of file +export const BASE_URL = window.location.protocol + '//' + window.location.host; From cfdbcc82b1e6e7d754239eb30d9224226460d2da Mon Sep 17 00:00:00 2001 From: MaryKilewe Date: Tue, 26 Nov 2024 15:36:35 +0300 Subject: [PATCH 2/4] -view, add, edit, delete stakeholders -cleaned up classname and css styling --- .env | 4 +- src/App.css | 24 +++ src/App.js | 18 +- src/components/AddFacility.js | 10 +- src/components/AddPartnerStakeholder.js | 132 +++++++++++++++ src/components/ApproveFacilityChanges.js | 12 +- src/components/EditPartnerStakeholder.js | 128 ++++++++++++++ src/components/EditPartners.js | 12 +- src/components/Footer.js | 2 +- src/components/Header.js | 4 +- src/components/Home.js | 4 +- src/components/UpdateFacility.js | 10 +- src/components/ViewFacility.js | 58 +++---- src/components/ViewPartnerStakeholdersList.js | 158 ++++++++++++++++++ src/components/ViewPartners.js | 32 ++-- src/components/ViewReports.js | 2 +- src/components/form_components/EMRInfo.js | 16 +- .../form_components/FacilityInfo.js | 26 +-- src/components/form_components/HTS_Info.js | 12 +- src/components/form_components/IL_Info.js | 10 +- src/components/form_components/MHealthInfo.js | 8 +- src/constants/index.js | 5 +- src/services/UserService.js | 11 +- 23 files changed, 578 insertions(+), 120 deletions(-) create mode 100644 src/components/AddPartnerStakeholder.js create mode 100644 src/components/EditPartnerStakeholder.js create mode 100644 src/components/ViewPartnerStakeholdersList.js diff --git a/.env b/.env index b9332c5..b553a48 100644 --- a/.env +++ b/.env @@ -1,3 +1,3 @@ -REACT_APP_AUTHORITY = 'https://auth.kenyahmis.org/dwhidentity' +REACT_APP_AUTHORITY = 'https://ip/dwhidentity' -REACT_APP_BACKEND_URL = "http://127.0.0.1:8000" \ No newline at end of file +REACT_APP_BACKEND_URL = "http://127.0.0.1:8000" diff --git a/src/App.css b/src/App.css index e662ec4..2e3327a 100644 --- a/src/App.css +++ b/src/App.css @@ -32,6 +32,26 @@ body { background-color:#31C48D !important; } +.green_text_dark{ + color:#00897B !important; +} + +.cyan_bg_color{ + background-color:#E0F7FA !important; +} +.teal_bg_color{ + background-color:#E0F2F1 !important; +} +.white_bg_color{ + background-color:#FFFFFF !important; +} +.blue_text_color{ + color:#0288D1 !important; +} +.red_text_dark{ + color:#D32F2F !important; +} + .alert_message{ width:80%; margin:auto; @@ -190,3 +210,7 @@ td{ .nav-link:hover{ color:silver !important; } + +.font-weight-bold{ + font-weight: bold; +} diff --git a/src/App.js b/src/App.js index f25df76..611b888 100644 --- a/src/App.js +++ b/src/App.js @@ -24,6 +24,10 @@ import SubmittedApprovals from "./components/SubmittedApprovals"; import PendingApprovals from "./components/PendingApprovals"; import userManager, { signinRedirectCallback, signoutRedirect } from './services/UserService'; +import ViewPartnerStakeholdersList from "./components/ViewPartnerStakeholdersList"; +import EditPartnerStakeholder from "./components/EditPartnerStakeholder"; +import AddPartnerStakeholder from "./components/AddPartnerStakeholder"; + function App() { @@ -38,7 +42,6 @@ function App() { await userManager.getUser().then((res) =>{ // console.log("show org data",res) setUser(res); - // console.log(res.profile) localStorage.setItem("OrganizationId", res.profile.OrganizationId); }); @@ -83,10 +86,15 @@ function App() { }/> - {/* }/> - } /> - } /> - } /> */} + }> + }/> + + }> + }/> + + }> + }/> + } /> } /> diff --git a/src/components/AddFacility.js b/src/components/AddFacility.js index 3767aeb..753626e 100644 --- a/src/components/AddFacility.js +++ b/src/components/AddFacility.js @@ -130,9 +130,9 @@ const AddFacility = (props) => { return ( -
- Add Facility -

Add new Facility to your List

+ + Add Facility +

Add new Facility to your List

{ Counties_list.length > 0 && @@ -174,8 +174,8 @@ const AddFacility = (props) => { }
-
- +
+
diff --git a/src/components/AddPartnerStakeholder.js b/src/components/AddPartnerStakeholder.js new file mode 100644 index 0000000..a6d054d --- /dev/null +++ b/src/components/AddPartnerStakeholder.js @@ -0,0 +1,132 @@ +import React, { Component, useEffect, useState } from "react"; +import {Button, Form, FormGroup, Input, Label, Alert, Table, Spinner, Col, + Container, Row} from "reactstrap"; + +import {FaEdit, FaInfoCircle, FaPlusCircle} from 'react-icons/fa'; +import Swal from 'sweetalert2' +import userManager, { signinRedirectCallback, signoutRedirect } from '../services/UserService'; + +import { API_URL, EMAIL_URL, BASE_URL } from "../constants"; + +import axios from "axios"; +import {Link, useParams,useLocation } from "react-router-dom"; +import initial_data from "./json_data/initial_data"; + + + +const EditPartnerStakeholder = (props) => { + + const location = useLocation(); + const searchParams = new URLSearchParams(location.search); + const stakeholder_id = searchParams.get('id'); + + + const [Stakeholder, setStakeholdersData] = useState([]); + const [partners_list, setPartners_list] = useState([]); + const [isOrgSteward, setIsOrgSteward] = useState(false); + const [showSpinner, setShowSpinner] = useState(false); + + + + const setInitialData = async() => { + const initial_data = { + "title":"", + "name":"", + "telno":"", + "email":"", + "partner_id":"" + } + setStakeholdersData(initial_data) + }; + + + // async function checkIfOrgSteward(emails) { + // await userManager.getUser().then((res) =>{ + // // setIsOrgSteward( emails.includes(res.profile.email.toLowerCase())) + // // default to true for all with login credentials + // setIsOrgSteward( true) + // }); + // + // } + + const get_partners_list = async() => { + // axios.get(API_URL+"/update_facility/981893d7-8488-4319-b976-747873551b71").then(res => this.setState({ facility: res.data })); + await axios.get(API_URL+"/get_partners_list").then(res => setPartners_list( res.data )); + }; + + + const handleSubmit = async (event) => { + + event.preventDefault(); + setShowSpinner(true) + + await axios.post(`${API_URL}/add_stakeholder`, Stakeholder) + .then(function (response) { + localStorage.setItem("flashMessage", "New Stakeholder successfully added"); + window.location.href = `${BASE_URL}/partner/stakeholders/${Stakeholder.partner_name}?id=${Stakeholder.partner_id}`; + setShowSpinner(false) + + }) + .catch(function (error) { + localStorage.setItem("flashMessage", "Something went wrong. Refresh and try again"); + setShowSpinner(false) + + }); + }; + + + useEffect(() => { + get_partners_list() + setInitialData() + }, []) + + + return( +
+ + + + Add Stakeholder +

Add details of a new stakeholder

+ + {/*
*/} +
+ + {setStakeholdersData({...Stakeholder, "partner_id":e.target.value}) }}> + + { partners_list.length > 0 && + partners_list.map(partner => ( + + )) + } + + + + {setStakeholdersData({...Stakeholder, "title":e.target.value}) }}/> + + + {setStakeholdersData({...Stakeholder, "name":e.target.value}) }}/> + + + {setStakeholdersData({...Stakeholder, "email":e.target.value}) }}/> + + + {setStakeholdersData({...Stakeholder, "telno":e.target.value}) }}/> +
+ + {showSpinner && } + +
+
+ +
+ ); + +} + +export default EditPartnerStakeholder; diff --git a/src/components/ApproveFacilityChanges.js b/src/components/ApproveFacilityChanges.js index 23d77c8..fc4c0bf 100644 --- a/src/components/ApproveFacilityChanges.js +++ b/src/components/ApproveFacilityChanges.js @@ -227,9 +227,9 @@ const ApproveFacilityChanges = (props) => { } -
- Approve Facility Data -

Approve or Reject data added to a Facility

+ + Approve Facility Data +

Approve or Reject data added to a Facility

@@ -271,10 +271,10 @@ const ApproveFacilityChanges = (props) => { } -
+
- diff --git a/src/components/ViewFacility.js b/src/components/ViewFacility.js index d2dc5c0..d9cbce7 100644 --- a/src/components/ViewFacility.js +++ b/src/components/ViewFacility.js @@ -127,10 +127,10 @@ const ViewFacility = () => { return ( -
-
- {Facility_data.name} Facility -

View facility details

+
+
+ {Facility_data.name} Facility +

View facility details

@@ -157,44 +157,44 @@ const ViewFacility = () => { -
Facility Information
-
+
Facility Information
+
-
+
MFL Code :

{Facility_data.mfl_code}

-
+
Facility Name :

{Facility_data.name}

-
+
Owner :

{Facility_data.owner}

-
+
County :

{Facility_data.county}

-
+
Sub-county :

{Facility_data.sub_county}

-
+
Latitude :

{Facility_data.lat}

-
+
Longitude :

{Facility_data.lon}

-
+
Agency :

{Facility_data.agency}

-
+
SDP :

{Facility_data.partner}

@@ -211,14 +211,14 @@ const ViewFacility = () => { Facility Type

{ - Facility_data.emr_site ? : - + Facility_data.emr_site ? : + } EMR site

{ - Facility_data.non_emr_site ? : - + Facility_data.non_emr_site ? : + } Non-EMR site

@@ -227,32 +227,32 @@ const ViewFacility = () => { Non-EMR sites Options

{ - Facility_data.asal ? : - + Facility_data.asal ? : + } ASAL

{ - Facility_data.pepfar ? : - + Facility_data.pepfar ? : + } PEPFAR

Implementation -
-
+
+

{ - Facility_data.CT ? : - + Facility_data.CT ? : + } C&T

-

{ Facility_data.HTS ? : - +

{ Facility_data.HTS ? : + } HTS

diff --git a/src/components/ViewPartnerStakeholdersList.js b/src/components/ViewPartnerStakeholdersList.js new file mode 100644 index 0000000..e1f595b --- /dev/null +++ b/src/components/ViewPartnerStakeholdersList.js @@ -0,0 +1,158 @@ +import React, { Component, useEffect, useState } from "react"; +import {Button, Form, FormGroup, Input, Label, Alert, Table, Spinner, Col, + Container, Row} from "reactstrap"; +import Swal from 'sweetalert2' + +import {FaEdit, FaTrash , FaPlusCircle} from 'react-icons/fa'; +import userManager, { signinRedirectCallback, signoutRedirect } from '../services/UserService'; + +import { API_URL, EMAIL_URL, BASE_URL } from "../constants"; + +import axios from "axios"; +import {Link, useParams,useLocation } from "react-router-dom"; + + + +const ViewPartnerStakeholdersList = (props) => { + + const location = useLocation(); + const searchParams = new URLSearchParams(location.search); + const part_id = searchParams.get('id'); + + const [StakeholdersList, setStakeholdersListData] = useState([]); + const [agecies_list, setAgencies_list] = useState([]); + const [isOrgSteward, setIsOrgSteward] = useState(false); + + const getStakeholdersListData = () => { + axios.get(API_URL+`/stakeholders_list/${part_id}`).then(res => { + setStakeholdersListData(res.data); + checkIfOrgSteward(res.data.org_steward_emails); + }); + + }; + + async function checkIfOrgSteward(emails) { + await userManager.getUser().then((res) =>{ + // setIsOrgSteward( emails.includes(res.profile.email.toLowerCase())) + // default to true for all with login credentials + setIsOrgSteward( true) + }); + + } + + + + const ConfirmDeletion = (stakeholder_id, stakeholder_name) =>{ + Swal.fire({ + title: 'Delete Stakeholder?', + text: "Are you sure you want to delete "+stakeholder_name+" stakeholder", + icon: 'warning', + showCancelButton: true, + confirmButtonColor: '#1ab394', + cancelButtonColor: '#d33', + confirmButtonText: 'Delete!' + + }).then((result) => { + if (result.isConfirmed) { + DeleteStakeholder(stakeholder_id) + Swal.fire( + 'Success!', + 'Success! Stakeholder Deleted form the System!', + 'success' + ); + + } else { + Swal.fire("Operation canceled!"); + } + }) + } + + + const DeleteStakeholder = async (stakeholder_id) => { + + await axios.post(`${API_URL}/delete_stakeholder/${stakeholder_id}`) + .then(function (response) { + window.location.href = `${BASE_URL}/partner/stakeholders/${StakeholdersList.partner}?id=${StakeholdersList.partner_id}`; + }) + .catch(function (error) { + console.log('failed ---/>', error); + }); + }; + + + + useEffect(() => { + getStakeholdersListData() + + }, []) + + + return( +
+ + + +
+ {StakeholdersList.partner}({StakeholdersList.sdp_code}) Stakeholders +
+ + + {/**/} + {/**/} + + +
+
+ + + + + + + + + + + + + + + {!StakeholdersList.users || StakeholdersList.users.length <= 0 ? ( + + + + ) : ( + StakeholdersList.users.map(stakeholder => ( + + + + + + + + + )) + )} + +
SDP CodePartner nameTitleNameEmailActions
+ No Stakeholders found. Add a stakeholder to the mailing list +
{stakeholder.sdp_code}{stakeholder.partner}{stakeholder.title}{stakeholder.name}{stakeholder.email} + + + + ConfirmDeletion(stakeholder.id, stakeholder.name)} + style={{fontSize:"15px", marginRight:"20px"}} /> +
+ +
+ ); + +} + +export default ViewPartnerStakeholdersList; diff --git a/src/components/ViewPartners.js b/src/components/ViewPartners.js index a0eb9d8..b50e522 100644 --- a/src/components/ViewPartners.js +++ b/src/components/ViewPartners.js @@ -1,6 +1,6 @@ import React, { Component, useEffect, useState } from "react"; import { Button, Form, FormGroup, Input, Label,Alert, Table } from "reactstrap"; -import {FaEdit } from 'react-icons/fa'; +import {FaEdit,FaPlusCircle ,FaArrowCircleRight } from 'react-icons/fa'; import Swal from 'sweetalert2' import { Link } from 'react-router-dom'; @@ -67,12 +67,12 @@ const EditPartners = () => { return( -
-
- +
+ handleSearchFilter(e)} />
- +
@@ -81,6 +81,8 @@ const EditPartners = () => { + + @@ -93,14 +95,20 @@ const EditPartners = () => { ) : ( filtereddata.map(partner => ( - - - - - - + + + + + + + diff --git a/src/components/ViewReports.js b/src/components/ViewReports.js index ffe66b4..d0b78b6 100644 --- a/src/components/ViewReports.js +++ b/src/components/ViewReports.js @@ -37,7 +37,7 @@ const ViewReports = () => { return( -
+

HIS Master List {!showSpinner && } {showSpinner && } diff --git a/src/components/form_components/EMRInfo.js b/src/components/form_components/EMRInfo.js index b857a47..c7ec722 100644 --- a/src/components/form_components/EMRInfo.js +++ b/src/components/form_components/EMRInfo.js @@ -23,9 +23,9 @@ function EMRInfo(props) { return (
-
EMR Information
-
-
+
EMR Information
+
+
-
+
props.setFacility_data({...props.facility_data, "date_of_emr_impl":e.target.value})}>
-
+
Hybrid Use
-
+
EMR modules -
+
-
Facility Information
-
-
+
Facility Information
+
+
-
+
{checkLength(e); props.setFacility_data({...props.facility_data, "mfl_code":e.target.value}) }}/> -

{error_message}

-
+
props.setFacility_data({...props.facility_data, "name":e.target.value})} />
-
+
-
+
-
+
-
+
{props.setFacility_data({...props.facility_data, "lat":e.target.value}) }}/>
-
+
{props.setFacility_data({...props.facility_data, "lon":e.target.value}) }}/>
-
+
-
+
-
HTS Information
-
+
HTS Information
+
HTS Information -
+
-
+
-
+
-
Interoperability(IL) and Integrations
+
Interoperability(IL) and Integrations
-
+
IL Participating Systems -
+
Integrations -
+
-
MHealth Information
-
+
MHealth Information
+
MHealth Information -
+
", client_id) + authority = AUTHORITY }else if (window.location.host === "prod.kenyahmis.org:3001"){ client_id = "dwh.his-prod" - authority = 'https://identity.kenyahmis.org' + authority = AUTHORITY }else if (window.location.host === "hisportal.kenyahmis.org"){ client_id = "dwh.his-portal" - authority = 'https://identity.kenyahmis.org' + authority = AUTHORITY } const config = { From 07197a0b21a770a5873c2f2def06e32404f238a4 Mon Sep 17 00:00:00 2001 From: MaryKilewe Date: Tue, 26 Nov 2024 15:54:01 +0300 Subject: [PATCH 3/4] change page title, and path variable passed in url --- src/App.js | 4 ++-- src/components/AddPartnerStakeholder.js | 8 ++++++-- src/components/ViewPartnerStakeholdersList.js | 3 ++- 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/src/App.js b/src/App.js index 611b888..c2558b7 100644 --- a/src/App.js +++ b/src/App.js @@ -86,8 +86,8 @@ function App() { }/> - }> - }/> + }> + }/> }> }/> diff --git a/src/components/AddPartnerStakeholder.js b/src/components/AddPartnerStakeholder.js index a6d054d..013049f 100644 --- a/src/components/AddPartnerStakeholder.js +++ b/src/components/AddPartnerStakeholder.js @@ -15,6 +15,7 @@ import initial_data from "./json_data/initial_data"; const EditPartnerStakeholder = (props) => { + const { part_name } = useParams(); const location = useLocation(); const searchParams = new URLSearchParams(location.search); @@ -34,7 +35,9 @@ const EditPartnerStakeholder = (props) => { "name":"", "telno":"", "email":"", - "partner_id":"" + "partner_id":"", + "partner_name":"" + } setStakeholdersData(initial_data) }; @@ -93,7 +96,8 @@ const EditPartnerStakeholder = (props) => {
{setStakeholdersData({...Stakeholder, "partner_id":e.target.value}) }}> + onChange={(e) => {setStakeholdersData({...Stakeholder, "partner_id":e.target.value, + "partner_name":part_name}) }}> { partners_list.length > 0 && partners_list.map(partner => ( diff --git a/src/components/ViewPartnerStakeholdersList.js b/src/components/ViewPartnerStakeholdersList.js index e1f595b..8c803d7 100644 --- a/src/components/ViewPartnerStakeholdersList.js +++ b/src/components/ViewPartnerStakeholdersList.js @@ -14,6 +14,7 @@ import {Link, useParams,useLocation } from "react-router-dom"; const ViewPartnerStakeholdersList = (props) => { + const { part_name } = useParams(); const location = useLocation(); const searchParams = new URLSearchParams(location.search); @@ -93,7 +94,7 @@ const ViewPartnerStakeholdersList = (props) => {

- {StakeholdersList.partner}({StakeholdersList.sdp_code}) Stakeholders + {part_name} Stakeholders
From bd24e776ac6e10087153274d88fbdc29ab20cb7a Mon Sep 17 00:00:00 2001 From: MaryKilewe Date: Wed, 18 Dec 2024 21:50:37 +0300 Subject: [PATCH 4/4] upload and export stakeholders list --- src/components/ViewPartners.js | 96 +++++++++++++++++++++++++++++++++- 1 file changed, 94 insertions(+), 2 deletions(-) diff --git a/src/components/ViewPartners.js b/src/components/ViewPartners.js index b50e522..ee0a73f 100644 --- a/src/components/ViewPartners.js +++ b/src/components/ViewPartners.js @@ -1,5 +1,5 @@ import React, { Component, useEffect, useState } from "react"; -import { Button, Form, FormGroup, Input, Label,Alert, Table } from "reactstrap"; +import {Button, Form, FormGroup, Input, Label, Alert, Table, Spinner} from "reactstrap"; import {FaEdit,FaPlusCircle ,FaArrowCircleRight } from 'react-icons/fa'; import Swal from 'sweetalert2' import { Link } from 'react-router-dom'; @@ -8,6 +8,9 @@ import { API_URL, EMAIL_URL, BASE_URL } from "../constants"; import axios from "axios"; import { useParams } from 'react-router-dom' +import {SiMicrosoftexcel} from "react-icons/si"; +import userManager from "../services/UserService"; +import ExportToExcel from "./ExportToExcel"; @@ -19,13 +22,27 @@ const EditPartners = () => { const [disabled, setDisabled] = useState(true) const [agencyId, setAgencyId]= useState(null); const [partnerId, setPartnerId]= useState(null); + const [showDownloadSpinner, setShowDownloadSpinner] = useState(true); + const [showUploadExcelSpinner, setShowUploadExcelSpinner] = useState(false); + const [fetchError, setFetchError] = useState(null); + const [fileUpload, setFileUpload] = useState() + const isAuthenticated = sessionStorage.getItem("isAuthenticated"); + const [isAllowedUser, setIsAllowedUser] = useState(false) + const [exceldata, setData] = useState([]) + const fileName = "Stakeholders List"; // Partner_data.map(partner => { // const identifier = partner.id // const item_ref = useRef("agency-"+identifier) // const item_ref = useRef("agency-"+identifier) // }); + const fetchStakeholdersData = () =>{ + axios.post(API_URL + '/stakeholders/excel/download').then(r =>{ + setShowDownloadSpinner(false) + setData(r.data) + }) + } const getPartners = () => { axios.get(API_URL+'/partners').then(res => { @@ -61,13 +78,88 @@ const EditPartners = () => { }; + + function uploadExcelStakeholders(event) { + setFileUpload(event.target.files[0]) + } + + const handleExcelStakeholdersSubmit= async () => { + setShowUploadExcelSpinner(true) + + if (fileUpload) { + const formData = new FormData(); + formData.append('file', fileUpload); + // Use fetch or a library like Axios to send the file to the server. + // Replace 'YOUR_UPLOAD_URL' with your server's upload endpoint. + await fetch(API_URL + "/uploadExcel/Stakeholders", { + method: 'POST', + body: formData, + }) .then(response => { + if (!response.ok) { + throw new Error('Network response was not ok'); + } + return response.json(); // Parse response body as JSON + }) + .then((data) => { + + if (data.status_code==200){ + localStorage.setItem("flashMessage", 'Successfully Synced!'); + window.location.href = BASE_URL+"/facilities/partners"; + }else{ + localStorage.setItem("flashMessage", 'Failed to Sync because of One or Two errors! Contact ' + + 'admin for assistance.'+data.status_message); + window.location.href = BASE_URL+"/facilities/partners"; + } + + setShowUploadExcelSpinner(false) + }) + .catch((error) => { + localStorage.setItem("flashMessage", error); + window.location.href = BASE_URL+"/facilities/partners"; + setShowUploadExcelSpinner(false) + + }); + } + }; + + const getAuthorizedUsers = async () => { + await userManager.getUser().then((res) => { + if (res.profile.UserType == "2" || res.profile.UserType == "5" || res.profile.UserType == "1") { + + setIsAllowedUser(true) + } else { + setIsAllowedUser(false) + } + }); + + }; + useEffect(() => { - getPartners() + getPartners(); + getAuthorizedUsers(); + fetchStakeholdersData(); }, []) return(
+
+

+ Partners Data + { !showDownloadSpinner && } + { showDownloadSpinner && } +

+
+ { isAllowedUser && +
+ + + +
+ }
handleSearchFilter(e)} />
AgencyPrime Partner Name HIS Approver ActionsStakeholdersActions
{partner.agency} {partner.sdp_code}{partner.name}{partner.prime_partner_name}{partner.approver} + {partner.agency}{partner.sdp_code}{partner.name}{partner.prime_partner_name}{partner.approver} - + + + {partner.stakeholder_list} +