Thank you for considering Granular! For a portion of your interview, you'll be live-coding a small React app in TypeScript based on the API provided in this repo. It's ok to work on the project beforehand, but be prepared to talk through your solution and potentially add to it in the interview.
Please make sure you have
- Installed the Zoom client and are able to screen-share
- Your favorite React + TypeScript programming setup all ready to go
Run with yarn start
and go to http://localhost:8000
.
To enable live-reloading for any reason, run yarn watch
. To change the host and port,
HOST="127.0.0.1" PORT=8080 yarn serve
Always replies with an application/json
content-type and has only two endpoints. Please look at resources/types.ts
for what you'll get back. You will want to use that file in your project.
Returns some basic information on all the fields in the backend. Here's a sample response:
{
"fields": [
{
"id": "318fcafb-a40c-425e-bb91-798f2b3e6c3e",
"name": "Makeba",
"type": "corporate"
},
{
"id": "2b103f85-919b-4826-9858-00b0729f2fb9",
"name": "Olathe Farms",
"type": "individual"
},
// ... more `BasicField`s
]
}
For the given field ID, returns its basic information plus extended information:
- Field geometry in valid GeoJSON
- The field's two-letter country code, and
- The field's owner
Here's a sample request and response:
GET /fields/318fcafb-a40c-425e-bb91-798f2b3e6c3e
{
"id": "318fcafb-a40c-425e-bb91-798f2b3e6c3e",
"countryCode": "IN",
"name": "Moyanka",
"owner": "Giuseppe Sydow",
"type": "collective",
"geoData": {
"type": "Feature",
"properties": {},
"geometry": {
"type": "Polygon",
"coordinates": [
[
[-95.42449951171875, 44.32384807250689],
[-95.152587890625, 44.32384807250689],
[-95.152587890625, 44.39257961837961],
[-95.42449951171875, 44.39257961837961],
[-95.42449951171875, 44.32384807250689]
]
]
}
}
}
You'll get the expected HTTP 404
if the Field ID was not found in the /fields
collection.
At Granular, our APIs are fast, resilient, and reliable 😎 But this API isn't any of these things. 🤦 For the sake of this exercise, consider it is an external, third-party API and build accordingly.
- For both endpoints, it will reply with a happy
HTTP 200
around 75% of the time and sulk with a sadHTTP 500
around 25% of the time. - You might wait between 10ms and 3s for all responses.
Locally, you can add these URL params to all endpoints so you can develop faster:
- Add
?fail
to get nothing but HTTP 500s - Add
?succeed
to get nothing but HTTP 200s (supercedesfail
(so let's not waste time being cheeky withfail&succeed
😁)) - Add
?fast
to enjoy a super-fast API without the simulated latency
Example: /fields?fail&fast
Create a React application that uses the API to render the list of fields and their extended information. Your app must factor in the API's latency and unreliability when displaying any information to the user.
Using the two endpoints, you'll need to show
- A list of all the Fields
- The total number of Fields
- The name of each Field
- A little icon for each Field's
type
- 🏦 when the
type
is "corporate" - 👥 when the
type
is "collective" - 👤 when the
type
is "individual"
- 🏦 when the
- A small flag based on a Field's
countryCode
- The Field's area in acres based on its
geoData
We use (a highly customized extension of) Reactstrap for our products so we'd prefer if you used that in your solution.
👉 If you're comfortable with a UI library other than Reactstrap, please use it instead.
👉 Don't worry about how your solution looks (we have a fantastic Design team for that.) Just focus on the states of the app and the information you're showing the user.
👉 Please be prepared for questions about how you'd test your app.
👉 Please be prepared for broad discussions about state management and performance.
Use this library to render a small flag for the countryCode
.
import Flag from "react-world-flags";
<Flag code="US" />
Use this library to compute the field's area from its geoData
attribute:
import GeoJSONArea from "@mapbox/geojson-area";
// If `fieldObject` is the upstream response,
const areaInSquaredMeters = GeoJSONArea.geometry(fieldObject.geoData.geometry);
The library will return squared meters. Convert that to acres with two decimal places of precision (1 m2 = 0.000247105 acres). The result must look like this: "3.43 ac".
- Add a toggler that allows the user to switch between acres and hectares (1 m2 = 0.0001 hectares)
- Add a dropdown to filter by Field
type
- Sort Fields by their area (ascending and descending)
- Group fields by Country Code