Browse Source

Datenanbindung und Kategorie Komponente implementiert.

master
Felix Diemar 4 years ago
parent
commit
5b9410cf1c

+ 6
- 0
app/components/kategorie.hbs View File

<h1 class="kategorie">{{@titel}}</h1>
<div class="kategorie">
{{yield}}
</div>



+ 11
- 0
app/components/produkt.hbs View File

<article class="kategorie">
<image src={{@produkt.bild}} alt="Ein Bild von {{@produkt.titel}}"/>
<div class="details">
<h3>{{@produkt.titel}}</h3>
<div class="detail owner">
<span>Menge:</span> {{@produkt.menge}}{{@produkt.einheit}}
</div>
</div>
</article>

+ 35
- 0
app/helpers/compare.js View File

import Ember from 'ember';

export function compare(params) {
if(params[3]){ //handle case insensitive conditions if 4 param is passed.
params[0]= params[0].toLowerCase();
params[2]= params[2].toLowerCase();
}
let v1 = params[0];
let operator = params[1];
let v2 = params[2];
switch (operator) {
case '==':
return (v1 == v2);
case '!=':
return (v1 != v2);
case '===':
return (v1 === v2);
case '<':
return (v1 < v2);
case '<=':
return (v1 <= v2);
case '>':
return (v1 > v2);
case '>=':
return (v1 >= v2);
case '&&':
return !!(v1 && v2);
case '||':
return !!(v1 || v2);
default:
return false;
}
}

export default Ember.Helper.helper(compare);

+ 30
- 0
app/routes/produkte.js View File

import Route from '@ember/routing/route';

const PRODUKT_KATEGORIEN = [
'Pasta',
'Gemüse',
'Milchprodukte',
'Fleisch'
];

export default class IndexRoute extends Route {
async model() {
let response = await fetch('/api/produkte.json');
let { data } = await response.json();

return data.map(model => {
let { attributes } = model;
let kategorie;

if (PRODUKT_KATEGORIEN.includes(attributes.kategorie)) {
kategorie = attributes.kategorie;
}
else
{
kategorie = 'Sonstiges';
}

return { kategorie, ...attributes };
});
}
}

+ 37
- 37
app/styles/app.css View File

bottom: 5px; bottom: 5px;
} }


.zettel label span {
.kategorie label span {
font-size: 140%; font-size: 140%;
margin: 50px auto 20px; margin: 50px auto 20px;
display: block; display: block;
font-style: italic; font-style: italic;
} }


.zettel input {
.kategorie input {
padding: 11px; padding: 11px;
font-size: 18px; font-size: 18px;
width: 500px; width: 500px;
} }


/** /**
* Individual zettel Listing
* Individual kategorie Listing
*/ */


.zettel {
.kategorie {
margin-top: 15px; margin-top: 15px;
background-color: #f6f6f6; background-color: #f6f6f6;
padding: 20px 25px; padding: 20px 25px;
flex-wrap: wrap; flex-wrap: wrap;
} }


.zettel:hover {
.kategorie:hover {
background-color: #f3f3f3; background-color: #f3f3f3;
} }


.zettel img {
.kategorie img {
border-radius: 5px; border-radius: 5px;
} }


.zettel .image {
.kategorie .image {
flex-grow: 0; flex-grow: 0;
flex-basis: 150px; flex-basis: 150px;
margin: 20px 25px; margin: 20px 25px;
text-align: center; text-align: center;
} }


.zettel button.image {
.kategorie button.image {
position: relative; position: relative;
cursor: pointer; cursor: pointer;
border: none; border: none;
z-index: 1; z-index: 1;
} }


.zettel button.image:focus {
.kategorie button.image:focus {
outline: none; outline: none;
} }


.zettel button.image:after {
.kategorie button.image:after {
content: ""; content: "";
position: absolute; position: absolute;
top: 0; top: 0;
transition: opacity 0.25s ease-in-out; transition: opacity 0.25s ease-in-out;
} }


.zettel button.image:focus:after, .zettel button.image:hover:after {
.kategorie button.image:focus:after, .kategorie button.image:hover:after {
opacity: 0.1; opacity: 0.1;
} }


.zettel .image img {
.kategorie .image img {
max-width: 100%; max-width: 100%;
} }


.zettel .image.large {
.kategorie .image.large {
margin: 30px 25px 50px 25px; margin: 30px 25px 50px 25px;
flex-basis: 100%; flex-basis: 100%;
} }


.zettel .image small {
.kategorie .image small {
display: block; display: block;
margin-top: 5px; margin-top: 5px;
margin-bottom: -15px; margin-bottom: -15px;
position: relative; position: relative;
} }


.zettel .image.large small {
.kategorie .image.large small {
margin-top: 10px; margin-top: 10px;
margin-bottom: 0px; margin-bottom: 0px;
font-size: 110%; font-size: 110%;
} }


.zettel .details {
.kategorie .details {
flex-basis: 50%; flex-basis: 50%;
flex-grow: 2; flex-grow: 2;
display: flex; display: flex;
align-content: space-around; align-content: space-around;
} }


.zettel h3 {
.kategorie h3 {
flex-basis: 100%; flex-basis: 100%;
} }


.zettel h3 a {
.kategorie h3 a {
display: inline; display: inline;
} }


.zettel .detail {
.kategorie .detail {
flex-basis: 50%; flex-basis: 50%;
font-weight: 300; font-weight: 300;
font-style: italic; font-style: italic;
white-space: nowrap; white-space: nowrap;
} }


.zettel .detail span {
.kategorie .detail span {
font-weight: 400; font-weight: 400;
font-style: normal; font-style: normal;
} }


.zettel .map {
.kategorie .map {
flex-grow: 0; flex-grow: 0;
flex-basis: 150px; flex-basis: 150px;
font-size: 0; font-size: 0;
margin: 0px 25px; margin: 0px 25px;
} }


.zettel .map img {
.kategorie .map img {
width: 150px; width: 150px;
height: 150px; height: 150px;
} }


.zettel.detailed {
.kategorie.detailed {
background: none; background: none;
align-items: flex-start; align-items: flex-start;
} }


.zettel.detailed .image {
.kategorie.detailed .image {
flex-basis: 320px; flex-basis: 320px;
} }


.zettel.detailed .image.large {
.kategorie.detailed .image.large {
margin: 30px 25px 50px 25px; margin: 30px 25px 50px 25px;
flex-basis: 100%; flex-basis: 100%;
} }


.zettel.detailed .details {
.kategorie.detailed .details {
height: auto; height: auto;
} }


.zettel.detailed h3 {
.kategorie.detailed h3 {
font-size: 200%; font-size: 200%;
margin-bottom: 10px; margin-bottom: 10px;
} }


.zettel.detailed .detail {
.kategorie.detailed .detail {
margin: 5px 0px; margin: 5px 0px;
flex-basis: 100%; flex-basis: 100%;
flex-shrink: 2; flex-shrink: 2;
} }


.zettel.detailed .description {
.kategorie.detailed .description {
white-space: normal; white-space: normal;
flex-basis: 100%; flex-basis: 100%;
flex-shrink: 1; flex-shrink: 1;
} }


.zettel.detailed .map {
.kategorie.detailed .map {
flex-basis: 100%; flex-basis: 100%;
margin: 50px 25px 25px 25px; margin: 50px 25px 25px 25px;
} }


.zettel.detailed .map img {
.kategorie.detailed .map img {
width: 100%; width: 100%;
height: auto; height: auto;
} }


@media only screen and (max-width: 919px) { @media only screen and (max-width: 919px) {
.zettel.detailed .image, .zettel.detailed .image.large {
.kategorie.detailed .image, .kategorie.detailed .image.large {
margin: 30px 25px 25px 25px; margin: 30px 25px 25px 25px;
flex-basis: 100%; flex-basis: 100%;
cursor: default; cursor: default;
} }


.zettel.detailed .image:hover {
.kategorie.detailed .image:hover {
flex-basis: 100%; flex-basis: 100%;
cursor: default; cursor: default;
} }


.zettel.detailed .image small {
.kategorie.detailed .image small {
display: none; display: none;
} }


.zettel.detailed button.image:hover:after {
.kategorie.detailed button.image:hover:after {
opacity: 0; opacity: 0;
} }


.zettel.detailed button.image:focus:after {
.kategorie.detailed button.image:focus:after {
opacity: 0.1; opacity: 0.1;
} }


.zettel.detailed .map {
.kategorie.detailed .map {
margin-top: 25px; margin-top: 25px;
} }
} }

+ 14
- 4
app/templates/produkte.hbs View File

<Jumbo> <Jumbo>
<h2>Produkte</h2>
<h2>deine Produkte</h2>
<p>Hier kannst du aus deinen Produkten wählen oder neue Produkte hinzufügen!</p> <p>Hier kannst du aus deinen Produkten wählen oder neue Produkte hinzufügen!</p>
<LinkTo @route="produkte" class="button">Produkte bearbeiten</LinkTo> <LinkTo @route="produkte" class="button">Produkte bearbeiten</LinkTo>
</Jumbo> </Jumbo>


<div class="zettel">
{{yield}}
</div>
<Kategorie @titel={{"Gemüse"}}>
<div class="rentals">
<ul class="results">
{{#each @model as |produkt|}}
{{#if (compare produkt.titel '===' 'Gemüse')}}
<li><Produkt @produkt={{produkt}} /></li>
{{/if}}
<li><Produkt @produkt={{produkt}} /></li>
{{/each}}
</ul>
</div>

</Kategorie>

+ 33
- 2
app/templates/rezepte.hbs View File

<Jumbo> <Jumbo>
<h2>Rezepte</h2>
<h2>deine Rezepte</h2>
<p>Hier kannst du aus deinen Rezepten wählen oder neue Rezepte hinzufügen!</p> <p>Hier kannst du aus deinen Rezepten wählen oder neue Rezepte hinzufügen!</p>
<LinkTo @route="rezepte" class="button">Rezepte bearbeiten</LinkTo> <LinkTo @route="rezepte" class="button">Rezepte bearbeiten</LinkTo>
</Jumbo> </Jumbo>


<div class="zettel">
<div class="kategorie">
<h2>Pasta</h2>
{{yield}}
</div>

<div class="kategorie">
<h2>Gemüse</h2>
{{yield}}
</div>

<div class="kategorie">
<h2>Geflügel</h2>
{{yield}}
</div>

<div class="kategorie">
<h2>Rind</h2>
{{yield}}
</div>

<div class="kategorie">
<h2>Schwein</h2>
{{yield}}
</div>

<div class="kategorie">
<h2>Nachspeise</h2>
{{yield}}
</div>

<div class="kategorie">
<h2>Backen</h2>
{{yield}} {{yield}}
</div> </div>

+ 49
- 0
public/api/produkte.json View File

{
"data": [
{
"type": "produkt",
"id": "spaghetti",
"attributes": {
"titel": "Spaghetti",
"kategorie": "Pasta",
"menge": 500,
"einheit": "Gramm",
"bild": "https://www.pastaweb.de/wp-content/uploads/2016/02/spaghetti.jpg"
}
},
{
"type": "produkt",
"id": "salat",
"attributes": {
"titel": "Salat",
"kategorie": "Gemüse",
"menge": 1,
"einheit": "Kopf",
"bild": "https://napolipizza-spiez.ch/WebRoot/Store2/Shops/178389/5BD1/5BA4/85F2/ACB6/97E9/D91A/30FA/F35F/gruener-salat-2464087.jpg"
}
},
{
"type": "produkt",
"id": "milch",
"attributes": {
"titel": "Milch",
"kategorie": "Milchprodukte",
"menge": 1,
"einheit": "Liter",
"bild": "https://lebensmittel-warenkunde.de/assets/images/milch-milchprodukte.jpg"
}
},
{
"type": "produkt",
"id": "kaese",
"attributes": {
"titel": "Käse",
"kategorie": "Milchprodukte",
"menge": 200,
"einheit": "Gramm",
"bild": "https://www.der-bank-blog.de/wp-content/uploads/2016/04/banking-schweizer-kaese.jpg"
}
}
]
}

+ 0
- 0
public/api/rezepte.json View File


+ 0
- 0
public/api/zettel.json View File


+ 35
- 1
tests/acceptance/einkaufszettel-test.js View File

assert.dom('nav a.menu-produkte').hasText('Produkte'); assert.dom('nav a.menu-produkte').hasText('Produkte');
assert.dom('nav a.menu-rezepte').hasText('Rezepte'); assert.dom('nav a.menu-rezepte').hasText('Rezepte');


assert.dom('.jumbo a.h2').hasText('deine Zettel');
assert.dom('.jumbo h2').hasText('deine Zettel');
assert.dom('.jumbo a.button').hasText('Zettel aktualisieren'); assert.dom('.jumbo a.button').hasText('Zettel aktualisieren');
await click('.jumbo a.button'); await click('.jumbo a.button');


assert.equal(currentURL(), '/zettel'); assert.equal(currentURL(), '/zettel');
}); });


test('visiting /produkte', async function(assert) {
await visit('/produkte');

assert.dom('nav').exists();
assert.dom('nav a.menu-index').hasText('EinkaufsZettel')
assert.dom('nav a.menu-zettel').hasText('Zettel');
assert.dom('nav a.menu-produkte').hasText('Produkte');
assert.dom('nav a.menu-rezepte').hasText('Rezepte');

assert.dom('.jumbo h2').hasText('deine Produkte');
assert.dom('.jumbo a.button').hasText('Produkte bearbeiten');
await click('.jumbo a.button');

assert.equal(currentURL(), '/produkte');
});

test('visiting /rezepte', async function(assert) {
await visit('/rezepte');

assert.dom('nav').exists();
assert.dom('nav a.menu-index').hasText('EinkaufsZettel')
assert.dom('nav a.menu-zettel').hasText('Zettel');
assert.dom('nav a.menu-produkte').hasText('Produkte');
assert.dom('nav a.menu-rezepte').hasText('Rezepte');

assert.dom('.jumbo h2').hasText('deine Rezepte');
assert.dom('.jumbo a.button').hasText('Rezepte bearbeiten');
await click('.jumbo a.button');

assert.equal(currentURL(), '/rezepte');
});



}); });

tests/integration/components/zettel-test.js → tests/integration/components/kategorie-test.js View File

import { render } from '@ember/test-helpers'; import { render } from '@ember/test-helpers';
import { hbs } from 'ember-cli-htmlbars'; import { hbs } from 'ember-cli-htmlbars';


module('Integration | Component | zettel', function(hooks) {
module('Integration | Component | kategorie', function(hooks) {
setupRenderingTest(hooks); setupRenderingTest(hooks);


test('it renders', async function(assert) { test('it renders', async function(assert) {
// Set any properties with this.set('myProperty', 'value'); // Set any properties with this.set('myProperty', 'value');
// Handle any actions with this.set('myAction', function(val) { ... }); // Handle any actions with this.set('myAction', function(val) { ... });


await render(hbs`<Zettel />`);
await render(hbs`<Kategorie />`);


assert.equal(this.element.textContent.trim(), ''); assert.equal(this.element.textContent.trim(), '');


// Template block usage: // Template block usage:
await render(hbs` await render(hbs`
<Zettel>
<Kategorie>
template block text template block text
</Zettel>
</Kategorie>
`); `);


assert.equal(this.element.textContent.trim(), 'template block text'); assert.equal(this.element.textContent.trim(), 'template block text');

tests/integration/components/rezepte-test.js → tests/integration/components/produkt-test.js View File

import { render } from '@ember/test-helpers'; import { render } from '@ember/test-helpers';
import { hbs } from 'ember-cli-htmlbars'; import { hbs } from 'ember-cli-htmlbars';


module('Integration | Component | rezepte', function(hooks) {
module('Integration | Component | produkt', function(hooks) {
setupRenderingTest(hooks); setupRenderingTest(hooks);


test('it renders', async function(assert) { test('it renders', async function(assert) {
// Set any properties with this.set('myProperty', 'value'); // Set any properties with this.set('myProperty', 'value');
// Handle any actions with this.set('myAction', function(val) { ... }); // Handle any actions with this.set('myAction', function(val) { ... });


await render(hbs`<Rezepte />`);
await render(hbs`<Produkt />`);


assert.equal(this.element.textContent.trim(), ''); assert.equal(this.element.textContent.trim(), '');


// Template block usage: // Template block usage:
await render(hbs` await render(hbs`
<Rezepte>
<Produkt>
template block text template block text
</Rezepte>
</Produkt>
`); `);


assert.equal(this.element.textContent.trim(), 'template block text'); assert.equal(this.element.textContent.trim(), 'template block text');

+ 0
- 26
tests/integration/components/produkte-test.js View File

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 | produkte', 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`<Produkte />`);

assert.equal(this.element.textContent.trim(), '');

// Template block usage:
await render(hbs`
<Produkte>
template block text
</Produkte>
`);

assert.equal(this.element.textContent.trim(), 'template block text');
});
});

Loading…
Cancel
Save