Skip to content

Commit

Permalink
OH2-291 | Vaccine list (#586)
Browse files Browse the repository at this point in the history
* feature/OH2-296 | Vaccine list

* Add filters
  • Loading branch information
SilverD3 authored Jun 7, 2024
1 parent e338e2e commit 3e4edb3
Show file tree
Hide file tree
Showing 20 changed files with 253 additions and 24 deletions.
1 change: 1 addition & 0 deletions src/components/accessories/admin/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@ export * from "./exams";
export * from "./diseases";
export * from "./users";
export * from "./operations";
export * from "./vaccines";
export * from "./suppliers";
2 changes: 2 additions & 0 deletions src/components/accessories/admin/suppliers/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
export * from "./Suppliers";
export * from "./editSupplier";
export * from "./newSupplier";
7 changes: 7 additions & 0 deletions src/components/accessories/admin/vaccines/Vaccines.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import React from "react";

import VaccinesTable from "./vaccinesTable";

export const Vaccines = () => {
return <VaccinesTable />;
};
1 change: 1 addition & 0 deletions src/components/accessories/admin/vaccines/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from "./Vaccines";
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
.table {
display: grid;
margin-top: 30px;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
import React, { useEffect } from "react";
import Table from "../../../table/Table";
import { useTranslation } from "react-i18next";
import InfoBox from "../../../infoBox/InfoBox";
import { CircularProgress } from "@material-ui/core";
import { useDispatch, useSelector } from "react-redux";
import { IState } from "../../../../../types";
import { VaccineDTO, VaccineTypeDTO } from "../../../../../generated";
import { ApiResponse } from "../../../../../state/types";
import classes from "./VaccinesTable.module.scss";
import { getVaccines } from "../../../../../state/vaccines/actions";
import { TFilterField } from "../../../table/filter/types";
import { getVaccineTypes } from "../../../../../state/vaccineTypes/actions";

export const VaccinesTable = () => {
const dispatch = useDispatch();
const { t } = useTranslation();

useEffect(() => {
dispatch(getVaccines());
dispatch(getVaccineTypes());
}, [dispatch]);

const header = ["code", "type", "description"];

const label = {
code: t("vaccine.code"),
type: t("vaccine.vaccinetype"),
description: t("vaccine.description"),
};

const order = ["code", "type", "description"];

const { data, status, error } = useSelector<
IState,
ApiResponse<VaccineDTO[]>
>((state) => state.vaccines.vaccineList);

const { data: vaccineTypes } = useSelector<
IState,
ApiResponse<VaccineTypeDTO[]>
>((state) => state.vaccineTypes.getVaccineTypes);

const filters: TFilterField[] = [
{
key: "type",
label: t("vaccine.vaccinetype"),
type: "select",
options:
vaccineTypes?.map((vt) => ({
label: vt.description,
value: vt.description,
})) ?? [],
},
{ key: "description", label: t("vaccine.description"), type: "text" },
];

const formatDataToDisplay = (data: VaccineDTO[]) => {
return data.map((item) => {
return {
code: item.code ?? "",
type: item.vaccineType?.description ?? "",
description: item.description ?? "",
};
});
};

return (
<div className={classes.table}>
{(() => {
switch (status) {
case "FAIL":
return <InfoBox type="error" message={error?.message} />;
case "LOADING":
return (
<div style={{ minWidth: "100%" }}>
<CircularProgress
style={{ marginLeft: "50%", position: "relative" }}
/>
</div>
);

case "SUCCESS":
return (
<Table
rowData={formatDataToDisplay(data ?? [])}
tableHeader={header}
labelData={label}
columnsOrder={order}
rowsPerPage={10}
isCollapsabile={false}
showEmptyCell={false}
filterColumns={filters}
manualFilter={false}
rowKey="code"
/>
);
case "SUCCESS_EMPTY":
return <InfoBox type="info" message={t("common.emptydata")} />;
default:
return;
}
})()}
</div>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { VaccinesTable } from "./VaccinesTable";

export default VaccinesTable;
2 changes: 2 additions & 0 deletions src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ import layouts from "./state/layouts/reducer";
import dashboard from "./state/dashboard/reducer";
import operationTypes from "./state/operationTypes/reducer";
import users from "./state/users/reducer";
import vaccines from "./state/vaccines/reducer";
import vaccineTypes from "./state/vaccineTypes/reducer";
import suppliers from "./state/suppliers/reducer";

Expand Down Expand Up @@ -70,6 +71,7 @@ const reducer = combineReducers<IState>({
dashboard,
operationTypes,
users,
vaccines,
vaccineTypes,
suppliers,
});
Expand Down
11 changes: 11 additions & 0 deletions src/mockServer/fixtures/vaccineDTO.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
export const vaccineDTO = [
{ "code": "1", "description": "BCG", "vaccineType": { "code": "C", "description": "Child" }, "lock": 0 },
{ "code": "6", "description": "DPT 1 - HepB + Hib 1", "vaccineType": { "code": "C", "description": "Child" }, "lock": 0 },
{ "code": "2", "description": "POLIO 0 C", "vaccineType": { "code": "C", "description": "Child" }, "lock": 0 },
{ "code": "3", "description": "POLIO 1 C", "vaccineType": { "code": "C", "description": "Child" }, "lock": 0 },
{ "code": "11", "description": "TT VACCINE DOSE 2", "vaccineType": { "code": "P", "description": "Pregnant" }, "lock": 0 },
{ "code": "16", "description": "TT VACCINE DOSE 3", "vaccineType": { "code": "N", "description": "No pregnant" }, "lock": 0 },
{ "code": "12", "description": "TT VACCINE DOSE 3", "vaccineType": { "code": "P", "description": "Pregnant" }, "lock": 0 },
{ "code": "17", "description": "TT VACCINE DOSE 4", "vaccineType": { "code": "N", "description": "No pregnant" }, "lock": 0 },
];

23 changes: 3 additions & 20 deletions src/mockServer/fixtures/vaccineTypesDTO.js
Original file line number Diff line number Diff line change
@@ -1,24 +1,7 @@
const vaccineTypesDTO = [
{
"code": "VC01",
"description": "Measles, Mumps, and Rubella (MMR) Vaccine"
},
{
"code": "VC02",
"description": "Varicella (Chickenpox) Vaccine"
},
{
"code": "VC03",
"description": "Tetanus, Diphtheria, and Acellular Pertussis (Tdap) Vaccine"
},
{
"code": "VC04",
"description": "Human Papillomavirus (HPV) Vaccine"
},
{
"code": "VC05",
"description": "Influenza (Flu) Vaccine"
}
{ "code": "C", "description": "Child" },
{ "code": "P", "description": "Pregnant" },
{ "code": "N", "description": "No pregnant" },
];

export default vaccineTypesDTO;
9 changes: 9 additions & 0 deletions src/mockServer/routes/vaccine.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { vaccineDTO } from "../fixtures/vaccineDTO";

export const vaccineRoutes = (server) => {
server.namespace("/vaccines", () => {
server.get("/").intercept((req, res) => {
res.status(200).json(vaccineDTO);
});
});
}
2 changes: 2 additions & 0 deletions src/mockServer/server.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import { pricesRoutes } from "./routes/prices";
import { operationRoutes } from "./routes/operations";
import { hospitalRoutes } from "./routes/hospital";
import { operationTypeRoutes } from "./routes/operationTypes";
import { vaccineRoutes } from './routes/vaccine'
import { vaccineTypesRoutes } from './routes/vaccineTypes'
import { suppliersRoutes } from './routes/suppliers';

Expand Down Expand Up @@ -59,6 +60,7 @@ export function makeServer() {
ageTypeRoutes(server);
hospitalRoutes(server);
operationTypeRoutes(server);
vaccineRoutes(server);
vaccineTypesRoutes(server);
suppliersRoutes(server);
});
Expand Down
5 changes: 5 additions & 0 deletions src/resources/i18n/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -822,6 +822,11 @@
"procedure": "Procedure",
"defaultResult": "Default value"
},
"vaccine": {
"code": "Code",
"vaccinetype": "Vaccine Type",
"description": "Name"
},
"types": {
"selectAType": "Select a type",
"vaccines": "Type of vaccines",
Expand Down
9 changes: 5 additions & 4 deletions src/routes/Admin/AdminRoutes.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,16 @@ import TypesRoutes from "./TypesRoutes";
import {
Diseases,
Operations,
Vaccines,
Suppliers,
NewSupplier,
EditSupplier,
NewDisease,
EditDisease,
NewOperation,
EditOperation,
Suppliers,
} from "../../components/accessories/admin";
import { PATHS } from "../../consts";
import { NewSupplier } from "../../components/accessories/admin/suppliers/newSupplier";
import { EditSupplier } from "../../components/accessories/admin/suppliers/editSupplier";

export const AdminRoutes = () => {
const { t } = useTranslation();
Expand Down Expand Up @@ -120,7 +121,7 @@ export const AdminRoutes = () => {
element: (
<AdminActivityContent
title={t("nav.vaccines")}
children={<Wards />}
children={<Vaccines />}
/>
),
},
Expand Down
41 changes: 41 additions & 0 deletions src/state/vaccines/actions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { isEmpty } from "lodash";
import { Dispatch } from "redux";
import { VaccineDTO, VaccinesApi } from "../../generated";
import { customConfiguration } from "../../libraries/apiUtils/configuration";
import { IAction } from "../types";
import {
GET_VACCINES_FAIL,
GET_VACCINES_LOADING,
GET_VACCINES_SUCCESS,
} from "./consts";

const vaccinesApi = new VaccinesApi(customConfiguration());

export const getVaccines =
() =>
(dispatch: Dispatch<IAction<VaccineDTO[], {}>>): void => {
dispatch({
type: GET_VACCINES_LOADING,
});
vaccinesApi.getVaccines().subscribe(
(payload) => {
if (typeof payload === "object" && !isEmpty(payload)) {
dispatch({
type: GET_VACCINES_SUCCESS,
payload: payload,
});
} else {
dispatch({
type: GET_VACCINES_SUCCESS,
payload: [],
});
}
},
(error) => {
dispatch({
type: GET_VACCINES_FAIL,
error: error?.response,
});
}
);
};
3 changes: 3 additions & 0 deletions src/state/vaccines/consts.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export const GET_VACCINES_LOADING = "vaccines/GET_VACCINES_LOADING";
export const GET_VACCINES_SUCCESS = "vaccines/GET_VACCINES_SUCCESS";
export const GET_VACCINES_FAIL = "vaccines/GET_VACCINES_FAIL";
6 changes: 6 additions & 0 deletions src/state/vaccines/initial.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { ApiResponse } from "../types";
import { IVaccineState } from "./types";

export const initial: IVaccineState = {
vaccineList: new ApiResponse({ status: "IDLE", data: [] }),
};
34 changes: 34 additions & 0 deletions src/state/vaccines/reducer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import produce from "immer";
import { IAction } from "../types";
import {
GET_VACCINES_FAIL,
GET_VACCINES_LOADING,
GET_VACCINES_SUCCESS,
} from "./consts";
import { initial } from "./initial";
import { IVaccineState } from "./types";

export default produce((draft: IVaccineState, action: IAction<any, any>) => {
switch (action.type) {
/**
* GET_EXAMS
*/
case GET_VACCINES_LOADING: {
draft.vaccineList.status = "LOADING";
break;
}

case GET_VACCINES_SUCCESS: {
draft.vaccineList.status = "SUCCESS";
draft.vaccineList.data = action.payload;
delete draft.vaccineList.error;
break;
}

case GET_VACCINES_FAIL: {
draft.vaccineList.status = "FAIL";
draft.vaccineList.error = action.error;
break;
}
}
}, initial);
6 changes: 6 additions & 0 deletions src/state/vaccines/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { VaccineDTO } from "../../generated";
import { ApiResponse } from "../types";

export type IVaccineState = {
vaccineList: ApiResponse<Array<VaccineDTO>>;
};
2 changes: 2 additions & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import { ILayoutsState } from "./state/layouts/types";
import { IDashboardState } from "./state/dashboard/types";
import { IOperationTypeState } from "./state/operationTypes/types";
import { IUserState } from "./state/users/types";
import { IVaccineState } from "./state/vaccines/types";
import { IVaccineTypesState } from "./state/vaccineTypes/types";
import { ISupplierState } from "./state/suppliers/types";

Expand Down Expand Up @@ -54,6 +55,7 @@ export interface IState {
dashboard: IDashboardState;
operationTypes: IOperationTypeState;
users: IUserState;
vaccines: IVaccineState;
vaccineTypes: IVaccineTypesState;
suppliers: ISupplierState;
}
Expand Down

0 comments on commit 3e4edb3

Please sign in to comment.