diff --git a/app/components/jumbo.hbs b/app/components/jumbo.hbs new file mode 100644 index 0000000..a2ebd39 --- /dev/null +++ b/app/components/jumbo.hbs @@ -0,0 +1,3 @@ +
+ {{yield}} +
\ No newline at end of file diff --git a/app/components/nav-bar.hbs b/app/components/nav-bar.hbs new file mode 100644 index 0000000..547c1da --- /dev/null +++ b/app/components/nav-bar.hbs @@ -0,0 +1,16 @@ + \ No newline at end of file diff --git a/app/router.js b/app/router.js index 224ca42..309f4e3 100644 --- a/app/router.js +++ b/app/router.js @@ -7,4 +7,7 @@ export default class Router extends EmberRouter { } Router.map(function() { + this.route('rezepte'); + this.route('zettel'); + this.route('produkte'); }); diff --git a/app/styles/app.css b/app/styles/app.css index e69de29..6975c04 100644 --- a/app/styles/app.css +++ b/app/styles/app.css @@ -0,0 +1,468 @@ +@import url(https://fonts.googleapis.com/css?family=Lato:300,300italic,400,700,700italic); + +/** + * Base Elements + */ + +* { + margin: 0; + padding: 0; +} + +body, +h1, +h2, +h3, +h4, +h5, +h6, +p, +div, +span, +a, +button { + font-family: 'Lato', 'Open Sans', 'Helvetica Neue', 'Segoe UI', Helvetica, Arial, sans-serif; + line-height: 1.5; +} + +body { + background: #f3f3f3; +} + +a { + color: #016aba; + text-decoration: none; +} + +button { + font-size: 100%; +} + +p { + line-height: 1.5; + margin-bottom: 15px; +} + +/** + * Button + */ + +.button { + padding: 10px 30px 10px; + text-decoration: none; + color: #fff; + background: #016aba; + border-radius: 5px; + border: none; + font-size: 20px; + font-weight: bold; + opacity: 0.9; + display: inline-block; +} + +.button:hover { + opacity: 1; +} +/** + * Body Container + */ + +.container { + max-width: 1024px; + min-height: 100vh; + background: #f9f9f9; + margin: 0 auto; +} +/** + * Top Navigation + */ + +.menu { + height: 4em; + background-color: #677ae4; + background-color: #05526A; + background-color: #e46855; +} + +.menu h1 { + position: relative; + padding: 5px 0 0 8px; + color: #f9f9f9; + font-size: 1.8em; + font-style: italic; +} + +.menu a, +.menu .links { + display: inline-block; +} + +.menu a { + text-decoration: none; + padding: 0 15px; + color: #fff; + font-size: 20px; + font-weight: bold; +} + +.menu a:hover, +.menu a.active { + opacity: 1; +} + +.menu .links { + padding: 0 21px; +} + +.menu .links a { + position: relative; + bottom: 5px; +} + +.zettel label span { + font-size: 140%; + margin: 50px auto 20px; + display: block; + text-align: center; + font-style: italic; +} + +.zettel input { + padding: 11px; + font-size: 18px; + width: 500px; + margin: 20px auto 50px; + background-color: rgba(255, 255, 255, 0.75); + border: solid 1px lightgray; + display: block; +} + +.menu input:focus { + background-color: #f9f9f9; + outline: none; +} + +.menu button { + margin-right: 15px; + position: relative; + top: -1px; + left: -5px; + border-top-left-radius: 0; + border-bottom-left-radius: 0; + background-color: #262626; + cursor: pointer; + opacity: 1; +} + +.menu button:hover { + background-color: #111; + opacity: 1; +} + +.menu .results { + display: none; + position: absolute; + width: 215px; + top: 54px; + left: 10px; + background-color: #f6f6f6; + border-right: 1px solid rgba(0, 0, 0, 0.05); + border-bottom: 1px solid rgba(0, 0, 0, 0.05); +} + +.results { + margin-top: -10px; +} + +.results li { + list-style: none; + padding: 10px 15px; +} + +.menu .results li:hover { + background: #f3f3f3; +} +/** + * Content Area + */ + +.body { + padding: 15px; +} +/** + * Similar to Jumbotron + */ + +.jumbo { + padding: 50px; + background: #f6f6f6; +} + +.jumbo:hover { + background-color: #f3f3f3; +} + +.jumbo h2 { + font-size: 3.2em; + margin-top: -25px; +} + +.jumbo p, +.jumbo address { + margin-bottom: 25px; +} + +.jumbo img { + height: 200px; + position: relative; + top: -25px; + right: -20px; +} + +/** + * Individual zettel Listing + */ + +.zettel { + margin-top: 15px; + background-color: #f6f6f6; + padding: 20px 25px; + display: flex; + justify-content: space-between; + align-items: center; + flex-wrap: wrap; +} + +.zettel:hover { + background-color: #f3f3f3; +} + +.zettel img { + border-radius: 5px; +} + +.zettel .image { + flex-grow: 0; + flex-basis: 150px; + margin: 20px 25px; + text-align: center; +} + +.zettel button.image { + position: relative; + cursor: pointer; + border: none; + background: transparent; + z-index: 1; +} + +.zettel button.image:focus { + outline: none; +} + +.zettel button.image:after { + content: ""; + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + z-index: -1; + margin: -20px; + padding: 20px; + border-radius: 5px; + background: #016aba; + opacity: 0; + transition: opacity 0.25s ease-in-out; +} + +.zettel button.image:focus:after, .zettel button.image:hover:after { + opacity: 0.1; +} + +.zettel .image img { + max-width: 100%; +} + +.zettel .image.large { + margin: 30px 25px 50px 25px; + flex-basis: 100%; +} + +.zettel .image small { + display: block; + margin-top: 5px; + margin-bottom: -15px; + text-align: center; + color: #016aba; + + /* This is needed to fix a safari clipping issue */ + position: relative; +} + +.zettel .image.large small { + margin-top: 10px; + margin-bottom: 0px; + font-size: 110%; +} + +.zettel .details { + flex-basis: 50%; + flex-grow: 2; + display: flex; + height: 150px; + margin: 20px 25px; + justify-content: space-between; + flex-wrap: wrap; + align-content: space-around; +} + +.zettel h3 { + flex-basis: 100%; +} + +.zettel h3 a { + display: inline; +} + +.zettel .detail { + flex-basis: 50%; + font-weight: 300; + font-style: italic; + white-space: nowrap; +} + +.zettel .detail span { + font-weight: 400; + font-style: normal; +} + +.zettel .map { + flex-grow: 0; + flex-basis: 150px; + font-size: 0; + margin: 0px 25px; +} + +.zettel .map img { + width: 150px; + height: 150px; +} + +.zettel.detailed { + background: none; + align-items: flex-start; +} + +.zettel.detailed .image { + flex-basis: 320px; +} + +.zettel.detailed .image.large { + margin: 30px 25px 50px 25px; + flex-basis: 100%; +} + +.zettel.detailed .details { + height: auto; +} + +.zettel.detailed h3 { + font-size: 200%; + margin-bottom: 10px; +} + +.zettel.detailed .detail { + margin: 5px 0px; + flex-basis: 100%; + flex-shrink: 2; +} + +.zettel.detailed .description { + white-space: normal; + flex-basis: 100%; + flex-shrink: 1; +} + +.zettel.detailed .map { + flex-basis: 100%; + margin: 50px 25px 25px 25px; +} + +.zettel.detailed .map img { + width: 100%; + height: auto; +} + +@media only screen and (max-width: 919px) { + .zettel.detailed .image, .zettel.detailed .image.large { + margin: 30px 25px 25px 25px; + flex-basis: 100%; + cursor: default; + } + + .zettel.detailed .image:hover { + flex-basis: 100%; + cursor: default; + } + + .zettel.detailed .image small { + display: none; + } + + .zettel.detailed button.image:hover:after { + opacity: 0; + } + + .zettel.detailed button.image:focus:after { + opacity: 0.1; + } + + .zettel.detailed .map { + margin-top: 25px; + } +} + +/** + * Utilities + */ + +.light { + font-weight: 300; +} + +.left { + float: left; +} + +.right { + float: right; +} + +.hidden { + display: none; +} + +.relative { + position: relative; +} + +.tomster { + background: url(../assets/images/teaching-tomster.png); + background-size: contain; + background-repeat: no-repeat; + height: 200px; + width: 200px; + + position: relative; + top: -25px; +} + +.screen-reader{ + position: absolute; + overflow: hidden; + clip: rect(0 0 0 0); + height: 1px; width: 1px; + margin: -1px; padding: 0; border: 0; +} + diff --git a/app/templates/application.hbs b/app/templates/application.hbs index 7b1b104..9fb3ba2 100644 --- a/app/templates/application.hbs +++ b/app/templates/application.hbs @@ -1,5 +1,6 @@ -{{!-- The following component displays Ember's default welcome message. --}} - -{{!-- Feel free to remove this! --}} - -{{outlet}} \ No newline at end of file +
+ +
+ {{outlet}} +
+
\ No newline at end of file diff --git a/app/templates/index.hbs b/app/templates/index.hbs new file mode 100644 index 0000000..4e527ce --- /dev/null +++ b/app/templates/index.hbs @@ -0,0 +1,11 @@ + +

Willkommen!

+

Hier kannst du eigenen online Einkaufszettel anlegen und mit deiner Familie und deinen Freunden teilen!

+

Einfach die benötigten Produkte oder ganze Rezepte auswählen und deinen Zettel automatisch zusammenstellen lassen!

+ Alle Zettel +
+ +
+ {{yield}} +
+ diff --git a/app/templates/produkte.hbs b/app/templates/produkte.hbs new file mode 100644 index 0000000..1e7e9e1 --- /dev/null +++ b/app/templates/produkte.hbs @@ -0,0 +1,9 @@ + +

Produkte

+

Hier kannst du aus deinen Produkten wählen oder neue Produkte hinzufügen!

+ Produkte bearbeiten +
+ +
+ {{yield}} +
\ No newline at end of file diff --git a/app/templates/rezepte.hbs b/app/templates/rezepte.hbs new file mode 100644 index 0000000..836b3c6 --- /dev/null +++ b/app/templates/rezepte.hbs @@ -0,0 +1,10 @@ + +

Rezepte

+

Hier kannst du aus deinen Rezepten wählen oder neue Rezepte hinzufügen!

+ Rezepte bearbeiten +
+ +
+ {{yield}} +
+ \ No newline at end of file diff --git a/app/templates/zettel.hbs b/app/templates/zettel.hbs new file mode 100644 index 0000000..f87252b --- /dev/null +++ b/app/templates/zettel.hbs @@ -0,0 +1,10 @@ + +

deine Zettel

+

Hier kannst du aus deinen aktuellen Zetteln wählen oder deine Zettel aktualisieren!

+ Zettel aktualisieren +
+ +
+ {{yield}} +
+ \ No newline at end of file diff --git a/tests/acceptance/einkaufszettel-test.js b/tests/acceptance/einkaufszettel-test.js new file mode 100644 index 0000000..f7e2a52 --- /dev/null +++ b/tests/acceptance/einkaufszettel-test.js @@ -0,0 +1,58 @@ +import { module, test } from 'qunit'; +import { click, visit, currentURL } from '@ember/test-helpers'; +import { setupApplicationTest } from 'ember-qunit'; + +module('Acceptance | einkaufszettel', function(hooks) { + setupApplicationTest(hooks); + + test('visiting /einkaufszettel', async function(assert) { + await visit('/'); + + assert.equal(currentURL(), '/'); + 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'); + + }); + + test('navigating using the nav-bar', async function(assert) { + await visit('/'); + + 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'); + + await click('nav a.menu-zettel'); + assert.equal(currentURL(), '/zettel'); + + await click('nav a.menu-produkte'); + assert.equal(currentURL(), '/produkte'); + + await click('nav a.menu-rezepte'); + assert.equal(currentURL(), '/rezepte'); + + await click('nav a.menu-index'); + assert.equal(currentURL(), '/'); + }); + + test('visiting /zettel', async function(assert) { + await visit('/zettel'); + + 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 a.h2').hasText('deine Zettel'); + assert.dom('.jumbo a.button').hasText('Zettel aktualisieren'); + await click('.jumbo a.button'); + + assert.equal(currentURL(), '/zettel'); + }); + +}); diff --git a/tests/integration/components/jumbo-test.js b/tests/integration/components/jumbo-test.js new file mode 100644 index 0000000..6a785df --- /dev/null +++ b/tests/integration/components/jumbo-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 | jumbo', 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/integration/components/produkte-test.js b/tests/integration/components/produkte-test.js new file mode 100644 index 0000000..7a6135a --- /dev/null +++ b/tests/integration/components/produkte-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 | 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``); + + 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/integration/components/rezepte-test.js b/tests/integration/components/rezepte-test.js new file mode 100644 index 0000000..3f11eed --- /dev/null +++ b/tests/integration/components/rezepte-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 | rezepte', 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/integration/components/zettel-test.js b/tests/integration/components/zettel-test.js new file mode 100644 index 0000000..677c2f1 --- /dev/null +++ b/tests/integration/components/zettel-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 | zettel', 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'); + }); +});