holiday.evinrevello.com/
A few months back I started working with someone who was a self-proclaimed holiday aficionado. After them showing me the top google result where they get their holiday knowledge from I proposed a better solution as the site had no style and I love doing remixes. Doing a little research on the subject of holidays, there are about 4 sites out there that seem to have most of these holidays listed with variations between them. When peeking into how these sites work, they all generate the pages on the server side therefore provide no API. With no API in place the first task at hand was getting the data and putting in somewhere that could be requested from an browser in its raw JSON form. A quick side note, when structuring holiday data there are two types of holidays, static ones that occur on the same day every year (such as Christmas on December 25th) and conditional holidays (like Thanksgiving, which occurs on the third Thursday of November). For the sake of simplicity I scrapped the entire year and figured I would deal with the computing of the conditionals at a later time.
Using a Node server was my go to solution for a couple of reasons, one being I write JavaScript everyday and two being that the asynchronous nature of Node/JavaScript made this a worthy challenge. After getting the data scraped from a single day I set out to get the data for a whole year, to overcome the issue of a request coming back at a different time than the rest I had to use the asynchronous promises and then resolve all of them. This process entails generating all of the promises in the same way that you would for a single day, but instead of executing them you save them all into an array and then execute all of the promises at once. Which doing 366 promises at once does not go as smoothly as it should. Some of the promises failed to resolved, which tuning it down to under 100 promises at a time made it where the data was able to be scraped with no missing values. At that point I had a JSON file which was around 500KB, which had issues when rendering into the browser and was still not in a easily consumable API. I ended up using Firebase to store the data, which required a little bit of refactoring as they do not let you use the anti-pattern of storing a list without keys. After getting the data formatted in a way that fit their requirements it was smooth sailing in terms of reading and writing the data.
With the data available via an API the front end work was able to begin. I set out creating a proof of concept that would render all of the holidays and allow for the data to be updated from the client side. With that working proof of concept, I then took my basic material card demo and integrated the holidays. I quickly determined that the urls that I had scrapped as the source for explaining the holiday were sometimes dead. When trying to programmatically determine if the links were valid I made the design decision to ditch the source url in favor of just opening a new tab with the holiday being searched on Google. Also when trying to get the descriptions for the holiday, I found that there was no consistent way to scrap the results as some of these holidays seemed to not exist (at least according to Google). This was frustrating, so to deal with it I added a flag that would allow for a person to flag a holiday as fake.
When a person wants to update a holiday, they just need to click on the menu which is represented by the three little dots on each card. A modal window will then appear allowing the user to update the details of the holiday.
Overall I am happy with how this turned out. This is the first fully vanilla JavaScript project I have done. Future enhancements would include two different approaches, the first being to automate everything and the second to making the tools for manual entry better. As for automating things, I would like the use the Google Images API to use the saturation and hue that is returned in the response to find images that meet the criteria for looking good on a material design card. As for better manual entry, creating a carousel that shows Google Image results that allow for the user to select one that then gets converted to base64 would be super cool. Also, taking the descriptions for the holidays from the top Google results would make it easier to craft an description that fits the 240 character limit for the material card.