202 lines
7.5 KiB
Markdown
202 lines
7.5 KiB
Markdown
# Elder Scroll: Legends Coding Challenge
|
|
|
|
Don't you love homework?
|
|
|
|
## Synopsis
|
|
|
|
The Highspot Coding Challenge. The premise is to display a deck-builder
|
|
card catalog (such as Magic The Gathering, although in this case it's
|
|
Elder Scrolls) made available via a RESTful API. The requirements as
|
|
set out in the Code Challenge are:
|
|
|
|
### Requirements Checklist
|
|
|
|
- ✓ Show results in a card grid format with the image prominently displayed.
|
|
- ✓ Each card displays: Image, Name, Text, Set Name, and Type. Additional fields are optional.
|
|
- ✓ Display a loading indicator when communicating with the API.
|
|
- ✓ Use a responsive design that accommod_es, at minimum, desktop and mobile.
|
|
- ✓ Initially, fetch and display the first 20 results returned by the API.
|
|
- ✓ As the user scrolls down the page, load and append additional cards using "infinite scroll."
|
|
- ✓ Retrieve additional pages of results as-needed but do not load more than 20 cards with
|
|
each request.
|
|
- ✓ Allow the user to search for cards by Name.
|
|
- ✓ Use modern open-source web technologies to implement your solution (React, Backbone,
|
|
Angular, Vue, Underscore, etc.).
|
|
- ✓ Provide instructions for prerequisites, installation, and application setup and build in a
|
|
README file.
|
|
|
|
### Evaluation Criteria
|
|
|
|
- Are all stated requirements met?
|
|
- Does the application successfully build and run?
|
|
- Is the code well-organized and easy to understand?
|
|
- Does the code reflect contemporary web development techniques?
|
|
- Are functions and variables clearly named to express their purpose?
|
|
- Was the solution visually appealing?
|
|
- Were any scope decisions, TODO items, and known issues called out in
|
|
code comments or the README file?
|
|
|
|
### Available Resources
|
|
|
|
- Endpoint: https://api.elderscrollslegends.io/v1/cards
|
|
- Documentation: https://docs.elderscrollslegends.io/,
|
|
https://docs.elderscrollslegends.io/#api_v1cards_list
|
|
|
|
The API includes this note:
|
|
|
|
> NOTE: The Elder Scrolls Legends API is a free, third-party service
|
|
> built by an independent developer; it is not affiliated with Highspot,
|
|
> or with the intellectual property owners of Elder Scrolls
|
|
> Legends. Please help us use it responsibly.
|
|
|
|
## Initial impressions
|
|
|
|
This is a single-page application. The 'search' is more of a filter,
|
|
sending the `?name=<param>` to the `/cards` API endpoint. To meet the
|
|
requirements of the application, the `pageSize=20` argument must be
|
|
passed to the endpoint.
|
|
|
|
Startup seems to be relatively straightforward, and there won't be
|
|
anything fancy here: A flexbox will probably do just fine, as will a
|
|
progressive fill. I'm inclined to _not_ use MaterialUI here; it's
|
|
probably overkill. Just an application, with some nice CSS and a decent
|
|
cache.
|
|
|
|
For the search feature, we'll want to go with whatever the API offers,
|
|
but when clearing the search, let's go for a fast reload with no data
|
|
requirements. That's provide some speed when going back to the basics.
|
|
I won't be using the ServiceWorker, as I don't feel confident enough in
|
|
my familiarity with it to make it matter.
|
|
|
|
Also, because I'm a *nerd*, I can't start without first picking out a
|
|
theme: white on black, with a paper texture from my design library
|
|
desaturated, darkened, and rendered a seamless tile, using the Google
|
|
'Marcellus' font, which kinda sorta looks Tolkeinesque. Not so sure
|
|
about the 'Morpheous' font for the title, though.
|
|
|
|
## Requirements
|
|
|
|
The following are all you need to have installed in order to get
|
|
started:
|
|
|
|
- NodeJS >= 10.0
|
|
- Yarn >= 1.18
|
|
- Git >= 2.0
|
|
|
|
Fetch the latest version from the git repository (this repository uses
|
|
the new "not master" terminology, so it may not be immediately visible
|
|
until you checkout the 'canon' branch), then install any prerequisites.
|
|
|
|
Assuming you have GNU Make installed:
|
|
|
|
``` shellsession
|
|
$ git clone https://git.elfsternberg.com/elf/elder_scrolling
|
|
$ cd elder_scrolling
|
|
$ git checkout canon
|
|
$ make serve
|
|
```
|
|
|
|
If you do NOT have GNU Make installed:
|
|
|
|
``` shellsession
|
|
$ git clone https://git.elfsternberg.com/elf/elder_scrolling
|
|
$ cd elder_scrolling
|
|
$ git checkout canon
|
|
$ yarn
|
|
$ yarn build
|
|
$ yarn run http-server build/
|
|
```
|
|
|
|
In both of the above, the server will be available on port 8080.
|
|
|
|
To run in dev mode:
|
|
|
|
``` shellsession
|
|
$ git clone https://git.elfsternberg.com/elf/elder_scrolling
|
|
$ cd elder_scrolling
|
|
$ git checkout canon
|
|
$ yarn
|
|
$ yarn server
|
|
```
|
|
|
|
The server will be available on port 3000.
|
|
|
|
If you have docker installed, you may run the app this way:
|
|
|
|
``` shellsession
|
|
$ git clone https://git.elfsternberg.com/elf/elder_scrolling
|
|
$ cd elder_scrolling
|
|
$ git checkout canon
|
|
$ docker build --tag elderscrolling:1.0 .
|
|
$ docker run --publish 8080:8080 --name elderscrolling --detach elderscrolling:1.0
|
|
```
|
|
|
|
The server will be available on port 8080. To stop the docker session,
|
|
remove it from the server, and clean up your disk space afterward:
|
|
|
|
``` shellsession
|
|
$ docker kill elderscrolling
|
|
$ docker rm elderscrolling
|
|
$ docker rmi elderscrolling:1.0
|
|
```
|
|
|
|
Note that this will not remove the node-alpine image on top of which
|
|
elderscrolling is build.
|
|
|
|
## Observations
|
|
|
|
This was a lot of fun. I don't know how "cheating" it was to use the
|
|
react-grid-layout library, or react-modal, but I'm always glad to let
|
|
the professionals do the work. Working "around" the way hooks really,
|
|
really want to avoid expensive paints, in order to get the search
|
|
feature working, was a lesson I know I've had before, but it always
|
|
frustrates me when I come across it.
|
|
|
|
There are lot of other things that could be done with the app, but this
|
|
is "good enough" for now without throwing something like Semantic or
|
|
Material at it. It's possible to search on fields other than `name`,
|
|
for example, and it would be nifty to be able to, say, see all the
|
|
Unique cards, or all the Creature cards, and so forth. That wasn't in
|
|
the requirements, and I've given you folks 8 hours already.
|
|
|
|
That may seem like a lot for such a minor project, but it's been awhile
|
|
since I last worked with React at this level, and it's also been awhile
|
|
since I got Emacs up and running with a proper JSX back-end. The LSP
|
|
server is pretty good, but there are still some rough edges. Using
|
|
`prettier` a lot, and setting the code into `strict` as much as
|
|
possible, was as helpful as always.
|
|
|
|
I think I'm going to take apart the scrolling library I used. It's a
|
|
native JS application with a React wrapper, rather than a full-on React
|
|
app "written in React," and I feel that there are lessons inside it I
|
|
could use.
|
|
|
|
If I had my druthers, I'd have done a two-stage build of the Dockerfile;
|
|
one just build the thing, but the second would consist only of the
|
|
'build/' directory and a static web server that only does fileserving;
|
|
one thing I dislike strongly about Dockerizing NodeJS (or any big
|
|
scripting language, like Python or Ruby) is just how much attack surface
|
|
area those languages carry with them.
|
|
|
|
But, like I said, I've given you folks enough time already.
|
|
|
|
## LICENSE
|
|
|
|
The Elder Scrolls, The Elder Scrolls: Legends, ZeniMax, Bethesda,
|
|
Bethesda Softworks and related logos are registered trademarks or
|
|
trademarks of ZeniMax Media Inc. This product is not produced, endorsed,
|
|
supported, or affiliated with ZeniMax Media Inc.
|
|
|
|
The coding challenge itself is probably copyright Highspot.
|
|
|
|
The fonts are covered by the SIL Open Font License. A copy of that
|
|
license can be found in the `./public/fonts` folder.
|
|
|
|
All original software, as well as the background images, contained in
|
|
this repository is copyright [Kenneth M. "Elf"
|
|
Sternberg](https://elfsternberg.com) (c) 2020, and is licensed with the
|
|
Mozilla Public License vers. 2.0. A copy of the license file is included
|
|
in the root folder.
|
|
|
|
|