|
<script setup lang="ts"> |
|
import { ref, onMounted, watch, computed } from 'vue' |
|
import { Button } from '@/components/ui/button' |
|
// Default prop values |
|
const props = defineProps({ |
|
variant: { default: 'default' }, |
|
demo: { default: false }, |
|
description: { |
|
default: |
|
'We use cookies to ensure you get the best experience on our website. For more information on how we use cookies, please see our cookie policy.', |
|
}, |
|
learnMoreHref: { default: '#' }, |
|
onAcceptCallback: { default: () => {} }, |
|
onDeclineCallback: { default: () => {} }, |
|
}) |
|
|
|
// States |
|
const isOpen = ref(false) |
|
const hide = ref(false) |
|
|
|
// Methods |
|
const handleAccept = () => { |
|
isOpen.value = false |
|
document.cookie = 'cookieConsent=true; expires=Fri, 31 Dec 9999 23:59:59 GMT' |
|
setTimeout(() => (hide.value = true), 700) |
|
//props.onAcceptCallback?.() |
|
} |
|
|
|
const handleDecline = () => { |
|
isOpen.value = false |
|
setTimeout(() => (hide.value = true), 700) |
|
//props.onDeclineCallback?.() |
|
} |
|
|
|
onMounted(() => { |
|
try { |
|
isOpen.value = true |
|
if (document.cookie.includes('cookieConsent=true') && !props.demo) { |
|
isOpen.value = false |
|
setTimeout(() => (hide.value = true), 700) |
|
} |
|
} catch (error) { |
|
console.warn('Cookie consent error:', error) |
|
} |
|
}) |
|
|
|
const wrapperClasses = computed(() => |
|
[ |
|
'fixed z-50 transition-all duration-700', |
|
isOpen.value ? 'translate-y-0 opacity-100' : 'translate-y-full opacity-0', |
|
props.variant === 'mini' |
|
? 'left-0 right-0 sm:left-4 bottom-4 w-full sm:max-w-3xl' |
|
: 'bottom-0 left-0 right-0 sm:left-4 sm:bottom-4 w-full sm:max-w-md', |
|
].join(' ') |
|
) |
|
</script> |
|
|
|
<template> |
|
<div v-if="!hide" :class="wrapperClasses"> |
|
<div class="m-3 shadow-lg bg-muted border rounded-lg"> |
|
<template v-if="variant === 'default'"> |
|
<div class="flex justify-between items-center p-4 pb-2"> |
|
<h2 class="text-lg font-semibold">We use cookies</h2> |
|
<Cookie class="h-5 w-5" /> |
|
</div> |
|
<div class="px-4 pb-4 space-y-2 text-sm"> |
|
<p>{{ description }}</p> |
|
<p class="text-xs text-muted-foreground"> |
|
By clicking <span class="font-medium">"Accept"</span>, you agree to our use of cookies. |
|
</p> |
|
<a |
|
:href="learnMoreHref" |
|
class="text-xs text-blue-600 underline underline-offset-4 hover:no-underline" |
|
> |
|
Learn more |
|
</a> |
|
</div> |
|
<div class="flex gap-2 p-4 pt-0"> |
|
<Button @click="handleDecline">Decline</Button> |
|
<Button @click="handleAccept">Accept</Button> |
|
</div> |
|
</template> |
|
|
|
<template v-else-if="variant === 'small'"> |
|
<div class="flex justify-between items-center px-4 pt-4 pb-2"> |
|
<h2 class="text-base font-medium">We use cookies</h2> |
|
<Cookie class="h-4 w-4" /> |
|
</div> |
|
<div class="px-4 pb-2 text-sm">{{ description }}</div> |
|
<div class="flex gap-2 px-4 pb-4"> |
|
<Button @click="handleDecline">Decline</button> |
|
<Button @click="handleAccept">Accept</button> |
|
</div> |
|
</template> |
|
|
|
<template v-else-if="variant === 'mini'"> |
|
<div class="grid sm:flex gap-4 px-3.5 py-3"> |
|
<p class="text-xs sm:text-sm flex-1">{{ description }}</p> |
|
<div class="flex justify-end items-center gap-2 sm:gap-3"> |
|
<Button @click="handleDecline"> |
|
Decline <span class="sr-only sm:hidden">Decline</span> |
|
</Button> |
|
<Button @click="handleAccept"> |
|
Accept <span class="sr-only sm:hidden">Accept</span> |
|
</Button> |
|
</div> |
|
</div> |
|
</template> |
|
</div> |
|
</div> |
|
</template> |