diff --git a/README.md b/README.md index 124bc46..e2f375f 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,7 @@ # Welcome to Resy FE Interview Exercise ## This is a hands-on test + Provided here is a skeleton application. You'll find an index.html, app.js, and app.css. The task is to look at the provided .mov and build what is represented therein. @@ -11,8 +12,8 @@ The task is to look at the provided .mov and build what is represented therein. - When the user selects an item from the list eg 'boxer', then an image of a boxer appears below the select control. You can use this URL: https://dog.ceo/api/breed/{breed}/images/random to retrieve an image showing an example of that breed. - Below the image there is a button. The button has the text "I don't like this one. Show me another." When the user clicks on this button a new call is made to retrieve a new image of a dog of that breed. - This task utilizes these open source urls: + - [https://dog.ceo/api/breeds/list/all](https://dog.ceo/api/breeds/list/all) - [https://dog.ceo/api/breeds/image/random](https://dog.ceo/api/breeds/image/random) - [https://dog.ceo/api/breed/affenpinscher/images/random](https://dog.ceo/api/breed/affenpinscher/images/random) @@ -21,6 +22,7 @@ You will utilize these urls to create a select control in which the user can cho If the user clicks a button - "I don't like that one. Show me another."" - then a new image will be presented. Some of the things evaluated in this exercise are: + - Retrieving data and translating that to the UI controls - Writing HTML using JavaScript - Writing functions, keeping track of variables @@ -28,3 +30,39 @@ Some of the things evaluated in this exercise are: You can use any resources available on the web. Please communicate with us with any questions you might have. + +--- + +## The solve + +After revisiting the problem to be solved, I decided that I didn't need the full weight of an ember application, this can likely be tackled using vanillaJS. + +Styling - I like to write scss and use BEM to help keep my specificity manageable, I didn't need to add a build tool for this so I'm just running the `sass --watch` command to pick up changes. I'd also almost always use a [reset](https://meyerweb.com/eric/tools/css/reset/) to get around opinionated browser styling and let me start fresh but the layout here was simple enough that I can build this implementation without needed to worry about that. + +## Todo + +- [] Create header + +DOD - It should: + +- display the Resy logo +- display header text + +[] Dropdown input field + +DOD - It should: + +- contain a list of dog breeds from [the following endpoint](https://dog.ceo/api/breeds/list/all) +- render 'select a breed' on render + +[] Image display + +DOD - It should: + +- render an image of a dog matching the selected breed [using this endpoint](https://dog.ceo/api/breeds/image/random) + +[] Button + +DOD - It should: + +- fetch a new image, on click [from this endpoint](https://dog.ceo/api/breed/affenpinscher/images/random) diff --git a/app.css b/app.css deleted file mode 100644 index b347124..0000000 --- a/app.css +++ /dev/null @@ -1,20 +0,0 @@ -box-sizing: border-box; - -html, -body { - font-family: "Open Sans", sans-serif; - margin: 0; - padding: 0; -} - -h1 { - font-family: "Playfair Display", serif; -} - -a { - color: #000; -} - -.Page { - background: #fafafa; -} diff --git a/app.js b/app.js index bd6b307..0064304 100644 --- a/app.js +++ b/app.js @@ -1 +1,71 @@ -// application code goes here +const dropdown = document.getElementById('breed-selector'); +const button = document.getElementById('moar-dogs'); +let breed = ''; +let element; +let imgUrl = ''; + +let getImage = (arg) => { + const image = document.getElementById('dog-img'); + + if (arg.target) { + imgUrl = `https://dog.ceo/api/breed/${breed}/images/random`; + } else { + try { + let url = new URL(arg); + image.src = arg; + image.alt = `Image of a dog`; + return; + } catch (_) { + imgUrl = `https://dog.ceo/api/breed/${arg}/images/random`; + button.removeAttribute('disabled'); + breed = arg; + return; + } + } + + fetch(imgUrl) + .then((resp) => resp.json()) + .then(function (data) { + image.src = data.message; + image.alt = `Image of a ${breed}`; + return; + }) + .catch(function (error) { + console.log(error); + }); +}; + +let populateDropdownList = (breeds) => { + const selectEl = document.getElementById('breed-selector'); + + for (const key in breeds) { + const optionEl = document.createElement('option'); + optionEl.value = key; + optionEl.text = key; + selectEl.add(optionEl); + } + return; +}; + +(function () { + let listUrl = 'https://dog.ceo/api/breeds/list/all'; + let randomImgUrl = 'https://dog.ceo/api/breeds/image/random'; + + fetch(randomImgUrl) + .then((resp) => resp.json()) + .then(function (data) { + return getImage(data.message); + }) + .catch(function (error) { + console.log(error); + }); + + fetch(listUrl) + .then((resp) => resp.json()) + .then(function (data) { + return populateDropdownList(data.message); + }) + .catch(function (error) { + console.log(error); + }); +})(); diff --git a/index.html b/index.html index f5f57d7..e4ad0af 100644 --- a/index.html +++ b/index.html @@ -1,29 +1,53 @@ - - - - - - - - + + + + + + + + + -
-

- Select a Breed -

+ +
+ +

Select a Breed

-
-
+
+
+

Ok, but which one?!

+ + -

Ok, but which one?!

- - - + +
-
+ + diff --git a/styles/app.css b/styles/app.css new file mode 100644 index 0000000..d6dc323 --- /dev/null +++ b/styles/app.css @@ -0,0 +1,57 @@ +html { + box-sizing: border-box; +} + +*, +*:before, +*:after { + box-sizing: inherit; +} + +.header-container { + padding: 8px 0 16px; + display: flex; + align-content: center; + justify-content: center; +} + +.header-container__logo, +.header-container__text { + margin: 0 8px; +} + +.dog-breed-selector__container { + height: 100vh; + background-color: #fafafa; + display: flex; + justify-content: center; + align-content: center; +} + +.dog-breed-selector-container__header { + font-size: 32px; + font-weight: 700; +} + +.dog-breed-selector__dropdown, +.dog-breed-selector__button { + display: block; + margin: 8px; + cursor: pointer; +} + +.dog-breed-selector__button { + background-color: #00c6ff; + color: #fafafa; + border-radius: 5px; + padding: 16px 8px; + border: none; + box-shadow: 0 3px 10px #808080; +} + +.dog-breed-selector__button:disabled { + background-color: #808080; + cursor: not-allowed; +} + +/*# sourceMappingURL=app.css.map */ diff --git a/styles/app.css.map b/styles/app.css.map new file mode 100644 index 0000000..d89f3e1 --- /dev/null +++ b/styles/app.css.map @@ -0,0 +1 @@ +{"version":3,"sourceRoot":"","sources":["app.scss"],"names":[],"mappings":"AACA;EACE;;;AAEF;AAAA;AAAA;EAGE;;;AAYF;EACE;EACA;EACA;EACA;;;AAGF;AAAA;EAEE;;;AAKF;EACE;EACA,kBAvBW;EAwBX;EACA;EACA;;;AAGF;EACE;EACA;;;AAGF;AAAA;EAEE;EACA;EACA;;;AAGF;EACE,kBAxCkB;EAyClB,OAxCY;EAyCZ;EACA;EACA;EACA;;;AAIA;EACE,kBAnDQ;EAoDR","file":"app.css"} \ No newline at end of file diff --git a/styles/app.scss b/styles/app.scss new file mode 100644 index 0000000..c82762d --- /dev/null +++ b/styles/app.scss @@ -0,0 +1,68 @@ +// global styles +html { + box-sizing: border-box; +} +*, +*:before, +*:after { + box-sizing: inherit; +} + +// variables + +$light-gray: #fafafa; +$dark-gray: #808080; +$button-background: #00c6ff; +$button-font: #fafafa; + +// header styles + +.header-container { + padding: 8px 0 16px; + display: flex; + align-content: center; + justify-content: center; +} + +.header-container__logo, +.header-container__text { + margin: 0 8px; +} + +// main feature styling + +.dog-breed-selector__container { + height: 100vh; + background-color: $light-gray; + display: flex; + justify-content: center; + align-content: center; +} + +.dog-breed-selector-container__header { + font-size: 32px; + font-weight: 700; +} + +.dog-breed-selector__dropdown, +.dog-breed-selector__button { + display: block; + margin: 8px; + cursor: pointer; +} + +.dog-breed-selector__button { + background-color: $button-background; + color: $button-font; + border-radius: 5px; + padding: 16px 8px; + border: none; + box-shadow: 0 3px 10px $dark-gray; +} + +.dog-breed-selector__button { + &:disabled { + background-color: $dark-gray; + cursor: not-allowed; + } +}