diff --git a/app/adapters/application.js b/app/adapters/application.js new file mode 100644 index 0000000..2744f76 --- /dev/null +++ b/app/adapters/application.js @@ -0,0 +1,5 @@ +import JSONAPIAdapter from '@ember-data/adapter/json-api'; + +export default class ApplicationAdapter extends JSONAPIAdapter { + host = 'https://www.themealdb.com/api/json/v1/1'; +} diff --git a/app/adapters/meal.js b/app/adapters/meal.js new file mode 100644 index 0000000..3183cb1 --- /dev/null +++ b/app/adapters/meal.js @@ -0,0 +1,40 @@ +import ApplicationAdapter from './application'; +import { dasherize } from '@ember/string'; + +export default class MealAdapter extends ApplicationAdapter { + async findRecord(store, model, id) { + let result = await fetch(`${this.host}/lookup.php?i=${id}`); + let json = await result.json(); + return normalize(json.meals[0]); + } + + async queryRecord(store, model, query) { + if (query === 'random') { + let result = await fetch(`${this.host}/random.php`); + let json = await result.json(); + return normalize(json.meals[0]); + } + } +} + +function normalize(obj) { + let attributes = {}; + + Object.keys(obj).forEach(key => attributes[cleanKey(key)] = obj[key]); + + return { + data: { + type: 'meal', + id: attributes.id, + attributes, + }, + }; +} + +function cleanKey(key) { + key = dasherize(key); + key = key.replace('str-', ''); + if (key === 'id-meal') key = 'id'; + if (key === 'meal') key = 'name'; + return key; +} diff --git a/app/components/meal-tag.hbs b/app/components/meal-tag.hbs new file mode 100644 index 0000000..50c1b23 --- /dev/null +++ b/app/components/meal-tag.hbs @@ -0,0 +1,3 @@ + + #{{yield}} + diff --git a/app/components/recipe-list.hbs b/app/components/recipe-list.hbs index f875b7f..12a6053 100644 --- a/app/components/recipe-list.hbs +++ b/app/components/recipe-list.hbs @@ -7,7 +7,7 @@ @model={{meal}} as |item|> - + {{/each}} @@ -15,6 +15,6 @@ diff --git a/app/components/recipe-list.js b/app/components/recipe-list.js index 0928a38..adca2ea 100644 --- a/app/components/recipe-list.js +++ b/app/components/recipe-list.js @@ -3,14 +3,24 @@ import { tracked } from "@glimmer/tracking"; import { action } from "@ember/object"; import { A } from '@ember/array'; import { task } from 'ember-concurrency'; +import { inject as service } from '@ember/service'; export default class RecipeListComponent extends Component { + @service store; @tracked items = A([]); + constructor() { + super(...arguments); + this.assignExistingItems(); + } + + async assignExistingItems() { + let items = await this.store.peekAll('meal'); + this.items = items; + } + @(task(function * () { - let response = yield fetch('https://www.themealdb.com/api/json/v1/1/random.php'); - response = yield response.json(); - return response.meals[0]; + return yield this.store.queryRecord('meal', 'random'); })) fetchRecipe; @action @@ -20,7 +30,6 @@ export default class RecipeListComponent extends Component { @action async addRecipe() { - let recipe = await this.fetchRecipe.perform(); - this.items.pushObject(recipe); + await this.fetchRecipe.perform(); } } diff --git a/app/components/recipe-preview.hbs b/app/components/recipe-preview.hbs index 3a3b83c..eb0503f 100644 --- a/app/components/recipe-preview.hbs +++ b/app/components/recipe-preview.hbs @@ -1,19 +1,19 @@
+ style="background-image: url('{{@meal.mealThumb}}')">
- {{@meal.strMeal}} + {{@meal.name}}

- Lorem... + Lorem ipsum dolor sit amet, consectetur adipisicing elit. Voluptatibus quia, nulla! Maiores et perferendis eaque, exercitationem praesentium nihil.

- #{{@meal.strCategory}} - #{{@meal.strArea}} + {{@meal.category}} + {{@meal.area}}
diff --git a/app/models/meal.js b/app/models/meal.js new file mode 100644 index 0000000..9474a35 --- /dev/null +++ b/app/models/meal.js @@ -0,0 +1,14 @@ +import DS from 'ember-data'; +const { Model, attr } = DS; + +export default class MealModel extends Model { + @attr name; + @attr dateModified; + @attr category; + @attr area; + @attr mealThumb; + @attr instructions; + @attr tags; + @attr youtube; + @attr source; +} diff --git a/app/router.js b/app/router.js index 224ca42..7e97e63 100644 --- a/app/router.js +++ b/app/router.js @@ -7,4 +7,5 @@ export default class Router extends EmberRouter { } Router.map(function() { + this.route('meal', { path: '/:id' }); }); diff --git a/app/routes/meal.js b/app/routes/meal.js new file mode 100644 index 0000000..2faa5e7 --- /dev/null +++ b/app/routes/meal.js @@ -0,0 +1,7 @@ +import Route from '@ember/routing/route'; + +export default class MealRoute extends Route { + model({ id }) { + return this.store.findRecord('meal', id); + } +} diff --git a/app/templates/application.hbs b/app/templates/application.hbs index 60c698c..fb86a52 100644 --- a/app/templates/application.hbs +++ b/app/templates/application.hbs @@ -1,11 +1,10 @@ -
-
+
+
-
- Content goes here. +
{{outlet}}
diff --git a/app/templates/meal.hbs b/app/templates/meal.hbs new file mode 100644 index 0000000..c76739a --- /dev/null +++ b/app/templates/meal.hbs @@ -0,0 +1,13 @@ +

+ {{@model.name}} +

+ +

+ {{@model.instructions}} +

+ + +
+ {{@model.category}} + {{@model.area}} +
diff --git a/tests/integration/components/meal-tag-test.js b/tests/integration/components/meal-tag-test.js new file mode 100644 index 0000000..f6599db --- /dev/null +++ b/tests/integration/components/meal-tag-test.js @@ -0,0 +1,26 @@ +import { module, test } from 'qunit'; +import { setupRenderingTest } from 'ember-qunit'; +import { render } from '@ember/test-helpers'; +import { hbs } from 'ember-cli-htmlbars'; + +module('Integration | Component | meal-tag', function(hooks) { + setupRenderingTest(hooks); + + test('it renders', async function(assert) { + // Set any properties with this.set('myProperty', 'value'); + // Handle any actions with this.set('myAction', function(val) { ... }); + + await render(hbs``); + + assert.equal(this.element.textContent.trim(), ''); + + // Template block usage: + await render(hbs` + + template block text + + `); + + assert.equal(this.element.textContent.trim(), 'template block text'); + }); +}); diff --git a/tests/unit/adapters/application-test.js b/tests/unit/adapters/application-test.js new file mode 100644 index 0000000..eff23bb --- /dev/null +++ b/tests/unit/adapters/application-test.js @@ -0,0 +1,12 @@ +import { module, test } from 'qunit'; +import { setupTest } from 'ember-qunit'; + +module('Unit | Adapter | application', function(hooks) { + setupTest(hooks); + + // Replace this with your real tests. + test('it exists', function(assert) { + let adapter = this.owner.lookup('adapter:application'); + assert.ok(adapter); + }); +}); diff --git a/tests/unit/adapters/meal-test.js b/tests/unit/adapters/meal-test.js new file mode 100644 index 0000000..4d6713f --- /dev/null +++ b/tests/unit/adapters/meal-test.js @@ -0,0 +1,12 @@ +import { module, test } from 'qunit'; +import { setupTest } from 'ember-qunit'; + +module('Unit | Adapter | meal', function(hooks) { + setupTest(hooks); + + // Replace this with your real tests. + test('it exists', function(assert) { + let adapter = this.owner.lookup('adapter:meal'); + assert.ok(adapter); + }); +}); diff --git a/tests/unit/models/meal-test.js b/tests/unit/models/meal-test.js new file mode 100644 index 0000000..c211490 --- /dev/null +++ b/tests/unit/models/meal-test.js @@ -0,0 +1,13 @@ +import { module, test } from 'qunit'; +import { setupTest } from 'ember-qunit'; + +module('Unit | Model | meal', function(hooks) { + setupTest(hooks); + + // Replace this with your real tests. + test('it exists', function(assert) { + let store = this.owner.lookup('service:store'); + let model = store.createRecord('meal', {}); + assert.ok(model); + }); +}); diff --git a/tests/unit/routes/meal-test.js b/tests/unit/routes/meal-test.js new file mode 100644 index 0000000..5077255 --- /dev/null +++ b/tests/unit/routes/meal-test.js @@ -0,0 +1,11 @@ +import { module, test } from 'qunit'; +import { setupTest } from 'ember-qunit'; + +module('Unit | Route | meal', function(hooks) { + setupTest(hooks); + + test('it exists', function(assert) { + let route = this.owner.lookup('route:meal'); + assert.ok(route); + }); +});