159 lines
5.4 KiB
Vue
159 lines
5.4 KiB
Vue
<template>
|
|
<div class="page-home d-flex">
|
|
<div class="container-fluid">
|
|
<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,
|
|
}"
|
|
>
|
|
<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,
|
|
}"
|
|
>
|
|
<div
|
|
class="brand d-inline-block text-center shadow"
|
|
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>
|
|
</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;
|
|
}
|
|
.brand {
|
|
border-radius: 2rem;
|
|
}
|
|
}
|
|
</style>
|