From 36674febe43f041034677f99af4a5d41f6285ba5 Mon Sep 17 00:00:00 2001 From: Ayushya Amitabh Date: Wed, 21 Apr 2021 00:00:42 -0400 Subject: [PATCH] V1.1.0/add compat functions, script to update, data source select --- functions/src/index.ts | 182 +++++++++++++++- functions/src/updateCounts.js | 186 +++++++++++++++++ website/public/styles/extrasmall.css | 31 +++ website/public/styles/medium.css | 22 +- website/src/index.js | 300 ++++++++++++++++----------- 5 files changed, 595 insertions(+), 126 deletions(-) create mode 100644 functions/src/updateCounts.js diff --git a/functions/src/index.ts b/functions/src/index.ts index 894c60c..a6abe10 100644 --- a/functions/src/index.ts +++ b/functions/src/index.ts @@ -45,6 +45,7 @@ const serializeGaId = (_gaid: string): string => { } return ""; }; + const addResultToStats = async (data : SaveResultRequestData) => { const cleanData : Record = Object.assign({}, data); @@ -56,6 +57,15 @@ const addResultToStats = async (data : SaveResultRequestData) => { count: admin.firestore.FieldValue.increment(1), }; if (data.name === VAX_NAMES.PB || data.name === VAX_NAMES.MD) { + if (data.dose === VAX_DOSES.ONE) { + updateDoc[`${VAX_DOSES.ONE}.${data.age}.count`] = + admin.firestore.FieldValue.increment(1); + } else if (data.dose === VAX_DOSES.TWO) { + updateDoc[`${VAX_DOSES.ONE}.${data.age}.count`] = + admin.firestore.FieldValue.increment(1); + updateDoc[`${VAX_DOSES.TWO}.${data.age}.count`] = + admin.firestore.FieldValue.increment(1); + } Object.keys(VAX_DOSES).forEach((doseKey : string) => { const dose : string = VAX_DOSES[doseKey]; Object.keys(cleanData[dose]).forEach((symptom : string) => { @@ -70,6 +80,8 @@ const addResultToStats = async (data : SaveResultRequestData) => { }); }); } else { + updateDoc[`${data.age}.count`] = + admin.firestore.FieldValue.increment(1); Object.keys(cleanData).forEach((symptom : string) => { let updateDocSymptom = symptom.replace("/", "OR"); if (symptom === "DIARRHEA") { @@ -119,7 +131,10 @@ const removeResultFromStats = async (data : FirebaseFirestore.DocumentData) => { admin.firestore().collection("stats").doc(data.name).update(updateDoc); }; -export const getStats = functions.https.onCall( +/** + * FUNCTIONS FROM V1.1.0 TO CURRENT + */ +export const getStatsV1 = functions.https.onCall( async () => { const stats = await admin.firestore().collection("stats").get(); const docs = stats.docs @@ -132,7 +147,7 @@ export const getStats = functions.https.onCall( return returnData; }); -export const saveResult = functions.https.onCall( +export const saveResultV1 = functions.https.onCall( async (data: SaveResultRequestData, context) => { if (!!data && !!context) { const {gid} = data; @@ -162,7 +177,7 @@ export const saveResult = functions.https.onCall( } }); -export const getPastResult = +export const getPastResultV1 = functions.https.onCall(async (data : {gid:string}, context) => { if (!!data && !!context) { const {gid} = data; @@ -227,3 +242,164 @@ export const getPastResult = } return undefined; }); + +/** + * FUNCTIONS FROM V1.0.0 TO V1.0.1 + */ +export const saveResult = functions.https.onCall( + async (data: SaveResultRequestData, context) => { + if (!!data && !!context) { + const {gid} = data; + const docId: string = serializeGaId(gid); + const docData: Record = + Object.assign({}, data); + delete docData.gid; + const existingData = await admin + .firestore() + .collection("results") + .doc(docId) + .get() + .then((doc) => doc.data()); + if (existingData !== undefined && existingData !== docData && + existingData.name === docData.name) { + // DATA EXISTS FOR USER + // BUT DIFF DATA SENT FOR UPDATE + await admin.firestore().collection("results").doc(docId).set(docData); + delete docData.age; + delete docData.name; + delete docData.dose; + const updateDoc : Record = {}; + Object.keys(docData).forEach((symptom : string) => { + // IF WAS TRUE, NOW FALSE = -1 + // IF WAS TRUE, NOW TRUE = 0 + // IF WAS FALSE, NOW TRUE = +1 + // IF WAS FALSE, NOW FALSE = 0 + let incrementValue = 0; + if (existingData[symptom] === true && docData[symptom] === false) { + incrementValue = -1; + } else if (existingData[symptom] === false && + docData[symptom] === true) { + incrementValue = 1; + } + if (data.dose) { + updateDoc[ + `${data.dose}.${data.age}.${symptom.replace("/", "OR")}`] = + admin.firestore.FieldValue.increment(incrementValue); + } else { + updateDoc[`${data.age}.${symptom.replace("/", "OR")}`] = + admin.firestore.FieldValue.increment(incrementValue); + } + }); + admin + .firestore() + .collection("stats") + .doc(data.name) + .update(updateDoc); + } else if (existingData !== undefined && existingData !== docData && + existingData.name !== docData.name) { + // UNDO DATA FOR OLD VAX + // DECREMENT VALUES FOR EACH SYMPTOM ON OLD VAX + const undoDoc : Record = { + count: admin.firestore.FieldValue.increment(-1), + }; + Object.keys(existingData).forEach((symptom : string) => { + if (symptom !== "name" && symptom !== "dose" && + symptom !== "age" ) { + if (existingData[symptom] === true) { + if (existingData.dose) { + undoDoc[ + `${existingData.dose}.${existingData.age}.${ + symptom.replace("/", "OR")}`] = + admin.firestore.FieldValue.increment(-1); + } else { + undoDoc[`${existingData.age}.${symptom.replace("/", "OR")}`] = + admin.firestore.FieldValue.increment(-1); + } + } + } + }); + admin + .firestore() + .collection("stats") + .doc(existingData.name) + .update(undoDoc); + // PROCESS NEW DATA FOR USE + // SAVE USER DATA + await admin.firestore().collection("results").doc(docId).set(docData); + delete docData.age; + delete docData.name; + delete docData.dose; + // INCREMENT TOTAL RESPONSE COUNT + const updateDoc : Record = { + count: admin.firestore.FieldValue.increment(1), + }; + // INCREMENT VALUES FOR EACH SYMPTOM + Object.keys(docData).forEach((symptom : string) => { + if (docData[symptom] === true) { + if (data.dose) { + updateDoc[ + `${data.dose}.${data.age}.${symptom.replace("/", "OR")}`] = + admin.firestore.FieldValue.increment(1); + } else { + updateDoc[`${data.age}.${symptom.replace("/", "OR")}`] = + admin.firestore.FieldValue.increment(1); + } + } + }); + admin + .firestore() + .collection("stats") + .doc(data.name) + .update(updateDoc); + } else if (existingData === undefined) { + // DATA DOESN'T EXIST FOR USER + // SAVE USER DATA + await admin.firestore().collection("results").doc(docId).set(docData); + delete docData.age; + delete docData.name; + delete docData.dose; + // INCREMENT TOTAL RESPONSE COUNT + const updateDoc : Record = { + count: admin.firestore.FieldValue.increment(1), + }; + // INCREMENT VALUES FOR EACH SYMPTOM + Object.keys(docData).forEach((symptom : string) => { + if (docData[symptom] === true) { + if (data.dose) { + updateDoc[ + `${data.dose}.${data.age}.${symptom.replace("/", "OR")}`] = + admin.firestore.FieldValue.increment(1); + } else { + updateDoc[`${data.age}.${symptom.replace("/", "OR")}`] = + admin.firestore.FieldValue.increment(1); + } + } + }); + admin + .firestore() + .collection("stats") + .doc(data.name) + .update(updateDoc); + } + } + }); + +export const getPastResult = functions.https.onCall(async (data, context) => { + if (!!data && !!context) { + const {gid} = data; + const existingData : admin.firestore.DocumentData | undefined = await admin + .firestore() + .collection("results") + .doc(serializeGaId(gid)) + .get() + .then((doc) => doc.data()); + if (existingData) { + if (existingData["NAUSEA / VOMITING"]) { + existingData["NAUSEA OR VOMITING"] = + existingData["NAUSEA / VOMITING"]; + } + return existingData; + } + } + return undefined; +}); diff --git a/functions/src/updateCounts.js b/functions/src/updateCounts.js new file mode 100644 index 0000000..3d561c0 --- /dev/null +++ b/functions/src/updateCounts.js @@ -0,0 +1,186 @@ + +const admin = require("firebase-admin"); +const firebaseSecret = require("./firebaseSecret.json"); + + +admin.initializeApp({ + credential: admin.credential.cert(firebaseSecret), +}); + +const VAX_NAMES = { + PB: "Pfizer-BioNTech", + MD: "Moderna", + JJ: "J&J Janssen", +}; + +const VAX_DOSES = { + ONE: "Dose 1", + TWO: "Dose 2", +}; + +const VAX_AGES = { + "Pfizer-BioNTech": { + YOUNGER: "18 - 55", + OLDER: "56 & Older", + }, + "Moderna": { + YOUNGER: "18 - 64", + OLDER: "65 & Older", + }, + "J&J Janssen": { + YOUNGER: "18 - 59", + OLDER: "60 & Older", + }, +}; + +// PFIZER COUNTS +admin.firestore().collection("results") + .where("name", "==", VAX_NAMES.PB) + .where("dose", "in", [VAX_DOSES.ONE, VAX_DOSES.TWO]) + .where("age", "==", VAX_AGES[VAX_NAMES.PB].YOUNGER) + .get() + .then((docs) => { + console.log("PB_ONE_YOUNGER", docs.docs.length); + admin.firestore() + .collection("stats") + .doc(VAX_NAMES.PB) + .update({ + [`${VAX_DOSES.ONE}.${VAX_AGES[VAX_NAMES.PB].YOUNGER}.count`]: + docs.docs.length, + }); + }); +admin.firestore().collection("results") + .where("name", "==", VAX_NAMES.PB) + .where("dose", "==", VAX_DOSES.TWO) + .where("age", "==", VAX_AGES[VAX_NAMES.PB].YOUNGER) + .get() + .then((docs) => { + console.log("PB_TWO_YOUNGER", docs.docs.length); + admin.firestore() + .collection("stats") + .doc(VAX_NAMES.PB) + .update({ + [`${VAX_DOSES.TWO}.${VAX_AGES[VAX_NAMES.PB].YOUNGER}.count`]: + docs.docs.length, + }); + }); +admin.firestore().collection("results") + .where("name", "==", VAX_NAMES.PB) + .where("dose", "in", [VAX_DOSES.ONE, VAX_DOSES.TWO]) + .where("age", "==", VAX_AGES[VAX_NAMES.PB].OLDER) + .get() + .then((docs) => { + console.log("PB_ONE_OLDER", docs.docs.length); + admin.firestore() + .collection("stats") + .doc(VAX_NAMES.PB) + .update({ + [`${VAX_DOSES.ONE}.${VAX_AGES[VAX_NAMES.PB].OLDER}.count`]: + docs.docs.length, + }); + }); +admin.firestore().collection("results") + .where("name", "==", VAX_NAMES.PB) + .where("dose", "==", VAX_DOSES.TWO) + .where("age", "==", VAX_AGES[VAX_NAMES.PB].OLDER) + .get() + .then((docs) => { + console.log("PB_TWO_OLDER", docs.docs.length); + admin.firestore() + .collection("stats") + .doc(VAX_NAMES.PB) + .update({ + [`${VAX_DOSES.TWO}.${VAX_AGES[VAX_NAMES.PB].OLDER}.count`]: + docs.docs.length, + }); + }); +// MODERNA COUNTS +admin.firestore().collection("results") + .where("name", "==", VAX_NAMES.MD) + .where("dose", "in", [VAX_DOSES.ONE, VAX_DOSES.TWO]) + .where("age", "==", VAX_AGES[VAX_NAMES.MD].YOUNGER) + .get() + .then((docs) => { + console.log("MD_ONE_YOUNGER", docs.docs.length); + admin.firestore() + .collection("stats") + .doc(VAX_NAMES.MD) + .update({ + [`${VAX_DOSES.ONE}.${VAX_AGES[VAX_NAMES.MD].YOUNGER}.count`]: + docs.docs.length, + }); + }); +admin.firestore().collection("results") + .where("name", "==", VAX_NAMES.MD) + .where("dose", "==", VAX_DOSES.TWO) + .where("age", "==", VAX_AGES[VAX_NAMES.MD].YOUNGER) + .get() + .then((docs) => { + console.log("MD_TWO_YOUNGER", docs.docs.length); + admin.firestore() + .collection("stats") + .doc(VAX_NAMES.MD) + .update({ + [`${VAX_DOSES.TWO}.${VAX_AGES[VAX_NAMES.MD].YOUNGER}.count`]: + docs.docs.length, + }); + }); +admin.firestore().collection("results") + .where("name", "==", VAX_NAMES.MD) + .where("dose", "in", [VAX_DOSES.ONE, VAX_DOSES.TWO]) + .where("age", "==", VAX_AGES[VAX_NAMES.MD].OLDER) + .get() + .then((docs) => { + console.log("MD_ONE_OLDER", docs.docs.length); + admin.firestore() + .collection("stats") + .doc(VAX_NAMES.MD) + .update({ + [`${VAX_DOSES.ONE}.${VAX_AGES[VAX_NAMES.MD].OLDER}.count`]: + docs.docs.length, + }); + }); +admin.firestore().collection("results") + .where("name", "==", VAX_NAMES.MD) + .where("dose", "==", VAX_DOSES.TWO) + .where("age", "==", VAX_AGES[VAX_NAMES.MD].OLDER) + .get() + .then((docs) => { + console.log("MD_TWO_OLDER", docs.docs.length); + admin.firestore() + .collection("stats") + .doc(VAX_NAMES.MD) + .update({ + [`${VAX_DOSES.TWO}.${VAX_AGES[VAX_NAMES.MD].OLDER}.count`]: + docs.docs.length, + }); + }); +// J&J COUNTS +admin.firestore().collection("results") + .where("name", "==", VAX_NAMES.JJ) + .where("age", "==", VAX_AGES[VAX_NAMES.JJ].YOUNGER) + .get() + .then((docs) => { + console.log("JJ_YOUNGER", docs.docs.length); + admin.firestore() + .collection("stats") + .doc(VAX_NAMES.JJ) + .update({ + [`${VAX_AGES[VAX_NAMES.JJ].YOUNGER}.count`]: + docs.docs.length, + }); + }); +admin.firestore().collection("results") + .where("name", "==", VAX_NAMES.JJ) + .where("age", "==", VAX_AGES[VAX_NAMES.JJ].OLDER) + .get() + .then((docs) => { + console.log("JJ_OLDER", docs.docs.length); + admin.firestore() + .collection("stats") + .doc(VAX_NAMES.JJ) + .update({ + [`${VAX_AGES[VAX_NAMES.JJ].OLDER}.count`]: + docs.docs.length, + }); + }); diff --git a/website/public/styles/extrasmall.css b/website/public/styles/extrasmall.css index 5ee2f36..e51f295 100644 --- a/website/public/styles/extrasmall.css +++ b/website/public/styles/extrasmall.css @@ -392,6 +392,37 @@ footer .by { animation: 2s ease-out 0s infinite loading; } +.result-header-contianer { + display: flex; + align-items: flex-start; + margin-top: 5rem; + flex-direction: column; + margin-bottom: 2rem; +} + +.result-header-contianer .symptom-container { + margin-top: 0; + flex: 1; + width: 100%; +} + +.result-header-select { + width: 100%; +} + +.result-header-select .overline { + font-size: 1.6rem; + margin-bottom: 0.75rem; +} + +.result-header-select select { + background-color: var(--color-tertiary); + border-radius: 1rem; + padding: 1rem 2rem; + outline: none; + width: 100%; +} + @media (hover: hover) and (pointer: fine) { .answer:hover, .answer.unselected:hover { diff --git a/website/public/styles/medium.css b/website/public/styles/medium.css index 9a26ba7..bf6937e 100644 --- a/website/public/styles/medium.css +++ b/website/public/styles/medium.css @@ -106,4 +106,24 @@ footer { .tip-container { width: fit-content; -} \ No newline at end of file +} + + +.result-header-contianer { + margin-bottom: 0; + flex-direction: row; +} + +.result-header-contianer .symptom-container { + width: fit-content; +} + +.result-header-select { + width: fit-content; + padding-left: 3rem; + border-left: 1px solid var(--color-secondary); +} + +.result-header-select select { + width: fit-content; +} diff --git a/website/src/index.js b/website/src/index.js index 95ec570..04f51a7 100644 --- a/website/src/index.js +++ b/website/src/index.js @@ -18,9 +18,9 @@ if (window.location.host.startsWith("localhost")) { firebase.functions().useEmulator("localhost", 5001); } const fb_functions = firebase.functions(); -const saveResult = fb_functions.httpsCallable("saveResult"); -const getPastResult = fb_functions.httpsCallable("getPastResult"); -const getStats = fb_functions.httpsCallable("getStats"); +const saveResult = fb_functions.httpsCallable("saveResultV1"); +const getPastResult = fb_functions.httpsCallable("getPastResultV1"); +const getStats = fb_functions.httpsCallable("getStatsV1"); const VAX_NAMES = { PB: "Pfizer-BioNTech", @@ -61,7 +61,7 @@ const VAX_EFFICACY = { "18 - 59": 66.1, "60 & Older": 66.2, }, -} +}; const PB_DOSE1_YOUNGER_RESULT = { "PAIN AT SITE": 1904, @@ -69,7 +69,7 @@ const PB_DOSE1_YOUNGER_RESULT = { "SWELLING AT SITE": 132, FATIGUE: 1085, HEADACHE: 959, - "NEED PAIN MED":638, + "NEED PAIN MED": 638, "MUSCLE PAIN": 487, CHILLS: 321, DIARRHEA: 255, @@ -120,74 +120,74 @@ const PB_DOSE2_OLDER_RESULT = { VOMITING: 11, }; const MD_DOSE1_YOUNGER_RESULT = { - "PAIN AT SITE": "9", - "RED AT SITE": "<1", - "SWELLING AT SITE": "<1", - HEADACHE: "4", - FATIGUE: "4", - "MUSCLE PAIN": "2", - "JOINT PAIN": "2", - "NAUSEA OR VOMITING": "1", - FEVER: "1", - CHILLS: "1", + "PAIN AT SITE": 9908, + "RED AT SITE": 344, + "SWELLING AT SITE": 2089, + HEADACHE: 4030, + FATIGUE: 4384, + "MUSCLE PAIN": 2699, + "JOINT PAIN": 1893, + "NAUSEA OR VOMITING": 1068, + FEVER: 105, + CHILLS: 1051, }; const MD_DOSE2_YOUNGER_RESULT = { - "PAIN AT SITE": "9", - "RED AT SITE": "1", - "SWELLING AT SITE": "1", - FATIGUE: "7", - HEADACHE: "6", - "JOINT PAIN": "5", - CHILLS: "5", - FEVER: "2", - "NAUSEA OR VOMITING": "2", - "MUSCLE PAIN": "1", + "PAIN AT SITE": 9873, + "RED AT SITE": 982, + "SWELLING AT SITE": 3164, + FATIGUE: 7430, + HEADACHE: 6898, + "JOINT PAIN": 4993, + CHILLS: 5341, + FEVER: 1908, + "NAUSEA OR VOMITING": 2348, + "MUSCLE PAIN": 6769, }; const MD_DOSE1_OLDER_RESULT = { - "PAIN AT SITE": "7", - "RED AT SITE": "<1", - "SWELLING AT SITE": "<1", - HEADACHE: "3", - FATIGUE: "3", - "MUSCLE PAIN": "2", - "JOINT PAIN": "2", - "NAUSEA OR VOMITING": "1", - CHILLS: "1", - FEVER: "<1", + "PAIN AT SITE": 2782, + "RED AT SITE": 86, + "SWELLING AT SITE": 396, + HEADACHE: 921, + FATIGUE: 1251, + "MUSCLE PAIN": 742, + "JOINT PAIN": 618, + "NAUSEA OR VOMITING": 194, + CHILLS: 202, + FEVER: 10, }; const MD_DOSE2_OLDER_RESULT = { - "PAIN AT SITE": "8", - "RED AT SITE": "1", - "SWELLING AT SITE": "1", - FATIGUE: "6", - HEADACHE: "5", - "MUSCLE PAIN": "5", - "JOINT PAIN": "4", - CHILLS: "3", - "NAUSEA OR VOMITING": "1", - FEVER: "1", + "PAIN AT SITE": 3070, + "RED AT SITE": 275, + "SWELLING AT SITE": 715, + FATIGUE: 2152, + HEADACHE: 1704, + "MUSCLE PAIN": 1739, + "JOINT PAIN": 1291, + CHILLS: 1141, + "NAUSEA OR VOMITING": 437, + FEVER: 370, }; const JJ_YOUNGER_RESULT = { - "PAIN AT SITE": "6", - "RED AT SITE": "1", - "SWELLING AT SITE": "1", - HEADACHE: "4", - FATIGUE: "4", - "MUSCLE PAIN": "4", - "NEED PAIN MED": "3", - "NAUSEA OR VOMITING": "2", - FEVER: "1", + "PAIN AT SITE": 1193, + "RED AT SITE": 184, + "SWELLING AT SITE": 142, + HEADACHE: 905, + FATIGUE: 891, + "MUSCLE PAIN": 796, + "NEED PAIN MED": 538, + "NAUSEA OR VOMITING": 315, + FEVER: 261, }; const JJ_OLDER_RESULT = { - "PAIN AT SITE": "3", - "RED AT SITE": "<1", - "SWELLING AT SITE": "<1", - HEADACHE: "3", - FATIGUE: "3", - "MUSCLE PAIN": "2", - "NAUSEA OR VOMITING": "1", - "NEED PAIN MED": "1", - FEVER: "<1", + "PAIN AT SITE": 439, + "RED AT SITE": 61, + "SWELLING AT SITE": 36, + HEADACHE: 401, + FATIGUE: 392, + "MUSCLE PAIN": 317, + "NAUSEA OR VOMITING": 162, + "NEED PAIN MED": 130, + FEVER: 41, }; const VAX_COUNTS = { @@ -203,17 +203,17 @@ const VAX_COUNTS = { }, Moderna: { "Dose 1": { - "18 - 64": 1, - "65 & Older": 1, + "18 - 64": 11406, + "65 & Older": 3762, }, "Dose 2": { - "18 - 64": 1, - "65 & Older": 1, + "18 - 64": 10985, + "65 & Older": 3692, }, }, "J&J Janssen": { - "18 - 59": 1, - "60 & Older": 1, + "18 - 59": 2036, + "60 & Older": 1320, }, }; @@ -260,6 +260,12 @@ const ICONS = { "NAUSEA OR VOMITING": "🤮", }; +const DATA_CHOICES = { + VNM: "Vax&Me Only", + VNM_FDA: "Vax&Me + FDA", + FDA: "FDA Only", +}; + class App extends React.Component { constructor(props) { super(props); @@ -270,9 +276,10 @@ class App extends React.Component { gid: "", showInputPopup: false, answers: {}, - fetchedResult : {}, + fetchedResult: {}, stats: {}, loading: true, + dataSource: DATA_CHOICES.FDA, }; } componentDidMount() { @@ -321,7 +328,15 @@ class App extends React.Component { const { data } = v; if (!!data) { const { name, age, dose } = data; - this.setState({ name, age, dose, showInputPopup: true, fetchedResult: data, answers: data, loading: false }); + this.setState({ + name, + age, + dose, + showInputPopup: true, + fetchedResult: data, + answers: data, + loading: false, + }); const inputPopupSubmit = document.querySelector( ".input-popup-submit" ); @@ -344,7 +359,7 @@ class App extends React.Component { this.setState({ loading: false }); } - getStats().then(v => this.setState({ stats: v.data })); + getStats().then((v) => this.setState({ stats: v.data })); } shouldShowDoses = () => { const { name } = this.state; @@ -449,7 +464,7 @@ class App extends React.Component { delete answers.name; delete answers.dose; delete answers.age; - if(!!dose) { + if (!!dose) { symptoms[VAX_DOSES.ONE] = {}; symptoms[VAX_DOSES.TWO] = {}; Object.keys(VAX_DOSES).forEach((dose) => { @@ -477,7 +492,7 @@ class App extends React.Component { saveResult(submitAnswers) .then(() => { delete submitAnswers.gid; - this.setState({ fetchedResult : submitAnswers }); + this.setState({ fetchedResult: submitAnswers }); const inputPopupSubmit = document.querySelector(".input-popup-submit"); if (inputPopupSubmit.classList.contains("errored")) { inputPopupSubmit.classList.remove("errored"); @@ -508,39 +523,51 @@ class App extends React.Component { getAnswerOptions = (answerDose) => { const { answers, dose } = this.state; const result = this.getResults(); - return
- {!!answerDose ? ( -
- {answerDose} -
- ) : null} -

- { ((dose === VAX_DOSES.ONE) && (answerDose === VAX_DOSES.TWO)) ? "(You can comeback later to tell us about Dose 2)":"(Select all side effects that you experienced)" } -

-
- {Object.keys(result).map((symptom) => ( - - ))} + }`} + onClick={() => this.updateAnswers(symptom, answerDose)} + > + {symptom} + + ))} +
- ; + ); }; render() { - const { name, dose, age, showInputPopup, loading, fetchedResult } = this.state; + const { + name, + dose, + age, + showInputPopup, + loading, + fetchedResult, + dataSource, + } = this.state; let result = {}; let resultAtSite = {}; if (this.shouldShowResults()) { @@ -663,20 +690,37 @@ class App extends React.Component { ) : null} {this.shouldShowResults() ? ( -
-

Here's what to expect.

-
- Share ↗ -
-
- Download Chart ↗ -
+
+
+

Here's what to expect.

+
+ Share ↗ +
+
+ Download Chart ↗ +
+
+
+
+ Use data from: +
+ +
) : null} @@ -684,7 +728,11 @@ class App extends React.Component {
ⓘ
-
+
NET EFFICACY
@@ -698,8 +746,7 @@ class App extends React.Component {
- ) : null - } + ) : null} {this.shouldShowResults() ? (
@@ -710,7 +757,12 @@ class App extends React.Component { {symptom}

- {resultAtSite[symptom]}/10 + {Math.ceil( + (!!dose + ? resultAtSite[symptom] / VAX_COUNTS[name][dose][age] + : resultAtSite[symptom] / VAX_COUNTS[name][age]) * 10 + )} + /10

))} @@ -721,13 +773,17 @@ class App extends React.Component { {symptom}

- {result[symptom]}/10 + {Math.ceil( + (!!dose + ? result[symptom] / VAX_COUNTS[name][dose][age] + : result[symptom] / VAX_COUNTS[name][age]) * 10 + )} + /10

))} ) : null} - {this.shouldShowResults() ? (