From 3e4edb3e90375cdc933e018f999dfe0a800302c2 Mon Sep 17 00:00:00 2001 From: Silevester Dongmo <58907550+SilverD3@users.noreply.github.com> Date: Fri, 7 Jun 2024 16:40:46 +0100 Subject: [PATCH] OH2-291 | Vaccine list (#586) * feature/OH2-296 | Vaccine list * Add filters --- src/components/accessories/admin/index.ts | 1 + .../accessories/admin/suppliers/index.ts | 2 + .../accessories/admin/vaccines/Vaccines.tsx | 7 ++ .../accessories/admin/vaccines/index.ts | 1 + .../vaccinesTable/VaccinesTable.module.scss | 4 + .../vaccines/vaccinesTable/VaccinesTable.tsx | 106 ++++++++++++++++++ .../admin/vaccines/vaccinesTable/index.ts | 3 + src/index.tsx | 2 + src/mockServer/fixtures/vaccineDTO.js | 11 ++ src/mockServer/fixtures/vaccineTypesDTO.js | 23 +--- src/mockServer/routes/vaccine.js | 9 ++ src/mockServer/server.js | 2 + src/resources/i18n/en.json | 5 + src/routes/Admin/AdminRoutes.tsx | 9 +- src/state/vaccines/actions.ts | 41 +++++++ src/state/vaccines/consts.ts | 3 + src/state/vaccines/initial.ts | 6 + src/state/vaccines/reducer.ts | 34 ++++++ src/state/vaccines/types.ts | 6 + src/types.ts | 2 + 20 files changed, 253 insertions(+), 24 deletions(-) create mode 100644 src/components/accessories/admin/vaccines/Vaccines.tsx create mode 100644 src/components/accessories/admin/vaccines/index.ts create mode 100644 src/components/accessories/admin/vaccines/vaccinesTable/VaccinesTable.module.scss create mode 100644 src/components/accessories/admin/vaccines/vaccinesTable/VaccinesTable.tsx create mode 100644 src/components/accessories/admin/vaccines/vaccinesTable/index.ts create mode 100644 src/mockServer/fixtures/vaccineDTO.js create mode 100644 src/mockServer/routes/vaccine.js create mode 100644 src/state/vaccines/actions.ts create mode 100644 src/state/vaccines/consts.ts create mode 100644 src/state/vaccines/initial.ts create mode 100644 src/state/vaccines/reducer.ts create mode 100644 src/state/vaccines/types.ts diff --git a/src/components/accessories/admin/index.ts b/src/components/accessories/admin/index.ts index 90bf439ee..67d6bce8c 100644 --- a/src/components/accessories/admin/index.ts +++ b/src/components/accessories/admin/index.ts @@ -3,4 +3,5 @@ export * from "./exams"; export * from "./diseases"; export * from "./users"; export * from "./operations"; +export * from "./vaccines"; export * from "./suppliers"; diff --git a/src/components/accessories/admin/suppliers/index.ts b/src/components/accessories/admin/suppliers/index.ts index 32662c0bb..cd9c2072d 100644 --- a/src/components/accessories/admin/suppliers/index.ts +++ b/src/components/accessories/admin/suppliers/index.ts @@ -1 +1,3 @@ export * from "./Suppliers"; +export * from "./editSupplier"; +export * from "./newSupplier"; diff --git a/src/components/accessories/admin/vaccines/Vaccines.tsx b/src/components/accessories/admin/vaccines/Vaccines.tsx new file mode 100644 index 000000000..545031db3 --- /dev/null +++ b/src/components/accessories/admin/vaccines/Vaccines.tsx @@ -0,0 +1,7 @@ +import React from "react"; + +import VaccinesTable from "./vaccinesTable"; + +export const Vaccines = () => { + return ; +}; diff --git a/src/components/accessories/admin/vaccines/index.ts b/src/components/accessories/admin/vaccines/index.ts new file mode 100644 index 000000000..97d26c2d9 --- /dev/null +++ b/src/components/accessories/admin/vaccines/index.ts @@ -0,0 +1 @@ +export * from "./Vaccines"; diff --git a/src/components/accessories/admin/vaccines/vaccinesTable/VaccinesTable.module.scss b/src/components/accessories/admin/vaccines/vaccinesTable/VaccinesTable.module.scss new file mode 100644 index 000000000..853d7c9fe --- /dev/null +++ b/src/components/accessories/admin/vaccines/vaccinesTable/VaccinesTable.module.scss @@ -0,0 +1,4 @@ +.table { + display: grid; + margin-top: 30px; +} diff --git a/src/components/accessories/admin/vaccines/vaccinesTable/VaccinesTable.tsx b/src/components/accessories/admin/vaccines/vaccinesTable/VaccinesTable.tsx new file mode 100644 index 000000000..a6bc24e23 --- /dev/null +++ b/src/components/accessories/admin/vaccines/vaccinesTable/VaccinesTable.tsx @@ -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 + >((state) => state.vaccines.vaccineList); + + const { data: vaccineTypes } = useSelector< + IState, + ApiResponse + >((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 ( +
+ {(() => { + switch (status) { + case "FAIL": + return ; + case "LOADING": + return ( +
+ +
+ ); + + case "SUCCESS": + return ( + + ); + case "SUCCESS_EMPTY": + return ; + default: + return; + } + })()} + + ); +}; diff --git a/src/components/accessories/admin/vaccines/vaccinesTable/index.ts b/src/components/accessories/admin/vaccines/vaccinesTable/index.ts new file mode 100644 index 000000000..8f1927234 --- /dev/null +++ b/src/components/accessories/admin/vaccines/vaccinesTable/index.ts @@ -0,0 +1,3 @@ +import { VaccinesTable } from "./VaccinesTable"; + +export default VaccinesTable; diff --git a/src/index.tsx b/src/index.tsx index 95237ce21..a707efc72 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -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"; @@ -70,6 +71,7 @@ const reducer = combineReducers({ dashboard, operationTypes, users, + vaccines, vaccineTypes, suppliers, }); diff --git a/src/mockServer/fixtures/vaccineDTO.js b/src/mockServer/fixtures/vaccineDTO.js new file mode 100644 index 000000000..2576551a1 --- /dev/null +++ b/src/mockServer/fixtures/vaccineDTO.js @@ -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 }, +]; + diff --git a/src/mockServer/fixtures/vaccineTypesDTO.js b/src/mockServer/fixtures/vaccineTypesDTO.js index 9db126440..9eac4ded8 100644 --- a/src/mockServer/fixtures/vaccineTypesDTO.js +++ b/src/mockServer/fixtures/vaccineTypesDTO.js @@ -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; \ No newline at end of file diff --git a/src/mockServer/routes/vaccine.js b/src/mockServer/routes/vaccine.js new file mode 100644 index 000000000..191750614 --- /dev/null +++ b/src/mockServer/routes/vaccine.js @@ -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); + }); + }); +} \ No newline at end of file diff --git a/src/mockServer/server.js b/src/mockServer/server.js index 2999a0f30..e169f5947 100644 --- a/src/mockServer/server.js +++ b/src/mockServer/server.js @@ -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'; @@ -59,6 +60,7 @@ export function makeServer() { ageTypeRoutes(server); hospitalRoutes(server); operationTypeRoutes(server); + vaccineRoutes(server); vaccineTypesRoutes(server); suppliersRoutes(server); }); diff --git a/src/resources/i18n/en.json b/src/resources/i18n/en.json index e48887774..bacfd877c 100644 --- a/src/resources/i18n/en.json +++ b/src/resources/i18n/en.json @@ -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", diff --git a/src/routes/Admin/AdminRoutes.tsx b/src/routes/Admin/AdminRoutes.tsx index 9e5e3d6bf..4ba801d1a 100644 --- a/src/routes/Admin/AdminRoutes.tsx +++ b/src/routes/Admin/AdminRoutes.tsx @@ -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(); @@ -120,7 +121,7 @@ export const AdminRoutes = () => { element: ( } + children={} /> ), }, diff --git a/src/state/vaccines/actions.ts b/src/state/vaccines/actions.ts new file mode 100644 index 000000000..2994dba47 --- /dev/null +++ b/src/state/vaccines/actions.ts @@ -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>): 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, + }); + } + ); + }; diff --git a/src/state/vaccines/consts.ts b/src/state/vaccines/consts.ts new file mode 100644 index 000000000..46c8aa4b9 --- /dev/null +++ b/src/state/vaccines/consts.ts @@ -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"; diff --git a/src/state/vaccines/initial.ts b/src/state/vaccines/initial.ts new file mode 100644 index 000000000..dc21dcc99 --- /dev/null +++ b/src/state/vaccines/initial.ts @@ -0,0 +1,6 @@ +import { ApiResponse } from "../types"; +import { IVaccineState } from "./types"; + +export const initial: IVaccineState = { + vaccineList: new ApiResponse({ status: "IDLE", data: [] }), +}; diff --git a/src/state/vaccines/reducer.ts b/src/state/vaccines/reducer.ts new file mode 100644 index 000000000..710a08738 --- /dev/null +++ b/src/state/vaccines/reducer.ts @@ -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) => { + 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); diff --git a/src/state/vaccines/types.ts b/src/state/vaccines/types.ts new file mode 100644 index 000000000..5933a3b4b --- /dev/null +++ b/src/state/vaccines/types.ts @@ -0,0 +1,6 @@ +import { VaccineDTO } from "../../generated"; +import { ApiResponse } from "../types"; + +export type IVaccineState = { + vaccineList: ApiResponse>; +}; diff --git a/src/types.ts b/src/types.ts index eb84e13c7..95b44f83e 100644 --- a/src/types.ts +++ b/src/types.ts @@ -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"; @@ -54,6 +55,7 @@ export interface IState { dashboard: IDashboardState; operationTypes: IOperationTypeState; users: IUserState; + vaccines: IVaccineState; vaccineTypes: IVaccineTypesState; suppliers: ISupplierState; }