Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add vaccine type filter, move all filters to separate component #13

Merged
merged 19 commits into from
Feb 19, 2021

Conversation

linusmarco
Copy link
Collaborator

@linusmarco linusmarco commented Feb 13, 2021

This PR:

  • Adds a vaccine type filter (Implements Allow filtering to type of vaccine #4)
  • Moves the added filter and the existing availability filter to their own component/panel
    • This new panel lives on the left side of the screen for md+ size screens (desktop, probably) and at the top on smaller screens (mobile, probably)
    • On larger screens, the filters are sticky so that they follow when the user scrolls down
  • Removes the .eslintcache file from version control
  • Fixes a few React warnings

Larger screen:
large-screen

Smaller screen:
small-screen

@harcod
Copy link
Collaborator

harcod commented Feb 13, 2021

Bug Report: "Amherst Regional High School" gets replicated in the listing when switching back and forth between "Pfizer" and "Moderna" filter. In addition, the replicas don't have any "More Information" attached to them. Please note that the current data feed has two separate cards for "Amherst Regional High School" even on the live site.

useEffect(() => {
onChange({
hasAppointments: hasAppointments ?
d => !!d.hasAppointments === hasAppointments
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't this function essentially the same as d => !!d.hasAppointments? Because it's only used when hasAppointments is true, so !!d.hasAppointments === hasAppointments is always just checking that !!d.hasAppointments is true.

Also, to avoid the ternary, this whole value could be simplified to hasAppointments: d => !hasAppointments || !!d.hasAppointments

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point. This was some real galaxy brain code...

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

d => !!d.hasAppointments === hasAppointments
:
() => true,
vaxType: vaxType !== 'Any' ?
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same idea here, I think the ternary is slightly harder to understand and could be replaced with vaxType: d => vaxType === 'Any' || (d.extraData && d.extraData['Vaccinations offered'] && d.extraData['Vaccinations offered'].includes(vaxType)).

I guess it comes down to preference, maybe the one-liner is harder to read, in which case ignore me!

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To me this feels a little less transparent, but if others prefer this way too I could change it.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think pretty much any use of the ternary operator that isn't for short simple expressions should be avoided, and it definitely shouldn't be combined with arrow functions. I would move the test into the function, and further simplify a bit:

d => {
  if (vaxType !== 'Any') {
    let vaxOffered = d.extraData && d.extraData['Vaccinations offered'];
    return vaxOffered && vaxOffered.includes(vaxType);
  } else {
    return true;
  }

(untested, but I think that's equivalent)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just as you have an aversion to ternary operators, I have one for assignment expressions with && or ||. They always require a second look. As a compromise, how about we go fully explicit?

           vaxType: d => {
                if (vaxType === 'Any') {
                    return true;
                } else {
                    if (d.extraData && d.extraData['Vaccinations offered']) {
                        return d.extraData['Vaccinations offered'].includes(vaxType);
                    } else {
                        return false;
                    }
                }
            }

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Err, to be clear, the concern is not the ternary operator — it's the ternary expression being split over 9 lines that include an arrow function, where the test is not obviously better outside the arrow function than in.

Why is && ok in

if (d.extraData && d.extraData['Vaccinations offered']) {

but not in

return vaxOffered && vaxOffered.includes(vaxType);

?

Also, part of the point of the simplification (and introduction of let vaxOffered) was to avoid searching the d.extraData dictionary twice (and cut down line length and cognitive load). Yours undoes that.

If you really like ?: and dislike && I'd replace

    return vaxOffered && vaxOffered.includes(vaxType);

with

    return vaxOffered ? vaxOffered.includes(vaxType) : false;

which, although silly to my eye, would seem better than having an entire 5-line if/else block to accomplish the same thing.

But I am In No Way King, and your revised solution eliminates the mass confusion point of the long ternary-operator-with-arrow-function-within, so is definitely an improvement over the original.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not trying to pick a fight here, man--just addressing readability. I'll go with the most recent revision with the explicit if-else's so we're not running in circles.

@linusmarco
Copy link
Collaborator Author

Bug Report: "Amherst Regional High School" gets replicated in the listing when switching back and forth between "Pfizer" and "Moderna" filter. In addition, the replicas don't have any "More Information" attached to them. Please note that the current data feed has two separate cards for "Amherst Regional High School" even on the live site.

I think the only real solution to this issue is to resolve this on the back end by giving each site a unique ID. Below are the two sites causing problems. The issue seems to be that they have a morning and an evening clinic listed separately so the key based on the basic site info (name, city) was not unique. For now I generated a key for each site based on the site's whole object. Not ideal for efficiency reasons but it will work for now.

        {
            "name": "Amherst Regional High School",
            "street": "21 Matoon St",
            "city": "Amherst",
            "zip": "01002",
            "availability": {
                "02/18/2021": {
                    "hasAvailability": true,
                    "numberAvailableAppointments": 365,
                    "signUpLink": "https://www.maimmunizations.org/client/registration?clinic_id=1070"
                }
            },
            "hasAvailability": true,
            "extraData": {
                "Vaccinations offered": "Pfizer-BioNTech COVID-19 Vaccine",
                "Age groups served": "Adults, Seniors",
                "Services offered": "Vaccination",
                "Clinic Hours": "09:00 am - 11:45 am"
            }
        },

and

        {
            "name": "Amherst Regional High School",
            "street": "21 Mattoon Street",
            "city": "Amherst",
            "zip": "01002",
            "availability": {
                "02/17/2021": {
                    "hasAvailability": true,
                    "numberAvailableAppointments": 229,
                    "signUpLink": "https://www.maimmunizations.org/client/registration?clinic_id=1055"
                }
            },
            "hasAvailability": true,
            "extraData": {
                "Vaccinations offered": "Pfizer-BioNTech COVID-19 Vaccine",
                "Age groups served": "Adults, Seniors",
                "Services offered": "Vaccination",
                "Clinic Hours": "01:00 pm - 02:45 pm"
            }
        },

@harcod
Copy link
Collaborator

harcod commented Feb 14, 2021

Bug Report: "Amherst Regional High School" gets replicated in the listing when switching back and forth between "Pfizer" and "Moderna" filter. In addition, the replicas don't have any "More Information" attached to them. Please note that the current data feed has two separate cards for "Amherst Regional High School" even on the live site.

Clarification and Steps to Reproduce Bug:

  1. Load the page the first time. The vax type "Any" is selected by default.
    There are two "Amherst Regional High School" entries in the list. This is correct because they are actually different times.

  2. Select filter Vax Type = "Pfizer".
    Now there are three "Amherst Regional High School" entries in the list.

  3. Select filter Vax Type = "Moderna".
    Now there are two "Amherst Regional High School" entries in the list. Neither of these two entries have any "More Information" available.

  4. Select filter Vax Type = "Pfizer"
    Now there are four "Amherst Regional High School" entries in the list.

If you continue to switch back and forth, more and more entries are created for "Amherst" in the listing.

@linusmarco
Copy link
Collaborator Author

Bug Report: "Amherst Regional High School" gets replicated in the listing when switching back and forth between "Pfizer" and "Moderna" filter. In addition, the replicas don't have any "More Information" attached to them. Please note that the current data feed has two separate cards for "Amherst Regional High School" even on the live site.

Clarification and Steps to Reproduce Bug:

  1. Load the page the first time. The vax type "Any" is selected by default.
    There are two "Amherst Regional High School" entries in the list. This is correct because they are actually different times.
  2. Select filter Vax Type = "Pfizer".
    Now there are three "Amherst Regional High School" entries in the list.
  3. Select filter Vax Type = "Moderna".
    Now there are two "Amherst Regional High School" entries in the list. Neither of these two entries have any "More Information" available.
  4. Select filter Vax Type = "Pfizer"
    Now there are four "Amherst Regional High School" entries in the list.

If you continue to switch back and forth, more and more entries are created for "Amherst" in the listing.

@harcod are you still seeing this after the most recent commits to address the issue? This was caused by dupe keys. See my previous comment on how I fixed it by creating a unique key. I don't see this bug after 158e646, but please let me know if you still do

@harcod
Copy link
Collaborator

harcod commented Feb 14, 2021

@linusmarco Fixed now. ( Sorry. For some reason, I didn't have that one update the fixed dupe keys. )

@livgust
Copy link
Owner

livgust commented Feb 16, 2021

OK so I mentioned this morning that I'm a little nervous about the design, since we have proximity filtering coming through soon too as well. What do you think about this? It's a common design pattern on other websites with filtering.
(Also ignore my bad Paint skills, replace [] with checkboxes, () with radio buttons, and use Material UI text styling)

Desktop:
image

Mobile:
image

@livgust
Copy link
Owner

livgust commented Feb 16, 2021

I like this component for a side bar - it's basically the same as what you did but it looks a little more "separate" which I like. Thoughts?

})
}, [onChange, hasAppointments, vaxType])

const vaxTypes = Array.from(
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm a little nervous here. Only the MA vaccination sites will have that "Vaccinations offered" information that we scrape up; no other sites will have it. Therefore by default we'll show them in the "Any" bucket which is misleading. It might be worth entering manually what sites (outside of the state sites) have which vaccines, but then that's something we would have to manually update if it ever changes.

Curious if you (or anyone else) have thoughts.

livgust and others added 11 commits February 17, 2021 11:37
* Update docs to make PRs to develop

* update develop again (livgust#32)

* Improve HTML semantics of a couple key elements

* Tweaks to elements

* Add eligibility accordion

* Remove extraneous prettierrc and prettify README.md

* Link to mass.gov/covidvaccine gave a security warning becuase the state didn't redirect properly. Link changed to a non-redirecting link.

* Update eligibility for feb 18, small refactor

* link to senior housing details

Co-authored-by: Matthew Cardarelli <mattrc7@gmx.com>
Co-authored-by: Jake Rogers <jake@dataplusmath.com>
Co-authored-by: Rob Harris <rob@harcod.com>
Co-authored-by: John Hawkinson <jhawk@alum.mit.edu>

* get filters into responsive drawer

Co-authored-by: Olivia Adams <liv.gust@gmail.com>
Co-authored-by: Matthew Cardarelli <mattrc7@gmx.com>
Co-authored-by: Jake Rogers <jake@dataplusmath.com>
Co-authored-by: Rob Harris <rob@harcod.com>
Co-authored-by: John Hawkinson <jhawk@alum.mit.edu>
@harcod harcod linked an issue Feb 18, 2021 that may be closed by this pull request
@linusmarco linusmarco changed the base branch from master to develop February 19, 2021 02:16
@linusmarco
Copy link
Collaborator Author

This has now been updated to use the new responsive drawer for the filters and now uses the checkbox-based design that @livgust proposed:

Desktop:
image

Mobile:
(filter panel closed)
image
(filter panel open)
image

@livgust livgust merged commit fda595e into livgust:develop Feb 19, 2021
@livgust
Copy link
Owner

livgust commented Feb 19, 2021

LOVE THIS so far!!!

I think next steps are:

  1. confirming design with Daniel Cho (danieljaecho93)
  2. adding proximity filtering (zip code search), which we already have some code for in another PR

@livgust
Copy link
Owner

livgust commented Feb 19, 2021

In true Olivia fashion, I was unable to pick this up today. Womp womp.

@linusmarco
Copy link
Collaborator Author

linusmarco commented Feb 20, 2021

@danieljaecho93, thoughts on the design here?

EDIT: sorry I hadn't refreshed and seen that this was merged...ignore me

@danieljae
Copy link
Collaborator

@linusmarco Looks great :) Something to consider on my end is what sorts of different categories do we want to display for the filters-for instance, I'm wondering how much people would want to filter for places with no available appointments? But I will do some research on my own and look into that, this will definitely work for the time being!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Allow filtering to type of vaccine
6 participants