diff --git a/pwa/cypress/plugins/cy-ts-preprocessor.js b/pwa/cypress/plugins/cy-ts-preprocessor.js new file mode 100644 index 0000000..7f0bba9 --- /dev/null +++ b/pwa/cypress/plugins/cy-ts-preprocessor.js @@ -0,0 +1,26 @@ +const wp = require('@cypress/webpack-preprocessor') + +const webpackOptions = { + resolve: { + extensions: ['.ts', '.js'] + }, + module: { + rules: [ + { + test: /\.ts$/, + exclude: [/node_modules/], + use: [ + { + loader: 'ts-loader' + } + ] + } + ] + } +} + +const options = { + webpackOptions +} + +module.exports = wp(options) diff --git a/pwa/src/App.tsx b/pwa/src/App.tsx index 0f251d0..65127ed 100644 --- a/pwa/src/App.tsx +++ b/pwa/src/App.tsx @@ -15,6 +15,7 @@ import TestResults from './components/TestResultsForm' import './scss/App.scss' import './antd-mobile.css' import DebugShowEasyPeasy from './components/DebugShowEasyPeasy' +import TreatmentForm from './components/TreatmentForm' const App: React.FunctionComponent = () => { return ( @@ -54,12 +55,20 @@ const App: React.FunctionComponent = () => { + + + + + diff --git a/pwa/src/components/TreatmentFields.json b/pwa/src/components/TreatmentFields.json new file mode 100644 index 0000000..b6c2de4 --- /dev/null +++ b/pwa/src/components/TreatmentFields.json @@ -0,0 +1,132 @@ +{ + "treatments": [ + { + "id": "multivitamins", + "group-title": "Multivitamins", + "group": [ + { "name": "Multivitamins - Childrens", "id": "vitamin-childrens" }, + { "name": "Multivitamins - Adult", "id": "vitamin-adult" }, + { "name": "Multivitamins - Prenatal", "id": "vitamin-prenatal" } + ] + }, + { + "id": "pain", + "group-title": "Pain", + "group": [ + { "name": "Acetaminophen - 500 tab", "id": "acetaminophen-500" }, + { "name": "Acetaminophen - 80 chew", "id": "acetaminophen-chew" }, + { "name": "Acetaminophen - 160 mg/5 cc", "id": "acetaminophen-mg" }, + { "name": "Ibuprofen - 200 mg", "id": "ibuprofen-200" }, + { "name": "Ibuprofen - 100 mg/5 cc", "id": "ibuprofen-100" } + ] + }, + { + "id": "gi", + "group-title": "GI", + "group": [ + { "name": "Omeprazole", "id": "omeprazole" }, + { "name": "Pepto Bismol", "id": "pepto-bismol" }, + { "name": "Ranitidine", "id": "ranitidine" }, + { "name": "Zinc", "id": "zinc" }, + { "name": "Tums", "id": "tums" }, + { "name": "ORS", "id": "ors" } + ] + }, + { + "id": "cardiac", + "group-title": "Cardiac", + "group": [ + { "name": "Amlodipine", "id": "amlodipine" }, + { "name": "Aspirin", "id": "aspirin" }, + { "name": "Atenolol", "id": "atenolol" }, + { "name": "Lisinopril", "id": "lisinopril" }, + { "name": "HCTZ", "id": "hctz" }, + { "name": "Lasix tab", "id": "lasix" } + ] + }, + { + "id": "anti-infectives", + "group-title": "Anti-infectives", + "group": [ + { "name": "Albendazole", "id": "albendazole" }, + { "name": "Amoxicillin - 500 tab", "id": "amoxicillin-tab" }, + { "name": "Amoxicillin - 250 chew", "id": "amoxicillin-chew" }, + { "name": "Amoxicillin - 250 mg/cc", "id": "amoxicillin-mg" }, + { "name": "Augmentin", "id": "augmentin" }, + { "name": "Azithromycin - 250 tab", "id": "azithromycin-tab" }, + { "name": "Azithromycin - 200 mg/5 cc", "id": "azithromycin-mg" }, + { "name": "Bactrim - DS tab", "id": "bactrim-tab" }, + { "name": "Bactrim - 40 mg/5 cc", "id": "bactrim-mg" }, + { "name": "Cipro", "id": "cipro" }, + { "name": "Chloroquine", "id": "chloroquine" }, + { "name": "Doxycycline", "id": "doxycycline" }, + { "name": "Flagyl", "id": "flagyl" }, + { "name": "Fluconazole", "id": "fluconazole" }, + { "name": "Griseofulvin - 500 mg", "id": "griseofulvin-500" }, + { "name": "Griseofulvin - 125 mg", "id": "griseofulvin-125" }, + { "name": "Ivermectin", "id": "ivermectin" }, + { "name": "Keflex 500 mg tab", "id": "keflex" }, + { "name": "Nitrofurantoin", "id": "nitrofurantoin" }, + { "name": "Rocephin Inj. - 50 mg/kg", "id": "rocephin-50" }, + { "name": "Rocephin Inj. - 250 mg", "id": "rocephin-250" }, + { "name": "Rocephin Inj. - 1 gm", "id": "rocephin-1" } + ] + }, + { + "id": "topical", + "group-title": "Topical", + "group": [ + { "name": "Clotrimazole", "id": "clotrimazole" }, + { "name": "Triple Antibiotic", "id": "triple-antibiotic" }, + { "name": "Hydrocortisone", "id": "hydrocortisone" }, + { "name": "Permethrine", "id": "permethrine" }, + { "name": "Silvadine", "id": "silvadine" } + ] + }, + { + "id": "im", + "group-title": "IM", + "group": [ + { "name": "Dexamethasone", "id": "dexamethasone" }, + { "name": "Lasix Injection", "id": "lasix-injection" } + ] + }, + { + "id": "misc", + "group-title": "Misc.", + "group": [ + { "name": "Albuterol", "id": "albuterol" }, + { "name": "Benadryl - 25 mg", "id": "benadryl-25" }, + { "name": "Benadryl - 12.5 mg/5 cc", "id": "benadryl-12-5" }, + { "name": "Depo-Provera", "id": "depo-provera" }, + { "name": "Ferrous sulfate", "id": "ferrous-sulfate" }, + { "name": "Paroxetine", "id": "paroxetine" }, + { "name": "Labetolol", "id": "labetolol" }, + { "name": "Methyldopa", "id": "methyldopa" }, + { "name": "Metformin", "id": "metformin" }, + { "name": "OCP", "id": "ocp" }, + { "name": "IUD", "id": "iud" }, + { "name": "Carbamazepine", "id": "carbamazepine" }, + { "name": "Keppra", "id": "keppra" }, + { "name": "Prednisone", "id": "prednisone" }, + { "name": "Terazosin", "id": "terazosin" }, + { "text-input-title": "Misc. Comments", "text-input-id": "misc-comments" } + ] + }, + { + "id": "referrals", + "group-title": "Referrals", + "group": [ + { "name": "Saw dentist", "id": "saw-dentist" }, + { "name": "Saw eye doctor", "id": "saw-eye-doctor" }, + { "name": "CHW", "id": "chw" }, + { "name": "Given Glasses", "id": "given-glasses" }, + { "name": "Outside", "id": "outside" } + ] + }, + { + "text-input-title": "Treatment Comments", + "text-input-id": "comments" + } + ] +} diff --git a/pwa/src/components/TreatmentForm.test.tsx b/pwa/src/components/TreatmentForm.test.tsx new file mode 100644 index 0000000..20fc2d9 --- /dev/null +++ b/pwa/src/components/TreatmentForm.test.tsx @@ -0,0 +1,103 @@ +import React from 'react' +import { render, fireEvent } from '@testing-library/react' +import TreatmentForm from './TreatmentForm' +import * as data from './TreatmentFields.json' + +/* + +Treatment Fields are stored in TreatmentFields.json in the format: + +{ + "treatments" : [ + { + "id": "multivitamins", + "group-title": "Multivitamins", + "group": [ + { "name": "Multivitamins - Childrens", "id": "vitamin-childrens" }, + { "name": "Multivitamins - Adult", "id": "vitamin-adult" }, + { "name": "Multivitamins - Prenatal", "id": "vitamin-prenatal" } + ] + }, + {...} + ] +} +*/ + +const treatmentFields = data.treatments + +test('renders the form', async () => { + const dom = render() + expect(dom.getByTestId('treatment-form-wrapper')).toBeTruthy() +}) + +test('renders each treatment.name data field', () => { + const { getByText } = render() + + treatmentFields.forEach((treatmentType) => { + if (treatmentType['group-title'] != null) { + const re = new RegExp(treatmentType['group-title'], 'gi') + const field = getByText(re) + expect(field).toBeInTheDocument() + } + }) +}) + +test('renders each diagnoses.text-input-title data field as a text entry field', () => { + const { getByTestId, getByText } = render( ) + + treatmentFields.forEach((treatment) => { + + if ( + treatment['text-input-title'] != null && + treatment['text-input-id'] != null + ) { + const re = new RegExp(`\^${treatment['text-input-id']}\$`, 'gi') + const field = getByTestId(re) + expect(field).toBeInTheDocument() + expect(field).toHaveAttribute('type', 'text') + } + + // To account for nested text fields in the misc. tab + if (treatment.group != null && treatment.id != null) { + fireEvent.click(getByText(treatment['group-title'])) + if ( + treatment['text-input-title'] != null && + treatment['text-input-id'] != null + ) { + const re = new RegExp(`\^${treatment['text-input-id']}\$`, 'gi') + const field = getByTestId(re) + expect(field).toBeInTheDocument() + expect(field).toHaveAttribute('type', 'text') + } + } + }) +}) + +test('expands each diagnoses.group accordion and checks functionality of checkboxes', () => { + const { getByTestId, getByText } = render() + treatmentFields.forEach((treatment) => { + if (treatment.group != null && treatment.id != null) { + // Expand the accordion + fireEvent.click(getByText(treatment['group-title'])) + + treatment.group.forEach((groupElement) => { + if (groupElement.id != null && groupElement.name != null) { + const re = new RegExp(`\^${groupElement.id}\$`, 'gi') + const groupCheckboxItem = getByTestId(re) + expect(groupCheckboxItem).toBeInTheDocument() + expect(groupCheckboxItem).toHaveClass('am-checkbox-item') + + const checkBox = groupCheckboxItem.getElementsByTagName( + 'span', + )[0] + expect(checkBox).not.toHaveClass('am-checkbox-checked') + const checkBoxInput = groupCheckboxItem.getElementsByClassName( + 'am-checkbox-input', + )[0] + fireEvent.click(checkBoxInput) + expect(checkBox).toHaveClass('am-checkbox-checked') + } + }) + } + }) +}) diff --git a/pwa/src/components/TreatmentForm.tsx b/pwa/src/components/TreatmentForm.tsx new file mode 100644 index 0000000..6ff3838 --- /dev/null +++ b/pwa/src/components/TreatmentForm.tsx @@ -0,0 +1,102 @@ +import React, { ReactElement } from 'react' +import { TextareaItem, Accordion, Checkbox, List, InputItem } from 'antd-mobile' +import '../scss/Login.scss' +import * as data from './TreatmentFields.json' + +/* + +Treatment Fields are stored in TreatmentFields.json in the format: + +{ + "treatments" : [ + { + "id": "multivitamins", + "group-title": "Multivitamins", + "group": [ + { "name": "Multivitamins - Childrens", "id": "vitamin-childrens" }, + { "name": "Multivitamins - Adult", "id": "vitamin-adult" }, + { "name": "Multivitamins - Prenatal", "id": "vitamin-prenatal" } + ] + }, + {...} + ] +} +*/ + +const CheckboxItem = Checkbox.CheckboxItem; +const treatmentFields = data.treatments + +export default function TreatmentForm(): ReactElement { + return ( +
+ {treatmentFields.map((field) => { + const formElements: ReactElement[] = [] + + if (field['text-input-title'] != null && field['text-input-id'] != null) { + formElements.push( + field['text-input-title']}> + + , + ) + } + + if (field.group != null) { + const groupElements: ReactElement[] = [] + + // add each group element to the internalElement array + field.group.forEach((ele: any) => { + if (ele.id != null && ele.name != null) { + groupElements.push( + + + {ele.name} + + , + ) + } + + if (ele['text-input-title'] != null && ele['text-input-id'] != null) { + groupElements.push( + + ) + } + }) + + // Render the entire list with the internal elements + if (field['group-title'] != null && field.id !== null) { + formElements.push( +
+ + + {groupElements} + + +
+ ) + } + } + + return <> {formElements} + })} +
+ ) +} \ No newline at end of file