|
|
@@ -1,29 +1,36 @@
|
|
|
+<!--
|
|
|
+Menu d'actions rapides (appel, contact, ...), qui reste accroché au bord droit
|
|
|
+de l'écran (ou au bas de l'écran sur les petits écrans)
|
|
|
+-->
|
|
|
+
|
|
|
<template>
|
|
|
- <div class="sticky-menu">
|
|
|
- <div class="container-square" v-if="lgAndUp">
|
|
|
- <v-row
|
|
|
- v-for="(action, index) in actionsOrDefault"
|
|
|
- :key="index"
|
|
|
- :class="['square', action.bgColor]"
|
|
|
- @click="() => onActionClick(action)"
|
|
|
- >
|
|
|
- <NuxtLink :to="action.url" class="link">
|
|
|
- <div>
|
|
|
- <v-icon :class="action.iconClass" />
|
|
|
- <p class="text-square mt-2">{{ action.text }}</p>
|
|
|
- </div>
|
|
|
- </NuxtLink>
|
|
|
- </v-row>
|
|
|
- </div>
|
|
|
-
|
|
|
- <div class="band" v-else-if="!layoutStore.isFooterVisible">
|
|
|
- <v-btn color="#9edbdd">
|
|
|
- Nous contacter
|
|
|
- </v-btn>
|
|
|
- <v-btn color="#0e2d32" style="color: white;">
|
|
|
- Nous appeler
|
|
|
- </v-btn>
|
|
|
- </div>
|
|
|
+ <!-- Écrans larges : menu lateral -->
|
|
|
+ <div class="sticky-menu lateral" v-if="lgAndUp">
|
|
|
+ <v-row
|
|
|
+ v-for="(action, index) in actionsOrDefault"
|
|
|
+ :key="index"
|
|
|
+ :class="['square', action.bgColor]"
|
|
|
+ @click="() => onActionClick(action)"
|
|
|
+ >
|
|
|
+ <NuxtLink :to="action.url" class="link">
|
|
|
+ <div>
|
|
|
+ <v-icon :class="action.iconClass" />
|
|
|
+ <p class="text-square mt-2">{{ action.text }}</p>
|
|
|
+ </div>
|
|
|
+ </NuxtLink>
|
|
|
+ </v-row>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <!-- Petits : menu sous forme de bandeau en pied de page (sauf si le footer du site est visible) -->
|
|
|
+ <div class="sticky-menu band" v-else-if="!layoutStore.isFooterVisible">
|
|
|
+ <v-btn
|
|
|
+ v-for="(action, index) in actionsOrDefault"
|
|
|
+ :key="index"
|
|
|
+ :class="[action.bgColor]"
|
|
|
+ @click="() => onActionClick(action)"
|
|
|
+ >
|
|
|
+ {{ action.text }}
|
|
|
+ </v-btn>
|
|
|
</div>
|
|
|
</template>
|
|
|
|
|
|
@@ -38,9 +45,12 @@ import { StickyMenuAction } from "~/types/interface";
|
|
|
const { mdAndDown, lgAndUp } = useDisplay();
|
|
|
const router = useRouter();
|
|
|
const layoutStore = useLayoutStore()
|
|
|
+const { isMobileDevice } = useClientDevice()
|
|
|
|
|
|
+// TODO: passer en conf?
|
|
|
const telephoneNumber = "09 72 12 60 17";
|
|
|
|
|
|
+// Actions par défaut du menu, peut-être surchargé via la propriété `actions`
|
|
|
const defaultActions: Array<StickyMenuAction> = [
|
|
|
{
|
|
|
type: StickyMenuActionType.FOLLOW_LINK,
|
|
|
@@ -58,6 +68,9 @@ const defaultActions: Array<StickyMenuAction> = [
|
|
|
];
|
|
|
|
|
|
const props = defineProps({
|
|
|
+ /**
|
|
|
+ * Actions accessibles via le menu (par défaut: "Nous contacter", "Nous appeller")
|
|
|
+ */
|
|
|
actions: {
|
|
|
type: Array<StickyMenuAction>,
|
|
|
required: false,
|
|
|
@@ -69,45 +82,57 @@ const actionsOrDefault: ComputedRef<Array<StickyMenuAction>> = computed(() => {
|
|
|
return props.actions.length > 0 ? props.actions : defaultActions
|
|
|
})
|
|
|
|
|
|
-const onActionClick = (action: StickyMenuAction) => {
|
|
|
- if (action.type === StickyMenuActionType.ASK_FOR_A_DEMO) {
|
|
|
- router.push({ path: action.url, query: { request: "demo" } });
|
|
|
- } else if (action.type === StickyMenuActionType.CALL_US) {
|
|
|
- if (isMobileDevice()) {
|
|
|
- window.location.href = `tel:${telephoneNumber}`;
|
|
|
- } else {
|
|
|
- alert(`Notre numéro de téléphone : ${telephoneNumber}`);
|
|
|
- }
|
|
|
- } else if (action.url) {
|
|
|
- router.push({ path: action.url });
|
|
|
+const callUs = () => {
|
|
|
+ if (isMobileDevice()) {
|
|
|
+ window.location.href = `tel:${telephoneNumber}`;
|
|
|
} else {
|
|
|
- throw Error('Unrecognized action')
|
|
|
+ alert(`Notre numéro de téléphone : ${telephoneNumber}`);
|
|
|
}
|
|
|
-};
|
|
|
+}
|
|
|
|
|
|
-const isMobileDevice = () => {
|
|
|
- return /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(
|
|
|
- navigator.userAgent
|
|
|
- );
|
|
|
+/**
|
|
|
+ * On a cliqué sur une des actions du menu
|
|
|
+ * @param action
|
|
|
+ */
|
|
|
+const onActionClick = (action: StickyMenuAction) => {
|
|
|
+ switch (action.type) {
|
|
|
+ case StickyMenuActionType.ASK_FOR_A_DEMO:
|
|
|
+ router.push({ path: action.url, query: { request: "demo" } });
|
|
|
+ break;
|
|
|
+
|
|
|
+ case StickyMenuActionType.CALL_US:
|
|
|
+ callUs()
|
|
|
+ break;
|
|
|
+
|
|
|
+ case StickyMenuActionType.FOLLOW_LINK:
|
|
|
+ if (!action.url) {
|
|
|
+ throw Error('Missing prop : url')
|
|
|
+ }
|
|
|
+ router.push({ path: action.url });
|
|
|
+ break
|
|
|
+
|
|
|
+ default:
|
|
|
+ throw Error('Unrecognized action')
|
|
|
+ }
|
|
|
};
|
|
|
+
|
|
|
+
|
|
|
</script>
|
|
|
|
|
|
<style scoped lang="scss">
|
|
|
-.square {
|
|
|
- transition: transform 0.3s ease-in-out;
|
|
|
-}
|
|
|
|
|
|
-.square:hover {
|
|
|
- transform: translateX(-10px);
|
|
|
+.sticky-menu {
|
|
|
+ z-index: 100;
|
|
|
}
|
|
|
|
|
|
-.link {
|
|
|
- text-decoration: none;
|
|
|
- color: white;
|
|
|
-}
|
|
|
+// Menu format lateral (pour affichage écrans larges)
|
|
|
+.sticky-menu.lateral {
|
|
|
+ position: sticky;
|
|
|
+ right: 0;
|
|
|
+ top: 50%;
|
|
|
+ transform: translateY(-50%);
|
|
|
+ float: right;
|
|
|
|
|
|
-.container-square {
|
|
|
- text-align: center !important;
|
|
|
display: flex;
|
|
|
flex-direction: column;
|
|
|
color: white;
|
|
|
@@ -119,16 +144,38 @@ const isMobileDevice = () => {
|
|
|
text-transform: uppercase;
|
|
|
}
|
|
|
|
|
|
-.red-square,
|
|
|
-.yellow-square,
|
|
|
-.blue-square,
|
|
|
-.darkblue-square,
|
|
|
-.green-square {
|
|
|
+// Menu format ruban (pour affichage petits écrans)
|
|
|
+.sticky-menu.band {
|
|
|
+ position: fixed;
|
|
|
+ height: 46px;
|
|
|
+ bottom: 0;
|
|
|
+ width: 100%;
|
|
|
+ display: flex;
|
|
|
+ justify-content: center;
|
|
|
+ background-color: white;
|
|
|
+
|
|
|
+ .v-btn {
|
|
|
+ margin: 4px 6px;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+.square {
|
|
|
position: relative;
|
|
|
- font-family: "Barlow";
|
|
|
+ font-family: "Barlow", serif;
|
|
|
width: 7rem;
|
|
|
padding: 1rem;
|
|
|
cursor: pointer;
|
|
|
+
|
|
|
+ transition: transform 0.3s ease-in-out;
|
|
|
+}
|
|
|
+
|
|
|
+.square:hover {
|
|
|
+ transform: translateX(-10px);
|
|
|
+}
|
|
|
+
|
|
|
+.link {
|
|
|
+ text-decoration: none;
|
|
|
+ color: white;
|
|
|
}
|
|
|
|
|
|
.yellow-square {
|
|
|
@@ -151,34 +198,4 @@ const isMobileDevice = () => {
|
|
|
.darkblue-square {
|
|
|
background: #0e2d32;
|
|
|
}
|
|
|
-
|
|
|
-.text-square {
|
|
|
-}
|
|
|
-
|
|
|
-@media (min-width: 1280px) {
|
|
|
- .sticky-menu {
|
|
|
- position: sticky;
|
|
|
- //right: 0;
|
|
|
- top: 50%;
|
|
|
- transform: translateY(-50%);
|
|
|
- z-index: 1;
|
|
|
- float: right;
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-// Menu format ruban (pour affichage petits écrans)
|
|
|
-.sticky-menu .band {
|
|
|
- position: fixed;
|
|
|
- height: 46px;
|
|
|
- bottom: 0;
|
|
|
- width: 100%;
|
|
|
- display: flex;
|
|
|
- justify-content: center;
|
|
|
- background-color: white;
|
|
|
- z-index: 100;
|
|
|
-
|
|
|
- .v-btn {
|
|
|
- margin: 4px 6px;
|
|
|
- }
|
|
|
-}
|
|
|
</style>
|