Adds a dropdown for language selection

This commit is contained in:
Moritz Kröger 2019-04-10 22:30:40 +01:00
parent 12fe4ef4e7
commit 8319bcf7a8
13 changed files with 218 additions and 103 deletions

View file

@ -20,25 +20,17 @@
<app-footer :menu="subMenu" :social="socialMedia" />
</footer>
<section v-if="showConsentLayer" id="analytics-consent">
<div class="consent-content">
<p>{{ $t('meta.cookieConsent.text') }}</p>
<div class="consent-actions">
<button @click="updateConsent(false)">
{{ $t('meta.cookieConsent.btnDecline') }}
</button>
<button @click="updateConsent(true)">
{{ $t('meta.cookieConsent.btnAccept') }}
</button>
</div>
</div>
</section>
<cookie-consent
v-if="showConsentLayer"
@cookie-consent="updateConsent"
/>
</div>
</template>
<script>
import '@/assets/icons/european-stars'
import { GA_COOKIE_NAME } from '@/config/analytics'
import { LOCALES } from '@/config'
import { setCookie, getCookie } from '@/helper/cookies'
export default {
@ -49,10 +41,11 @@
showConsentLayer: getCookie(GA_COOKIE_NAME) === null,
euromatLogo: require('@/assets/svg/euromat-logo.svg'),
logoSize: 220,
languages: [
{ icon: require('@/assets/svg/flag-de.svg'), locale: 'de' },
{ icon: require('@/assets/svg/flag-uk.svg'), locale: 'en' }
]
languages: LOCALES.map(([locale, language]) => ({
icon: require(`@/assets/svg/flag-${locale}.svg`),
locale,
language
}))
}
},
@ -133,8 +126,6 @@
@import "~@/styles/colors";
@import "~@/styles/layout";
$app-width: 930px;
* {
padding: 0;
margin: 0;
@ -273,38 +264,4 @@
margin-top: $base-gap;
}
}
#analytics-consent {
position: fixed;
z-index: 4;
bottom: 0;
width: 100vw;
max-width: $app-width;
background: $background-secondary;
color: $text-color-secondary;
display: flex;
justify-content: center;
padding: $small-gap;
margin-bottom: $base-gap;
border-radius: $border-radius;
box-shadow: $button-shadow;
@media (max-width: $app-width) {
margin-bottom: 0;
border-radius: 0;
box-shadow: 0;
}
.consent-content {
max-width: $app-width;
width: 100%;
display: flex;
justify-content: space-between;
align-items: center;
& button {
margin-left: $small-gap;
}
}
}
</style>

View file

@ -1,10 +1,6 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 512 512" style="enable-background:new 0 0 512 512;" xml:space="preserve">
<path style="fill:#464655;" d="M473.655,88.276H38.345C17.167,88.276,0,105.443,0,126.621v73.471h512v-73.471
C512,105.443,494.833,88.276,473.655,88.276z"/>
<path style="fill:#FFE15A;" d="M0,385.379c0,21.177,17.167,38.345,38.345,38.345h435.31c21.177,0,38.345-17.167,38.345-38.345
v-73.471H0V385.379z"/>
<rect y="200.09" style="fill:#FF4B55;" width="512" height="111.81"/>
</svg>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 5 3">
<desc>Flag of Germany</desc>
<rect id="black_stripe" width="5" height="3" y="0" x="0" fill="#000"/>
<rect id="red_stripe" width="5" height="2" y="1" x="0" fill="#D00"/>
<rect id="gold_stripe" width="5" height="1" y="2" x="0" fill="#FFCE00"/>
</svg>

Before

Width:  |  Height:  |  Size: 742 B

After

Width:  |  Height:  |  Size: 308 B

View file

@ -0,0 +1,10 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 60 30">
<clipPath id="t">
<path d="M30,15 h30 v15 z v15 h-30 z h-30 v-15 z v-15 h30 z"/>
</clipPath>
<path d="M0,0 v30 h60 v-30 z" fill="#00247d"/>
<path d="M0,0 L60,30 M60,0 L0,30" stroke="#fff" stroke-width="6"/>
<path d="M0,0 L60,30 M60,0 L0,30" clip-path="url(#t)" stroke="#cf142b" stroke-width="4"/>
<path d="M30,0 v30 M0,15 h60" stroke="#fff" stroke-width="10"/>
<path d="M30,0 v30 M0,15 h60" stroke="#cf142b" stroke-width="6"/>
</svg>

After

Width:  |  Height:  |  Size: 495 B

View file

@ -0,0 +1,5 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 3 2">
<rect width="3" height="2" fill="#ED2939"/>
<rect width="2" height="2" fill="#fff"/>
<rect width="1" height="2" fill="#002395"/>
</svg>

After

Width:  |  Height:  |  Size: 195 B

View file

@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" id="Flag of Poland" viewBox="0 0 16 10">
<rect width="16" height="10" fill="#fff"/>
<rect width="16" height="5" fill="#dc143c" y="5"/>
</svg>

After

Width:  |  Height:  |  Size: 182 B

View file

@ -1,23 +0,0 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 512 512" style="enable-background:new 0 0 512 512;" xml:space="preserve">
<path style="fill:#41479B;" d="M473.655,88.276H38.345C17.167,88.276,0,105.443,0,126.621V385.38
c0,21.177,17.167,38.345,38.345,38.345h435.31c21.177,0,38.345-17.167,38.345-38.345V126.621
C512,105.443,494.833,88.276,473.655,88.276z"/>
<path style="fill:#F5F5F5;" d="M511.469,120.282c-3.022-18.159-18.797-32.007-37.814-32.007h-9.977l-163.54,107.147V88.276h-88.276
v107.147L48.322,88.276h-9.977c-19.017,0-34.792,13.847-37.814,32.007l139.778,91.58H0v88.276h140.309L0.531,391.717
c3.022,18.159,18.797,32.007,37.814,32.007h9.977l163.54-107.147v107.147h88.276V316.577l163.54,107.147h9.977
c19.017,0,34.792-13.847,37.814-32.007l-139.778-91.58H512v-88.276H371.691L511.469,120.282z"/>
<g>
<polygon style="fill:#FF4B55;" points="282.483,88.276 229.517,88.276 229.517,229.517 0,229.517 0,282.483 229.517,282.483
229.517,423.724 282.483,423.724 282.483,282.483 512,282.483 512,229.517 282.483,229.517 "/>
<path style="fill:#FF4B55;" d="M24.793,421.252l186.583-121.114h-32.428L9.224,410.31
C13.377,415.157,18.714,418.955,24.793,421.252z"/>
<path style="fill:#FF4B55;" d="M346.388,300.138H313.96l180.716,117.305c5.057-3.321,9.277-7.807,12.287-13.075L346.388,300.138z"
/>
<path style="fill:#FF4B55;" d="M4.049,109.475l157.73,102.387h32.428L15.475,95.842C10.676,99.414,6.749,104.084,4.049,109.475z"/>
<path style="fill:#FF4B55;" d="M332.566,211.862l170.035-110.375c-4.199-4.831-9.578-8.607-15.699-10.86L300.138,211.862H332.566z"
/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.8 KiB

View file

@ -8,20 +8,40 @@
</li>
</ul>
<div class="menu-language">
<div :class="['menu-language', { 'show-languages': languageMenuSelected }]">
<button
v-for="lang of languages"
:key="lang.locale"
class="btn-txt"
type="button"
@click="changeLanguage(lang.locale)"
@click="toggleLanguageSelection"
>
<img :src="lang.icon"
<img :src="selectedLanguage.icon"
:width="buttonSize"
:height="buttonSize"
:alt="lang.locale"
:alt="selectedLanguage.locale"
>
</button>
<div
class="menu-language-select"
@click.self="hideLanguageSelection"
>
<ul>
<li
v-for="lang of languages"
:key="lang.locale"
:class="{ selected: $i18n.locale === lang.locale }"
>
<button @click="changeLanguage(lang.locale)">
<img :src="lang.icon"
:width="buttonSize"
:height="buttonSize"
:alt="lang.locale"
>
<span>{{ lang.language }}</span>
</button>
</li>
</ul>
</div>
</div>
</div>
</template>
@ -37,16 +57,30 @@
data () {
return {
buttonSize: 20
buttonSize: 20,
languageMenuSelected: false
}
},
computed: {
selectedLanguage () {
return this.languages.find(lang => lang.locale === this.$i18n.locale)
}
},
methods: {
toggleLanguageSelection () {
this.languageMenuSelected = !this.languageMenuSelected
},
hideLanguageSelection () {
this.languageMenuSelected = false
},
changeLanguage (locale) {
this.$i18n.locale = locale
if (this.$browser.supports('localStorage')) {
localStorage.setItem('euromat-locale', locale)
}
this.hideLanguageSelection()
}
}
}
@ -100,8 +134,9 @@
.menu-language {
display: flex;
justify-content: space-around;
position: relative;
button {
> button {
display: flex;
justify-content: center;
align-items: center;
@ -113,7 +148,7 @@
transition: background 150ms $easeOutBack;
&:hover {
background: rgba(0, 0, 0, 0.15);
background: $transparent-black;
}
&:focus {
@ -126,4 +161,62 @@
margin: 0 auto;
}
}
.menu-language-select {
display: none;
position: absolute;
top: 0;
right: 0;
@media (max-width: 480px) {
position: fixed;
width: 100vw;
height: 100vh;
align-items: center;
background: rgba(0, 0, 0, 0.55);
}
.show-languages & {
display: flex;
}
ul {
background: $background-secondary;
width: 100%;
border-radius: 10px;
box-shadow: $button-shadow;
@media (max-width: 480px) {
width: 95%;
margin: 0 auto;
}
}
ul li {
&:not(:last-child) {
border-bottom: 2px solid $transparent-black;
}
}
ul button {
width: 100%;
background: none;
box-shadow: none;
border-radius: 0;
color: $text-color-secondary;
&:hover {
transform: translateY(0);
box-shadow: none;
}
& span {
margin-left: 0.5em;
}
& img {
margin: 0;
}
}
}
</style>

View file

@ -0,0 +1,68 @@
<template>
<section id="analytics-consent">
<div class="consent-content">
<p>{{ $t('meta.cookieConsent.text') }}</p>
<div class="consent-actions">
<button @click="updateConsent(false)">
{{ $t('meta.cookieConsent.btnDecline') }}
</button>
<button @click="updateConsent(true)">
{{ $t('meta.cookieConsent.btnAccept') }}
</button>
</div>
</div>
</section>
</template>
<script>
export default {
name: 'CookieConsent',
methods: {
updateConsent (consent) {
this.$emit('cookie-consent', consent)
}
}
}
</script>
<style lang="scss" scoped>
@import "~@/styles/fonts";
@import "~@/styles/buttons";
@import "~@/styles/colors";
@import "~@/styles/layout";
#analytics-consent {
position: fixed;
z-index: 4;
bottom: 0;
width: 100vw;
max-width: $app-width;
background: $background-secondary;
color: $text-color-secondary;
display: flex;
justify-content: center;
padding: $small-gap;
margin-bottom: $base-gap;
border-radius: $border-radius;
box-shadow: $button-shadow;
@media (max-width: $app-width) {
margin-bottom: 0;
border-radius: 0;
box-shadow: 0;
}
.consent-content {
max-width: $app-width;
width: 100%;
display: flex;
justify-content: space-between;
align-items: center;
& button {
margin-left: $small-gap;
}
}
}
</style>

View file

@ -2,9 +2,11 @@ export const LOCALE_GERMAN = 'de'
export const LOCALE_ENGLISH = 'en'
export const LOCALE_FRENCH = 'fr'
export const LOCALE_POLISH = 'pl'
export const DEFAULT_LOCALE = LOCALE_GERMAN
export const DEFAULT_LOCALE = LOCALE_ENGLISH
export const LOCALES = [
LOCALE_GERMAN,
LOCALE_ENGLISH
[LOCALE_ENGLISH, 'English'],
[LOCALE_GERMAN, 'Deutsch'],
[LOCALE_FRENCH, 'Français'],
[LOCALE_POLISH, 'Polski']
]

View file

@ -1,5 +1,5 @@
{
"language": "de",
"language": "en",
"topMenu": {
"index": "Landing page",
"faq": "FAQ",

View file

@ -23,18 +23,18 @@ const messages = [
press, imprint, privacy
]
function getLanguage (lang) {
function getLanguage (locale) {
return messages.reduce((acc, cur) => ({
...acc,
...cur[lang]
...cur[locale]
}), {})
}
export default new VueI18n({
locale: localStorage.getItem('euromat-locale') || DEFAULT_LOCALE,
fallbackLocale: DEFAULT_LOCALE,
messages: LOCALES.reduce((acc, cur) => ({
messages: LOCALES.reduce((acc, [locale]) => ({
...acc,
[cur]: getLanguage(cur)
[locale]: getLanguage(locale)
}), {})
})

View file

@ -1,4 +1,5 @@
$transparent-white: rgba(255, 255, 255, 0.21);
$transparent-black: rgba(0, 0, 0, 0.15);
$blue: #40A6EE;
$dark-blue: #296E9F;
$yellow: #FEE872;

View file

@ -8,3 +8,5 @@ $font-size-xlarge: 275%;
$small-gap: 20px;
$base-gap: 30px;
$border-radius: 100px;
$app-width: 930px;