Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 39 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -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.

Expand All @@ -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)
Expand All @@ -21,10 +22,47 @@ 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
- Basic styling of the page

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)
20 changes: 0 additions & 20 deletions app.css

This file was deleted.

72 changes: 71 additions & 1 deletion app.js
Original file line number Diff line number Diff line change
@@ -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);
});
})();
62 changes: 43 additions & 19 deletions index.html
Original file line number Diff line number Diff line change
@@ -1,29 +1,53 @@
<html lang="en"><head>
<meta charset="utf-8">
<link rel="shortcut icon" href="/favicon.ico">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="theme-color" content="#000000">
<link href="https://fonts.googleapis.com/css?family=Open+Sans:400,700|Playfair+Display" rel="stylesheet">
<link href="app.css" rel="stylesheet">
</head>
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="shortcut icon" href="/favicon.ico" />
<meta
name="viewport"
content="width=device-width, initial-scale=1, shrink-to-fit=no"
/>
<meta name="theme-color" content="#000000" />
<link
href="https://fonts.googleapis.com/css?family=Open+Sans:400,700|Playfair+Display"
rel="stylesheet"
/>
<link href="styles/app.css" rel="stylesheet" />
</head>
<body>
<noscript> You need to enable JavaScript to run this app. </noscript>
<header>
<h1>
<img> Select a Breed
</h1>

<header class="header-container">
<img class="header-container__logo" src="logo.svg" alt="resy logo" />
<h1 class="header-container__text">Select a Breed</h1>
</header>
<div class="Page">

<div class="ShowMeABreed">
<section class="dog-breed-selector__container">
<div class="dog-breed-selector-container__display-wrapper">
<p class="dog-breed-selector-container__header">Ok, but which one?!</p>

<select
onchange="getImage(this.value)"
class="dog-breed-selector__dropdown"
name="dog-breed-selector"
id="breed-selector"
aria-label="Choose a breed"
>
<option value="" selected="selected" disabled>Select a breed</option>
</select>

<h1>Ok, but which one?!</h1>
<select></select>
<img src=""/>
<button>I don't like that one. Show me another.</button>
<img id="dog-img" class="dog-breed-selector__image" src="" />

<button
onclick="getImage(event)"
id="moar-dogs"
class="dog-breed-selector__button"
disabled
>
I don't like that one. Show me another.
</button>
</div>
</div>
</section>

<script src="app.js"></script>
</body>
</html>
57 changes: 57 additions & 0 deletions styles/app.css

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions styles/app.css.map

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

68 changes: 68 additions & 0 deletions styles/app.scss
Original file line number Diff line number Diff line change
@@ -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;
}
}