v1.1.0/release
This commit is contained in:
+210
-84
@@ -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,58 +316,78 @@ class App extends React.Component {
|
||||
}
|
||||
}
|
||||
|
||||
if (!window.localStorage.getItem("hasExistingAnswer")) {
|
||||
this.setState({ loading: false });
|
||||
}
|
||||
|
||||
if (window.gtag) {
|
||||
window.gtag("get", "G-7VZCY223NG", "client_id", (client_id) => {
|
||||
if (!!client_id) {
|
||||
this.setState({ gid: client_id });
|
||||
getPastResult({ gid: client_id })
|
||||
.then((v) => {
|
||||
const { data } = v;
|
||||
if (!!data) {
|
||||
const { name, age, dose } = data;
|
||||
this.setState({
|
||||
name,
|
||||
age,
|
||||
dose,
|
||||
showInputPopup: true,
|
||||
fetchedResult: data,
|
||||
answers: data,
|
||||
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;
|
||||
if (!!data) {
|
||||
const { name, age, dose } = data;
|
||||
this.setState({
|
||||
name,
|
||||
age,
|
||||
dose,
|
||||
showInputPopup: true,
|
||||
fetchedResult: data,
|
||||
answers: data,
|
||||
loading: false,
|
||||
});
|
||||
const inputPopupSubmit = document.querySelector(
|
||||
".input-popup-submit"
|
||||
);
|
||||
if (inputPopupSubmit) {
|
||||
inputPopupSubmit.classList.add("submitted");
|
||||
inputPopupSubmit.innerHTML = "UPDATE ANSWER";
|
||||
}
|
||||
window.localStorage.setItem("hasExistingAnswer", true);
|
||||
} else {
|
||||
this.setState({ loading: false });
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
console.error("ERROR Getting Past Answer", err);
|
||||
this.setState({ loading: false });
|
||||
});
|
||||
const inputPopupSubmit = document.querySelector(
|
||||
".input-popup-submit"
|
||||
);
|
||||
if (inputPopupSubmit) {
|
||||
inputPopupSubmit.classList.add("submitted");
|
||||
inputPopupSubmit.innerHTML = "UPDATE ANSWER";
|
||||
}
|
||||
window.localStorage.setItem("hasExistingAnswer", true);
|
||||
} else {
|
||||
this.setState({ loading: false });
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
console.error("ERROR Getting Past Answer", err);
|
||||
} else {
|
||||
this.setState({ loading: false });
|
||||
});
|
||||
}
|
||||
});
|
||||
} else {
|
||||
this.setState({ loading: false });
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
console.error("ERROR GETTING STATS", err);
|
||||
this.setState({ loading: false });
|
||||
});
|
||||
} else {
|
||||
this.setState({ loading: false });
|
||||
}
|
||||
|
||||
getStats().then((v) => this.setState({ stats: v.data }));
|
||||
}
|
||||
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&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,32 +931,36 @@ class App extends React.Component {
|
||||
▼
|
||||
</button>
|
||||
</div>
|
||||
<div className="input-popup-body">
|
||||
<p className="question" data-font="sans">
|
||||
I am in age group <strong>{age}</strong> and got the
|
||||
<strong> {name}</strong> vaccine. I experienced:
|
||||
</p>
|
||||
{this.shouldShowDoses()
|
||||
? Object.keys(VAX_DOSES).map((dose) =>
|
||||
this.getAnswerOptions(VAX_DOSES[dose])
|
||||
)
|
||||
: this.getAnswerOptions()}
|
||||
<div className="question-container">
|
||||
{showInputPopup ? (
|
||||
<div className="input-popup-body">
|
||||
<p className="question" data-font="sans">
|
||||
You can comeback and update your experience at any time!
|
||||
</p>
|
||||
<p className="question" data-font="sans-italic">
|
||||
(Just use the same device)
|
||||
I am in age group <strong>{age}</strong> and got the
|
||||
<strong> {name}</strong> vaccine. I experienced:
|
||||
</p>
|
||||
{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 at any time!
|
||||
</p>
|
||||
<p className="question" data-font="sans-italic">
|
||||
(Just use the same device)
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
onClick={this.submitAnswer}
|
||||
className="input-popup-submit"
|
||||
data-font="sans-bold"
|
||||
>
|
||||
SUBMIT
|
||||
</div>
|
||||
) : null}
|
||||
{showInputPopup ? (
|
||||
<div
|
||||
onClick={this.submitAnswer}
|
||||
className="input-popup-submit"
|
||||
data-font="sans-bold"
|
||||
>
|
||||
SUBMIT
|
||||
</div>
|
||||
) : null}
|
||||
</div>
|
||||
) : null}
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user