CookiesConsent.vue 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498
  1. <template>
  2. <div v-if="showPopup || show" class="cookie-consent-banner">
  3. <div class="continue-wrapper">
  4. <a class="continue" href="#" @click.prevent="continueWithoutAccepting">
  5. Continuer sans accepter
  6. </a>
  7. <v-icon size="20" class="fa-solid fa-arrow-right ml-6" @click="showPopup = false"></v-icon>
  8. </div>
  9. <v-row justify="center">
  10. <v-col cols="12">
  11. <img
  12. src="/images/logos/cookies/A_cute_and_beautiful_illustration_of_a_cookie_list-removebg-preview.png"
  13. alt="Cookie"
  14. class="cookie-image"
  15. />
  16. </v-col>
  17. </v-row>
  18. <v-row no-gutters>
  19. <v-col cols="12">
  20. <div class="text">
  21. <p>GESTION DES COOKIES ! !</p>
  22. </div>
  23. </v-col>
  24. </v-row>
  25. <p class="details-cookies" style="padding-left: 20px">
  26. Le site Opentalent.fr utilise des cookies fonctionnels nécessaires à la
  27. navigation du site et d'autres technologies similaire pour plusieurs
  28. objectifs : des cookies d'analyse de l'audience du site, des cookies de
  29. personnalisation de contenu et des cookies publicitaires. Pour plus de
  30. détail, veuillez consulter notre
  31. <NuxtLink to="/politique-de-confidentialite#cookie-policy">
  32. Politique de confidentialité</NuxtLink
  33. >. Vous pouvez ajuster vos préférences en matière de cookies à tout moment
  34. en cliquant sur le bouton "Gérer mes préférences"
  35. </p>
  36. <div class="horizontal-line"></div>
  37. <div class="actions">
  38. <button class="customize-button" @click="customizeCookies">
  39. Gérer mes préférences
  40. </button>
  41. <button class="accept-button" @click="acceptAllCookies">
  42. Tout accepter
  43. </button>
  44. <!-- <button class="decline-button" @click="declineCookies">Refuser</button> -->
  45. </div>
  46. </div>
  47. <v-dialog v-model="customizeDialog" persistent max-width="600px">
  48. <v-card>
  49. <v-row class="headline">
  50. <v-btn class="close-dialog" icon @click="closeCustomizeDialog"
  51. ><v-icon size="20" class="fas fa-times"></v-icon
  52. ></v-btn>
  53. <v-card-title>Gérer mes préferences</v-card-title>
  54. </v-row>
  55. <p class="gestion-preferences">
  56. Vous pouvez définir vos préférences sur la manière dont vous souhaitez
  57. que vos données soient utilisées en fonction des finalités et des
  58. entreprises tierces ci-dessous. Certains tiers peuvent traiter des
  59. données sur la base d'un intérêt légitime et vous pouvez choisir de vous
  60. désinscrire.
  61. </p>
  62. <v-container class="text-end">
  63. <button class="decline-button" @click="declineCookies">
  64. Tout refuser
  65. </button>
  66. <button class="accept-button" @click="acceptAllCookies">
  67. Tout accepter
  68. </button>
  69. </v-container>
  70. <v-card-text>
  71. <h4>Des cookies tiers permettant de réaliser des statistiques</h4>
  72. <v-row align="center">
  73. <v-col cols="auto">
  74. <v-switch
  75. v-model="tempCookiesOptions.googleAnalytics"
  76. label="Google Analytics"
  77. hide-details
  78. color="green"
  79. inset
  80. />
  81. </v-col>
  82. <v-col></v-col>
  83. </v-row>
  84. <p>
  85. Ces cookies nous permettent d'établir des statistiques, des volumes de
  86. fréquentation et d'utilisation des divers éléments de notre site, nous
  87. permettant d’optimiser son fonctionnement. Lien vers la Politique de
  88. protection des données de Google Analytics :
  89. <a href="https://policies.google.com/">
  90. https://policies.google.com/</a
  91. >
  92. </p>
  93. <h4 class="mt-6">Des cookies tiers à visée publicitaire</h4>
  94. <v-row align="center">
  95. <v-col cols="auto">
  96. <v-switch
  97. v-model="tempCookiesOptions.metaPixel"
  98. label="Meta Pixel"
  99. hide-details
  100. color="green"
  101. inset
  102. />
  103. </v-col>
  104. <v-col></v-col>
  105. </v-row>
  106. <p>
  107. Ces cookies sont installés par Facebook. Ce service nous permet
  108. d'établir des statistiques de consultation des publicités. Lien vers
  109. la Politique de protection des données de Facebook Pixel :
  110. <a
  111. href="https://www.facebook.com/privacy/policies/cookies/?entry_point=cookie_policy_redirect&entry=0"
  112. >
  113. https://www.facebook.com/privacy/policies/cookies/?entry_point=cookie_policy_redirect&entry=0
  114. </a>
  115. </p>
  116. </v-card-text>
  117. <v-card-actions>
  118. <v-btn color="secondary" @click="closeCustomizeDialog">Fermer</v-btn>
  119. <v-spacer></v-spacer>
  120. <button class="accept-button" @click="saveCookiesPreferences">
  121. Sauvegarder
  122. </button>
  123. </v-card-actions>
  124. </v-card>
  125. </v-dialog>
  126. <div v-if="showNotification" class="cookie-notification">
  127. Vous avez refusé nos cookies. Vous pouvez modifier votre décision
  128. <a href="#" @click="modifyDecision">ici</a>.
  129. </div>
  130. </template>
  131. <script setup lang="ts">
  132. import { ref, onMounted, watch, defineProps } from 'vue'
  133. import { useCookies } from 'vue3-cookies'
  134. import { useEventStore } from '~/stores/eventStore'
  135. const { cookies } = useCookies()
  136. const showPopup = ref(false)
  137. const customizeDialog = ref(false)
  138. const showNotification = ref(false)
  139. const eventStore = useEventStore()
  140. /**
  141. * Cookies options
  142. */
  143. const cookiesOptions = ref({
  144. googleAnalytics: true,
  145. metaPixel: true,
  146. })
  147. /**
  148. * Temporary cookies options
  149. */
  150. const tempCookiesOptions = ref({
  151. googleAnalytics: true,
  152. metaPixel: true,
  153. })
  154. /**
  155. * Continue without accepting cookies
  156. */
  157. const continueWithoutAccepting = () => {
  158. showPopup.value = false
  159. }
  160. /**
  161. * Accept all cookies
  162. */
  163. const acceptAllCookies = () => {
  164. cookies.set('cookie_consent', 'accepted', '365d')
  165. cookies.set('ga_consent', 'true', '365d')
  166. cookies.set('mp_consent', 'true', '365d')
  167. cookiesOptions.value.googleAnalytics = true
  168. cookiesOptions.value.metaPixel = true
  169. tempCookiesOptions.value.googleAnalytics = true
  170. tempCookiesOptions.value.metaPixel = true
  171. initializeAnalytics()
  172. showPopup.value = false
  173. customizeDialog.value = false
  174. }
  175. const removeCookie = (cookieName) => {
  176. cookies.remove(cookieName)
  177. }
  178. const closeCustomizeDialog = () => {
  179. customizeDialog.value = false
  180. showPopup.value = true
  181. }
  182. const declineCookies = () => {
  183. cookies.set('cookie_consent', 'declined', '7d')
  184. cookies.set('ga_consent', 'false', '7d')
  185. cookies.set('mp_consent', 'false', '7d')
  186. showPopup.value = false
  187. showNotification.value = true
  188. customizeDialog.value = false
  189. // Hide the notification after 1 minute
  190. setTimeout(() => {
  191. showNotification.value = false
  192. }, 60000)
  193. }
  194. const customizeCookies = () => {
  195. tempCookiesOptions.value = { ...cookiesOptions.value }
  196. customizeDialog.value = true
  197. showPopup.value = false
  198. }
  199. const saveCookiesPreferences = () => {
  200. console.log('Saving cookies preferences')
  201. cookies.set('cookie_consent', 'customized', '365d')
  202. cookies.set(
  203. 'ga_consent',
  204. tempCookiesOptions.value.googleAnalytics.toString(),
  205. '365d',
  206. )
  207. cookies.set('mp_consent', tempCookiesOptions.value.metaPixel.toString(), '365d')
  208. // Supprimer les cookies si les options sont désactivées
  209. if (!tempCookiesOptions.value.googleAnalytics) {
  210. removeCookie('ga_consent')
  211. }
  212. if (!tempCookiesOptions.value.metaPixel) {
  213. removeCookie('mp_consent')
  214. }
  215. // Stocker la preuve de consentement
  216. localStorage.setItem(
  217. 'cookie_consent',
  218. JSON.stringify({
  219. date: new Date(),
  220. consent: tempCookiesOptions.value,
  221. }),
  222. )
  223. cookiesOptions.value = { ...tempCookiesOptions.value }
  224. if (cookiesOptions.value.googleAnalytics) initializeAnalytics()
  225. customizeDialog.value = false
  226. showPopup.value = false
  227. }
  228. /**
  229. * Modify the decision
  230. */
  231. const modifyDecision = () => {
  232. showNotification.value = false
  233. showPopup.value = true
  234. }
  235. /**
  236. * Initialize Google Analytics and Meta Pixel
  237. */
  238. const initializeAnalytics = () => {
  239. if (cookiesOptions.value.googleAnalytics) {
  240. // Load Google Analytics script
  241. ;(function (i, s, o, g, r, a, m) {
  242. i['GoogleAnalyticsObject'] = r
  243. ;(i[r] =
  244. i[r] ||
  245. function () {
  246. ;(i[r].q = i[r].q || []).push(arguments)
  247. }),
  248. (i[r].l = 1 * new Date())
  249. ;(a = s.createElement(o)), (m = s.getElementsByTagName(o)[0])
  250. a.async = 1
  251. a.src = g
  252. m.parentNode.insertBefore(a, m)
  253. })(
  254. window,
  255. document,
  256. 'script',
  257. 'https://www.googletagmanager.com/gtag/js?id=G-L8PZ9TEFNX',
  258. 'ga',
  259. )
  260. ga('create', 'UA-XXXXX-Y', 'auto')
  261. ga('send', 'pageview')
  262. }
  263. if (cookiesOptions.value.metaPixel) {
  264. // Load Meta Pixel script
  265. !(function (f, b, e, v, n, t, s) {
  266. if (f.fbq) return
  267. n = f.fbq = function () {
  268. n.callMethod
  269. ? n.callMethod.apply(n, arguments)
  270. : n.queue.push(arguments)
  271. }
  272. if (!f._fbq) f._fbq = n
  273. n.push = n
  274. n.loaded = !0
  275. n.version = '2.0'
  276. n.queue = []
  277. t = b.createElement(e)
  278. t.async = !0
  279. t.src = v
  280. s = b.getElementsByTagName(e)[0]
  281. s.parentNode.insertBefore(t, s)
  282. })(
  283. window,
  284. document,
  285. 'script',
  286. 'https://connect.facebook.net/en_US/fbevents.js',
  287. )
  288. fbq('init', '1045498113172655')
  289. fbq('track', 'PageView')
  290. }
  291. }
  292. /**
  293. * Check if the user has already accepted the cookies
  294. */
  295. onMounted(() => {
  296. const cookieConsent = cookies.get('cookie_consent')
  297. if (!cookieConsent) {
  298. showPopup.value = true
  299. }
  300. const gaConsent = cookies.get('ga_consent')
  301. const mpConsent = cookies.get('mp_consent')
  302. if (gaConsent !== undefined)
  303. cookiesOptions.value.googleAnalytics = gaConsent === 'false'
  304. if (mpConsent !== undefined)
  305. cookiesOptions.value.metaPixel = mpConsent === 'false'
  306. eventStore.on('openCustomizeDialog', customizeCookies)
  307. })
  308. </script>
  309. <style scoped>
  310. .gestion-preferences {
  311. font-size: 1.2rem;
  312. font-weight: 500;
  313. margin-bottom: 10px;
  314. padding: 20px;
  315. text-align: justify;
  316. }
  317. .headline {
  318. font-size: 1.5rem;
  319. font-weight: 500;
  320. margin-bottom: 10px;
  321. background-color: #9edbdd;
  322. text-transform: uppercase;
  323. padding: 15px;
  324. }
  325. .cookie-consent-banner {
  326. background: #fff;
  327. box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
  328. position: fixed;
  329. bottom: 10px;
  330. left: 15px;
  331. max-width: 550px;
  332. z-index: 1000 !important;
  333. display: flex;
  334. flex-direction: column;
  335. align-items: center;
  336. box-shadow: 0 0 10px rgba(0, 0, 0, 0.3);
  337. border-radius: 15px;
  338. padding: 20px;
  339. }
  340. .cookie-image {
  341. width: 150px;
  342. margin: 0;
  343. }
  344. .text {
  345. padding-top: 10px;
  346. padding-bottom: 0;
  347. font-family: 'Barlow';
  348. font-weight: 600;
  349. font-size: 1.3rem;
  350. text-align: center;
  351. }
  352. .details-cookies {
  353. font-family: 'Barlow';
  354. padding: 10px;
  355. text-align: center;
  356. text-align: justify;
  357. }
  358. .horizontal-line {
  359. width: 90%;
  360. height: 1px;
  361. background-color: #7e7d7d;
  362. margin-top: 10px;
  363. margin-bottom: 10px;
  364. }
  365. .actions {
  366. margin-top: 10px;
  367. margin-bottom: 10px;
  368. display: flex;
  369. justify-content: center;
  370. }
  371. .accept-button,
  372. .customize-button {
  373. background-color: var(--on-primary-color-alt);
  374. border: none;
  375. padding: 10px 20px;
  376. margin: 5px;
  377. cursor: pointer;
  378. }
  379. .decline-button {
  380. border: 1px solid var(--on-neutral-color);
  381. padding: 10px 20px;
  382. margin: 5px;
  383. cursor: pointer;
  384. }
  385. .accept-button:hover,
  386. .customize-button:hover {
  387. background-color: var(--on-primary-color-alt);
  388. }
  389. .cookie-notification {
  390. position: fixed;
  391. bottom: 20px;
  392. left: 20px;
  393. background-color: rgba(0, 0, 0, 0.8);
  394. color: white;
  395. padding: 15px;
  396. border-radius: 5px;
  397. z-index: 1100;
  398. }
  399. .cookie-description {
  400. margin: 0;
  401. font-size: 0.875rem;
  402. color: #555;
  403. }
  404. .custom-switch .v-input--selection-controls__ripple .v-ripple__container {
  405. background-color: var(--v-primary-base);
  406. }
  407. .custom-switch
  408. .v-input--selection-controls__ripple--active
  409. .v-ripple__container {
  410. background-color: var(--v-primary-darken4);
  411. }
  412. .custom-switch .v-input--selection-controls__input {
  413. --v-theme-primary: var(--v-primary-base);
  414. --v-theme-primary-lighten4: var(--v-primary-lighten4);
  415. --v-theme-primary-darken4: var(--v-primary-darken4);
  416. }
  417. .custom-switch
  418. .v-input--selection-controls__input
  419. input:checked
  420. + .v-input--selection-controls__ripple
  421. .v-ripple__container {
  422. background-color: var(--v-primary-darken4);
  423. }
  424. .custom-switch
  425. .v-input--selection-controls__input
  426. input:checked
  427. + .v-input--selection-controls__ripple
  428. .v-ripple__container
  429. .v-ripple__animation {
  430. background-color: var(--v-primary-darken4);
  431. }
  432. :deep().v-switch__track {
  433. background-color: red;
  434. }
  435. .close-dialog {
  436. background: none !important;
  437. box-shadow: none !important;
  438. }
  439. .continue{
  440. font-size: .9rem;
  441. font-weight: 500;
  442. text-decoration: underline;
  443. cursor: pointer;
  444. text-decoration: none !important;
  445. color: black ;
  446. }
  447. .continue-wrapper{
  448. display: flex;
  449. justify-content: end;
  450. align-items: center;
  451. margin-left: auto;
  452. }
  453. </style>