284 lines
8.4 KiB
Vue
284 lines
8.4 KiB
Vue
|
|
<template>
|
|
<nav
|
|
id="top-navbar"
|
|
class="navbar navbar-expand-lg position-relative p-0"
|
|
:style="`background-color: ${activeRange && brandWithMultipleRanges ? activeRange.color : activeBrand?.color} !important`"
|
|
>
|
|
<div class="container-fluid">
|
|
<!-- UNE MARQUE EST SELECTIONNEE -->
|
|
<div
|
|
v-if="activeBrand"
|
|
:class="{
|
|
'd-flex flex-row flex-grow-1 justify-content-center align-items-center': true,
|
|
'mx-auto': !activeRange,
|
|
}"
|
|
>
|
|
<NuxtLinkLocale
|
|
:to="`/brands/${transField(activeBrand, 'slug')}`"
|
|
:class="{
|
|
'd-inline-block py-3 px-2 text-center': true,
|
|
'flex-grow-1': !activeRange
|
|
}"
|
|
data-bs-toggle="tooltip"
|
|
:title="t('view_brand_ranges', {'brand_name': transField(activeBrand, 'name')})"
|
|
>
|
|
<img
|
|
class="img-fluid main-logo"
|
|
:src="`/data/${activeBrand.picture}`"
|
|
:alt="`Marque ${transField(activeBrand, 'name')}`"
|
|
:title="t('brands_logo', {'brand_name': transField(activeBrand, 'name')})"
|
|
data-bs-toggle="tooltip"
|
|
>
|
|
</NuxtLinkLocale>
|
|
<div v-if="activeRange && brandWithMultipleRanges" class="flex-grow-1 text-center">
|
|
<span
|
|
:class="{...{
|
|
'title': true,
|
|
'ps-md-5 d-inline-block px-5 py-3 rounded text-capitalize': true,
|
|
'text-dark': getContrastYIQ(activeRange.color) === '#000000',
|
|
'text-light': getContrastYIQ(activeRange.color) === '#FFFFFF',
|
|
}, ...rangeFont(activeRange.font_id)}"
|
|
:style="{
|
|
'text-shadow': `0 0 0.2rem ${toRGBA(getContrastYIQ(activeRange.color), 0.8)}`
|
|
}"
|
|
>
|
|
{{ transField(activeRange, 'name') }}
|
|
</span>
|
|
</div>
|
|
</div>
|
|
<!-- HOME (PAS DE MARQUE) -->
|
|
<div v-else class="row text-bg-light">
|
|
<div class="col-12 g-0 pb-5">
|
|
<img
|
|
src="assets/pictures/layout/top-hr.png"
|
|
alt="Top bar"
|
|
class="img-fluid d-block"
|
|
>
|
|
</div>
|
|
<div class="col-12 mx-auto text-center mb-3 mt-3 pb-5">
|
|
<div class="d-inline-block bg-white p-4 rounded">
|
|
<img :src="`/data/${settings.logo}`" alt="Logo" class="img-fluid main-logo d-inline-block">
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<button
|
|
class="navbar-toggler"
|
|
data-bs-toggle="collapse"
|
|
data-bs-target="#navbar-menu"
|
|
type="button"
|
|
aria-controls="navbar-menu"
|
|
aria-expanded="false"
|
|
:aria-label="t('show_hide_languages')"
|
|
>
|
|
<span class="navbar-toggler-icon" />
|
|
</button>
|
|
|
|
<div id="navbar-menu" class="lang-bar navbar-collapse collapse flex-grow-0">
|
|
<div class="btn-group z-1">
|
|
<button
|
|
v-for="(localeObject,localeIndex) of locales"
|
|
:key="localeIndex"
|
|
:class="{
|
|
'btn ms-3 px-4 mx-0 shadow fw-bold': true,
|
|
'btn-white bg-white': locale !== localeObject.iso,
|
|
'btn-secondary': locale === localeObject.iso,
|
|
}"
|
|
:title="localeObject.label"
|
|
data-bs-toggle="tooltip"
|
|
@click.prevent="switchLocale(localeObject)"
|
|
>
|
|
<span class="text-uppercase fs-5">{{ localeObject.flag }}</span>
|
|
<!-- <span :class="`fi fi-${localeObject.flag}`" /> -->
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</nav>
|
|
</template>
|
|
|
|
<script lang="ts">
|
|
import log from "electron-log";
|
|
import { defineComponent } from "vue";
|
|
import type { RouteLocationNormalizedLoaded } from "vue-router";
|
|
import ToolboxHelper from "~/classes/ToolboxHelper";
|
|
import { useAppStore } from "~/stores/useAppStore";
|
|
import { Tooltips } from "~/vueModules/bsTooltips";
|
|
|
|
type LocaleParams = {
|
|
iso: string,
|
|
flag: string,
|
|
label: string,
|
|
};
|
|
|
|
export default defineComponent({
|
|
name: "AppHeader",
|
|
props: {
|
|
activeBrand: {
|
|
type: Object as PropType<TypeBrand|null>,
|
|
required: false,
|
|
default: null
|
|
},
|
|
activeRange: {
|
|
type: Object as PropType<TypeRange|null>,
|
|
required: false,
|
|
default: null
|
|
},
|
|
},
|
|
data(): {
|
|
versions: typeof window.versions;
|
|
settings: TypeSettings;
|
|
locales: Array<LocaleParams>,
|
|
locale: string;
|
|
route: RouteLocationNormalizedLoaded;
|
|
tooltips: Tooltips|null;
|
|
} {
|
|
return {
|
|
versions: window.versions,
|
|
settings: {} as TypeSettings,
|
|
locales: [],
|
|
locale: "",
|
|
route: useRoute(),
|
|
tooltips: null
|
|
};
|
|
},
|
|
computed: {
|
|
brandWithMultipleRanges(): boolean {
|
|
if(!this.activeBrand) {
|
|
return false;
|
|
}
|
|
return this.activeBrand.ranges.length > 1;
|
|
}
|
|
},
|
|
watch: {
|
|
$route(to: RouteLocationNormalizedLoaded) {
|
|
log.debug(`Swithing to route ${String(to.name)}`);
|
|
if(to.name?.toString().startsWith("index")) {
|
|
// * Reset active Brand on main page
|
|
useAppStore().setActiveBrand(null);
|
|
}
|
|
const { locale } = useAppStore().getI18n();
|
|
this.locale = locale;
|
|
},
|
|
},
|
|
beforeMount() {
|
|
this.settings = useAppStore().data.settings();
|
|
const { locale, availableLocales } = useI18n({ useScope: "global"});
|
|
this.locale = locale.value;
|
|
const localeSortArr = ["fr", "nl"];
|
|
this.locales = availableLocales.sort((LocA, LocB) => localeSortArr.indexOf(LocA) - localeSortArr.indexOf(LocB)).map(localeStr => {
|
|
return {
|
|
iso: localeStr,
|
|
flag: this.t("_flag", {}, localeStr),
|
|
label: this.t("_lang", {}, localeStr),
|
|
};
|
|
});
|
|
},
|
|
mounted() {
|
|
this.$nextTick(() => {this.tooltips = Tooltips.make({type:"parent", parentSelector: "#top-navbar"});});
|
|
},
|
|
beforeUnmount() {
|
|
this.tooltips?.closeBootstrapTooltip();
|
|
},
|
|
methods: {
|
|
t(text: string, params: Record<string,string> = {}, localeToUse: string|null = null): string {
|
|
return ToolboxHelper.trans(text, params, localeToUse);
|
|
},
|
|
transField(model: Typei18nModel, field: Typei18nFieldList) {
|
|
return ToolboxHelper.getTranslatableField(model, field);
|
|
},
|
|
switchLocale(localeToSwitch:LocaleParams) {
|
|
const switchLocalePath = useSwitchLocalePath();
|
|
// Toast.toast(localeToSwitch.label, ToastTypeEnum.default);
|
|
useAppStore().switchLocale(localeToSwitch.iso);
|
|
navigateTo(switchLocalePath(localeToSwitch.iso));
|
|
},
|
|
rangeFont(fontId: number) {
|
|
const font = useAppStore().getFont(fontId);
|
|
const out: Map<string, boolean> = new Map<string, boolean>();
|
|
if(font) {
|
|
out.set(`f-${font.font_name}`, true);
|
|
}
|
|
return Object.fromEntries(out.entries());
|
|
},
|
|
getContrastYIQ(hexcolor: string): string {
|
|
return ToolboxHelper.getContrastYIQ(hexcolor);
|
|
},
|
|
toRGBA(hexcolor: string, alpha: number = 1): string {
|
|
return ToolboxHelper.toRGBA(hexcolor, alpha);
|
|
},
|
|
}
|
|
});
|
|
</script>
|
|
|
|
<style lang="postcss">
|
|
@import "flag-icons/sass/flag-icons.scss";
|
|
</style>
|
|
|
|
<style lang="scss" scoped>
|
|
@import "bootstrap/scss/functions";
|
|
@import "bootstrap/scss/variables";
|
|
@import "bootstrap/scss/variables-dark";
|
|
@import "bootstrap/scss/maps";
|
|
@import "bootstrap/scss/mixins";
|
|
@import "bootstrap/scss/vendor/rfs";
|
|
#top-navbar {
|
|
.title {
|
|
@include rfs(2rem, font-size);
|
|
|
|
@include media-breakpoint-up(md) {
|
|
@include rfs(3rem, font-size);
|
|
}
|
|
@include media-breakpoint-up(xxl) {
|
|
@include rfs(5rem, font-size);
|
|
}
|
|
}
|
|
|
|
.sub-title {
|
|
@include rfs(1.2rem, font-size);
|
|
|
|
@include media-breakpoint-up(md) {
|
|
@include rfs(1.8rem, font-size);
|
|
}
|
|
@include media-breakpoint-up(xxl) {
|
|
@include rfs(3.2rem, font-size);
|
|
}
|
|
}
|
|
|
|
.main-logo {
|
|
@include rfs(7rem, max-height);
|
|
height: 20vh;
|
|
@include media-breakpoint-up(md) {
|
|
@include rfs(15rem, max-height);
|
|
}
|
|
@include media-breakpoint-up(xxl) {
|
|
@include rfs(30rem, max-height);
|
|
}
|
|
}
|
|
.fi {
|
|
@include media-breakpoint-up(md) {
|
|
@include rfs(2em, line-height);
|
|
@include rfs(4em, width);
|
|
}
|
|
@include media-breakpoint-up(xxl) {
|
|
@include rfs(3em, line-height);
|
|
@include rfs(5em, width);
|
|
}
|
|
}
|
|
.lang-bar {
|
|
position: absolute;
|
|
right: 1rem;
|
|
top: 0;
|
|
}
|
|
.lang-bar .btn-group {
|
|
border-radius: 0;
|
|
}
|
|
.lang-bar .btn-group button {
|
|
border-top-left-radius: 0;
|
|
border-top-right-radius: 0;
|
|
border-bottom-left-radius: 1rem;
|
|
border-bottom-right-radius: 1rem;
|
|
}
|
|
}
|
|
</style>
|