Shopies is a project realized for Shopify's UI & Web Development Intern Challenge.
Challenge statement
We need a webpage that can search OMDB for movies, and allow the user to save their favourite films they feel should be up for nomination. When they've selected 5 nominees they should be notified they're finished.
We'd like a simple to use interface that makes it easy to:
- Search OMDB and display the results (movies only)
- Add a movie from the search results to our nomination list
- View the list of films already nominated
- Remove a nominee from the nomination list
Technical requirements
- Search results should come from OMDB's API (free API key: http://www.omdbapi.com/apikey.aspx).
- Each search result should list at least its title, year of release and a button to nominate that film.
- Updates to the search terms should update the result list
- Movies in search results can be added and removed from the nomination list.
- If a search result has already been nominated, disable its nominate button.
- Display a banner when the user has 5 nominations.
The app, per se, has no complex, moving parts which is why I treated the whole process of building it from a real-world usability perspective - thinking why anyone would want such a tool and what use-cases/scenarios would such an app be beneficial in.
Getting 5 nominations and having a banner display is cool - but "what can we do further with this?" was the question I seeked to answer with my process.
With the direction in mind, I had to pick out my tools of the trade.
Coming from a background of primarily working with statically typed, compiled languages, I felt it was imperative to dive straight into what was to be expected of me at work if I were to join Shopify as an intern.
Upon reading various blogs by the web dev teams at Shopify, and as clearly stated on the job posting
Our Web Developers use modern technologies and frameworks like Typescript, React, GraphQL and Apollo to develop large front-end web applications that scale and perform well on all devices.
I decided to try and encompass as much of the aforementioned technologies as possible.
Therefore this app uses:
- Create React App to bootstrap a React app with the TypeScript template along with React Hooks and functional style of writing code
- Apollo Client with GraphQL for making queries and API requests to OMDB.
- Husky, Prettier, Pretty-fast as a precommit hook to "prettify" staged files before commit to maintain code formatting and consistency
For the UI, I initially thought of resorting to Semantic UI or Ant Design. But upon further reading, I found Shopify has their own design system called Polaris and so, without hesitation, utilized it for the components and design for the application.
Every tool mentioned above was completely new for me - a lot of hours spent sifting through documentation for this project (wiki) and I must say, I thoroughly enjoyed the outcome, and came out of it learning A LOT in a short span of time!
With the tools at hand, I began refining the Use case scenario.
As a movie buff myself, I envisioned a scenario where fellow movie buffs at Shopify would use this app as a "just for fun" tool internally to nominate their picks for Oscar season, and have a draw of the most popular/nominated movie title by the employees.
This can be further used to dictate which movie gets played during movie-nights/social events (okay, it's a bit farfetched but bare with me π ).
If not at Shopify, I also figured this could be a tool that users can, in general, pick nominations on, and then tally up the information somehow to create a consensus of sorts.
With that in mind, I documented which features users would find most useful, and also fell under the scope for this project.
Additionally, the more I read through Shopify docs and blogs, it became clear to me that the company is truly passionate about collaboration, enablement, engagement, and empowerment - all of which resonated with my values and the direction I wanted to take this application with its features.
So without much ado, here are the features I implemented keeping the aforementioned in mind...
- debounced Search function to optimize number of API calls made to fetch data as user types
- Apollo InMemoryCache utility to cache request data and images being fetched
- Banner upon 5 nominations + disable search bar and nomination buttons to prevent users from adding/searching more movies
- Have design adhere to the one provided in the instructions with the addition of a logo, simple animations, custom favicon (free from icons8), and toasts for notifications.
In line with enablement and empowerment, I wanted to ensure all aditional features are not forced onto the user and remain opt-in. The user has the flexibility to incorporate them as they perform core functionalities.
1. Personalization
Who, what, why?
Let's add some flare to the nominations list that you've personally curated. This is akin to making a Spotify playlist. You can then choose a title
for the list, and add your name
as a curator!
Personalization is entirely application state based. As such, no changes are saved unless the user wants it saved using pinning or sharing.
2. Pinning
Okay so you start working on a list but have an urgent meeting to tend to - no worries, simply pin the current state of the building process you're at, and it'll be there for you when you come back to the app!
Or maybe John collaborated with Lisa to make that really cool list of movies you've always wanted to watch and you wanted maintain access to it - no problem, "pin that for the weekend!"
Pinning uses localStorage to store the state of the current application to your browser and persist it even after you close it.
3. Sharing
With collaboration & engagement in mind, I wanted to make building nominations exactly that - a collaborative and engaging experience.
With share
, a user can build upon a list, add details if they want, and simply click Share
to receive a link which they can further send out to others to collaborate on, or to simply provide an overview of their nominations. If collaborating, this can be chained by multiple users up until 5 total nominations are reached, so choose wisely!
Sharing is done using URL manipulation and parsing. Almost using the URL like a database π€
4. Downloading
You're planning the next movie-night at Shopify but those lame mixed answer surveys and confusing slack polls ain't cutting it. What you actually want to do is write up a script to read in people's nominations that they've gathered using this app and tally up the most popular nomination.
Pro-tip: To make your life easier, you can tell all the users to download their nominations directly from the app and send in the JSON files to you.
π One nomination to rule them all, one nomination to find the best movie for movie-night!
Apart from these features, I also wanted to optimize my site to pass all lighthouse audits as a benchmark for optimal work done.
In order to run this app locally, ensure you have one of the following installed on your system:
If you have Docker and the cli tools installed, you can simply use the no hassle production image, produced using using the config files present within the repo:
- Open up your terminal and type the following to pull the image
docker pull chakrakan/shopies:prod
- Expose port 1337 to run the app on it using this command (
-it
interactive mode,-rm
remove container once you're done running,-p
flag for host:container ports)
docker run -it --rm -p 1337:80 chakrakan/shopies:prod
- Visit
localhost:1337
to see the app served by NGINX web server
- Clone the repo and ensure you're in the default branch
git clone https://github.com/chakrakan/shopies.git
- Install NPM packages
npm install
- Create a
.env
file at the root of the project based on theenv.example
file provided in the repo and provide your OMDB API key
# Sign up and request a key at https://www.omdbapi.com/
REACT_APP_API_KEY=YOUR_API_KEY
REACT_APP_BASE_API=https://www.omdbapi.com/
- Start the development server using
npm start
and visitlocalhost:3000
to see it running.
If you have any questions or concerns, or just want to say hi, you can find me using:
- Linked-In
- Email
dev.kanisk@gmail.com
Check out the deployed project at shopies-kanisk.netlify.app/
In an attempt to not clutter the README, the full exhaustive list of resources used to build this app is avaiable in the Project Wiki. Also, shoutout to @jharrilim for helping clarify my questions and concerns as I traversed new technology.