v1.1.0/release

This commit is contained in:
2021-04-21 13:04:00 -04:00
parent 36674febe4
commit abb00ef27b
7 changed files with 452 additions and 227 deletions
+3
View File
@@ -54,12 +54,15 @@
},
"emulators": {
"functions": {
"host": "192.168.86.46",
"port": 5001
},
"firestore": {
"host": "192.168.86.46",
"port": 8080
},
"hosting": {
"host": "192.168.86.46",
"port": 5000
},
"ui": {
+1 -1
View File
@@ -1,5 +1,5 @@
{
"name": "functions",
"name": "vaxandme-api",
"scripts": {
"lint": "eslint --ext .js,.ts .",
"build": "tsc",
+153 -69
View File
@@ -30,6 +30,21 @@ const VAX_DOSES : Record<string, string> = {
TWO: "Dose 2",
};
const VAX_AGES: Record<string, Record<string, string>> = {
"Pfizer-BioNTech": {
YOUNGER: "18 - 55",
OLDER: "56 & Older",
},
"Moderna": {
YOUNGER: "18 - 64",
OLDER: "65 & Older",
},
"J&J Janssen": {
YOUNGER: "18 - 59",
OLDER: "60 & Older",
},
};
type SaveResultRequestData = {
name: string;
age: string;
@@ -47,8 +62,7 @@ const serializeGaId = (_gaid: string): string => {
};
const addResultToStats = async (data: SaveResultRequestData) => {
const cleanData : Record<string, any> =
Object.assign({}, data);
const cleanData: Record<string, any> = Object.assign({}, data);
delete cleanData.name;
delete cleanData.dose;
delete cleanData.age;
@@ -58,13 +72,16 @@ const addResultToStats = async (data : SaveResultRequestData) => {
};
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);
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);
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];
@@ -74,29 +91,29 @@ const addResultToStats = async (data : SaveResultRequestData) => {
if (symptom === "DIARRHEA") {
updateDocSymptom = "DIRRHEA";
}
updateDoc[`${dose}.${data.age}.${updateDocSymptom}`] =
admin.firestore.FieldValue.increment(1);
updateDoc[
`${dose}.${data.age}.${updateDocSymptom}`
] = admin.firestore.FieldValue.increment(1);
}
});
});
} else {
updateDoc[`${data.age}.count`] =
admin.firestore.FieldValue.increment(1);
updateDoc[`${data.age}.count`] = admin.firestore.FieldValue.increment(1);
Object.keys(cleanData).forEach((symptom: string) => {
let updateDocSymptom = symptom.replace("/", "OR");
if (symptom === "DIARRHEA") {
updateDocSymptom = "DIRRHEA";
}
updateDoc[`${data.age}.${updateDocSymptom}`] =
admin.firestore.FieldValue.increment(1);
updateDoc[
`${data.age}.${updateDocSymptom}`
] = admin.firestore.FieldValue.increment(1);
});
}
admin.firestore().collection("stats").doc(data.name).update(updateDoc);
};
const removeResultFromStats = async (data: FirebaseFirestore.DocumentData) => {
const cleanData : Record<string, any> =
Object.assign({}, data);
const cleanData: Record<string, any> = Object.assign({}, data);
delete cleanData.name;
delete cleanData.dose;
delete cleanData.age;
@@ -113,8 +130,9 @@ const removeResultFromStats = async (data : FirebaseFirestore.DocumentData) => {
if (symptom === "DIARRHEA") {
updateDocSymptom = "DIRRHEA";
}
updateDoc[`${dose}.${data.age}.${updateDocSymptom}`] =
admin.firestore.FieldValue.increment(-1);
updateDoc[
`${dose}.${data.age}.${updateDocSymptom}`
] = admin.firestore.FieldValue.increment(-1);
}
});
});
@@ -124,8 +142,9 @@ const removeResultFromStats = async (data : FirebaseFirestore.DocumentData) => {
if (symptom === "DIARRHEA") {
updateDocSymptom = "DIRRHEA";
}
updateDoc[`${data.age}.${updateDocSymptom}`] =
admin.firestore.FieldValue.increment(-1);
updateDoc[
`${data.age}.${updateDocSymptom}`
] = admin.firestore.FieldValue.increment(-1);
});
}
admin.firestore().collection("stats").doc(data.name).update(updateDoc);
@@ -134,13 +153,62 @@ const removeResultFromStats = async (data : FirebaseFirestore.DocumentData) => {
/**
* FUNCTIONS FROM V1.1.0 TO CURRENT
*/
export const getStatsV1 = functions.https.onCall(
async () => {
export const getStatsV1 = functions.https.onCall(async () => {
const stats = await admin.firestore().collection("stats").get();
const docs = stats.docs
.map((docSnap) => ({name: docSnap.id, result: docSnap.data()}));
const docs = stats.docs.map((docSnap) => ({
name: docSnap.id,
result: docSnap.data(),
}));
const returnData: Record<string, unknown> = {};
docs.forEach((vaxResult) => {
if (vaxResult.name === VAX_NAMES.PB || vaxResult.name === VAX_NAMES.MD) {
Object.keys(VAX_DOSES).forEach((doseKey) => {
const dose: string = VAX_DOSES[doseKey];
Object.keys(VAX_AGES[vaxResult.name]).forEach((ageKey) => {
const age: string = VAX_AGES[vaxResult.name][ageKey];
if (vaxResult.result[dose][age]["NAUSEA / VOMITING"] >= 0) {
if (vaxResult.result[dose][age]["NAUSEA OR VOMITING"] >= 0) {
vaxResult.result[dose][age]["NAUSEA OR VOMITING"] +=
vaxResult.result[dose][age]["NAUSEA / VOMITING"];
} else {
vaxResult.result[dose][age]["NAUSEA OR VOMITING"] =
vaxResult.result[dose][age]["NAUSEA / VOMITING"];
}
}
if (vaxResult.result[dose][age]["DIRRHEA"] >= 0) {
if (vaxResult.result[dose][age]["DIARRHEA"] >= 0) {
vaxResult.result[dose][age]["DIARRHEA"] +=
vaxResult.result[dose][age]["DIRRHEA"];
} else {
vaxResult.result[dose][age]["DIARRHEA"] =
vaxResult.result[dose][age]["DIRRHEA"];
}
}
});
});
} else {
Object.keys(VAX_AGES[vaxResult.name]).forEach((ageKey) => {
const age: string = VAX_AGES[vaxResult.name][ageKey];
if (vaxResult.result[age]["NAUSEA / VOMITING"] >= 0) {
if (vaxResult.result[age]["NAUSEA OR VOMITING"] >= 0) {
vaxResult.result[age]["NAUSEA OR VOMITING"] +=
vaxResult.result[age]["NAUSEA / VOMITING"];
} else {
vaxResult.result[age]["NAUSEA OR VOMITING"] =
vaxResult.result[age]["NAUSEA / VOMITING"];
}
}
if (vaxResult.result[age]["DIRRHEA"] >= 0) {
if (vaxResult.result[age]["DIARRHEA"] >= 0) {
vaxResult.result[age]["DIARRHEA"] +=
vaxResult.result[age]["DIRRHEA"];
} else {
vaxResult.result[age]["DIARRHEA"] =
vaxResult.result[age]["DIRRHEA"];
}
}
});
}
returnData[vaxResult.name] = {};
returnData[vaxResult.name] = vaxResult.result;
});
@@ -159,8 +227,7 @@ export const saveResultV1 = functions.https.onCall(
.get()
.then((docSnap) => docSnap.data());
// Update user result
const cleanData : Record<string, any> =
Object.assign({}, data);
const cleanData: Record<string, any> = Object.assign({}, data);
delete cleanData.gid;
await admin
.firestore()
@@ -175,10 +242,11 @@ export const saveResultV1 = functions.https.onCall(
await addResultToStats(data);
}
}
});
}
);
export const getPastResultV1 =
functions.https.onCall(async (data : {gid:string}, context) => {
export const getPastResultV1 = functions.https.onCall(
async (data: { gid: string }, context) => {
if (!!data && !!context) {
const {gid} = data;
let hasToUpdateDb = false;
@@ -190,19 +258,24 @@ export const getPastResultV1 =
.get()
.then((doc) => doc.data());
if (existingData) {
const returnData : admin.firestore.DocumentData | undefined =
Object.assign({}, existingData);
if (existingData.name === VAX_NAMES.PB ||
existingData.name === VAX_NAMES.MD) {
const returnData:
| admin.firestore.DocumentData
| undefined = Object.assign({}, existingData);
if (
existingData.name === VAX_NAMES.PB ||
existingData.name === VAX_NAMES.MD
) {
Object.keys(VAX_DOSES).forEach((doseKey: string) => {
const dose: string = VAX_DOSES[doseKey];
if (!existingData[dose]) {
hasToUpdateDb = true;
const temp: Record<string, unknown> = {};
Object.keys(existingData).forEach((symptom) => {
if (symptom !== "name" &&
if (
symptom !== "name" &&
symptom !== "age" &&
symptom !== "dose") {
symptom !== "dose"
) {
if (existingData.dose === dose) {
temp[symptom] = existingData[symptom];
delete returnData[symptom];
@@ -214,11 +287,11 @@ export const getPastResultV1 =
returnData[dose] = temp;
}
if (returnData[dose]["NAUSEA / VOMITING"]) {
returnData["NAUSEA OR VOMITING"] =
returnData["NAUSEA / VOMITING"];
returnData[dose]["NAUSEA OR VOMITING"] =
returnData[dose]["NAUSEA / VOMITING"];
}
if (returnData["DIRRHEA"]) {
returnData["DIARRHEA"] = returnData["DIRRHEA"];
if (returnData[dose]["DIRRHEA"]) {
returnData[dose]["DIARRHEA"] = returnData["DIRRHEA"];
}
});
} else {
@@ -241,7 +314,8 @@ export const getPastResultV1 =
}
}
return undefined;
});
}
);
/**
* FUNCTIONS FROM V1.0.0 TO V1.0.1
@@ -260,8 +334,11 @@ export const saveResult = functions.https.onCall(
.doc(docId)
.get()
.then((doc) => doc.data());
if (existingData !== undefined && existingData !== docData &&
existingData.name === docData.name) {
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);
@@ -277,17 +354,20 @@ export const saveResult = functions.https.onCall(
let incrementValue = 0;
if (existingData[symptom] === true && docData[symptom] === false) {
incrementValue = -1;
} else if (existingData[symptom] === false &&
docData[symptom] === true) {
} 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);
`${data.dose}.${data.age}.${symptom.replace("/", "OR")}`
] = admin.firestore.FieldValue.increment(incrementValue);
} else {
updateDoc[`${data.age}.${symptom.replace("/", "OR")}`] =
admin.firestore.FieldValue.increment(incrementValue);
updateDoc[
`${data.age}.${symptom.replace("/", "OR")}`
] = admin.firestore.FieldValue.increment(incrementValue);
}
});
admin
@@ -295,25 +375,27 @@ export const saveResult = functions.https.onCall(
.collection("stats")
.doc(data.name)
.update(updateDoc);
} else if (existingData !== undefined && existingData !== docData &&
existingData.name !== docData.name) {
} 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<string, admin.firestore.FieldValue> = {
count: admin.firestore.FieldValue.increment(-1),
};
Object.keys(existingData).forEach((symptom: string) => {
if (symptom !== "name" && symptom !== "dose" &&
symptom !== "age" ) {
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);
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);
undoDoc[
`${existingData.age}.${symptom.replace("/", "OR")}`
] = admin.firestore.FieldValue.increment(-1);
}
}
}
@@ -338,11 +420,12 @@ export const saveResult = functions.https.onCall(
if (docData[symptom] === true) {
if (data.dose) {
updateDoc[
`${data.dose}.${data.age}.${symptom.replace("/", "OR")}`] =
admin.firestore.FieldValue.increment(1);
`${data.dose}.${data.age}.${symptom.replace("/", "OR")}`
] = admin.firestore.FieldValue.increment(1);
} else {
updateDoc[`${data.age}.${symptom.replace("/", "OR")}`] =
admin.firestore.FieldValue.increment(1);
updateDoc[
`${data.age}.${symptom.replace("/", "OR")}`
] = admin.firestore.FieldValue.increment(1);
}
}
});
@@ -367,11 +450,12 @@ export const saveResult = functions.https.onCall(
if (docData[symptom] === true) {
if (data.dose) {
updateDoc[
`${data.dose}.${data.age}.${symptom.replace("/", "OR")}`] =
admin.firestore.FieldValue.increment(1);
`${data.dose}.${data.age}.${symptom.replace("/", "OR")}`
] = admin.firestore.FieldValue.increment(1);
} else {
updateDoc[`${data.age}.${symptom.replace("/", "OR")}`] =
admin.firestore.FieldValue.increment(1);
updateDoc[
`${data.age}.${symptom.replace("/", "OR")}`
] = admin.firestore.FieldValue.increment(1);
}
}
});
@@ -382,7 +466,8 @@ export const saveResult = functions.https.onCall(
.update(updateDoc);
}
}
});
}
);
export const getPastResult = functions.https.onCall(async (data, context) => {
if (!!data && !!context) {
@@ -395,8 +480,7 @@ export const getPastResult = functions.https.onCall(async (data, context) => {
.then((doc) => doc.data());
if (existingData) {
if (existingData["NAUSEA / VOMITING"]) {
existingData["NAUSEA OR VOMITING"] =
existingData["NAUSEA / VOMITING"];
existingData["NAUSEA OR VOMITING"] = existingData["NAUSEA / VOMITING"];
}
return existingData;
}
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "vaxandme",
"version": "0.1.0",
"version": "1.1.0",
"private": true,
"dependencies": {
"firebase": "^8.4.1",
+16 -4
View File
@@ -392,22 +392,23 @@ footer .by {
animation: 2s ease-out 0s infinite loading;
}
.result-header-contianer {
.result-header-container {
display: flex;
align-items: flex-start;
align-items: center;
margin-top: 5rem;
flex-direction: column;
margin-bottom: 2rem;
}
.result-header-contianer .symptom-container {
margin-top: 0;
.result-header-container .symptom-container {
margin: 0;
flex: 1;
width: 100%;
}
.result-header-select {
width: 100%;
margin-top: 2rem;
}
.result-header-select .overline {
@@ -415,6 +416,17 @@ footer .by {
margin-bottom: 0.75rem;
}
.result-header-select .overline.errored {
margin-bottom: 0;
margin-top: 0.75rem;
color: #c43d34;
}
.result-header-select .overline.success {
margin-bottom: 0;
margin-top: 0.75rem;
}
.result-header-select select {
background-color: var(--color-tertiary);
border-radius: 1rem;
+3 -3
View File
@@ -109,16 +109,16 @@ footer {
}
.result-header-contianer {
margin-bottom: 0;
.result-header-container {
flex-direction: row;
}
.result-header-contianer .symptom-container {
.result-header-container .symptom-container {
width: fit-content;
}
.result-header-select {
margin-top: 0rem;
width: fit-content;
padding-left: 3rem;
border-left: 1px solid var(--color-secondary);
+152 -26
View File
@@ -14,8 +14,8 @@ const FIREBASE_CONFIG = {
};
firebase.initializeApp(FIREBASE_CONFIG);
if (window.location.host.startsWith("localhost")) {
firebase.functions().useEmulator("localhost", 5001);
if (window.location.host !== "www.vaxand.me") {
firebase.functions().useEmulator(window.location.host.split(":")[0], 5001);
}
const fb_functions = firebase.functions();
const saveResult = fb_functions.httpsCallable("saveResultV1");
@@ -280,6 +280,7 @@ class App extends React.Component {
stats: {},
loading: true,
dataSource: DATA_CHOICES.FDA,
loadingMessage: "Gettings stats...",
};
}
componentDidMount() {
@@ -315,14 +316,23 @@ class App extends React.Component {
}
}
if (!window.localStorage.getItem("hasExistingAnswer")) {
this.setState({ loading: false });
}
getStats()
.then((v) => {
// GET & SET STATS
this.setState({
stats: v.data,
loadingMessage: "Checking for existing answers...",
dataSource: DATA_CHOICES.VNM_FDA,
});
// HAS GID?
if (window.gtag) {
// GET GID
window.gtag("get", "G-7VZCY223NG", "client_id", (client_id) => {
// GOT GID?
if (!!client_id) {
// SAVE GID
this.setState({ gid: client_id });
// GET PAST ANSWER FOR GID
getPastResult({ gid: client_id })
.then((v) => {
const { data } = v;
@@ -353,20 +363,31 @@ class App extends React.Component {
console.error("ERROR Getting Past Answer", err);
this.setState({ loading: false });
});
} else {
this.setState({ loading: false });
}
});
} else {
this.setState({ loading: false });
}
getStats().then((v) => this.setState({ stats: v.data }));
})
.catch((err) => {
console.error("ERROR GETTING STATS", err);
this.setState({ loading: false });
});
}
shouldShowDoses = () => {
const { name } = this.state;
const { name, loading } = this.state;
if (loading) {
return false;
}
return name && (name === VAX_NAMES.PB || name === VAX_NAMES.MD);
};
shouldShowAgeGroup = () => {
const { name, dose } = this.state;
const { name, dose, loading } = this.state;
if (loading) {
return false;
}
switch (name) {
case VAX_NAMES.JJ:
return true;
@@ -378,7 +399,10 @@ class App extends React.Component {
}
};
shouldShowResults = () => {
const { name, dose, age } = this.state;
const { name, dose, age, loading } = this.state;
if (loading) {
return false;
}
switch (name) {
case VAX_NAMES.JJ:
return !!age;
@@ -390,7 +414,10 @@ class App extends React.Component {
}
};
getResults = () => {
const { name, dose, age } = this.state;
const { name, dose, age, loading } = this.state;
if (loading) {
return null;
}
switch (name) {
case VAX_NAMES.JJ:
return VAX_RESULTS[name][age];
@@ -558,6 +585,96 @@ class App extends React.Component {
</div>
);
};
getStatForSymptom = (symptom) => {
const { dataSource, name, dose, age, stats } = this.state;
switch (dataSource) {
case DATA_CHOICES.FDA:
if (!!dose) {
return Math.ceil(
(VAX_RESULTS[name][dose][age][symptom] /
VAX_COUNTS[name][dose][age]) *
10
);
} else {
return Math.ceil(
(VAX_RESULTS[name][age][symptom] / VAX_COUNTS[name][age]) * 10
);
}
case DATA_CHOICES.VNM:
if (Object.keys(stats).length > 0) {
if (!!dose) {
return Math.ceil(
(stats[name][dose][age][symptom] / stats[name][dose][age].count) *
10
);
} else {
return Math.ceil(
(stats[name][age][symptom] / stats[name][age].count) * 10
);
}
} else {
return 0;
}
case DATA_CHOICES.VNM_FDA:
let symptomCount = 0;
let totalCount = 0;
if (Object.keys(stats).length > 0) {
if (!!dose) {
symptomCount =
VAX_RESULTS[name][dose][age][symptom] +
stats[name][dose][age][symptom];
totalCount =
VAX_COUNTS[name][dose][age] + stats[name][dose][age].count;
} else {
symptomCount =
VAX_RESULTS[name][age][symptom] + stats[name][age][symptom];
totalCount = VAX_COUNTS[name][age] + stats[name][age].count;
}
} else {
symptomCount = VAX_RESULTS[name][dose][age][symptom];
totalCount = VAX_COUNTS[name][dose][age];
}
return Math.ceil((symptomCount / totalCount) * 10);
default:
return 1;
}
};
getSampleSize = () => {
const { dataSource, name, dose, age, stats } = this.state;
switch (dataSource) {
case DATA_CHOICES.FDA:
if (!!dose) {
return VAX_COUNTS[name][dose][age];
} else {
return VAX_COUNTS[name][age];
}
case DATA_CHOICES.VNM:
if (Object.keys(stats).length > 0) {
if (!!dose) {
return stats[name][dose][age].count;
} else {
return stats[name][age].count;
}
} else {
return 0;
}
case DATA_CHOICES.VNM_FDA:
let totalCount = 0;
if (Object.keys(stats).length > 0) {
if (!!dose) {
totalCount =
VAX_COUNTS[name][dose][age] + stats[name][dose][age].count;
} else {
totalCount = VAX_COUNTS[name][age] + stats[name][age].count;
}
} else {
totalCount = VAX_COUNTS[name][dose][age];
}
return totalCount;
default:
return 0;
}
};
render() {
const {
name,
@@ -567,6 +684,8 @@ class App extends React.Component {
loading,
fetchedResult,
dataSource,
loadingMessage,
stats,
} = this.state;
let result = {};
let resultAtSite = {};
@@ -598,7 +717,7 @@ class App extends React.Component {
{loading ? (
<div className="loading-container">
<p className="question" data-font="sans">
Checking for existing answers...
{loadingMessage}
</p>
<div className="loading-bar-container">
<div className="loading-bar"></div>
@@ -690,7 +809,7 @@ class App extends React.Component {
) : null}
{this.shouldShowResults() ? (
<div className="result-header-contianer">
<div className="result-header-container">
<div className="symptom-container subheader">
<h3 data-font="sans-bold">Here's what to expect.</h3>
<h6
@@ -711,6 +830,7 @@ class App extends React.Component {
Use data from:
</h6>
<select
disabled={Object.keys(stats).length < 1}
onChange={(e) =>
this.setState({ dataSource: e.target.value })
}
@@ -720,6 +840,18 @@ class App extends React.Component {
<option key={dataKey}>{DATA_CHOICES[dataKey]}</option>
))}
</select>
<h6 className="overline success" data-font="sans-italic">
Based on{" "}
{this.getSampleSize()
.toString()
.replace(/\B(?=(\d{3})+(?!\d))/g, ",")}{" "}
individual experiences
</h6>
{Object.keys(stats).length < 1 ? (
<h6 className="overline errored" data-font="sans-italic">
Failed to get stats from Vax&amp;Me
</h6>
) : null}
</div>
</div>
) : null}
@@ -757,12 +889,7 @@ class App extends React.Component {
{symptom}
</p>
<p data-font="sans-bold" className="symptom-chance">
{Math.ceil(
(!!dose
? resultAtSite[symptom] / VAX_COUNTS[name][dose][age]
: resultAtSite[symptom] / VAX_COUNTS[name][age]) * 10
)}
/10
{this.getStatForSymptom(symptom)}/10
</p>
</div>
))}
@@ -773,12 +900,7 @@ class App extends React.Component {
{symptom}
</p>
<p data-font="sans-bold" className="symptom-chance">
{Math.ceil(
(!!dose
? result[symptom] / VAX_COUNTS[name][dose][age]
: result[symptom] / VAX_COUNTS[name][age]) * 10
)}
/10
{this.getStatForSymptom(symptom)}/10
</p>
</div>
))}
@@ -809,6 +931,7 @@ class App extends React.Component {
&#9660;
</button>
</div>
{showInputPopup ? (
<div className="input-popup-body">
<p className="question" data-font="sans">
I am in age group <strong>{age}</strong> and got the
@@ -828,6 +951,8 @@ class App extends React.Component {
</p>
</div>
</div>
) : null}
{showInputPopup ? (
<div
onClick={this.submitAnswer}
className="input-popup-submit"
@@ -835,6 +960,7 @@ class App extends React.Component {
>
SUBMIT
</div>
) : null}
</div>
) : null}
</div>