ldc-showroom/components/layout/AppHeader.vue

298 lines
8.8 KiB
Vue
Raw Permalink Normal View History

<template>
2024-01-11 15:21:59 +01:00
<nav
id="top-navbar"
2024-03-13 12:10:51 +01:00
class="navbar navbar-expand-lg position-relative p-0"
:style="`background-color: ${activeRange && brandWithMultipleRanges ? activeRange.color : activeBrand?.color} !important`"
2024-01-11 15:21:59 +01:00
>
2024-01-12 16:36:16 +01:00
<div class="container-fluid">
<!-- UNE MARQUE EST SELECTIONNEE -->
<div
v-if="activeBrand"
:class="{
2024-01-12 18:06:16 +01:00
'd-flex flex-row flex-grow-1 justify-content-center align-items-center': true,
2024-01-12 16:36:16 +01:00
'mx-auto': !activeRange,
}"
>
<button
2024-01-12 18:06:16 +01:00
:class="{
'd-inline-block py-3 px-2 text-center bg-transparent border-0': true,
2024-01-12 18:06:16 +01:00
'flex-grow-1': !activeRange
}"
2024-01-11 17:20:05 +01:00
data-bs-toggle="tooltip"
2024-01-17 17:44:12 +01:00
:title="t('view_brand_ranges', {'brand_name': transField(activeBrand, 'name')})"
@click="goToBrand(activeBrand)"
2024-01-11 17:20:05 +01:00
>
2024-01-17 10:36:44 +01:00
<img
class="img-fluid main-logo"
:src="`/data/${activeBrand.picture}`"
2024-01-17 17:44:12 +01:00
:alt="`Marque ${transField(activeBrand, 'name')}`"
:title="t('brands_logo', {'brand_name': transField(activeBrand, 'name')})"
2024-01-31 17:21:05 +01:00
data-bs-toggle="tooltip"
2024-01-17 10:36:44 +01:00
>
</button>
<div v-if="activeRange && brandWithMultipleRanges" class="flex-grow-1 text-center">
2024-01-16 10:25:13 +01:00
<span
2024-01-16 15:43:21 +01:00
:class="{...{
2024-01-31 17:02:55 +01:00
'title': true,
'ps-md-5 d-inline-block px-5 py-3 rounded text-capitalize': true,
2024-01-16 10:25:13 +01:00
'text-dark': getContrastYIQ(activeRange.color) === '#000000',
'text-light': getContrastYIQ(activeRange.color) === '#FFFFFF',
2024-01-16 15:43:21 +01:00
}, ...rangeFont(activeRange.font_id)}"
2024-01-16 10:25:13 +01:00
:style="{
'text-shadow': `0 0 0.2rem ${toRGBA(getContrastYIQ(activeRange.color), 0.8)}`
}"
>
2024-01-17 17:44:12 +01:00
{{ transField(activeRange, 'name') }}
2024-01-16 10:25:13 +01:00
</span>
2024-01-12 18:06:16 +01:00
</div>
2024-01-11 17:20:05 +01:00
</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"
2024-01-17 10:36:44 +01:00
: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">
2024-01-12 18:06:16 +01:00
<button
v-for="(localeObject, localeIndex) of locales"
2024-01-12 16:36:16 +01:00
:key="localeIndex"
2024-01-17 17:44:12 +01:00
:class="{
'btn ms-3 px-4 mx-0 shadow fw-bold': true,
'btn-secondary': locale === localeObject.iso,
'btn-white bg-white': locale !== localeObject.iso,
2024-01-17 17:44:12 +01:00
}"
2024-01-16 18:15:07 +01:00
:title="localeObject.label"
2024-01-12 18:06:16 +01:00
data-bs-toggle="tooltip"
data-bs-placement="bottom"
2024-01-16 18:15:07 +01:00
@click.prevent="switchLocale(localeObject)"
2024-01-12 16:36:16 +01:00
>
<span class="text-uppercase fs-5">{{ localeObject.flag }}</span>
<span :class="`fi fi-${localeObject.flag}`" />
2024-01-12 18:06:16 +01:00
</button>
</div>
</div>
</div>
</nav>
</template>
<script lang="ts">
2024-01-17 09:38:51 +01:00
import log from "electron-log";
import { defineComponent } from "vue";
2024-01-11 15:21:59 +01:00
import type { RouteLocationNormalizedLoaded } from "vue-router";
2024-01-16 10:25:13 +01:00
import ToolboxHelper from "~/classes/ToolboxHelper";
import { useAppStore } from "~/stores/useAppStore";
2024-02-02 08:47:23 +01:00
import { Tooltips } from "~/vueModules/bsTooltips";
2024-01-17 17:44:12 +01:00
type LocaleParams = {
2024-01-16 18:15:07 +01:00
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;
2024-01-17 17:44:12 +01:00
locales: Array<LocaleParams>,
locale: string;
2024-01-11 15:21:59 +01:00
route: RouteLocationNormalizedLoaded;
2024-02-02 08:47:23 +01:00
tooltips: Tooltips|null;
} {
return {
versions: window.versions,
2024-01-11 15:21:59 +01:00
settings: {} as TypeSettings,
2024-01-16 18:15:07 +01:00
locales: [],
2024-01-17 17:44:12 +01:00
locale: "",
2024-01-11 15:21:59 +01:00
route: useRoute(),
2024-02-02 08:47:23 +01:00
tooltips: null
};
},
computed: {
brandWithMultipleRanges(): boolean {
if(!this.activeBrand) {
return false;
}
return this.activeBrand.ranges.length > 1;
}
},
2024-01-11 17:20:05 +01:00
watch: {
$route(to: RouteLocationNormalizedLoaded) {
2024-01-17 09:38:51 +01:00
log.debug(`Swithing to route ${String(to.name)}`);
if(to.name?.toString().startsWith("index")) {
2024-01-11 17:20:05 +01:00
// * Reset active Brand on main page
2024-01-11 17:43:37 +01:00
useAppStore().setActiveBrand(null);
2024-01-11 17:20:05 +01:00
}
2024-01-17 17:44:12 +01:00
const { locale } = useAppStore().getI18n();
this.locale = locale;
2024-01-11 17:20:05 +01:00
},
},
beforeMount() {
2024-01-11 15:21:59 +01:00
this.settings = useAppStore().data.settings();
2024-01-17 17:44:12 +01:00
const { locale, availableLocales } = useI18n({ useScope: "global"});
2024-01-16 18:15:07 +01:00
this.locale = locale.value;
let localeSortArr = [] as Array<string>;
window.ipcRendererObject.getJsonData().then((dataJson) => {
localeSortArr = dataJson.settings.locales;
});
this.locales = availableLocales.sort((LocA, LocB) => localeSortArr.indexOf(LocA) - localeSortArr.indexOf(LocB)).map(localeStr => {
2024-01-16 18:15:07 +01:00
return {
iso: localeStr,
2024-01-17 10:36:44 +01:00
flag: this.t("_flag", {}, localeStr),
label: this.t("_lang", {}, localeStr),
2024-01-16 18:15:07 +01:00
};
});
},
mounted() {
2024-02-02 08:47:23 +01:00
this.$nextTick(() => {this.tooltips = Tooltips.make({type:"parent", parentSelector: "#top-navbar"});});
},
beforeUnmount() {
this.tooltips?.closeBootstrapTooltip();
},
2024-01-12 16:36:16 +01:00
methods: {
2024-01-17 10:36:44 +01:00
t(text: string, params: Record<string,string> = {}, localeToUse: string|null = null): string {
return ToolboxHelper.trans(text, params, localeToUse);
2024-01-16 18:15:07 +01:00
},
2024-01-31 16:59:54 +01:00
transField(model: Typei18nModel, field: Typei18nFieldList) {
2024-01-17 17:44:12 +01:00
return ToolboxHelper.getTranslatableField(model, field);
},
switchLocale(localeToSwitch:LocaleParams) {
const switchLocalePath = useSwitchLocalePath();
2024-01-19 09:39:32 +01:00
// Toast.toast(localeToSwitch.label, ToastTypeEnum.default);
2024-01-17 17:44:12 +01:00
useAppStore().switchLocale(localeToSwitch.iso);
navigateTo(switchLocalePath(localeToSwitch.iso));
2024-01-16 10:25:13 +01:00
},
2024-01-16 15:43:21 +01:00
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());
},
2024-01-16 10:25:13 +01:00
getContrastYIQ(hexcolor: string): string {
return ToolboxHelper.getContrastYIQ(hexcolor);
},
toRGBA(hexcolor: string, alpha: number = 1): string {
return ToolboxHelper.toRGBA(hexcolor, alpha);
},
goToBrand(activeBrand: TypeBrand): void {
if(!activeBrand) {
return;
}
useAppStore().setActiveRange(null);
navigateTo(useLocaleRoute()({"name": "brands-slug", "params": {"slug": activeBrand.slug[this.locale]}}));
}
2024-01-12 16:36:16 +01:00
}
});
</script>
<style lang="postcss">
@import "flag-icons/sass/flag-icons.scss";
</style>
2024-01-11 12:42:33 +01:00
<style lang="scss" scoped>
2024-01-12 18:06:16 +01:00
@import "bootstrap/scss/functions";
@import "bootstrap/scss/variables";
@import "bootstrap/scss/variables-dark";
@import "bootstrap/scss/maps";
@import "bootstrap/scss/mixins";
2024-01-11 12:42:33 +01:00
@import "bootstrap/scss/vendor/rfs";
#top-navbar {
2024-01-12 18:06:16 +01:00
.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);
}
}
2024-01-31 17:02:55 +01:00
.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 {
2024-01-12 18:06:16 +01:00
@include rfs(7rem, max-height);
2025-06-26 13:15:13 +02:00
& {
height: 20vh;
}
2024-01-12 18:06:16 +01:00
@include media-breakpoint-up(md) {
@include rfs(15rem, max-height);
}
@include media-breakpoint-up(xxl) {
@include rfs(30rem, max-height);
}
}
2024-01-11 12:42:33 +01:00
.fi {
2024-01-12 18:06:16 +01:00
@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;
2024-01-11 12:42:33 +01:00
}
}
</style>