浏览代码

refactor CookieConsent

Olivier Massot 1 年之前
父节点
当前提交
99470a56a2
共有 6 个文件被更改,包括 372 次插入318 次删除
  1. 2 0
      assets/style/theme.scss
  2. 301 317
      components/Common/CookiesConsent.vue
  3. 1 1
      plugins/vue3-cookies.ts
  4. 57 0
      services/CookieManager.js
  5. 6 0
      types/enum/enums.ts
  6. 5 0
      types/interface.d.ts

+ 2 - 0
assets/style/theme.scss

@@ -37,6 +37,8 @@ body {
   --artist-color-light: #fef3ce;
   --school-color-light: #a5d4e5;
   --manager-color-light: #f7cdce;
+
+  --warning-color: #D8050B;
 }
 
 body {

+ 301 - 317
components/Common/CookiesConsent.vue

@@ -1,338 +1,310 @@
 <template>
-  <div v-if="showPopup || show" class="cookie-consent-banner">
-        <div class="continue-wrapper">
-          <a class="continue" href="#" @click.prevent="continueWithoutAccepting">
-            Continuer sans accepter
-          </a>
-          <v-icon size="20" class="fa-solid fa-arrow-right ml-6" @click="showPopup = false"></v-icon>
-        </div>
-    <v-row justify="center">
-      <v-col cols="12">
-        <img
-          src="/images/logos/cookies/A_cute_and_beautiful_illustration_of_a_cookie_list-removebg-preview.png"
-          alt="Cookie"
-          class="cookie-image"
-        />
-      </v-col>
-    </v-row>
-    <v-row no-gutters>
-      <v-col cols="12">
-        <div class="text">
-          <p>GESTION DES COOKIES ! !</p>
-        </div>
-      </v-col>
-    </v-row>
-    <p class="details-cookies" style="padding-left: 20px">
-      Le site Opentalent.fr utilise des cookies fonctionnels nécessaires à la
-      navigation du site et d'autres technologies similaire pour plusieurs
-      objectifs : des cookies d'analyse de l'audience du site, des cookies de
-      personnalisation de contenu et des cookies publicitaires. Pour plus de
-      détail, veuillez consulter notre
-      <NuxtLink to="/politique-de-confidentialite#cookie-policy">
-        Politique de confidentialité</NuxtLink
-      >. Vous pouvez ajuster vos préférences en matière de cookies à tout moment
-      en cliquant sur le bouton "Gérer mes préférences"
-    </p>
-    <div class="horizontal-line"></div>
-    <div class="actions">
-      <button class="customize-button" @click="customizeCookies">
-        Gérer mes préférences
-      </button>
-      <button class="accept-button" @click="acceptAllCookies">
-        Tout accepter
-      </button>
-      <!-- <button class="decline-button" @click="declineCookies">Refuser</button> -->
-    </div>
-  </div>
-  <v-dialog v-model="customizeDialog" persistent max-width="600px">
-    <v-card>
-      <v-row class="headline">
-        <v-btn class="close-dialog" icon @click="closeCustomizeDialog"
-          ><v-icon size="20" class="fas fa-times"></v-icon
-        ></v-btn>
-
-        <v-card-title>Gérer mes préferences</v-card-title>
+  <div v-if="showPopupStatus">
+    <div class="cookie-consent-banner">
+      <div class="continue-wrapper">
+        <a class="continue" href="#" @click.prevent="continueWithoutAccepting">
+          Continuer sans accepter
+        </a>
+        <v-icon
+          size="20"
+          class="fa-solid fa-arrow-right ml-6"
+          @click="showPopupStatus = false"
+        ></v-icon>
+      </div>
+      <v-row justify="center">
+        <v-col cols="12">
+          <img
+            src="/images/logos/cookies/A_cute_and_beautiful_illustration_of_a_cookie_list-removebg-preview.png"
+            alt="Cookie"
+            class="cookie-image"
+          />
+        </v-col>
       </v-row>
-
-      <p class="gestion-preferences">
-        Vous pouvez définir vos préférences sur la manière dont vous souhaitez
-        que vos données soient utilisées en fonction des finalités et des
-        entreprises tierces ci-dessous. Certains tiers peuvent traiter des
-        données sur la base d'un intérêt légitime et vous pouvez choisir de vous
-        désinscrire.
+      <v-row no-gutters>
+        <v-col cols="12">
+          <div class="text">
+            <p>GESTION DES COOKIES</p>
+          </div>
+        </v-col>
+      </v-row>
+      <p class="details-cookies" style="padding-left: 20px">
+        Le site Opentalent.fr utilise des cookies fonctionnels nécessaires à la
+        navigation du site et d'autres technologies similaire pour plusieurs
+        objectifs : des cookies d'analyse de l'audience du site, des cookies de
+        personnalisation de contenu et des cookies publicitaires. Pour plus de
+        détail, veuillez consulter notre
+        <NuxtLink to="/politique-de-confidentialite#cookie-policy">
+          Politique de confidentialité</NuxtLink
+        >. Vous pouvez ajuster vos préférences en matière de cookies à tout
+        moment en cliquant sur le bouton "Gérer mes préférences"
       </p>
-
-      <v-container class="text-end">
-        <button class="decline-button" @click="declineCookies">
-          Tout refuser
+      <div class="horizontal-line"></div>
+      <div class="actions">
+        <button
+          class="customize-button"
+          @click="showCustomizationOptions = true"
+        >
+          Gérer mes préférences
         </button>
         <button class="accept-button" @click="acceptAllCookies">
           Tout accepter
         </button>
-      </v-container>
-      <v-card-text>
-        <h4>Des cookies tiers permettant de réaliser des statistiques</h4>
-
-        <v-row align="center">
-          <v-col cols="auto">
-            <v-switch
-              v-model="tempCookiesOptions.googleAnalytics"
-              label="Google Analytics"
-              hide-details
-              color="green"
-              inset
-            />
-          </v-col>
-          <v-col></v-col>
-        </v-row>
-        <p>
-          Ces cookies nous permettent d'établir des statistiques, des volumes de
-          fréquentation et d'utilisation des divers éléments de notre site, nous
-          permettant d’optimiser son fonctionnement. Lien vers la Politique de
-          protection des données de Google Analytics :
-          <a href="https://policies.google.com/">
-            https://policies.google.com/</a
+        <!-- <button class="decline-button" @click="declineCookies">Refuser</button> -->
+      </div>
+    </div>
+    <v-dialog v-model="showCustomizationOptions" persistent max-width="600px">
+      <v-card>
+        <v-row class="headline">
+          <v-btn
+            class="close-dialog"
+            :icon="true"
+            @click="showCustomizationOptions = false"
           >
-        </p>
-        <h4 class="mt-6">Des cookies tiers à visée publicitaire</h4>
-
-        <v-row align="center">
-          <v-col cols="auto">
-            <v-switch
-              v-model="tempCookiesOptions.metaPixel"
-              label="Meta Pixel"
-              hide-details
-              color="green"
-              inset
-            />
-          </v-col>
-          <v-col></v-col>
+            <v-icon size="20" class="fas fa-times" />
+          </v-btn>
+
+          <v-card-title>Gérer mes préferences</v-card-title>
         </v-row>
-        <p>
-          Ces cookies sont installés par Facebook. Ce service nous permet
-          d'établir des statistiques de consultation des publicités. Lien vers
-          la Politique de protection des données de Facebook Pixel :
-          <a
-            href="https://www.facebook.com/privacy/policies/cookies/?entry_point=cookie_policy_redirect&entry=0"
-          >
-            https://www.facebook.com/privacy/policies/cookies/?entry_point=cookie_policy_redirect&entry=0
-          </a>
+
+        <p class="gestion-preferences">
+          Vous pouvez définir vos préférences sur la manière dont vous souhaitez
+          que vos données soient utilisées en fonction des finalités et des
+          entreprises tierces ci-dessous. Certains tiers peuvent traiter des
+          données sur la base d'un intérêt légitime et vous pouvez choisir de
+          vous désinscrire.
         </p>
-      </v-card-text>
-      <v-card-actions>
-        <v-btn color="secondary" @click="closeCustomizeDialog">Fermer</v-btn>
-        <v-spacer></v-spacer>
-        <button class="accept-button" @click="saveCookiesPreferences">
-          Sauvegarder
-        </button>
-      </v-card-actions>
-    </v-card>
-  </v-dialog>
-  <div v-if="showNotification" class="cookie-notification">
-    Vous avez refusé nos cookies. Vous pouvez modifier votre décision
-    <a href="#" @click="modifyDecision">ici</a>.
+
+        <v-container class="preferences-actions text-end">
+          <button class="decline-button" @click="declineCookies">
+            Tout refuser
+          </button>
+          <button class="accept-button" @click="acceptAllCookies">
+            Tout accepter
+          </button>
+        </v-container>
+
+        <v-card-text>
+          <h4>Des cookies tiers permettant de réaliser des statistiques</h4>
+
+          <v-row align="center">
+            <v-col cols="auto">
+              <v-switch
+                v-model="cookiesPreferences.allowGoogleAnalytics"
+                label="Google Analytics"
+                hide-details
+                color="green"
+                inset
+              />
+            </v-col>
+            <v-col>{{
+              cookiesPreferences.allowGoogleAnalytics
+                ? 'Autorisé'
+                : 'Non-autorisé'
+            }}</v-col>
+          </v-row>
+          <p>
+            Ces cookies nous permettent d'établir des statistiques, des volumes
+            de fréquentation et d'utilisation des divers éléments de notre site,
+            nous permettant d’optimiser son fonctionnement. Lien vers la
+            Politique de protection des données de Google Analytics :
+            <a href="https://policies.google.com/">
+              https://policies.google.com/</a
+            >
+          </p>
+          <h4 class="mt-6">Des cookies tiers à visée publicitaire</h4>
+
+          <v-row align="center">
+            <v-col cols="auto">
+              <v-switch
+                v-model="cookiesPreferences.allowMetaPixel"
+                label="Meta Pixel"
+                hide-details
+                color="green"
+                inset
+              />
+            </v-col>
+            <v-col>{{
+              cookiesPreferences.allowMetaPixel ? 'Autorisé' : 'Non-autorisé'
+            }}</v-col>
+          </v-row>
+          <p>
+            Ces cookies sont installés par Facebook. Ce service nous permet
+            d'établir des statistiques de consultation des publicités. Lien vers
+            la Politique de protection des données de Facebook Pixel :
+            <a
+              href="https://www.facebook.com/privacy/policies/cookies/?entry_point=cookie_policy_redirect&entry=0"
+            >
+              https://www.facebook.com/privacy/policies/cookies/?entry_point=cookie_policy_redirect&entry=0
+            </a>
+          </p>
+        </v-card-text>
+
+        <v-card-actions>
+          <v-btn color="secondary" @click="showCustomizationOptions = false">
+            Fermer
+          </v-btn>
+
+          <v-spacer />
+
+          <button class="accept-button" @click="saveCookiesPreferences">
+            Sauvegarder
+          </button>
+        </v-card-actions>
+      </v-card>
+    </v-dialog>
   </div>
+  <v-alert
+    v-model="showNotification"
+    title="Confirmation"
+    type="warning"
+    width="400"
+    closable
+    transition="fade-transition"
+    density="compact"
+    class="alert"
+  >
+    Vous avez refusé nos cookies. Si vous le souhaitez, vous pouvez encore
+    modifier votre décision en
+    <a href="#" @click="showPopup()">cliquant ici</a>.
+  </v-alert>
 </template>
 
 <script setup lang="ts">
-import { ref, onMounted, watch, defineProps } from 'vue'
+import { onMounted, type Ref, ref } from 'vue'
 import { useCookies } from 'vue3-cookies'
-import { useEventStore } from '~/stores/eventStore'
+import CookieManager from '~/services/CookieManager'
+import { COOKIE_CONSENT_CHOICE } from '~/types/enum/enums'
+import type { CookiesPreferences } from '~/types/interface'
 
 const { cookies } = useCookies()
-const showPopup = ref(false)
-const customizeDialog = ref(false)
+const showPopupStatus = ref(false)
+const showCustomizationOptions = ref(false)
 const showNotification = ref(false)
-const eventStore = useEventStore()
 
 /**
  * Cookies options
  */
-const cookiesOptions = ref({
-  googleAnalytics: true,
-  metaPixel: true,
-})
-
-/**
- * Temporary cookies options
- */
-const tempCookiesOptions = ref({
-  googleAnalytics: true,
-  metaPixel: true,
+const cookiesPreferences: Ref<CookiesPreferences> = ref({
+  allowGoogleAnalytics: true,
+  allowMetaPixel: true,
 })
 
-/**
- * Continue without accepting cookies
- */
-const continueWithoutAccepting = () => {
-  showPopup.value = false
-}
-
-/**
- * Accept all cookies
- */
-const acceptAllCookies = () => {
-  cookies.set('cookie_consent', 'accepted', '365d')
-  cookies.set('ga_consent', 'true', '365d')
-  cookies.set('mp_consent', 'true', '365d')
-  cookiesOptions.value.googleAnalytics = true
-  cookiesOptions.value.metaPixel = true
-  tempCookiesOptions.value.googleAnalytics = true
-  tempCookiesOptions.value.metaPixel = true
-  initializeAnalytics()
-  showPopup.value = false
-  customizeDialog.value = false
-}
-
-const removeCookie = (cookieName) => {
-  cookies.remove(cookieName)
+const showPopup = () => {
+  showPopupStatus.value = true
+  showCustomizationOptions.value = false
+  showNotification.value = false
 }
 
-const closeCustomizeDialog = () => {
-  customizeDialog.value = false
-  showPopup.value = true 
+const closePopup = () => {
+  showPopupStatus.value = false
 }
 
-const declineCookies = () => {
-  cookies.set('cookie_consent', 'declined', '7d')
-  cookies.set('ga_consent', 'false', '7d')
-  cookies.set('mp_consent', 'false', '7d')
-  showPopup.value = false
+const notify = () => {
   showNotification.value = true
-  customizeDialog.value = false
-  // Hide the notification after 1 minute
-  setTimeout(() => {
-    showNotification.value = false
-  }, 60000)
-}
 
-const customizeCookies = () => {
-  tempCookiesOptions.value = { ...cookiesOptions.value }
-  customizeDialog.value = true
-  showPopup.value = false
+  // Hide the notification after 1 minute
+  // setTimeout(() => {
+  //   showNotification.value = false
+  // }, 60000)
 }
 
-const saveCookiesPreferences = () => {
-  console.log('Saving cookies preferences')
-  cookies.set('cookie_consent', 'customized', '365d')
-  cookies.set(
-    'ga_consent',
-    tempCookiesOptions.value.googleAnalytics.toString(),
-    '365d',
-  )
-  cookies.set('mp_consent', tempCookiesOptions.value.metaPixel.toString(), '365d')
-
-  // Supprimer les cookies si les options sont désactivées
-  if (!tempCookiesOptions.value.googleAnalytics) {
-    removeCookie('ga_consent')
+const setupCookies = (
+  choice: COOKIE_CONSENT_CHOICE,
+  allowGoogleAnalytics: boolean,
+  allowMetaPixel: boolean,
+  duration: number = 365
+) => {
+  cookies.set('cookie_consent', choice, duration + 'd')
+
+  cookiesPreferences.value.allowGoogleAnalytics = allowGoogleAnalytics
+  cookies.set('ga_consent', allowGoogleAnalytics.toString(), duration + 'd')
+  if (allowGoogleAnalytics) {
+    CookieManager.makeGoogleAnalyticsCookies('UA-XXXXX-Y')
+  } else {
+    purgeGoogleCookies()
   }
-  if (!tempCookiesOptions.value.metaPixel) {
-    removeCookie('mp_consent')
+
+  cookiesPreferences.value.allowMetaPixel = allowMetaPixel
+  cookies.set('mp_consent', allowMetaPixel.toString(), duration + 'd')
+  if (allowMetaPixel) {
+    CookieManager.makeMetaPixelCookies('1045498113172655')
+  } else {
+    purgeMetaCookies()
   }
-  // Stocker la preuve de consentement
+
+  // Store consent date and status
   localStorage.setItem(
     'cookie_consent',
     JSON.stringify({
       date: new Date(),
-      consent: tempCookiesOptions.value,
-    }),
+      consent: { allowGoogleAnalytics, allowMetaPixel },
+    })
   )
+}
 
-  cookiesOptions.value = { ...tempCookiesOptions.value }
+const purgeGoogleCookies = () => {
+  cookies.remove('google') // TODO: complete
+}
 
-  if (cookiesOptions.value.googleAnalytics) initializeAnalytics()
-  customizeDialog.value = false
-  showPopup.value = false
+const purgeMetaCookies = () => {
+  cookies.remove('google') // TODO: complete
 }
 
 /**
- * Modify the decision
+ * Accept and setup all the cookies and close the popup
  */
-const modifyDecision = () => {
-  showNotification.value = false
-  showPopup.value = true
+const acceptAllCookies = () => {
+  setupCookies(COOKIE_CONSENT_CHOICE.ACCEPTED, true, true)
+  closePopup()
 }
 
 /**
- * Initialize Google Analytics and Meta Pixel
+ * Refuse all the cookies, set up the cookie_consent cookie and close the popup
  */
-const initializeAnalytics = () => {
-  if (cookiesOptions.value.googleAnalytics) {
-    // Load Google Analytics script
-    ;(function (i, s, o, g, r, a, m) {
-      i['GoogleAnalyticsObject'] = r
-      ;(i[r] =
-        i[r] ||
-        function () {
-          ;(i[r].q = i[r].q || []).push(arguments)
-        }),
-        (i[r].l = 1 * new Date())
-      ;(a = s.createElement(o)), (m = s.getElementsByTagName(o)[0])
-      a.async = 1
-      a.src = g
-      m.parentNode.insertBefore(a, m)
-    })(
-      window,
-      document,
-      'script',
-      'https://www.googletagmanager.com/gtag/js?id=G-L8PZ9TEFNX',
-      'ga',
-    )
-
-    ga('create', 'UA-XXXXX-Y', 'auto')
-    ga('send', 'pageview')
-  }
-  if (cookiesOptions.value.metaPixel) {
-    // Load Meta Pixel script
-    !(function (f, b, e, v, n, t, s) {
-      if (f.fbq) return
-      n = f.fbq = function () {
-        n.callMethod
-          ? n.callMethod.apply(n, arguments)
-          : n.queue.push(arguments)
-      }
-      if (!f._fbq) f._fbq = n
-      n.push = n
-      n.loaded = !0
-      n.version = '2.0'
-      n.queue = []
-      t = b.createElement(e)
-      t.async = !0
-      t.src = v
-      s = b.getElementsByTagName(e)[0]
-      s.parentNode.insertBefore(t, s)
-    })(
-      window,
-      document,
-      'script',
-      'https://connect.facebook.net/en_US/fbevents.js',
-    )
-    fbq('init', '1045498113172655')
-    fbq('track', 'PageView')
-  }
+const declineCookies = () => {
+  setupCookies(COOKIE_CONSENT_CHOICE.DECLINED, false, false, 7)
+  notify()
+  closePopup()
+}
+
+/**
+ * Set up the cookies following user preferences and close the popup
+ */
+const saveCookiesPreferences = () => {
+  setupCookies(
+    COOKIE_CONSENT_CHOICE.CUSTOMIZED,
+    cookiesPreferences.value.allowGoogleAnalytics,
+    cookiesPreferences.value.allowMetaPixel
+  )
+  closePopup()
 }
 
 /**
- * Check if the user has already accepted the cookies
+ * Continue without accepting cookies
+ */
+const continueWithoutAccepting = () => {
+  closePopup()
+}
+
+const loadActivePreferences = () => {
+  cookiesPreferences.value.allowGoogleAnalytics =
+    cookies.get('ga_consent') === 'true'
+  cookiesPreferences.value.allowMetaPixel = cookies.get('mp_consent') === 'true'
+}
+
+/**
+ * Check if the user has already accepted the cookies when page is mounted
  */
 onMounted(() => {
   const cookieConsent = cookies.get('cookie_consent')
   if (!cookieConsent) {
-    showPopup.value = true
+    showPopup()
   }
-  const gaConsent = cookies.get('ga_consent')
-  const mpConsent = cookies.get('mp_consent')
-  if (gaConsent !== undefined)
-    cookiesOptions.value.googleAnalytics = gaConsent === 'false'
-  if (mpConsent !== undefined)
-    cookiesOptions.value.metaPixel = mpConsent === 'false'
-
-    eventStore.on('openCustomizeDialog', customizeCookies)
+  loadActivePreferences()
 })
-
 </script>
 
-<style scoped>
+<style scoped lang="scss">
 .gestion-preferences {
   font-size: 1.2rem;
   font-weight: 500;
@@ -341,17 +313,22 @@ onMounted(() => {
   text-align: justify;
 }
 
+.preferences-actions {
+  overflow: visible;
+}
+
 .headline {
   font-size: 1.5rem;
   font-weight: 500;
-  margin-bottom: 10px;
-  background-color: #9edbdd;
+  margin: 0 0 10px 0;
+  background-color: var(--secondary-color);
+  color: var(--on-secondary-color);
   text-transform: uppercase;
   padding: 15px;
 }
+
 .cookie-consent-banner {
-  background: #fff;
-  box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
+  background: var(--neutral-color);
   position: fixed;
   bottom: 10px;
   left: 15px;
@@ -373,23 +350,20 @@ onMounted(() => {
 .text {
   padding-top: 10px;
   padding-bottom: 0;
-  font-family: 'Barlow';
   font-weight: 600;
   font-size: 1.3rem;
   text-align: center;
 }
 
 .details-cookies {
-  font-family: 'Barlow';
   padding: 10px;
-  text-align: center;
   text-align: justify;
 }
 
 .horizontal-line {
   width: 90%;
   height: 1px;
-  background-color: #7e7d7d;
+  background-color: var(--neutral-color-alt-strong);
   margin-top: 10px;
   margin-bottom: 10px;
 }
@@ -422,30 +396,19 @@ onMounted(() => {
   background-color: var(--on-primary-color-alt);
 }
 
-.cookie-notification {
-  position: fixed;
-  bottom: 20px;
-  left: 20px;
-  background-color: rgba(0, 0, 0, 0.8);
-  color: white;
-  padding: 15px;
-  border-radius: 5px;
-  z-index: 1100;
-}
-
 .cookie-description {
   margin: 0;
   font-size: 0.875rem;
-  color: #555;
+  color: var(--on-neutral-color-light);
 }
 
 .custom-switch .v-input--selection-controls__ripple .v-ripple__container {
-  background-color: var(--v-primary-base);
+  background-color: var(--v-primary-color);
 }
 
-.custom-switch
-  .v-input--selection-controls__ripple--active
-  .v-ripple__container {
+.custom-switch,
+.v-input--selection-controls__ripple--active,
+.v-ripple__container {
   background-color: var(--v-primary-darken4);
 }
 
@@ -455,44 +418,65 @@ onMounted(() => {
   --v-theme-primary-darken4: var(--v-primary-darken4);
 }
 
-.custom-switch
-  .v-input--selection-controls__input
-  input:checked
-  + .v-input--selection-controls__ripple
-  .v-ripple__container {
+.custom-switch,
+.v-input--selection-controls__input,
+input:checked,
++ .v-input--selection-controls__ripple,
+.v-ripple__container {
   background-color: var(--v-primary-darken4);
 }
 
-.custom-switch
-  .v-input--selection-controls__input
-  input:checked
-  + .v-input--selection-controls__ripple
-  .v-ripple__container
-  .v-ripple__animation {
+.custom-switch,
+.v-input--selection-controls__input,
+input:checked,
++ .v-input--selection-controls__ripple,
+.v-ripple__container,
+.v-ripple__animation {
   background-color: var(--v-primary-darken4);
 }
 
-:deep().v-switch__track {
-  background-color: red;
+:deep(.v-switch__track) {
+  background-color: var(--warning-color);
 }
 
 .close-dialog {
   background: none !important;
   box-shadow: none !important;
 }
-.continue{
-  font-size: .9rem;
+
+.continue {
+  font-size: 0.9rem;
   font-weight: 500;
-  text-decoration: underline;
   cursor: pointer;
   text-decoration: none !important;
-  color: black ;
+  color: var(--on-neutral-color);
 }
 
-.continue-wrapper{
+.continue-wrapper {
   display: flex;
   justify-content: end;
   align-items: center;
   margin-left: auto;
 }
+
+:deep(.v-switch .v-label) {
+  opacity: 0.8;
+}
+
+.alert {
+  position: fixed;
+  bottom: 20px;
+  right: 20px;
+  z-index: 1000;
+
+  a {
+    color: var(--on-primary-color);
+    font-weight: 700;
+    text-decoration: none;
+  }
+
+  a:hover {
+    text-decoration: underline;
+  }
+}
 </style>

+ 1 - 1
plugins/vue3-cookies.js → plugins/vue3-cookies.ts

@@ -1,5 +1,5 @@
 import { defineNuxtPlugin } from '#app'
-import  VueCookies  from 'vue3-cookies'
+import VueCookies from 'vue3-cookies'
 
 export default defineNuxtPlugin((nuxtApp) => {
   nuxtApp.vueApp.use(VueCookies)

+ 57 - 0
services/CookieManager.js

@@ -0,0 +1,57 @@
+// Load Google Analytics script
+
+export default class CookieManager {
+  static makeGoogleAnalyticsCookies(id) {
+    ;(function (i, s, o, g, r, a, m) {
+      i.GoogleAnalyticsObject = r
+      ;(i[r] =
+        i[r] ||
+        function () {
+          ;(i[r].q = i[r].q || []).push(arguments)
+        }),
+        (i[r].l = 1 * new Date())
+      ;(a = s.createElement(o)), (m = s.getElementsByTagName(o)[0])
+      a.async = 1
+      a.src = g
+      m.parentNode.insertBefore(a, m)
+    })(
+      window,
+      document,
+      'script',
+      'https://www.googletagmanager.com/gtag/js?id=G-L8PZ9TEFNX',
+      'ga'
+    )
+
+    ga('create', id, 'auto')
+    ga('send', 'pageview')
+  }
+
+  static makeMetaPixelCookies(id) {
+    // Load Meta Pixel script
+    !(function (f, b, e, v, n, t, s) {
+      if (f.fbq) return
+      n = f.fbq = function () {
+        n.callMethod
+          ? n.callMethod.apply(n, arguments)
+          : n.queue.push(arguments)
+      }
+      if (!f._fbq) f._fbq = n
+      n.push = n
+      n.loaded = !0
+      n.version = '2.0'
+      n.queue = []
+      t = b.createElement(e)
+      t.async = !0
+      t.src = v
+      s = b.getElementsByTagName(e)[0]
+      s.parentNode.insertBefore(t, s)
+    })(
+      window,
+      document,
+      'script',
+      'https://connect.facebook.net/en_US/fbevents.js'
+    )
+    fbq('init', id)
+    fbq('track', 'PageView')
+  }
+}

+ 6 - 0
types/enum/enums.ts

@@ -28,3 +28,9 @@ export const enum QUERY_TYPE {
   IMAGE,
   FILE,
 }
+
+export const enum COOKIE_CONSENT_CHOICE {
+  ACCEPTED = 'accepted',
+  DECLINED = 'declined',
+  CUSTOMIZED = 'customized',
+}

+ 5 - 0
types/interface.d.ts

@@ -164,3 +164,8 @@ interface ContactFormData {
   concernedProduct: string | null
   newsletterSubscription: boolean
 }
+
+interface CookiesPreferences {
+  allowGoogleAnalytics: boolean,
+  allowMetaPixel: boolean
+}