Skip to content

Commit

Permalink
added ahd dashboards
Browse files Browse the repository at this point in the history
  • Loading branch information
cbrianbet committed Sep 26, 2024
1 parent bac497a commit 4115965
Show file tree
Hide file tree
Showing 13 changed files with 363 additions and 2 deletions.
34 changes: 34 additions & 0 deletions src/actions/CT/AHD/AhdSceeningActions.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import moment from 'moment';
import { CACHING, PAGES } from '../../../constants';
import * as actionTypes from '../../types';
import { getAll } from '../../../views/Shared/Api';

export const loadAhdScreening = () => async (dispatch, getState) => {
const diffInMinutes = moment().diff(
moment(getState().ahdScreening.lastFetch),
'minutes'
);
if (getState().ui.currentPage !== PAGES.ct) {
return;
}
else if ((diffInMinutes < CACHING.LONG) && getState().filters.filtered === false) {
return;
} else {
await dispatch(fetchAhdScreening());
}
}

export const fetchAhdScreening = () => async (dispatch, getState) => {
dispatch({ type: actionTypes.AHD_SCREENING_REQUEST });
const params = {
county: getState().filters.counties,
subCounty: getState().filters.subCounties,
facility: getState().filters.facilities,
partner: getState().filters.partners,
agency: getState().filters.agencies,
gender: getState().filters.genders,
datimAgeGroup: getState().filters.datimAgeGroups,
};
const response = await getAll('care-treatment/getAHDScreened', params);
dispatch({ type: actionTypes.AHD_SCREENING_FETCH, payload: { filtered: getState().filters.filtered, list: response }});
};
4 changes: 4 additions & 0 deletions src/actions/types.js
Original file line number Diff line number Diff line change
Expand Up @@ -1062,6 +1062,10 @@ export const ART_VERIFICATION_REASONS_REQUEST = 'ART_VERIFICATION_REASONS_REQUES
export const ART_VERIFICATION_REASONS_FETCH = 'ART_VERIFICATION_REASONS_FETCH';
export const ART_VERIFICATION_REASONS_FAILED = 'ART_VERIFICATION_REASONS_FAILED';

export const AHD_SCREENING_REQUEST = 'AHD_SCREENING_REQUEST';
export const AHD_SCREENING_FETCH = 'AHD_SCREENING_FETCH';
export const AHD_SCREENING_FAILED = 'AHD_SCREENING_FAILED';

export const SERVICE_DESK_OVERVIEW_REQUEST = 'SERVICE_DESK_OVERVIEW_REQUEST';
export const SERVICE_DESK_OVERVIEW_FETCH = 'SERVICE_DESK_OVERVIEW_FETCH';
export const SERVICE_DESK_OVERVIEW_FAILED = 'SERVICE_DESK_OVERVIEW_FAILED';
Expand Down
1 change: 1 addition & 0 deletions src/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ export const CT_TABS = {
ovc: 'OVC',
covid: 'COVID-19',
artVerification: 'ART VERIFICATION',
ahd: 'AHD'
};

export const SD_TABS = {
Expand Down
31 changes: 31 additions & 0 deletions src/reducers/CT/AHD/ahdScreening.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import * as actionTypes from "../../../actions/types";

const initialState = {
lastFetch: null,
loading: false,
listUnfiltered: [],
listFiltered: [],
};

export default (state = initialState, action) => {
let newState = { ...state };
switch (action.type) {
case actionTypes.AHD_SCREENING_REQUEST:
newState.loading = true;
return newState;
case actionTypes.AHD_SCREENING_FETCH:
if (action.payload.filtered === true) {
newState.listFiltered = action.payload.list;
} else {
newState.listUnfiltered = action.payload.list;
newState.lastFetch = Date.now();
}
newState.loading = false;
return newState;
case actionTypes.AHD_SCREENING_FAILED:
newState.loading = false;
return newState;
default:
return state
}
}
3 changes: 3 additions & 0 deletions src/reducers/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,7 @@ import viralLoadOverallUptakeGt1000CopiesReceivedFollowTestsAll
from './CT/ViralLoad/viralLoadOverallUptakeGt1000CopiesReceivedFollowTestsAll';
import viralLoadOverallNumberTestsGt1000CopiesSecondlineRegiment
from './CT/ViralLoad/viralLoadOverallNumberTestsGt1000CopiesSecondlineRegiment';
import ahdScreening from './CT/AHD/ahdScreening'


import htsPosByGenderKHIS from './Operational&HIS/Comparison/htsPosByGenderKHIS';
Expand Down Expand Up @@ -672,4 +673,6 @@ export default combineReducers({
hisFacilityByInfrastructureCounty,
hisFacilityStatusByCounty,
hisFacilityArtHtsMnch,

ahdScreening,
});
14 changes: 14 additions & 0 deletions src/selectors/CT/AHD/ahdSelectors.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { createSelector } from 'reselect';

const listUnfiltered = state => state.ahdScreening.listUnfiltered;
const listFiltered = state => state.ahdScreening.listFiltered;
const filtered = state => state.filters.filtered;


export const getAHDIndicators = createSelector(
[listUnfiltered, listFiltered, filtered],
(listUnfiltered, listFiltered, filtered) => {
console.log(listUnfiltered, listFiltered)
return filtered ? listFiltered : listUnfiltered;
}
)
79 changes: 79 additions & 0 deletions src/views/CT/AHD/AHD.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import React from 'react';
import Loadable from 'react-loadable';
import VisibilitySensor from 'react-visibility-sensor';
import { useDispatch } from 'react-redux';
import moment from 'moment';
import { Col, Row } from 'reactstrap';
import {
enableStickyFilter,
disableStickyFilter,
} from '../../../actions/Shared/uiActions';
import { LOADING_DELAY } from '../../../constants';
import Loading from './../../Shared/Loading';
import SectionFooter from './../../Shared/SectionFooter';
import SectionHeader from './../../Shared/SectionHeader';
import UniversalFilter from './../../Shared/UniversalFilter';
import { useParams } from 'react-router-dom';

const CD4Testing = Loadable({
loader: () => import('./CD4Testing'),
loading: Loading,
delay: LOADING_DELAY,
});
const AHDScreening = Loadable({
loader: () => import('./AHDScreening'),
loading: Loading,
delay: LOADING_DELAY,
});
const TBScreeningAndManagement = Loadable({
loader: () => import('./TBScreeningAndManagement'),
loading: Loading,
delay: LOADING_DELAY,
});
const CryptococcalMeningitis = Loadable({
loader: () => import('./CryptococcalMeningitis'),
loading: Loading,
delay: LOADING_DELAY,
});

const ArtVerification = () => {
const branding = {
title: 'AHD',
description: 'OVERVIEW',
overview: 'AHD',
};
const { active_tab } = useParams();
const ctTab = active_tab;
const dispatch = useDispatch();
const onVisibilityChange = (isVisible) => {
if (ctTab === 'ahd') {
if (isVisible) {
dispatch(disableStickyFilter());
} else {
dispatch(enableStickyFilter());
}
}
};
return (
<div className="animated fadeIn">
<SectionHeader
title={branding.title}
description={`Year ${moment().format('YYYY')}`}
/>
<VisibilitySensor onChange={onVisibilityChange}>
<UniversalFilter />
</VisibilitySensor>

<AHDScreening />
<SectionFooter overview={branding.overview} />
<CD4Testing />
<SectionFooter overview={branding.overview} />
<TBScreeningAndManagement />
<SectionFooter overview={branding.overview} />
<CryptococcalMeningitis />
<SectionFooter overview={branding.overview} />
</div>
);
};

export default ArtVerification;
52 changes: 52 additions & 0 deletions src/views/CT/AHD/AHDScreening.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import React, { useEffect, useState, useCallback } from 'react';
import { useSelector } from 'react-redux';
import { Card, CardHeader, CardBody } from "reactstrap";
import Highcharts from "highcharts";
import HighchartsReact from "highcharts-react-official";
import * as ahdSelectors from '../../../selectors/CT/AHD/ahdSelectors';

const AHDScreening = () => {
const [ahdScreeningChart, setAhdScreeningChart] = useState({});
const ahdScreeningData = useSelector(ahdSelectors.getAHDIndicators);

const loadAHDScreening = useCallback(async () => {
setAhdScreeningChart({
title: { text: '' },
xAxis: [{ categories: [
'PATIENTS ON CARE(TREATMENT NEW/RTT/CTF)',
// 'NO. SCREENED',
'NO. WITH AHD'
], title: { text: 'AHD SCREENING' }, crosshair: true }],
yAxis: [{ title: { text: '' }}],
plotOptions: { column: { dataLabels: { enabled: true, crop: false, overflow: 'none' } } },
tooltip: { shared: true },
legend: { align: 'left', verticalAlign: 'top', y: 0, x: 80 },
series: [
{ name: 'AHD SCREENED', data: [
ahdScreeningData?.NewPatient,
// 100,
ahdScreeningData?.AHD
], type: 'column', color: "#142459" },
]
});
}, [ahdScreeningData]);

useEffect(() => {
loadAHDScreening();
}, [loadAHDScreening]);

return (
<Card className="trends-card">
<CardHeader className="trends-header">
AHD SCREENING
</CardHeader>
<CardBody className="trends-body">
<div className="col-12">
<HighchartsReact highcharts={Highcharts} options={ahdScreeningChart} />
</div>
</CardBody>
</Card>
);
};

export default AHDScreening;
44 changes: 44 additions & 0 deletions src/views/CT/AHD/CD4Testing.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import React, { useEffect, useState, useCallback } from 'react';
import { useSelector } from 'react-redux';
import { Card, CardHeader, CardBody } from "reactstrap";
import Highcharts from "highcharts";
import HighchartsReact from "highcharts-react-official";
import * as ahdSelectors from '../../../selectors/CT/AHD/ahdSelectors';

const AHDScreening = () => {
const [cd4TestingChart, setCd4TestingChart] = useState({});
const cd4TestingData = useSelector(ahdSelectors.getAHDIndicators);

const loadCD4Testing = useCallback(async () => {
setCd4TestingChart({
title: { text: '' },
xAxis: [{ categories: ['PATIENTS ON CARE(TREATMENT NEW/RTT/CTF)', 'DONE CD4 TEST', 'CD4 <200(OR <25%)'], title: { text: 'CD4' }, crosshair: true }],
yAxis: [{ title: { text: '' }}],
plotOptions: { column: { dataLabels: { enabled: true, crop: false, overflow: 'none' } } },
tooltip: { shared: true },
legend: { align: 'left', verticalAlign: 'top', y: 0, x: 80 },
series: [
{ name: 'CD4 TESTING', data: [cd4TestingData?.NewPatient, cd4TestingData?.DoneCD4Test, cd4TestingData?.less200CD4], type: 'column', color: "#142459" },
]
});
}, [cd4TestingData]);

useEffect(() => {
loadCD4Testing();
}, [loadCD4Testing]);

return (
<Card className="trends-card">
<CardHeader className="trends-header">
CD4 TESTING
</CardHeader>
<CardBody className="trends-body">
<div className="col-12">
<HighchartsReact highcharts={Highcharts} options={cd4TestingChart} />
</div>
</CardBody>
</Card>
);
};

export default AHDScreening;
44 changes: 44 additions & 0 deletions src/views/CT/AHD/CryptococcalMeningitis.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import React, { useEffect, useState, useCallback } from 'react';
import { useSelector } from 'react-redux';
import { Card, CardHeader, CardBody } from "reactstrap";
import Highcharts from "highcharts";
import HighchartsReact from "highcharts-react-official";
import * as ahdSelectors from '../../../selectors/CT/AHD/ahdSelectors';

const CryptococcalMeningitis = () => {
const [cryptococcalMeningitisChart, setCryptococcalMeningitisChart] = useState({});
const cryptococcalMeningitisData = useSelector(ahdSelectors.getAHDIndicators);

const loadCryptococcalMeningitis = useCallback(async () => {
setCryptococcalMeningitisChart({
title: { text: '' },
xAxis: [{ categories: ['PATIENTS WITH AHD', 'DONE CrAg TEST', 'CrAg POSITIVE', 'DONE CSF CrAg', 'CSF CrAg POS', 'INITIATED CM TREATMENT', 'PATIENTS DUE FOR PRE-EMPTIVE CM THERAPY'], title: { text: 'CrAg' }, crosshair: true }],
yAxis: [{ title: { text: '' }}],
plotOptions: { column: { dataLabels: { enabled: true, crop: false, overflow: 'none' } } },
tooltip: { shared: true },
legend: { align: 'left', verticalAlign: 'top', y: 0, x: 80 },
series: [
{ name: 'CrAg', data: [cryptococcalMeningitisData?.AHD, cryptococcalMeningitisData?.DoneCrAgTest, cryptococcalMeningitisData?.CrAgPositive, cryptococcalMeningitisData?.CSFCrAg, cryptococcalMeningitisData?.CSFCrAgPositive, cryptococcalMeningitisData?.InitiatedCMTreatment, cryptococcalMeningitisData?.PreemtiveCMTheraphy], type: 'column', color: "#142459" },
]
});
}, [cryptococcalMeningitisData]);

useEffect(() => {
loadCryptococcalMeningitis();
}, [loadCryptococcalMeningitis]);

return (
<Card className="trends-card">
<CardHeader className="trends-header">
CRYPTOCOCCAL MENINGITIS SCREENING & MANAGEMENT
</CardHeader>
<CardBody className="trends-body">
<div className="col-12">
<HighchartsReact highcharts={Highcharts} options={cryptococcalMeningitisChart} />
</div>
</CardBody>
</Card>
);
};

export default CryptococcalMeningitis;
44 changes: 44 additions & 0 deletions src/views/CT/AHD/TBScreeningAndManagement.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import React, { useEffect, useState, useCallback } from 'react';
import { useSelector } from 'react-redux';
import { Card, CardHeader, CardBody } from "reactstrap";
import Highcharts from "highcharts";
import HighchartsReact from "highcharts-react-official";
import * as ahdSelectors from '../../../selectors/CT/AHD/ahdSelectors';

const TBScreeningAndManagement = () => {
const [tbScreeningAndManagementChart, setTbScreeningAndManagementChart] = useState({});
const tbScreeningAndManagementData = useSelector(ahdSelectors.getAHDIndicators);

const loadTBScreeningAndManagement = useCallback(async () => {
setTbScreeningAndManagementChart({
title: { text: '' },
xAxis: [{ categories: ['PATIENTS WITH AHD', 'DONE TB LAM TEST', 'TB LAM POS', 'INITIATED ON TB TREATMENT'], title: { text: 'TB SCREENING & MANAGEMENT' }, crosshair: true }],
yAxis: [{ title: { text: '' }}],
plotOptions: { column: { dataLabels: { enabled: true, crop: false, overflow: 'none' } } },
tooltip: { shared: true },
legend: { align: 'left', verticalAlign: 'top', y: 0, x: 80 },
series: [
{ name: 'PATIENTS', data: [tbScreeningAndManagementData?.AHD, tbScreeningAndManagementData?.DoneTBLamTest, tbScreeningAndManagementData?.TBLamPositive, tbScreeningAndManagementData?.tbInitiated ], type: 'column', color: "#142459" },
]
});
}, [tbScreeningAndManagementData]);

useEffect(() => {
loadTBScreeningAndManagement();
}, [loadTBScreeningAndManagement]);

return (
<Card className="trends-card">
<CardHeader className="trends-header">
TB SCREENING & MANAGEMENT
</CardHeader>
<CardBody className="trends-body">
<div className="col-12">
<HighchartsReact highcharts={Highcharts} options={tbScreeningAndManagementChart} />
</div>
</CardBody>
</Card>
);
};

export default TBScreeningAndManagement;
4 changes: 2 additions & 2 deletions src/views/CT/ArtVerification/ArtVerification.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import React from 'react';
import Loadable from 'react-loadable';
import VisibilitySensor from 'react-visibility-sensor';
import { useDispatch, useSelector } from 'react-redux';
import { useDispatch } from 'react-redux';
import moment from 'moment';
import { Card, CardBody, CardHeader, Col, Row } from 'reactstrap';
import { Col, Row } from 'reactstrap';
import {
enableStickyFilter,
disableStickyFilter,
Expand Down
Loading

0 comments on commit 4115965

Please sign in to comment.