Past Project: Healthy Living Challenge
A couple of years ago my family wanted to do a month-long challenge to help develop a healthy lifestyle. As this was toward the end of my college education, I figured rather than using an existing application to handle it, I would roll my own web app as a fun side project.
Just so you don't have to scroll to the end of this article to know what this is all about, here is a link to the now-static version of the Healthy Living Challenge, and this is what it looks like:
Before starting on anything, I needed to know how I was going to collect data from the participants and also where that data would be stored. I ended up settling on a solution that's not the flashiest but certainly gets the job done: Google Forms.
You've probably participated in a Google Form before. It was around this time that I'd come across an article that explained how you could use Google Sheets as a very basic database. It works like this:
- Set up your Google Form to collect the data you want
- Pull up the "Responses" spreadsheet that stores the data from your Google Form
- Make the spreadsheet publicly available (The option is:
Anyone on the internet with this link can view)
- Find the URL to access the spreadsheet as a CSV
- Parse the data and profit!
Obviously this "solution" has some serious flaws, most notably making your data publicly available, but also it's not the speediest. However, for throwing together something that has very basic, non-critical data needs, it does the trick.
The way you get the CSV URL mentioned above is to do the following, replacing
LONG_INCOMPREHENSIBLE_STRING_KEY with the key that you see in the URL bar when editing the spreadsheet in a browser:
With the data now stored, I built a simple Python Flask application that fetched the CSV and parsed it into the core data I wanted. Then I used the built-in Jinja templating to insert the data into the HTML for each participant.
The frontend ✨
There's not a ton to say about the frontend, so here's some bullet points:
- Again, the Jinja templating provided by Flask was pretty much all I needed to make it "dynamic"
- I used a framework called Basscss that is a super lightweight modular CSS library for the site's core structure
- For animation, I used the classic animate.css in addition to the basic jQuery
slideTogglefunction for expand/collapse
- For the rest of the styles I used SCSS and just had fun with the design!
There are a couple other fun things I did with this project that I'd like to mention:
Add to Home screen
Naturally when my family brought up this idea it was described as being an "app for your phone." That sounds great and all, but compared to spinning up a basic website as described, making an app that's compatible with iOS and Android and distributing it on both platforms would be a lot of work and would also likely cost money.
Still, I wanted to preserve some of that initial vision so I built the website as an "Add to Home screen" (A2HS) app. Sites occasionally advertise that you can add their site to your home screen. This gives you a shortcut that pops open the website in your web browser.
However, there is a way to make it sort of behave as an app and occupy its own "window" instead of opening your web browser. This makes it feel much more like an app and less just like a hyperlink/bookmark. In addition you can even specify the app icon you want to use!
This is the secret sauce that you put in your
<head> to make it all work:
<!-- Web app configuration --> <meta name="apple-mobile-web-app-capable" content="yes"> <meta name="apple-mobile-web-app-title" content="hlc"> <link rel="apple-touch-startup-image" href="public/img/splash.png">
After opening it, the end result looks something like this:
One other problem I wanted to handle was tie conditions. You'll notice a 5 way tie for 1st place, meaning the next person was in 6th place. I could have written the code for this manually, but I discovered there was a small library called ranking that handled it perfectly!
This project certainly isn't my magnum opus, but I like to think about this project as a microcosm of the larger engineering process. Someone presented a problem that needed solving, we established the requirements and the timeframe, I designed a simple solution that could be completed in the time allowed without over-engineering, and the project was delivered just in time for a month of health-related excitement!