Many changes haha
This commit is contained in:
parent
0c5a350425
commit
ae43285239
16 changed files with 182 additions and 17 deletions
5
app/adapters/application.js
Normal file
5
app/adapters/application.js
Normal file
|
@ -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';
|
||||
}
|
40
app/adapters/meal.js
Normal file
40
app/adapters/meal.js
Normal file
|
@ -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;
|
||||
}
|
3
app/components/meal-tag.hbs
Normal file
3
app/components/meal-tag.hbs
Normal file
|
@ -0,0 +1,3 @@
|
|||
<span class="inline-block bg-gray-200 rounded-full px-3 py-1 text-sm font-semibold text-gray-700 mr-2">
|
||||
#{{yield}}
|
||||
</span>
|
|
@ -7,7 +7,7 @@
|
|||
@model={{meal}}
|
||||
as |item|>
|
||||
<item.handle>
|
||||
<RecipePreview @meal={{meal}} />
|
||||
<RecipePreview @meal={{meal}} {{on "click" this.openMealDetails}} />
|
||||
</item.handle>
|
||||
</group.item>
|
||||
{{/each}}
|
||||
|
@ -15,6 +15,6 @@
|
|||
|
||||
<button
|
||||
{{on "click" this.addRecipe}}
|
||||
class="bg-blue-500 hover:bg-blue-400 text-white font-bold py-2 px-4 border-b-4 border-blue-700 hover:border-blue-500 rounded">
|
||||
Button
|
||||
class="w-full bg-teal-500 hover:bg-teal-400 text-white font-bold mt-4 py-2 px-4 border-b-4 border-teal-700 hover:border-teal-500 rounded">
|
||||
Add Another Recipe
|
||||
</button>
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,19 +1,19 @@
|
|||
<div class="max-w-sm w-full lg:max-w-full lg:flex">
|
||||
<div class="h-48 lg:h-auto lg:w-48 flex-none bg-cover text-center overflow-hidden"
|
||||
style="background-image: url('{{@meal.strMealThumb}}')">
|
||||
style="background-image: url('{{@meal.mealThumb}}')">
|
||||
</div>
|
||||
<div class="border-r border-b border-l border-gray-400 lg:border-l-0 lg:border-t lg:border-gray-400 bg-white p-4 flex flex-col justify-between leading-normal">
|
||||
<div class="mb-8">
|
||||
<div class="text-gray-900 font-bold text-xl mb-2">
|
||||
{{@meal.strMeal}}
|
||||
{{@meal.name}}
|
||||
</div>
|
||||
<p class="text-gray-700 text-base">
|
||||
Lorem...
|
||||
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Voluptatibus quia, nulla! Maiores et perferendis eaque, exercitationem praesentium nihil.
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
<span class="inline-block bg-gray-200 rounded-full px-3 py-1 text-sm font-semibold text-gray-700 mr-2">#{{@meal.strCategory}}</span>
|
||||
<span class="inline-block bg-gray-200 rounded-full px-3 py-1 text-sm font-semibold text-gray-700 mr-2">#{{@meal.strArea}}</span>
|
||||
<MealTag>{{@meal.category}}</MealTag>
|
||||
<MealTag>{{@meal.area}}</MealTag>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
14
app/models/meal.js
Normal file
14
app/models/meal.js
Normal file
|
@ -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;
|
||||
}
|
|
@ -7,4 +7,5 @@ export default class Router extends EmberRouter {
|
|||
}
|
||||
|
||||
Router.map(function() {
|
||||
this.route('meal', { path: '/:id' });
|
||||
});
|
||||
|
|
7
app/routes/meal.js
Normal file
7
app/routes/meal.js
Normal file
|
@ -0,0 +1,7 @@
|
|||
import Route from '@ember/routing/route';
|
||||
|
||||
export default class MealRoute extends Route {
|
||||
model({ id }) {
|
||||
return this.store.findRecord('meal', id);
|
||||
}
|
||||
}
|
|
@ -1,11 +1,10 @@
|
|||
<HeaderNav />
|
||||
|
||||
<div class="flex mb-4">
|
||||
<div class="w-1/4">
|
||||
<div class="flex p-4">
|
||||
<div class="w-2/6">
|
||||
<RecipeList />
|
||||
</div>
|
||||
<div class="w-3/4">
|
||||
Content goes here.
|
||||
<div class="w-4/6 pl-4">
|
||||
{{outlet}}
|
||||
</div>
|
||||
</div>
|
||||
|
|
13
app/templates/meal.hbs
Normal file
13
app/templates/meal.hbs
Normal file
|
@ -0,0 +1,13 @@
|
|||
<h1 class="text-5xl text-teal-500 font-hairline">
|
||||
{{@model.name}}
|
||||
</h1>
|
||||
|
||||
<p class="text-gray-700 text-base whitespace-pre-line">
|
||||
{{@model.instructions}}
|
||||
</p>
|
||||
|
||||
|
||||
<div class="mt-4">
|
||||
<MealTag>{{@model.category}}</MealTag>
|
||||
<MealTag>{{@model.area}}</MealTag>
|
||||
</div>
|
26
tests/integration/components/meal-tag-test.js
Normal file
26
tests/integration/components/meal-tag-test.js
Normal file
|
@ -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`<MealTag />`);
|
||||
|
||||
assert.equal(this.element.textContent.trim(), '');
|
||||
|
||||
// Template block usage:
|
||||
await render(hbs`
|
||||
<MealTag>
|
||||
template block text
|
||||
</MealTag>
|
||||
`);
|
||||
|
||||
assert.equal(this.element.textContent.trim(), 'template block text');
|
||||
});
|
||||
});
|
12
tests/unit/adapters/application-test.js
Normal file
12
tests/unit/adapters/application-test.js
Normal file
|
@ -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);
|
||||
});
|
||||
});
|
12
tests/unit/adapters/meal-test.js
Normal file
12
tests/unit/adapters/meal-test.js
Normal file
|
@ -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);
|
||||
});
|
||||
});
|
13
tests/unit/models/meal-test.js
Normal file
13
tests/unit/models/meal-test.js
Normal file
|
@ -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);
|
||||
});
|
||||
});
|
11
tests/unit/routes/meal-test.js
Normal file
11
tests/unit/routes/meal-test.js
Normal file
|
@ -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);
|
||||
});
|
||||
});
|
Loading…
Add table
Reference in a new issue