Using the api available at https://github.com/harvardartmuseums/api-docs please create a basic front end app which does the following:
- A feed using the URL https://api.harvardartmuseums.org/object?classification=Prints&hasimage=1&sort=title&sortorder=desc&apikey=c28e4be0-4c0e-11ea-90d6-25d9a9fe80fc&size=10&page=1
- Provide a basic react driven front end that utilises Material UI and TypeScript for a feed that displays the image and some artwork information. (Use npx create-react-app harvard --template typescript)
- Commit your code for the client to GitHub and provide us with the url to the repository.
Time on task:
Using Create React APP, build app structure, install npm/npx modules as required: 15 mins Connect to API using the above URL and page parameter for paging, build basic model: 45 mins Build a front end to display images with a small amount of detail on each image (Title, Artist, Year), show infinite scrolling: 1hr 30 mins
Total time 2.5 hrs.
We will inspect the quality of the code and your design approach, however please also provide any demo code you have and associated repositories.
- The payload has
info
andrecords
keys. The former contains the search metadata; the latter the data for works of art - 10 results per page
- 1000s of results, so many pages!
- works have
primaryimageurl
, an array ofpeople
, which may hold just the artist - people don't have unique keys, so probably best to leave them nested within the records rather than normalise them out
- results pages have both an index/page_number and also prev/next links. Experience suggests it'll be easier to embed the main search url in code and increment a page count, than to use the prev/next links.
- Added Material-UI and removed the fluff CRA put in.
- Add a basic APi read to get first page of data. Component state is fine for this stage of development
- Lay out some cards for art items: use MUI
- Some of the card layout was really fiddly... I changed my mind around artist/title a couple of times. Eventually used the title as the "h2" because it was more consistently present in the data
- Added a grid to hold the cards. Mostly stole the code from CSS-Tricks.
- It's not IE-friendly code. I decided this was ok for a tech test that was supposed to be complete in 2-3 hours
- TBH it took me a lot longer than 2-3 hours. GEtting the logic and code factoring around loading multiple pages of data was troublesome. I tried two or three different factors (including trying to abstract it out of the Gallery.tsx into its own hook because that would have given me a more sensible place to define the Record and Person types, too). The submitted solution uses
useEffect()
in the Gallery component itself. This was the more comfortable blend of factoring that prevented infinite retries - I tried to factor out the Progress Indicator into its own component, but Waypoint didn't tolerate the child component defined in a different file. I attempted to fix this following the suggestions on Waypoint's docs, around forwarding a DOM ref, but that didn't fix the problem. I gave up.
- There's an error in the console about the wrong sort of child. It's something to do with the Cards. It only appeared after I started loading mutliple pages of records. I don't know what it is. I tried a couple of things to make it go away but gave up due to spending too long on it. I wouldn't tolerate this in production.
- I didn't write any tests. There was no stateful business logic beyond fetching data. I could have written component tests using react-testing-library, but I thought that showing paged data and some comfortable CSS + ui was more valuable in a job application, givewn the recommended time constraint. Again, I would write more tests in production. I'm not one to aim for 100% coverage. I like to write end-to-end "smoke tests" to prove out core functionality/experience, and "contract tests" to prove out glue between components/modules/domain boundaries. I'm sorry I didn't show these here.
This project was bootstrapped with Create React App.
In the project directory, you can run:
Runs the app in the development mode.
Open http://localhost:3000 to view it in the browser.
The page will reload if you make edits.
You will also see any lint errors in the console.
Launches the test runner in the interactive watch mode.
See the section about running tests for more information.
Builds the app for production to the build
folder.
It correctly bundles React in production mode and optimizes the build for the best performance.
The build is minified and the filenames include the hashes.
Your app is ready to be deployed!
See the section about deployment for more information.
Note: this is a one-way operation. Once you eject
, you can’t go back!
If you aren’t satisfied with the build tool and configuration choices, you can eject
at any time. This command will remove the single build dependency from your project.
Instead, it will copy all the configuration files and the transitive dependencies (webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except eject
will still work, but they will point to the copied scripts so you can tweak them. At this point you’re on your own.
You don’t have to ever use eject
. The curated feature set is suitable for small and middle deployments, and you shouldn’t feel obligated to use this feature. However we understand that this tool wouldn’t be useful if you couldn’t customize it when you are ready for it.
You can learn more in the Create React App documentation.
To learn React, check out the React documentation.