Added i18n to all components

This commit is contained in:
Moritz Kröger 2017-08-13 14:03:38 +02:00
parent 3382cc3ae5
commit cb4d15aa3c
28 changed files with 401 additions and 232 deletions

View file

@ -1,22 +1,23 @@
<template>
<section>
<h1>404</h1>
<p>
Content to be written.
</p>
<h1>{{ $t('fourzerofour.headline') }}</h1>
<p>{{ $t('fourzerofour.content') }}</p>
<router-link class="btn" :to="{ path: '/' }">
{{ $t('fourzerofour.button') }}
</router-link>
</section>
</template>
<script>
export default {
name: '404'
name: 'FourZeroFour'
}
</script>
<style lang="scss" scoped>
@import "~styles/layout";
h1 {
h1, p {
margin-bottom: $base-gap;
}
</style>

16
src/app/404/i18n.js Normal file
View file

@ -0,0 +1,16 @@
export default {
de: {
fourzerofour: {
headline: '404 — Oops! Da ist wohl etwas falsch gelaufen.',
content: 'Einführung und Aufbau müssen noch definiert werden.',
button: 'Zurück zur Startseite'
}
},
en: {
fourzerofour: {
headline: '404 — Whoops! Something went wrong.',
content: 'Content to be written.',
button: 'Back to main page'
}
}
}

View file

@ -1 +1,2 @@
export { default as routes } from './routes'
export { default as i18n } from './i18n'

View file

@ -1,6 +1,6 @@
<template>
<div id="app">
<app-menu :menu="menu" />
<app-menu :menu="menu" :languages="languages" />
<main>
<router-view></router-view>
</main>
@ -26,13 +26,43 @@
'app-menu': Menu
},
i18n: {
messages: {
de: {
menu: {
index: 'Startseite',
faq: 'FAQ',
press: 'Presse',
imprint: 'Impressum'
}
},
en: {
menu: {
index: 'Main page',
faq: 'FAQ',
press: 'Press',
imprint: 'Imprint'
}
}
}
},
data () {
return {
menu: [
{ label: 'Startseite', route: { path: '/' } },
{ label: 'FAQ', route: { path: '/faq' } },
{ label: 'Presse', route: { path: '/presse' } },
{ label: 'Impressum', route: { path: '/impressum' } }
languages: [
{ label: '🇩🇪', locale: 'de' },
{ label: '🇬🇧', locale: 'en' }
]
}
},
computed: {
menu () {
return [
{ label: this.$t('menu.index'), route: { path: '/' } },
{ label: this.$t('menu.faq'), route: { path: '/faq' } },
{ label: this.$t('menu.press'), route: { path: '/presse' } },
{ label: this.$t('menu.imprint'), route: { path: '/impressum' } }
]
}
}
@ -41,6 +71,7 @@
<style lang="scss">
@import "~node_modules/normalize.css/normalize";
@import "~styles/buttons";
@import "~styles/colors";
@import "~styles/layout";
@ -79,74 +110,6 @@
}
}
button {
padding: 10px 20px;
background: $button-background;
color: $button-color;
border-radius: $border-radius;
border: 2px solid $button-background;
cursor: pointer;
position: relative;
transition: background 50ms, border-color 0.4s;
transition-timing-function: cubic-bezier(0.2, 1, 0.3, 1);
&::before,
&::after {
content: '';
position: absolute;
top: 0;
left: -2px;
width: calc(100% + 4px);
height: 100%;
border-radius: $border-radius;
}
&::before {
background: $yellow;
border-radius: $border-radius;
opacity: 0;
z-index: -1;
transform: scale3d(0.7, 1, 1);
transition: transform 0.4s, opacity 0.4s;
transition-timing-function: cubic-bezier(0.2, 1, 0.3, 1);
}
&::after {
background: $button-background;
z-index: -2;
}
&:hover {
background: transparent;
border-color: $yellow;
&::before {
opacity: 1;
transform: translate3d(0, 0, 0);
}
}
&:active,
&:focus {
outline: none;
background: $yellow;
}
&.btn-txt {
background: transparent;
color: $text-color-base;
border: none;
&::before, &::after {
content: none;
}
&:hover {
color: $text-color-special;
}
}
}
#app {
max-width: 750px;
width: 95vw;

View file

@ -0,0 +1,120 @@
<template>
<section class="euromat">
<div class="header-progress">
<span>{{ currentThesis + 1 }}/{{ thesesCount }}</span>
<thesis-progress :value="currentThesis + 1" :max="thesesCount" />
</div>
<header class="euromat-header">
<h1 class="thesis">{{ thesisTitle }}</h1>
</header>
<div class="euromat-controls">
<ul class="euromat-btns">
<li v-for="option in options" v-if="option.position !== 'skipped'">
<button type="button" @click="submitAnswer(option, $event)">
{{ option.label }}
</button>
</li>
</ul>
<button class="controls-skip btn-txt" type="button" @click="submitAnswer(optionSkip)">
{{ optionSkip.label }}
</button>
</div>
</section>
</template>
<script>
import { getAllOptions, getThesis, getThesesCount } from '@/utils/data'
import Progress from '@/components/progress'
export default {
name: 'EuroMat',
components: {
'thesis-progress': Progress
},
data () {
return {
currentThesis: 0,
thesesCount: getThesesCount(),
options: getAllOptions(),
answers: []
}
},
computed: {
thesisTitle () {
if (this.currentThesis === this.thesesCount) {
return
}
return getThesis(this.currentThesis).thesis
},
optionSkip () {
return this.options[this.options.length - 1]
}
},
methods: {
submitAnswer (option, event) {
if (!option) {
return console.warn('Invalid answer')
}
if (this.currentThesis === this.thesesCount - 1) {
this.forwardToResults()
}
const thesis = getThesis(this.currentThesis)
this.answers.push({ thesis, option })
this.currentThesis += 1
event && event.target.blur()
},
forwardToResults () {
localStorage.setItem('euromat-results', JSON.stringify(this.answers, null, 2))
this.$router.push({ path: '/thesen/gewichtung' })
}
}
}
</script>
<style lang="scss" scoped>
@import "~styles/colors";
@import "~styles/layout";
.header-progress {
display: flex;
align-items: center;
margin-bottom: $base-gap * 2;
span {
margin-right: 15px;
}
}
.euromat-header {
margin-bottom: $base-gap * 2;
}
.euromat-controls {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
.controls-skip {
font-style: italic;
margin-top: $base-gap / 2;
}
.euromat-btns {
list-style: none;
display: flex;
justify-content: center;
li:not(:last-child) {
margin-right: 15px;
}
}
</style>

View file

@ -1,120 +1,9 @@
<template>
<section class="euromat">
<div class="header-progress">
<span>{{ currentThesis + 1 }}/{{ thesesCount }}</span>
<thesis-progress :value="currentThesis + 1" :max="thesesCount" />
</div>
<header class="euromat-header">
<h1 class="thesis">{{ thesisTitle }}</h1>
</header>
<div class="euromat-controls">
<ul class="euromat-btns">
<li v-for="option in options" v-if="option.position !== 'skipped'">
<button type="button" @click="submitAnswer(option, $event)">
{{ option.label }}
</button>
</li>
</ul>
<button class="controls-skip btn-txt" type="button" @click="submitAnswer(optionSkip)">
{{ optionSkip.label }}
</button>
</div>
</section>
<router-view></router-view>
</template>
<script>
import { getAllOptions, getThesis, getThesesCount } from '@/utils/data'
import Progress from '@/components/progress'
export default {
name: 'EuroMat',
components: {
'thesis-progress': Progress
},
data () {
return {
currentThesis: 0,
thesesCount: getThesesCount(),
options: getAllOptions(),
answers: []
}
},
computed: {
thesisTitle () {
if (this.currentThesis === this.thesesCount) {
return
}
return getThesis(this.currentThesis).thesis
},
optionSkip () {
return this.options[this.options.length - 1]
}
},
methods: {
submitAnswer (option, event) {
if (!option) {
return console.warn('Invalid answer')
}
if (this.currentThesis === this.thesesCount - 1) {
this.forwardToResults()
}
const thesis = getThesis(this.currentThesis)
this.answers.push({ thesis, option })
this.currentThesis += 1
event.target.blur()
},
forwardToResults () {
localStorage.setItem('euromat-results', JSON.stringify(this.answers, null, 2))
this.$router.push({ path: 'ergebnisse' })
}
}
name: 'EuromatIndex'
}
</script>
<style lang="scss" scoped>
@import "~styles/colors";
@import "~styles/layout";
.header-progress {
display: flex;
align-items: center;
margin-bottom: $base-gap * 2;
span {
margin-right: 15px;
}
}
.euromat-header {
margin-bottom: $base-gap * 2;
}
.euromat-controls {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
.controls-skip {
font-style: italic;
margin-top: $base-gap / 2;
}
.euromat-btns {
list-style: none;
display: flex;
justify-content: center;
li:not(:last-child) {
margin-right: 15px;
}
}
</style>

View file

@ -0,0 +1,16 @@
<template>
<section>
<h1>Gewichtung deiner Antworten</h1>
<router-link :to="{ path: '/thesen/ergebnis' }">
Weiter
</router-link>
</section>
</template>
<script>
export default {
name: 'Weighting'
}
</script>
<style lang="scss" scoped></style>

8
src/app/euromat/i18n.js Normal file
View file

@ -0,0 +1,8 @@
export default {
de: {
},
en: {
}
}

View file

@ -1 +1,2 @@
export { default as routes } from './routes'
export { default as i18n } from './i18n'

View file

@ -1,9 +1,28 @@
import EuroMat from './components/index'
import Index from './components/index'
import EuroMat from './components/euromat'
import Weighting from './components/weighting'
import Results from './components/results'
export default [
{
path: '/thesen',
name: 'euromat',
component: EuroMat
component: Index,
children: [
{
path: '',
name: 'euromat',
component: EuroMat
},
{
path: 'gewichtung',
name: 'weighting',
component: Weighting
},
{
path: 'ergebnis',
name: 'results',
component: Results
}
]
}
]

View file

@ -1,7 +1,7 @@
<template>
<section>
<h1>FAQ</h1>
<p>FAQ to be written.</p>
<h1>{{ $t('faq.headline') }}</h1>
<p>{{ $t('faq.content') }}</p>
</section>
</template>

14
src/app/faq/i18n.js Normal file
View file

@ -0,0 +1,14 @@
export default {
de: {
faq: {
headline: 'FAQ',
content: 'FAQ müssen noch definiert werden.'
}
},
en: {
faq: {
headline: 'FAQ',
content: 'FAQ to be written.'
}
}
}

View file

@ -1 +1,2 @@
export { default as routes } from './routes'
export { default as i18n } from './i18n'

View file

@ -1,7 +1,7 @@
<template>
<section>
<h1>{{ $t('headline') }}</h1>
<p>Content to be written.</p>
<h1>{{ $t('imprint.headline') }}</h1>
<p>{{ $t('imprint.content') }}</p>
</section>
</template>

14
src/app/imprint/i18n.js Normal file
View file

@ -0,0 +1,14 @@
export default {
de: {
imprint: {
headline: 'Impressum',
content: 'Muss noch geschrieben werden.'
}
},
en: {
imprint: {
headline: 'Imprint',
content: 'Imprint to be written.'
}
}
}

View file

@ -1 +1,2 @@
export { default as routes } from './routes'
export { default as i18n } from './i18n'

View file

@ -2,7 +2,7 @@
<section>
<h1>{{ $t('intro.headline') }}</h1>
<p>{{ $t('intro.content') }}</p>
<router-link tag="button" :to="{ path: '/thesen' }">
<router-link class="btn" :to="{ path: '/thesen' }">
{{ $t('intro.button') }}
</router-link>
</section>

View file

@ -2,7 +2,7 @@ export default {
de: {
intro: {
headline: 'Willkommen beim Euromat',
content: 'Content to be written.',
content: 'Einführung und Aufbau müssen noch definiert werden.',
button: 'Start'
}
},

View file

@ -1,7 +1,7 @@
<template>
<section>
<h1>Presse</h1>
<p>Content to be written.</p>
<h1>{{ $t('press.headline') }}</h1>
<p>{{ $t('press.content') }}</p>
</section>
</template>

14
src/app/press/i18n.js Normal file
View file

@ -0,0 +1,14 @@
export default {
de: {
press: {
headline: 'Presse',
content: 'Presseinhalte müssen noch definiert werden.'
}
},
en: {
press: {
headline: 'Press',
content: 'Press to be written.'
}
}
}

View file

@ -1 +1,2 @@
export { default as routes } from './routes'
export { default as i18n } from './i18n'

View file

@ -1 +0,0 @@
export { default as routes } from './routes'

View file

@ -1,9 +0,0 @@
import Results from './components/index'
export default [
{
path: '/ergebnis',
name: 'results',
component: Results
}
]

View file

@ -8,15 +8,19 @@
</li>
</ul>
<router-link class="menu-impressum" :to="impressum.route">
{{ impressum.label }}
</router-link>
<div class="menu-language">
<button v-for="lang of languages" type="button" @click="changeLanguage(lang.locale)">
<button
class="btn-txt"
v-for="lang of languages"
type="button"
@click="changeLanguage(lang.locale)">
{{ lang.label }}
</button>
</div>
<router-link class="menu-impressum" :to="impressum.route">
{{ impressum.label }}
</router-link>
</aside>
</template>
@ -25,16 +29,8 @@
name: 'Menu',
props: {
menu: { type: Array, default: () => [] }
},
data () {
return {
languages: [
{ label: 'DE', locale: 'de' },
{ label: 'EN', locale: 'en' }
]
}
menu: { type: Array, default: () => [] },
languages: { type: Array, default: () => [] }
},
computed: {
@ -100,4 +96,17 @@
color: $text-color-special;
}
}
.menu-language {
margin-top: $base-gap / 2;
background: $dark-blue;
padding: 5px;
border-radius: $border-radius;
display: flex;
justify-content: space-around;
button {
padding: 10px;
}
}
</style>

View file

@ -2,6 +2,11 @@ import Vue from 'vue'
import VueI18n from 'vue-i18n'
import { i18n as intro } from '@/app/intro'
import { i18n as euromat } from '@/app/euromat'
import { i18n as fourzerofour } from '@/app/404'
import { i18n as faq } from '@/app/faq'
import { i18n as press } from '@/app/press'
import { i18n as imprint } from '@/app/imprint'
Vue.use(VueI18n)
@ -9,6 +14,21 @@ export default new VueI18n({
locale: localStorage.getItem('euromat-locale') || 'de',
fallbackLocale: 'de',
messages: {
...intro
de: {
...intro.de,
...euromat.de,
...fourzerofour.de,
...faq.de,
...press.de,
...imprint.de
},
en: {
...intro.en,
...euromat.en,
...fourzerofour.en,
...faq.en,
...press.en,
...imprint.en
}
}
})

View file

@ -3,7 +3,6 @@ import Router from 'vue-router'
import { routes as intro } from '@/app/intro'
import { routes as euromat } from '@/app/euromat'
import { routes as results } from '@/app/results'
import { routes as faq } from '@/app/faq'
import { routes as press } from '@/app/press'
import { routes as imprint } from '@/app/imprint'
@ -16,7 +15,6 @@ export default new Router({
routes: [
...intro,
...euromat,
...results,
...faq,
...press,
...imprint,

73
src/styles/buttons.scss Normal file
View file

@ -0,0 +1,73 @@
@import "~styles/colors";
@import "~styles/layout";
button, .btn {
display: inline-block;
text-decoration: none;
padding: 10px 20px;
background: $button-background;
color: $button-color;
border-radius: $border-radius;
border: 2px solid $button-background;
cursor: pointer;
position: relative;
transition: background 50ms, border-color 0.4s;
transition-timing-function: cubic-bezier(0.2, 1, 0.3, 1);
&::before,
&::after {
content: '';
position: absolute;
top: 0;
left: -2px;
width: calc(100% + 4px);
height: 100%;
border-radius: $border-radius;
}
&::before {
background: $yellow;
border-radius: $border-radius;
opacity: 0;
z-index: -1;
transform: scale3d(0.7, 1, 1);
transition: transform 0.4s, opacity 0.4s;
transition-timing-function: cubic-bezier(0.2, 1, 0.3, 1);
}
&::after {
background: $button-background;
z-index: -2;
}
&:hover {
background: transparent;
border-color: $yellow;
color: $button-color;
&::before {
opacity: 1;
transform: translate3d(0, 0, 0);
}
}
&:active,
&:focus {
outline: none;
background: $yellow;
}
&.btn-txt {
background: transparent;
color: $text-color-base;
border: none;
&::before, &::after {
content: none;
}
&:hover {
color: $text-color-special;
}
}
}