v1.1.0/number values and efficacy
This commit is contained in:
+225
-100
@@ -20,6 +20,7 @@ if (window.location.host.startsWith("localhost")) {
|
||||
const fb_functions = firebase.functions();
|
||||
const saveResult = fb_functions.httpsCallable("saveResult");
|
||||
const getPastResult = fb_functions.httpsCallable("getPastResult");
|
||||
const getStats = fb_functions.httpsCallable("getStats");
|
||||
|
||||
const VAX_NAMES = {
|
||||
PB: "Pfizer-BioNTech",
|
||||
@@ -47,61 +48,76 @@ const VAX_AGES = {
|
||||
},
|
||||
};
|
||||
|
||||
const VAX_EFFICACY = {
|
||||
"Pfizer-BioNTech": {
|
||||
"18 - 55": 95.3,
|
||||
"56 & Older": 93.8,
|
||||
},
|
||||
Moderna: {
|
||||
"18 - 64": 95.6,
|
||||
"65 & Older": 86.4,
|
||||
},
|
||||
"J&J Janssen": {
|
||||
"18 - 59": 66.1,
|
||||
"60 & Older": 66.2,
|
||||
},
|
||||
}
|
||||
|
||||
const PB_DOSE1_YOUNGER_RESULT = {
|
||||
"PAIN AT SITE": "8",
|
||||
"RED AT SITE": "1",
|
||||
"SWELLING AT SITE": "1",
|
||||
FATIGUE: "5",
|
||||
HEADACHE: "4",
|
||||
"NEED PAIN MED": "3",
|
||||
"MUSCLE PAIN": "2",
|
||||
CHILLS: "1",
|
||||
DIRRHEA: "1",
|
||||
"JOINT PAIN": "1",
|
||||
FEVER: "<1",
|
||||
VOMITING: "<1",
|
||||
"PAIN AT SITE": 1904,
|
||||
"RED AT SITE": 104,
|
||||
"SWELLING AT SITE": 132,
|
||||
FATIGUE: 1085,
|
||||
HEADACHE: 959,
|
||||
"NEED PAIN MED":638,
|
||||
"MUSCLE PAIN": 487,
|
||||
CHILLS: 321,
|
||||
DIARRHEA: 255,
|
||||
"JOINT PAIN": 251,
|
||||
FEVER: 85,
|
||||
VOMITING: 28,
|
||||
};
|
||||
const PB_DOSE2_YOUNGER_RESULT = {
|
||||
"PAIN AT SITE": "8",
|
||||
"RED AT SITE": "1",
|
||||
"SWELLING AT SITE": "1",
|
||||
FATIGUE: "6",
|
||||
HEADACHE: "5",
|
||||
"NEED PAIN MED": "5",
|
||||
"MUSCLE PAIN": "4",
|
||||
CHILLS: "4",
|
||||
"JOINT PAIN": "2",
|
||||
FEVER: "2",
|
||||
DIRRHEA: "1",
|
||||
VOMITING: "<1",
|
||||
"PAIN AT SITE": 1632,
|
||||
"RED AT SITE": 123,
|
||||
"SWELLING AT SITE": 132,
|
||||
FATIGUE: 1247,
|
||||
HEADACHE: 1085,
|
||||
"NEED PAIN MED": 945,
|
||||
"MUSCLE PAIN": 783,
|
||||
CHILLS: 737,
|
||||
"JOINT PAIN": 459,
|
||||
FEVER: 331,
|
||||
DIARRHEA: 219,
|
||||
VOMITING: 40,
|
||||
};
|
||||
const PB_DOSE1_OLDER_RESULT = {
|
||||
"PAIN AT SITE": "7",
|
||||
"RED AT SITE": "1",
|
||||
"SWELLING AT SITE": "1",
|
||||
FATIGUE: "3",
|
||||
HEADACHE: "3",
|
||||
"NEED PAIN MED": "2",
|
||||
"MUSCLE PAIN": "1",
|
||||
CHILLS: "1",
|
||||
DIRRHEA: "1",
|
||||
"JOINT PAIN": "1",
|
||||
FEVER: "<1",
|
||||
VOMITING: "<1",
|
||||
"PAIN AT SITE": 1282,
|
||||
"RED AT SITE": 85,
|
||||
"SWELLING AT SITE": 118,
|
||||
FATIGUE: 615,
|
||||
HEADACHE: 454,
|
||||
"NEED PAIN MED": 358,
|
||||
"MUSCLE PAIN": 251,
|
||||
CHILLS: 113,
|
||||
DIARRHEA: 147,
|
||||
"JOINT PAIN": 155,
|
||||
FEVER: 26,
|
||||
VOMITING: 9,
|
||||
};
|
||||
const PB_DOSE2_OLDER_RESULT = {
|
||||
"PAIN AT SITE": "7",
|
||||
"RED AT SITE": "1",
|
||||
"SWELLING AT SITE": "1",
|
||||
FATIGUE: "5",
|
||||
HEADACHE: "4",
|
||||
"NEED PAIN MED": "4",
|
||||
"MUSCLE PAIN": "3",
|
||||
CHILLS: "2",
|
||||
"JOINT PAIN": "2",
|
||||
DIRRHEA: "1",
|
||||
FEVER: "1",
|
||||
VOMITING: "<1",
|
||||
"PAIN AT SITE": 1098,
|
||||
"RED AT SITE": 120,
|
||||
"SWELLING AT SITE": 124,
|
||||
FATIGUE: 839,
|
||||
HEADACHE: 647,
|
||||
"NEED PAIN MED": 625,
|
||||
"MUSCLE PAIN": 477,
|
||||
CHILLS: 377,
|
||||
"JOINT PAIN": 313,
|
||||
DIARRHEA: 137,
|
||||
FEVER: 181,
|
||||
VOMITING: 11,
|
||||
};
|
||||
const MD_DOSE1_YOUNGER_RESULT = {
|
||||
"PAIN AT SITE": "9",
|
||||
@@ -174,6 +190,33 @@ const JJ_OLDER_RESULT = {
|
||||
FEVER: "<1",
|
||||
};
|
||||
|
||||
const VAX_COUNTS = {
|
||||
"Pfizer-BioNTech": {
|
||||
"Dose 1": {
|
||||
"18 - 55": 2291,
|
||||
"56 & Older": 1802,
|
||||
},
|
||||
"Dose 2": {
|
||||
"18 - 55": 2098,
|
||||
"56 & Older": 1660,
|
||||
},
|
||||
},
|
||||
Moderna: {
|
||||
"Dose 1": {
|
||||
"18 - 64": 1,
|
||||
"65 & Older": 1,
|
||||
},
|
||||
"Dose 2": {
|
||||
"18 - 64": 1,
|
||||
"65 & Older": 1,
|
||||
},
|
||||
},
|
||||
"J&J Janssen": {
|
||||
"18 - 59": 1,
|
||||
"60 & Older": 1,
|
||||
},
|
||||
};
|
||||
|
||||
const VAX_RESULTS = {
|
||||
"Pfizer-BioNTech": {
|
||||
"Dose 1": {
|
||||
@@ -210,7 +253,7 @@ const ICONS = {
|
||||
"NEED PAIN MED": "💊",
|
||||
"MUSCLE PAIN": "😫",
|
||||
CHILLS: "🥶",
|
||||
DIRRHEA: "💩",
|
||||
DIARRHEA: "💩",
|
||||
"JOINT PAIN": "🦵",
|
||||
FEVER: "🤒",
|
||||
VOMITING: "🤮",
|
||||
@@ -227,6 +270,8 @@ class App extends React.Component {
|
||||
gid: "",
|
||||
showInputPopup: false,
|
||||
answers: {},
|
||||
fetchedResult : {},
|
||||
stats: {},
|
||||
loading: true,
|
||||
};
|
||||
}
|
||||
@@ -276,11 +321,7 @@ class App extends React.Component {
|
||||
const { data } = v;
|
||||
if (!!data) {
|
||||
const { name, age, dose } = data;
|
||||
this.setState({ name, age, dose, showInputPopup: true });
|
||||
delete data.name;
|
||||
delete data.age;
|
||||
delete data.dose;
|
||||
this.setState({ answers: data, loading: false });
|
||||
this.setState({ name, age, dose, showInputPopup: true, fetchedResult: data, answers: data, loading: false });
|
||||
const inputPopupSubmit = document.querySelector(
|
||||
".input-popup-submit"
|
||||
);
|
||||
@@ -302,7 +343,13 @@ class App extends React.Component {
|
||||
} else {
|
||||
this.setState({ loading: false });
|
||||
}
|
||||
|
||||
getStats().then(v => this.setState({ stats: v.data }));
|
||||
}
|
||||
shouldShowDoses = () => {
|
||||
const { name } = this.state;
|
||||
return name && (name === VAX_NAMES.PB || name === VAX_NAMES.MD);
|
||||
};
|
||||
shouldShowAgeGroup = () => {
|
||||
const { name, dose } = this.state;
|
||||
switch (name) {
|
||||
@@ -373,25 +420,55 @@ class App extends React.Component {
|
||||
document.querySelector("#share-result").innerHTML = "Share ↗";
|
||||
}, 1500);
|
||||
};
|
||||
updateAnswers = (symptom) => {
|
||||
updateAnswers = (symptom, dose) => {
|
||||
const { answers } = this.state;
|
||||
const newAnswers = Object.assign({}, answers);
|
||||
if (answers[symptom]) {
|
||||
newAnswers[symptom] = !answers[symptom];
|
||||
if (!!dose) {
|
||||
if (!newAnswers[dose]) {
|
||||
newAnswers[dose] = {};
|
||||
}
|
||||
if (newAnswers[dose][symptom]) {
|
||||
newAnswers[dose][symptom] = !newAnswers[dose][symptom];
|
||||
} else {
|
||||
newAnswers[dose][symptom] = true;
|
||||
}
|
||||
} else {
|
||||
newAnswers[symptom] = true;
|
||||
if (newAnswers[symptom]) {
|
||||
newAnswers[symptom] = !newAnswers[symptom];
|
||||
} else {
|
||||
newAnswers[symptom] = true;
|
||||
}
|
||||
}
|
||||
this.setState({ answers: newAnswers });
|
||||
};
|
||||
submitAnswer = () => {
|
||||
document.querySelector(".input-popup-submit").innerHTML = "SENDING...";
|
||||
const { name, dose, age, answers, gid } = this.state;
|
||||
const result = Object.assign({}, this.getResults());
|
||||
const result = this.getResults();
|
||||
const symptoms = {};
|
||||
Object.keys(result).forEach((symptom) => {
|
||||
symptoms[symptom] = false;
|
||||
});
|
||||
const submitAnswers = Object.assign({}, symptoms, answers, {
|
||||
delete answers.name;
|
||||
delete answers.dose;
|
||||
delete answers.age;
|
||||
if(!!dose) {
|
||||
symptoms[VAX_DOSES.ONE] = {};
|
||||
symptoms[VAX_DOSES.TWO] = {};
|
||||
Object.keys(VAX_DOSES).forEach((dose) => {
|
||||
Object.keys(result).forEach((symptom) => {
|
||||
symptoms[VAX_DOSES[dose]][symptom] = false;
|
||||
if (answers[VAX_DOSES[dose]] && answers[VAX_DOSES[dose]][symptom]) {
|
||||
symptoms[VAX_DOSES[dose]][symptom] = true;
|
||||
}
|
||||
});
|
||||
});
|
||||
} else {
|
||||
Object.keys(result).forEach((symptom) => {
|
||||
symptoms[symptom] = false;
|
||||
if (answers[symptom]) {
|
||||
symptoms[symptom] = true;
|
||||
}
|
||||
});
|
||||
}
|
||||
const submitAnswers = Object.assign({}, symptoms, {
|
||||
name,
|
||||
dose,
|
||||
age,
|
||||
@@ -399,7 +476,12 @@ class App extends React.Component {
|
||||
});
|
||||
saveResult(submitAnswers)
|
||||
.then(() => {
|
||||
delete submitAnswers.gid;
|
||||
this.setState({ fetchedResult : submitAnswers });
|
||||
const inputPopupSubmit = document.querySelector(".input-popup-submit");
|
||||
if (inputPopupSubmit.classList.contains("errored")) {
|
||||
inputPopupSubmit.classList.remove("errored");
|
||||
}
|
||||
if (!inputPopupSubmit.classList.contains("submitted")) {
|
||||
inputPopupSubmit.classList.add("submitted");
|
||||
}
|
||||
@@ -408,10 +490,57 @@ class App extends React.Component {
|
||||
inputPopupSubmit.innerHTML = "UPDATE ANSWER";
|
||||
}, 1500);
|
||||
})
|
||||
.catch((err) => console.error("ERROR Saving Answer", err));
|
||||
.catch((err) => {
|
||||
const inputPopupSubmit = document.querySelector(".input-popup-submit");
|
||||
if (!inputPopupSubmit.classList.contains("errored")) {
|
||||
inputPopupSubmit.classList.add("errored");
|
||||
}
|
||||
if (inputPopupSubmit.classList.contains("submitted")) {
|
||||
inputPopupSubmit.classList.remove("submitted");
|
||||
}
|
||||
inputPopupSubmit.innerHTML = "UH OH...UNABLE TO SEND";
|
||||
setTimeout(() => {
|
||||
inputPopupSubmit.innerHTML = "TRY AGAIN";
|
||||
}, 1500);
|
||||
console.error("ERROR Saving Answer", err);
|
||||
});
|
||||
};
|
||||
getAnswerOptions = (answerDose) => {
|
||||
const { answers, dose } = this.state;
|
||||
const result = this.getResults();
|
||||
return <div className="question-container" key={`answer-dose-${answerDose}`}>
|
||||
{!!answerDose ? (
|
||||
<h6 className="overline" data-font="sans">
|
||||
{answerDose}
|
||||
</h6>
|
||||
) : null}
|
||||
<p className="question" data-font="sans-italic">
|
||||
{ ((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)" }
|
||||
</p>
|
||||
<div className="answers-container">
|
||||
{Object.keys(result).map((symptom) => (
|
||||
<button
|
||||
key={`ans-${answerDose}-${symptom}`}
|
||||
data-font="sans-bold"
|
||||
className={`answer${
|
||||
!!answerDose
|
||||
? (answers[answerDose] && answers[answerDose][symptom])
|
||||
? " selected"
|
||||
: ""
|
||||
: answers[symptom]
|
||||
? " selected"
|
||||
: ""
|
||||
}`}
|
||||
onClick={() => this.updateAnswers(symptom, answerDose)}
|
||||
>
|
||||
{symptom}
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
</div>;
|
||||
};
|
||||
render() {
|
||||
const { name, dose, age, showInputPopup, answers, loading } = this.state;
|
||||
const { name, dose, age, showInputPopup, loading, fetchedResult } = this.state;
|
||||
let result = {};
|
||||
let resultAtSite = {};
|
||||
if (this.shouldShowResults()) {
|
||||
@@ -463,7 +592,7 @@ class App extends React.Component {
|
||||
name: v,
|
||||
dose: "",
|
||||
age: "",
|
||||
answers: {},
|
||||
answers: v === fetchedResult.name ? fetchedResult : {},
|
||||
showInputPopup: false,
|
||||
})
|
||||
}
|
||||
@@ -478,7 +607,7 @@ class App extends React.Component {
|
||||
</div>
|
||||
</div>
|
||||
) : null}
|
||||
{name && (name === VAX_NAMES.PB || name === VAX_NAMES.MD) ? (
|
||||
{this.shouldShowDoses() ? (
|
||||
<div className="question-container">
|
||||
<p className="question" data-font="sans-italic">
|
||||
Select Dose
|
||||
@@ -491,7 +620,6 @@ class App extends React.Component {
|
||||
this.setState({
|
||||
dose: v,
|
||||
age: "",
|
||||
answers: {},
|
||||
showInputPopup: false,
|
||||
})
|
||||
}
|
||||
@@ -519,7 +647,6 @@ class App extends React.Component {
|
||||
onClick={() =>
|
||||
this.setState({
|
||||
age: v,
|
||||
answers: {},
|
||||
showInputPopup: false,
|
||||
})
|
||||
}
|
||||
@@ -553,6 +680,27 @@ class App extends React.Component {
|
||||
</div>
|
||||
) : null}
|
||||
|
||||
{this.shouldShowResults() ? (
|
||||
<div className="tip-container">
|
||||
<div className="tip-icon">ⓘ</div>
|
||||
<div className="tip">
|
||||
<h6 style={{marginBottom: '1.2rem'}} className="overline" data-font="sans">
|
||||
NET EFFICACY
|
||||
</h6>
|
||||
<h6 className="overline" data-font="sans-italic">
|
||||
{name} was effective for
|
||||
</h6>
|
||||
<h3 className="subheader" data-font="sans-bold">
|
||||
{VAX_EFFICACY[name][age]}%
|
||||
</h3>
|
||||
<h6 className="overline" data-font="sans-italic">
|
||||
of people who took it, in the {age} age group
|
||||
</h6>
|
||||
</div>
|
||||
</div>
|
||||
) : null
|
||||
}
|
||||
|
||||
{this.shouldShowResults() ? (
|
||||
<div className="symptom-container">
|
||||
{Object.keys(resultAtSite).map((symptom) => (
|
||||
@@ -579,6 +727,7 @@ class App extends React.Component {
|
||||
))}
|
||||
</div>
|
||||
) : null}
|
||||
|
||||
</main>
|
||||
{this.shouldShowResults() ? (
|
||||
<div className={`input-popup${showInputPopup ? " expanded" : ""}`}>
|
||||
@@ -606,41 +755,17 @@ class App extends React.Component {
|
||||
</div>
|
||||
<div className="input-popup-body">
|
||||
<p className="question" data-font="sans">
|
||||
I am in age group <strong>{age}</strong> and got
|
||||
<strong>{!!dose ? ` ${dose} ` : ""}</strong>
|
||||
{!!dose ? `of` : ""} the
|
||||
I am in age group <strong>{age}</strong> and got the
|
||||
<strong> {name}</strong> vaccine. I experienced:
|
||||
</p>
|
||||
<div className="question-container">
|
||||
<p className="question" data-font="sans-italic">
|
||||
(Select all side effects that you experienced)
|
||||
</p>
|
||||
<div className="answers-container">
|
||||
{Object.keys(resultAtSite).map((symptom) => (
|
||||
<button
|
||||
key={`ans-${symptom}`}
|
||||
data-font="sans-bold"
|
||||
className={`answer${answers[symptom] ? " selected" : ""}`}
|
||||
onClick={() => this.updateAnswers(symptom)}
|
||||
>
|
||||
{symptom}
|
||||
</button>
|
||||
))}
|
||||
{Object.keys(result).map((symptom) => (
|
||||
<button
|
||||
key={`ans-${symptom}`}
|
||||
data-font="sans-bold"
|
||||
className={`answer${answers[symptom] ? " selected" : ""}`}
|
||||
onClick={() => this.updateAnswers(symptom)}
|
||||
>
|
||||
{symptom}
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
{this.shouldShowDoses()
|
||||
? Object.keys(VAX_DOSES).map((dose) =>
|
||||
this.getAnswerOptions(VAX_DOSES[dose])
|
||||
)
|
||||
: this.getAnswerOptions()}
|
||||
<div className="question-container">
|
||||
<p className="question" data-font="sans">
|
||||
You can comeback and update your experience later!
|
||||
You can comeback and update your experience at any time!
|
||||
</p>
|
||||
<p className="question" data-font="sans-italic">
|
||||
(Just use the same device)
|
||||
|
||||
Reference in New Issue
Block a user