import React from "react"; import ReactDOM from "react-dom"; import firebase from "firebase/app"; import "firebase/functions"; const FIREBASE_CONFIG = { apiKey: "AIzaSyDKw8HXWRn3dtkIRETv-BxtwnklZIpIkxU", authDomain: "vaxandme.firebaseapp.com", projectId: "vaxandme", storageBucket: "vaxandme.appspot.com", messagingSenderId: "614738281692", appId: "1:614738281692:web:7a89e0af76675e4f0ea019", measurementId: "G-N016TVJ6JC", }; firebase.initializeApp(FIREBASE_CONFIG); 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 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", }, }; 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", }; 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", }; 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", }; 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", }; 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", }; 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", }; 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", }; 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", }; 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", }; 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", }; const VAX_RESULTS = { "Pfizer-BioNTech": { "Dose 1": { "18 - 55": PB_DOSE1_YOUNGER_RESULT, "56 & Older": PB_DOSE1_OLDER_RESULT, }, "Dose 2": { "18 - 55": PB_DOSE2_YOUNGER_RESULT, "56 & Older": PB_DOSE2_OLDER_RESULT, }, }, Moderna: { "Dose 1": { "18 - 64": MD_DOSE1_YOUNGER_RESULT, "65 & Older": MD_DOSE1_OLDER_RESULT, }, "Dose 2": { "18 - 64": MD_DOSE2_YOUNGER_RESULT, "65 & Older": MD_DOSE2_OLDER_RESULT, }, }, "J&J Janssen": { "18 - 59": JJ_YOUNGER_RESULT, "60 & Older": JJ_OLDER_RESULT, }, }; const ICONS = { "PAIN AT SITE": "💪", "RED AT SITE": "🔴", "SWELLING AT SITE": "💢", FATIGUE: "🥱", HEADACHE: "🤕", "NEED PAIN MED": "💊", "MUSCLE PAIN": "😫", CHILLS: "🥶", DIRRHEA: "💩", "JOINT PAIN": "🦵", FEVER: "🤒", VOMITING: "🤮", "NAUSEA OR VOMITING": "🤮", }; class App extends React.Component { constructor(props) { super(props); this.state = { name: "", dose: "", age: "", gid: "", showInputPopup: false, answers: {}, loading: true, }; } componentDidMount() { const params = window.location.pathname .toUpperCase() .split("/") .filter((v) => v.length > 0); if (params) { if (params[0] && VAX_NAMES[params[0]]) { const name = VAX_NAMES[params[0]]; this.setState({ name }); switch (name) { case VAX_NAMES.PB: case VAX_NAMES.MD: if (params[1] && VAX_DOSES[params[1]]) { const dose = VAX_DOSES[params[1]]; this.setState({ dose }); if (params[2] && VAX_AGES[name][params[2]]) { const age = VAX_AGES[name][params[2]]; this.setState({ age }); } } break; case VAX_NAMES.JJ: if (params[1] && VAX_AGES[name][params[1]]) { const age = VAX_AGES[name][params[1]]; this.setState({ age }); } break; default: break; } } } 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 }); delete data.name; delete data.age; delete data.dose; this.setState({ 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 }); }); } }); } else { this.setState({ loading: false }); } } shouldShowAgeGroup = () => { const { name, dose } = this.state; switch (name) { case VAX_NAMES.JJ: return true; case VAX_NAMES.MD: case VAX_NAMES.PB: return !!dose; default: return false; } }; shouldShowResults = () => { const { name, dose, age } = this.state; switch (name) { case VAX_NAMES.JJ: return !!age; case VAX_NAMES.MD: case VAX_NAMES.PB: return !!dose && !!age; default: return false; } }; getResults = () => { const { name, dose, age } = this.state; switch (name) { case VAX_NAMES.JJ: return VAX_RESULTS[name][age]; case VAX_NAMES.MD: case VAX_NAMES.PB: return VAX_RESULTS[name][dose][age]; default: return null; } }; copyShareLink = () => { const { name, dose, age } = this.state; let SHARE_URL = window.location.host; const serialize_name = Object.keys(VAX_NAMES).filter( (k) => VAX_NAMES[k] === name )[0]; const serialize_dose = Object.keys(VAX_DOSES).filter( (k) => VAX_DOSES[k] === dose )[0]; const serialize_age = Object.keys(VAX_AGES[name]).filter( (k) => VAX_AGES[name][k] === age )[0]; if (serialize_name) { SHARE_URL += `/${serialize_name}`; } if (serialize_dose) { SHARE_URL += `/${serialize_dose}`; } if (serialize_age) { SHARE_URL += `/${serialize_age}`; } const copyTextInput = document.createElement("input"); document.body.appendChild(copyTextInput); copyTextInput.value = SHARE_URL.toLowerCase(); copyTextInput.select(); document.execCommand("copy"); copyTextInput.remove(); document.querySelector("#share-result").innerHTML = "Copied Link"; setTimeout(() => { document.querySelector("#share-result").innerHTML = "Share ↗"; }, 1500); }; updateAnswers = (symptom) => { const { answers } = this.state; const newAnswers = Object.assign({}, answers); if (answers[symptom]) { newAnswers[symptom] = !answers[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 symptoms = {}; Object.keys(result).forEach((symptom) => { symptoms[symptom] = false; }); const submitAnswers = Object.assign({}, symptoms, answers, { name, dose, age, gid, }); saveResult(submitAnswers) .then(() => { const inputPopupSubmit = document.querySelector(".input-popup-submit"); if (!inputPopupSubmit.classList.contains("submitted")) { inputPopupSubmit.classList.add("submitted"); } inputPopupSubmit.innerHTML = "THANK YOU!"; setTimeout(() => { inputPopupSubmit.innerHTML = "UPDATE ANSWER"; }, 1500); }) .catch((err) => console.error("ERROR Saving Answer", err)); }; render() { const { name, dose, age, showInputPopup, answers, loading } = this.state; let result = {}; let resultAtSite = {}; if (this.shouldShowResults()) { result = Object.assign({}, this.getResults()); Object.keys(result).forEach((s) => { if (s.includes("AT SITE")) { resultAtSite[s] = result[s]; delete result[s]; } }); } return (
Getting vaccinated?

Find out what to expect.

{loading ? (

Checking for existing answers...

) : null} {!loading ? (

Select Vaccine

{Object.values(VAX_NAMES).map((v) => ( ))}
) : null} {name && (name === VAX_NAMES.PB || name === VAX_NAMES.MD) ? (

Select Dose

{Object.values(VAX_DOSES).map((v) => ( ))}
) : null} {this.shouldShowAgeGroup() ? (

Select Age Group

{Object.values(VAX_AGES[name]).map((v) => ( ))}
) : null} {this.shouldShowResults() ? (

Here's what to expect.

Share ↗
Download Chart ↗
) : null} {this.shouldShowResults() ? (
{Object.keys(resultAtSite).map((symptom) => (
{ICONS[symptom]}

{symptom}

{resultAtSite[symptom]}/10

))} {Object.keys(result).map((symptom) => (
{ICONS[symptom]}

{symptom}

{result[symptom]}/10

))}
) : null}
{this.shouldShowResults() ? (
this.setState({ showInputPopup: !showInputPopup })} >
Already vaxxed?

Tell us how it went.

I am in age group {age} and got {!!dose ? ` ${dose} ` : ""} {!!dose ? `of` : ""} the {name} vaccine. I experienced:

(Select all side effects that you experienced)

{Object.keys(resultAtSite).map((symptom) => ( ))} {Object.keys(result).map((symptom) => ( ))}

You can comeback and update your experience later!

(Just use the same device)

SUBMIT
) : null}
); } } ReactDOM.render( , document.querySelector("#root") );