Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions app.config.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
export default defineAppConfig({
ui: {
primary: "neutral",
notification: {
background: 'bg-white dark:bg-black',
},
},
header: {
menu: {
Expand Down
12 changes: 11 additions & 1 deletion app.vue
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,21 @@
<NuxtPage />
</div>
<AppFooter v-if="route.path !== '/' && route" />
<UNotifications />
<AppCookieConsent />
<UNotifications>
<template #description="{ description }">
<span v-html="description" />
</template>
</UNotifications>
</div>
</template>

<script setup lang="ts">

const main = useAppConfig().main;
const route = useRoute();
const toast = useToast();
const { init: initCookieConsent } = useCookieConsent();

const theme = useColorMode();

Expand All @@ -41,6 +48,9 @@ useHead(() => ({

// Use onMounted to ensure the code runs only on the client side
onMounted(() => {
// Initialize cookie consent — GTM stays disabled until user explicitly accepts
initCookieConsent();

for (let i = 1; i <= 7; i++) {
document.documentElement.style.setProperty(`--h${i}-font-type`, main[`h${i}`].font.type);
document.documentElement.style.setProperty(`--h${i}-font-size`, main[`h${i}`].font.size);
Expand Down
51 changes: 51 additions & 0 deletions components/app/cookie-consent.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
<template>
<Transition name="slide-up">
<div v-if="showBanner" class="fixed bottom-0 left-0 right-0 z-[100] p-4 md:p-6">
<div
class="mx-auto max-w-2xl rounded-xl border border-primary/20 bg-white/95 dark:bg-neutral-900/95 backdrop-blur-sm shadow-xl p-5 md:p-6"
>
<div class="flex items-start gap-3 mb-4">
<UIcon name="i-heroicons-shield-check" class="text-primary text-xl mt-0.5 shrink-0" />
<div>
<h3 class="text-sm font-semibold text-gray-900 dark:text-white">Cookie Consent</h3>
<p class="mt-1 text-sm text-gray-600 dark:text-gray-300">
We use cookies for analytics and marketing to improve your experience.
No cookies are set until you make a choice.
Read our <NuxtLink to="/about/legal#cookie-policy" class="text-primary underline">Cookie Policy</NuxtLink>.
</p>
</div>
</div>
<div class="flex flex-col sm:flex-row gap-2 sm:justify-end">
<UButton
label="Reject All"
variant="outline"
size="sm"
@click="reject"
/>
<UButton
label="Accept All"
variant="outline"
size="sm"
@click="accept"
/>
</div>
</div>
</div>
</Transition>
</template>

<script setup lang="ts">
const { showBanner, accept, reject } = useCookieConsent()
</script>

<style scoped>
.slide-up-enter-active,
.slide-up-leave-active {
transition: transform 0.3s ease, opacity 0.3s ease;
}
.slide-up-enter-from,
.slide-up-leave-to {
transform: translateY(100%);
opacity: 0;
}
</style>
1 change: 1 addition & 0 deletions components/app/footer.vue
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
import { useQueryCollection } from '~/composables/nuxt/query/useQueryCollection';

const { data: data } = useQueryCollection('content', '/footer-content');
const { openSettings } = useCookieConsent();

const date = new Date();
const year = date.getFullYear();
Expand Down
40 changes: 32 additions & 8 deletions components/content/sh-form-contact-us.vue
Original file line number Diff line number Diff line change
@@ -1,22 +1,34 @@
<template>
<div id="hubspot-form"></div>
<div>
<div id="hubspot-form"></div>
<p v-if="consentStatus !== 'accepted'" class="text-sm text-gray-500 dark:text-gray-400 py-4">
To use this form, please
<button class="text-primary underline" @click="openSettings">accept cookies</button>.
</p>
</div>
</template>

<script setup lang="ts">
const { consentStatus, openSettings } = useCookieConsent()

const loadHubSpotForm = () => {
if (window.hbspt) {
window.hbspt.forms.create({
region: 'na1',
portalId: '21247113',
formId: 'c9bf8828-7520-4e8c-987b-70fe763e77eb',
target: '#hubspot-form',
});
return;
}

onMounted(() => {
// Add HubSpot embed script
const script = document.createElement('script');
script.src = '//js.hsforms.net/forms/embed/v2.js';
script.charset = 'utf-8';
script.type = 'text/javascript';

// Append the script to the document head
document.head.appendChild(script);

// Once the script is loaded, initialize the form
script.onload = () => {
// Ensure hbspt exists after script is loaded
if (window.hbspt) {
window.hbspt.forms.create({
region: 'na1',
Expand All @@ -26,5 +38,17 @@ onMounted(() => {
});
}
};
});
}

onMounted(() => {
if (consentStatus.value === 'accepted') {
loadHubSpotForm();
}
})

watch(consentStatus, (status) => {
if (status === 'accepted') {
nextTick(() => loadHubSpotForm());
}
})
</script>
64 changes: 46 additions & 18 deletions components/content/sh-form-newsletter.vue
Original file line number Diff line number Diff line change
@@ -1,27 +1,55 @@
<template>
<div id="contact-us-form">
</div>
</template>

<script setup lang="ts">
import { onMounted } from 'vue'

onMounted(() => {
const script = document.createElement('script')
script.src = "//js.hsforms.net/forms/embed/v2.js"
script.type = "text/javascript"
script.charset = "utf-8"

script.onload = () => {
<div>
<div id="contact-us-form"></div>
<p v-if="consentStatus !== 'accepted'" class="text-sm text-gray-500 dark:text-gray-400 py-4">
To use this form, please
<button class="text-primary underline" @click="openSettings">accept cookies</button>.
</p>
</div>
</template>

<script setup lang="ts">
const { consentStatus, openSettings } = useCookieConsent()

const loadHubSpotForm = () => {
if (window.hbspt) {
window.hbspt.forms.create({
region: "na1",
portalId: "21247113",
formId: "56969656-646b-423d-98af-133ab4c4e2dd",
target: "#contact-us-form"
});
return;
}

const script = document.createElement('script')
script.src = "//js.hsforms.net/forms/embed/v2.js"
script.type = "text/javascript"
script.charset = "utf-8"
document.body.appendChild(script)

script.onload = () => {
if (window.hbspt) {
window.hbspt.forms.create({
region: "na1",
portalId: "21247113",
formId: "56969656-646b-423d-98af-133ab4c4e2dd",
target: "#contact-us-form"
})
}

document.body.appendChild(script)
})
</script>
}
}

onMounted(() => {
if (consentStatus.value === 'accepted') {
loadHubSpotForm()
}
})

watch(consentStatus, (status) => {
if (status === 'accepted') {
nextTick(() => loadHubSpotForm())
}
})
</script>

40 changes: 40 additions & 0 deletions composables/useCookieConsent.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
export const useCookieConsent = () => {
const gtm = useGtm()
const consentStatus = useState<string | null>('cookie-consent-status', () => null)
const showBanner = useState<boolean>('cookie-consent-banner', () => false)

const enableGtm = () => {
gtm?.enable(true)
}

const init = () => {
if (import.meta.client) {
const stored = localStorage.getItem('cookie-consent')
consentStatus.value = stored
if (!stored) {
showBanner.value = true
} else if (stored === 'accepted') {
enableGtm()
}
}
}

const accept = () => {
consentStatus.value = 'accepted'
localStorage.setItem('cookie-consent', 'accepted')
showBanner.value = false
enableGtm()
}

const reject = () => {
consentStatus.value = 'rejected'
localStorage.setItem('cookie-consent', 'rejected')
showBanner.value = false
}

const openSettings = () => {
showBanner.value = true
}

return { consentStatus, showBanner, init, accept, reject, openSettings }
}
11 changes: 8 additions & 3 deletions content/80.about/8070.legal/807010.index.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,13 +50,18 @@ OMA implements appropriate technical and organizational measures to ensure the s
## COOKIE POLICY

### INTRODUCTION
OMA is committed to ensuring transparency in how we use cookies on our website. However, we currently do not collect or store cookies from users visiting our website, and we do not plan to implement cookie tracking.
We use cookies to enhance your browsing experience, analyze website traffic, and support our marketing efforts.

Cookies are small text files stored on your device when you visit our website. They help us understand how users interact with our site and enable certain functionalities.

### TYPE OF COOKIES
Since OMA does not use cookies, there are no types of cookies collected or stored on this website.
We use the following types of cookies:

- **Analytics Cookies**: These cookies help us understand how visitors interact with our website by collecting and reporting information anonymously (e.g., via Google Analytics).
- **Marketing Cookies**: These cookies are used to track visitors across websites and may be used to deliver relevant marketing content (e.g., via HubSpot).

### MANAGING COOKIE PREFERENCES
Users do not need to manage cookie preferences as OMA does not collect or use cookies.
By continuing to use our website, you consent to the use of cookies as described in this policy. You can manage or disable cookies through your browser settings at any time.

---

Expand Down
3 changes: 2 additions & 1 deletion nuxt.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,8 @@ export default defineNuxtConfig({
},

gtm: {
id: 'GTM-T55F5MHQ', // Your GTM single container ID, array of container ids ['GTM-xxxxxx', 'GTM-yyyyyy'] or array of objects [{id: 'GTM-xxxxxx', queryParams: { gtm_auth: 'abc123', gtm_preview: 'env-4', gtm_cookies_win: 'x'}}, {id: 'GTM-yyyyyy', queryParams: {gtm_auth: 'abc234', gtm_preview: 'env-5', gtm_cookies_win: 'x'}}], // Your GTM single container ID or array of container ids ['GTM-xxxxxx', 'GTM-yyyyyy']
id: 'GTM-T55F5MHQ',
enabled: false, // Disabled by default — enabled only after user consents (GDPR/ePrivacy)
},

googleFonts: {
Expand Down