Front-end Test
Working version at http://ec2-3-16-76-129.us-east-2.compute.amazonaws.com/
About
This app is built to complete an interview test. It renders reddit hot topics. Its bootstrapped from create-react-app and has a minimal server to help with reddit oauth credentials.
Running
First copy .env.example
file to .env
and configure it.
Then run npm run build
to build the client and finally npm start
.
Development
To run a dev version of the client run npm run client
.
To run a dev version of the server run npm run server
. This runs the server with nodemon so changes on server folder are instantly reflected.
TODO
As every project this one has room for improvement. Some stuff from that list:
- add proptypes
- cleanup server code
- cleanup CSS in post list
- refactor animation code to be shared
Notes
Login
This app uses reddit oauth API. So for a first use you need to authorize reddit to provide data for the app. In order to do that the app redirects to reddit authorize page. Then reddit redirects back with an authorization code. The app clears that authorization code from the url for security reasons.
For the first render we are forced to send the user though login because there is no data to show. For a second visit we have some data to hidrate, however we can or not send them though login on background data fetch error. I decided to send the user to login or else this is an unrecoverable state. That is, once you have stored data and token expired, there is no functionality to login again. This could be easily changed by checking data on store before sending to login.
Handling secrets
Reddit app data is not public so its not commited to the repo nor served to the client side. This data can be configured in .env
file.
Testing
Testing is a very important topic for me. It was not requested though, so I added some test to example some tests.
Hosting
App is hosted in http://ec2-3-16-76-129.us-east-2.compute.amazonaws.com/ I went for AWS EC2 as I am familiar with the UI and a simple server is included on AWS free tier.
Deployment
Deployment is done manually by loggin into a server and:
- configuring
.env
file - running
npm i
- running
npm run build
- running
npm start
You can set the SERVER_PORT
variable in .env
to change the default port (3001)
This process can be improved by dockerizing the app.
Data sotorage
Data is stored using localstorage. I could have used cookies but I though this was a simpler yet functional approach.
Performing API calls
I went for a React hooks approach, dispatching actions there. An alternative would have been using a redux middleware. I decide the hook approach was a better fit.
redditDataMiddleware
middleware
I noticed storing reddit posts and seen data become a bit dirty on the code, so I decided to build a small middleware that watches for some actions and stores the data.
Data reload
Data is stored by keys so when new data arrives old data is updated and new data is added to the list. We could improve the functionality by polling data on interval or subscribing to a live endpoint.
Accesibility
Some elements are intentionally left with an outline for accesibility reasons. Examples are the dismiss button and the arrow to present main content. Try navigating the app with tabs.
Pagination
After loading multiple pages the DOM can get quite big. To clear data from storage run this on browser console: localStorage.removeItem('REDDIT_CLIENT__REDDIT_POSTS')
Please consider that posts under /top
are not sorted by chronologically so the "hours ago" may look weird.
Also, when reloading the app we start loading pages from the start again. This may feel strange when you have quite some data stored, but it's intentional so we refresh that data.
React hooks vs async actions
For side effects I went for a React hooks approach instead of an async redux actions. The reason for that is that react hooks are newer and in a simple project they probably make more sense. If I were to rebuild this I would use the later since they seem a better fir for redux itself.