fix: 🎨 update layout for multiple brands and single brand
This commit is contained in:
parent
889ead5101
commit
ce5e29cbbd
8 changed files with 101 additions and 508 deletions
21
app.vue
21
app.vue
|
|
@ -86,6 +86,7 @@ export default defineComponent({
|
|||
this.loading = false;
|
||||
this.setTimeout();
|
||||
dataJson.fonts.forEach(font => this.injectFontFace(font.font_name, font.font));
|
||||
this.redirectIfOneBrand(dataJson.items);
|
||||
});
|
||||
},
|
||||
mounted() {
|
||||
|
|
@ -103,6 +104,9 @@ export default defineComponent({
|
|||
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);
|
||||
},
|
||||
injectFontFace(fontName: string, fontPath: string|null) {
|
||||
const newStyle = document.createElement("style");
|
||||
if(fontPath) {
|
||||
|
|
@ -113,7 +117,18 @@ export default defineComponent({
|
|||
}
|
||||
document.head.appendChild(newStyle);
|
||||
},
|
||||
/** Prolong le timer pour revenir au home screen */
|
||||
/** Redirect to ranges.index if there is only one brand. */
|
||||
redirectIfOneBrand(brands: Array<TypeBrand>): void {
|
||||
if (brands.length === 1) {
|
||||
useAppStore().setActiveBrand(brands[0]);
|
||||
this.activeBrand = brands[0];
|
||||
navigateTo(useLocaleRoute()({"name": "brands-slug", "params": {"slug": this.transField(brands[0], "slug")}}));
|
||||
} else {
|
||||
useAppStore().setActiveBrand(null);
|
||||
this.activeBrand = null;
|
||||
}
|
||||
},
|
||||
/** Prolong le timer pour revenir au home screen. */
|
||||
setTimeout(): void {
|
||||
if(this.timeout) {
|
||||
clearTimeout(this.timeout);
|
||||
|
|
@ -121,7 +136,9 @@ export default defineComponent({
|
|||
this.$nextTick(() => {
|
||||
this.timeout = setTimeout(() => {
|
||||
useAppStore().setActiveRange(null);
|
||||
useAppStore().setActiveBrand(null);
|
||||
window.ipcRendererObject.getJsonData().then((dataJson) => {
|
||||
this.redirectIfOneBrand(dataJson.items);
|
||||
});
|
||||
navigateTo(useLocaleRoute()({"name": "index"}));
|
||||
}, useAppStore().getSettings().home_timeout * 1000);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -170,7 +170,6 @@ export default defineComponent({
|
|||
return ToolboxHelper.getContrastYIQ(hexcolor);
|
||||
},
|
||||
gotoBrand(brand: TypeBrand) {
|
||||
useAppStore().setActiveBrand(null);
|
||||
useAppStore().setActiveRange(null);
|
||||
useAppStore().setActiveBrand(brand);
|
||||
navigateTo(useLocaleRoute()({"name": "brands-slug", "params": {"slug": this.transField(brand, "slug")}}));
|
||||
|
|
|
|||
|
|
@ -1,289 +0,0 @@
|
|||
|
||||
<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;
|
||||
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 => {
|
||||
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>
|
||||
|
|
@ -14,14 +14,14 @@
|
|||
'mx-auto': !activeRange,
|
||||
}"
|
||||
>
|
||||
<NuxtLinkLocale
|
||||
:to="`/brands/${transField(activeBrand, 'slug')}`"
|
||||
<button
|
||||
:class="{
|
||||
'd-inline-block py-3 px-2 text-center': true,
|
||||
'd-inline-block py-3 px-2 text-center bg-transparent border-0': true,
|
||||
'flex-grow-1': !activeRange
|
||||
}"
|
||||
data-bs-toggle="tooltip"
|
||||
:title="t('view_brand_ranges', {'brand_name': transField(activeBrand, 'name')})"
|
||||
@click="goToBrand(activeBrand)"
|
||||
>
|
||||
<img
|
||||
class="img-fluid main-logo"
|
||||
|
|
@ -30,7 +30,7 @@
|
|||
:title="t('brands_logo', {'brand_name': transField(activeBrand, 'name')})"
|
||||
data-bs-toggle="tooltip"
|
||||
>
|
||||
</NuxtLinkLocale>
|
||||
</button>
|
||||
<div v-if="activeRange && brandWithMultipleRanges" class="flex-grow-1 text-center">
|
||||
<span
|
||||
:class="{...{
|
||||
|
|
@ -47,6 +47,21 @@
|
|||
</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"
|
||||
|
|
@ -60,15 +75,15 @@
|
|||
<span class="navbar-toggler-icon" />
|
||||
</button>
|
||||
|
||||
<div v-if="activeBrand" id="navbar-menu" class="lang-bar navbar-collapse collapse flex-grow-0">
|
||||
<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-2 mx-0 shadow fw-bold': true,
|
||||
'btn-secondary': locale !== localeObject.iso,
|
||||
'btn-white bg-white': locale === localeObject.iso,
|
||||
'btn ms-3 px-4 mx-0 shadow fw-bold': true,
|
||||
'btn-secondary': locale === localeObject.iso,
|
||||
'btn-white bg-white': locale !== localeObject.iso,
|
||||
}"
|
||||
:title="localeObject.label"
|
||||
data-bs-toggle="tooltip"
|
||||
|
|
@ -76,7 +91,7 @@
|
|||
@click.prevent="switchLocale(localeObject)"
|
||||
>
|
||||
<span class="text-uppercase fs-5">{{ localeObject.flag }}</span>
|
||||
<!-- <span :class="`fi fi-${localeObject.flag}`" /> -->
|
||||
<span :class="`fi fi-${localeObject.flag}`" />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -178,11 +193,10 @@ export default defineComponent({
|
|||
return ToolboxHelper.getTranslatableField(model, field);
|
||||
},
|
||||
switchLocale(localeToSwitch:LocaleParams) {
|
||||
// const switchLocalePath = useSwitchLocalePath();
|
||||
const switchLocalePath = useSwitchLocalePath();
|
||||
// Toast.toast(localeToSwitch.label, ToastTypeEnum.default);
|
||||
useAppStore().switchLocale(localeToSwitch.iso);
|
||||
this.locale = localeToSwitch.iso;
|
||||
// navigateTo(switchLocalePath(localeToSwitch.iso));
|
||||
navigateTo(switchLocalePath(localeToSwitch.iso));
|
||||
},
|
||||
rangeFont(fontId: number) {
|
||||
const font = useAppStore().getFont(fontId);
|
||||
|
|
@ -198,6 +212,13 @@ export default defineComponent({
|
|||
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]}}));
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -71,13 +71,14 @@ app.whenReady().then(() => {
|
|||
// width: 1280,
|
||||
// height: 900,
|
||||
center: true,
|
||||
kiosk: false,
|
||||
kiosk: process.env.NODE_ENV !== "development",
|
||||
closable: false,
|
||||
alwaysOnTop: true,
|
||||
fullscreen: false,
|
||||
fullscreen: process.env.NODE_ENV !== "development",
|
||||
autoHideMenuBar: true,
|
||||
webPreferences: {
|
||||
preload: path.join(__dirname, "preload.js")
|
||||
preload: path.join(__dirname, "preload.js"),
|
||||
devTools: process.env.NODE_ENV === "development",
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
export default {
|
||||
"_flag": "en",
|
||||
"_flag": "us",
|
||||
"_lang": "English",
|
||||
"error_occured": "An error has occured",
|
||||
"loading": "Loading",
|
||||
|
|
|
|||
|
|
@ -1,189 +0,0 @@
|
|||
<template>
|
||||
<div class="page-home d-flex text-bg-light">
|
||||
<div class="container-fluid justify-content-center d-flex flex-column">
|
||||
<div class="row">
|
||||
<div class="col-12 text-center overflow-hidden pb-5">
|
||||
<div class="home-title">
|
||||
{{ t('welcome_to_ldc') }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 text-center pb-5">
|
||||
<video
|
||||
class="object-fit-contain w-100"
|
||||
playsinline
|
||||
autoplay
|
||||
muted
|
||||
loop
|
||||
controls
|
||||
controlsList="nodownload noremoteplayback nofullscreen"
|
||||
>
|
||||
<source src="assets/videos/groupe-ldc-presentation-groupe-V7.webm" type="video/webm">
|
||||
<!-- <source src="assets/videos/groupe-ldc-presentation-groupe-V7.mp4" type="video/mp4"> -->
|
||||
</video>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="appState.brands" class="row">
|
||||
<div class="col-12 text-center overflow-hidden pb-5">
|
||||
<div class="home-title">
|
||||
{{ t('discover_our_brands') }}
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
v-for="(brand, brandIndex) of appState.brands()"
|
||||
:key="brandIndex"
|
||||
:class="{
|
||||
'col-12 col-md-6 px-5 my-3': true,
|
||||
}"
|
||||
>
|
||||
<div
|
||||
:class="{
|
||||
'd-flex align-items-center h-100 my-2': true,
|
||||
'justify-content-start': brandIndex %2 !== 0,
|
||||
'justify-content-end': brandIndex %2 === 0,
|
||||
}"
|
||||
>
|
||||
<div
|
||||
class="d-inline-block text-center"
|
||||
role="button"
|
||||
:title="t('view_brand_ranges', {'brand_name': transField(brand, 'name')})"
|
||||
data-bs-toggle="tooltip"
|
||||
@click="gotoBrand(brand)"
|
||||
>
|
||||
<div class="d-inline-block brand-picture-wrapper">
|
||||
<img
|
||||
class="img-fluid"
|
||||
:src="`/data/${brand.picture}`"
|
||||
:alt="t('brands_logo', {'brand_name': transField(brand, 'name')})"
|
||||
:title="t('brands_logo', {'brand_name': transField(brand, 'name')})"
|
||||
>
|
||||
</div>
|
||||
<!-- :class="{...{'brand-title fw-bold text-capitalize fs-1 animate__animated p-3 mt-5 d-inline-block': true}, ...titleAnimations(brandIndex)}" -->
|
||||
<span
|
||||
class="d-none"
|
||||
:style="{
|
||||
'color': getContrastYIQ(brand.color),
|
||||
'background-color': brand.color
|
||||
}"
|
||||
>
|
||||
{{ transField(brand, 'name') }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else class="row">
|
||||
<div class="col">
|
||||
<span class="h4">{{ t('no_brands_available') }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row my-5 pb-5">
|
||||
<div class="col py-5 my-5 pb-5">
|
||||
<img
|
||||
src="assets/pictures/layout/home-bottom-banner.png"
|
||||
alt="Bottom Banner"
|
||||
class="img-fluid"
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent } from "vue";
|
||||
import type AppState from "~/classes/AppState";
|
||||
import ToolboxHelper from "~/classes/ToolboxHelper";
|
||||
import { useAppStore } from "~/stores/useAppStore";
|
||||
import { Tooltips } from "~/vueModules/bsTooltips";
|
||||
|
||||
export default defineComponent({
|
||||
name: "HomePage",
|
||||
data() : {
|
||||
appState: AppState;
|
||||
animateTimeout: NodeJS.Timeout|undefined;
|
||||
animateIndex: number|null;
|
||||
animations: Array<string>;
|
||||
tooltips: Tooltips|null;
|
||||
} {
|
||||
return {
|
||||
appState: {} as AppState,
|
||||
animateTimeout: undefined,
|
||||
animateIndex: null,
|
||||
animations: ["heartBeat", "tada", "shakeX", "rubberBand"],
|
||||
tooltips: null
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
this.$nextTick(() => {this.tooltips = Tooltips.make({type:"parent", parentSelector: ".page-home"});});
|
||||
this.appState = useAppStore().data;
|
||||
|
||||
// * ANIMATIONS
|
||||
clearTimeout(this.animateTimeout);
|
||||
this.$nextTick(() => {
|
||||
[...document.getElementsByClassName("brand-title")].forEach(el => {
|
||||
el.classList.add("animate__bounce");
|
||||
});
|
||||
this.animateTimeout = setTimeout(() => {
|
||||
[...document.getElementsByClassName("brand-title")].forEach(el => {
|
||||
el.classList.remove("animate__bounce");
|
||||
});
|
||||
this.setBrandToAnimate();
|
||||
}, ToolboxHelper.randomInteger(4000, 8000));
|
||||
});
|
||||
},
|
||||
beforeUnmount() {
|
||||
this.tooltips?.closeBootstrapTooltip();
|
||||
clearTimeout(this.animateTimeout);
|
||||
},
|
||||
methods: {
|
||||
getContrastYIQ(hexcolor: string): string {
|
||||
return ToolboxHelper.getContrastYIQ(hexcolor);
|
||||
},
|
||||
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);
|
||||
},
|
||||
setBrandToAnimate(): void {
|
||||
clearTimeout(this.animateTimeout);
|
||||
this.animateIndex = ToolboxHelper.randomInteger(0, this.appState.brands().length -1);
|
||||
this.animateTimeout = setTimeout(this.setBrandToAnimate, ToolboxHelper.randomInteger(2000, 6000));
|
||||
},
|
||||
titleAnimations(brandIndex: number) {
|
||||
const animation = this.animations.at(ToolboxHelper.randomInteger(0, this.animations.length -1));
|
||||
const out: Map<string, boolean> = new Map<string, boolean>();
|
||||
out.set(`animate__${animation}`, this.animateIndex === brandIndex);
|
||||
return Object.fromEntries(out.entries());
|
||||
},
|
||||
gotoBrand(brand: TypeBrand) {
|
||||
useAppStore().setActiveBrand(brand);
|
||||
navigateTo(useLocaleRoute()({"name": "brands-slug", "params": {"slug": this.transField(brand, "slug")}}));
|
||||
}
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import "../assets/scss/variables";
|
||||
@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";
|
||||
|
||||
.page-home, .page-home>div {
|
||||
min-height: 100%;
|
||||
|
||||
.brand-picture-wrapper {
|
||||
@include rfs(5rem, border-radius);
|
||||
@include rfs(3rem, padding-top);
|
||||
@include rfs(3rem, padding-bottom);
|
||||
@include rfs(8rem, padding-right);
|
||||
@include rfs(8rem, padding-left);
|
||||
|
||||
background-color: $color-white;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
@ -1,32 +1,53 @@
|
|||
<template>
|
||||
<div class="page-home d-flex">
|
||||
<div class="container-fluid">
|
||||
<div :class="{'page-home d-flex': true, 'text-bg-light': multipleBrands}">
|
||||
<div class="container-fluid justify-content-center d-flex flex-column">
|
||||
<div v-if="multipleBrands" class="row">
|
||||
<div class="col-12 text-center overflow-hidden pb-5">
|
||||
<div class="home-title">
|
||||
{{ t('welcome_to_ldc') }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 text-center pb-5">
|
||||
<video
|
||||
class="object-fit-contain w-100"
|
||||
playsinline
|
||||
autoplay
|
||||
muted
|
||||
loop
|
||||
controls
|
||||
controlsList="nodownload noremoteplayback nofullscreen"
|
||||
>
|
||||
<source src="assets/videos/groupe-ldc-presentation-groupe-V7.webm" type="video/webm">
|
||||
<!-- <source src="assets/videos/groupe-ldc-presentation-groupe-V7.mp4" type="video/mp4"> -->
|
||||
</video>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="appState.brands" class="row h-100 align-items-center">
|
||||
<div
|
||||
v-for="(brand, brandIndex) of appState.brands()"
|
||||
:key="brandIndex"
|
||||
:class="{
|
||||
'align-items-center': true,
|
||||
'col-12': appState.brands().length == 1,
|
||||
'col-12 col-md-6 px-5 my-3': appState.brands().length > 1,
|
||||
'col-12': !multipleBrands,
|
||||
'col-12 col-md-6 px-5 my-3': multipleBrands,
|
||||
}"
|
||||
>
|
||||
<div
|
||||
:class="{
|
||||
'd-flex h-100 my-2': true,
|
||||
'justify-content-start': brandIndex %2 !== 0 && appState.brands().length > 1,
|
||||
'justify-content-end': brandIndex %2 === 0 && appState.brands().length > 1,
|
||||
'justify-content-center': appState.brands().length === 1,
|
||||
'justify-content-start': brandIndex %2 !== 0 && multipleBrands,
|
||||
'justify-content-end': brandIndex %2 === 0 && multipleBrands,
|
||||
'justify-content-center': !multipleBrands,
|
||||
}"
|
||||
>
|
||||
<div
|
||||
class="brand d-inline-block text-center shadow"
|
||||
class="d-inline-block text-center"
|
||||
role="button"
|
||||
:title="t('view_brand_ranges', {'brand_name': transField(brand, 'name')})"
|
||||
data-bs-toggle="tooltip"
|
||||
@click="gotoBrand(brand)"
|
||||
>
|
||||
<div class="d-inline-block brand-picture-wrapper">
|
||||
<div class="d-inline-block brand-picture-wrapper shadow">
|
||||
<img
|
||||
class="img-fluid"
|
||||
:src="`/data/${brand.picture}`"
|
||||
|
|
@ -53,6 +74,15 @@
|
|||
<span class="h4">{{ t('no_brands_available') }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="multipleBrands" class="row my-5 pb-5">
|
||||
<div class="col py-5 my-5 pb-5">
|
||||
<img
|
||||
src="assets/pictures/layout/home-bottom-banner.png"
|
||||
alt="Bottom Banner"
|
||||
class="img-fluid"
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
|
@ -72,18 +102,21 @@ export default defineComponent({
|
|||
animateIndex: number|null;
|
||||
animations: Array<string>;
|
||||
tooltips: Tooltips|null;
|
||||
multipleBrands: boolean;
|
||||
} {
|
||||
return {
|
||||
appState: {} as AppState,
|
||||
animateTimeout: undefined,
|
||||
animateIndex: null,
|
||||
animations: ["heartBeat", "tada", "shakeX", "rubberBand"],
|
||||
tooltips: null
|
||||
tooltips: null,
|
||||
multipleBrands: false,
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
this.$nextTick(() => {this.tooltips = Tooltips.make({type:"parent", parentSelector: ".page-home"});});
|
||||
this.appState = useAppStore().data;
|
||||
this.multipleBrands = this.appState.brands().length > 1;
|
||||
|
||||
// * ANIMATIONS
|
||||
clearTimeout(this.animateTimeout);
|
||||
|
|
@ -115,7 +148,7 @@ export default defineComponent({
|
|||
},
|
||||
setBrandToAnimate(): void {
|
||||
clearTimeout(this.animateTimeout);
|
||||
this.animateIndex = ToolboxHelper.randomInteger(0, this.appState.brands().length -1);
|
||||
this.animateIndex = ToolboxHelper.randomInteger(0, this.appState.brands().length - 1);
|
||||
this.animateTimeout = setTimeout(this.setBrandToAnimate, ToolboxHelper.randomInteger(2000, 6000));
|
||||
},
|
||||
titleAnimations(brandIndex: number) {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue