diff --git a/apps/marketing/src/app/[lang]/components/HeroSection/HeroSection.tsx b/apps/marketing/src/app/[lang]/components/HeroSection/HeroSection.tsx index 1b99e8a5251..903e1084712 100644 --- a/apps/marketing/src/app/[lang]/components/HeroSection/HeroSection.tsx +++ b/apps/marketing/src/app/[lang]/components/HeroSection/HeroSection.tsx @@ -115,7 +115,10 @@ export function HeroSection() {

-
+
setIsWaitlistOpen(true)} diff --git a/apps/marketing/src/app/[lang]/components/ProductHeroActions/ProductHeroActions.tsx b/apps/marketing/src/app/[lang]/components/ProductHeroActions/ProductHeroActions.tsx index 5210b628d08..b434e87af05 100644 --- a/apps/marketing/src/app/[lang]/components/ProductHeroActions/ProductHeroActions.tsx +++ b/apps/marketing/src/app/[lang]/components/ProductHeroActions/ProductHeroActions.tsx @@ -19,7 +19,10 @@ export function ProductHeroActions({ return ( <> -
+
setIsWaitlistOpen(true)} diff --git a/apps/marketing/src/components/CookieConsent/CookieConsent.tsx b/apps/marketing/src/components/CookieConsent/CookieConsent.tsx index 51964a88488..a3f306c3d02 100644 --- a/apps/marketing/src/components/CookieConsent/CookieConsent.tsx +++ b/apps/marketing/src/components/CookieConsent/CookieConsent.tsx @@ -2,16 +2,83 @@ import { Trans } from "@lingui/react/macro"; import { Button } from "@superset/ui/button"; +import { cn } from "@superset/ui/utils"; import { AnimatePresence, m } from "framer-motion"; import Link from "next/link"; -import { useEffect, useState } from "react"; +import { useEffect, useLayoutEffect, useRef, useState } from "react"; import { declineAnalytics } from "@/lib/analytics/decline"; import { withPosthog } from "@/lib/analytics/lazy"; import { ANALYTICS_CONSENT_KEY } from "@/lib/constants"; +/** Elements the banner must never cover, such as the hero download buttons. */ +export const KEEP_CLEAR_ATTRIBUTE = "data-cookie-banner-keep-clear"; + +// Tried in order; the first one that leaves every keep-clear element +// uncovered wins. A browser window is often smaller than the screen, so no +// single fixed position is safe: on a 1000x560 Safari window a bottom bar +// covers the hero CTA, and on a phone a corner card does. +const PLACEMENTS = [ + { + name: "corner-left", + container: "bottom-4 left-4 w-72 flex-col items-stretch", + compact: false, + }, + { + name: "corner-right", + container: "bottom-4 right-4 w-72 flex-col items-stretch", + compact: false, + }, + { + name: "bar", + container: "inset-x-4 bottom-4 flex-col sm:flex-row sm:items-center", + compact: false, + }, + { + name: "compact-right", + container: "bottom-2 right-2 flex-row items-center", + compact: true, + }, + { + name: "compact-left", + container: "bottom-2 left-2 flex-row items-center", + compact: true, + }, +] as const; + +function overlaps(a: DOMRect, b: DOMRect): boolean { + return ( + a.left < b.right && b.left < a.right && a.top < b.bottom && b.top < a.bottom + ); +} + +function coversKeepClear(banner: HTMLElement): boolean { + // Measure where the banner sits once its entrance animation ends. + const rect = banner.getBoundingClientRect(); + const offsetY = Number.parseFloat( + getComputedStyle(banner).transform.split(",")[5] ?? "0", + ); + const settled = new DOMRect( + rect.x, + rect.y - (Number.isFinite(offsetY) ? offsetY : 0), + rect.width, + rect.height, + ); + for (const element of document.querySelectorAll( + `[${KEEP_CLEAR_ATTRIBUTE}]`, + )) { + const target = element.getBoundingClientRect(); + if (target.width === 0 || target.height === 0) continue; + if (overlaps(settled, target)) return true; + } + return false; +} + export function CookieConsent() { const [showBanner, setShowBanner] = useState(false); + const [placementIndex, setPlacementIndex] = useState(0); + const [viewport, setViewport] = useState(null); + const bannerRef = useRef(null); useEffect(() => { const consent = localStorage.getItem(ANALYTICS_CONSENT_KEY); @@ -20,6 +87,30 @@ export function CookieConsent() { } }, []); + // Start over from the preferred placement whenever the window changes size. + useEffect(() => { + if (!showBanner) return; + const onResize = () => + setViewport(`${window.innerWidth}x${window.innerHeight}`); + onResize(); + window.addEventListener("resize", onResize); + return () => window.removeEventListener("resize", onResize); + }, [showBanner]); + + // biome-ignore lint/correctness/useExhaustiveDependencies: viewport is the trigger + useLayoutEffect(() => { + setPlacementIndex(0); + }, [viewport]); + + // biome-ignore lint/correctness/useExhaustiveDependencies: re-measure after a resize even when the placement stays the same + useLayoutEffect(() => { + const banner = bannerRef.current; + if (!showBanner || !banner) return; + if (placementIndex < PLACEMENTS.length - 1 && coversKeepClear(banner)) { + setPlacementIndex(placementIndex + 1); + } + }, [showBanner, placementIndex, viewport]); + const handleAccept = () => { localStorage.setItem(ANALYTICS_CONSENT_KEY, "accepted"); setShowBanner(false); @@ -32,36 +123,59 @@ export function CookieConsent() { setShowBanner(false); }; + const placement = PLACEMENTS[placementIndex] ?? PLACEMENTS[0]; + return ( {showBanner && ( -

- - We only collect analytics cookies so we can improve your - experience. - -

-
- + -
- - -
)} diff --git a/packages/i18n/locales/cs/messages.po b/packages/i18n/locales/cs/messages.po index 4830dd34ccf..a30bcad2d9b 100644 --- a/packages/i18n/locales/cs/messages.po +++ b/packages/i18n/locales/cs/messages.po @@ -2605,6 +2605,9 @@ msgstr "Došlo k neznámé chybě" msgid "An update is ready to install." msgstr "Aktualizace je připravena k instalaci." +msgid "Analytics cookies" +msgstr "Analytické cookies" + msgid "Android is on the way. Be first to know when it ships." msgstr "Android je na cestě. Dozvíte se jako první, až vyjde." diff --git a/packages/i18n/locales/de/messages.po b/packages/i18n/locales/de/messages.po index 2d0059807c2..78d9aab43c1 100644 --- a/packages/i18n/locales/de/messages.po +++ b/packages/i18n/locales/de/messages.po @@ -2605,6 +2605,9 @@ msgstr "Ein unbekannter Fehler ist aufgetreten" msgid "An update is ready to install." msgstr "Ein Update ist bereit zur Installation." +msgid "Analytics cookies" +msgstr "Analyse-Cookies" + msgid "Android is on the way. Be first to know when it ships." msgstr "Android ist unterwegs. Erfahre als Erstes, wenn es erscheint." diff --git a/packages/i18n/locales/en/messages.po b/packages/i18n/locales/en/messages.po index 2b8ab234650..6368d4de925 100644 --- a/packages/i18n/locales/en/messages.po +++ b/packages/i18n/locales/en/messages.po @@ -2605,6 +2605,9 @@ msgstr "An unknown error occurred" msgid "An update is ready to install." msgstr "An update is ready to install." +msgid "Analytics cookies" +msgstr "Analytics cookies" + msgid "Android is on the way. Be first to know when it ships." msgstr "Android is on the way. Be first to know when it ships." diff --git a/packages/i18n/locales/es/messages.po b/packages/i18n/locales/es/messages.po index a66eba788de..836b0d45126 100644 --- a/packages/i18n/locales/es/messages.po +++ b/packages/i18n/locales/es/messages.po @@ -2605,6 +2605,9 @@ msgstr "Se produjo un error desconocido" msgid "An update is ready to install." msgstr "Hay una actualización lista para instalar." +msgid "Analytics cookies" +msgstr "Cookies de analítica" + msgid "Android is on the way. Be first to know when it ships." msgstr "Android está en camino. Sé el primero en enterarte cuando salga." diff --git a/packages/i18n/locales/fr/messages.po b/packages/i18n/locales/fr/messages.po index 6164b31ef46..8b47b3e2992 100644 --- a/packages/i18n/locales/fr/messages.po +++ b/packages/i18n/locales/fr/messages.po @@ -2605,6 +2605,9 @@ msgstr "Une erreur inconnue est survenue" msgid "An update is ready to install." msgstr "Une mise à jour est prête à être installée." +msgid "Analytics cookies" +msgstr "Cookies d'analyse" + msgid "Android is on the way. Be first to know when it ships." msgstr "Android arrive. Soyez le premier informé de sa sortie." diff --git a/packages/i18n/locales/id/messages.po b/packages/i18n/locales/id/messages.po index a915fdc9f9b..c105df22d2c 100644 --- a/packages/i18n/locales/id/messages.po +++ b/packages/i18n/locales/id/messages.po @@ -2605,6 +2605,9 @@ msgstr "Terjadi kesalahan yang tidak diketahui" msgid "An update is ready to install." msgstr "Pembaruan siap dipasang." +msgid "Analytics cookies" +msgstr "Cookie analitik" + msgid "Android is on the way. Be first to know when it ships." msgstr "Android sedang dalam perjalanan. Jadilah yang pertama tahu saat dirilis." diff --git a/packages/i18n/locales/it/messages.po b/packages/i18n/locales/it/messages.po index f9fdd2dfccb..1438d3dd4c7 100644 --- a/packages/i18n/locales/it/messages.po +++ b/packages/i18n/locales/it/messages.po @@ -2605,6 +2605,9 @@ msgstr "Si è verificato un errore sconosciuto" msgid "An update is ready to install." msgstr "Un aggiornamento è pronto per l'installazione." +msgid "Analytics cookies" +msgstr "Cookie di analisi" + msgid "Android is on the way. Be first to know when it ships." msgstr "Android è in arrivo. Scoprilo per primo quando sarà disponibile." diff --git a/packages/i18n/locales/ja/messages.po b/packages/i18n/locales/ja/messages.po index 89e57cd7673..b2b1a3fb9a6 100644 --- a/packages/i18n/locales/ja/messages.po +++ b/packages/i18n/locales/ja/messages.po @@ -2605,6 +2605,9 @@ msgstr "不明なエラーが発生しました" msgid "An update is ready to install." msgstr "アップデートをインストールする準備ができました。" +msgid "Analytics cookies" +msgstr "分析用 Cookie" + msgid "Android is on the way. Be first to know when it ships." msgstr "Android 版を準備中です。リリース時にいち早くお知らせします。" diff --git a/packages/i18n/locales/ko/messages.po b/packages/i18n/locales/ko/messages.po index 6481e0fc0b3..d94eba0b2d6 100644 --- a/packages/i18n/locales/ko/messages.po +++ b/packages/i18n/locales/ko/messages.po @@ -2605,6 +2605,9 @@ msgstr "알 수 없는 오류가 발생했습니다" msgid "An update is ready to install." msgstr "설치할 업데이트가 준비되었습니다." +msgid "Analytics cookies" +msgstr "분석 쿠키" + msgid "Android is on the way. Be first to know when it ships." msgstr "Android 버전이 곧 나옵니다. 출시되면 가장 먼저 알려드릴게요." diff --git a/packages/i18n/locales/nl/messages.po b/packages/i18n/locales/nl/messages.po index 88439e88ca6..5376c66bf6b 100644 --- a/packages/i18n/locales/nl/messages.po +++ b/packages/i18n/locales/nl/messages.po @@ -2605,6 +2605,9 @@ msgstr "Er is een onbekende fout opgetreden" msgid "An update is ready to install." msgstr "Er staat een update klaar om te installeren." +msgid "Analytics cookies" +msgstr "Analytische cookies" + msgid "Android is on the way. Be first to know when it ships." msgstr "Android komt eraan. Hoor het als eerste wanneer het uitkomt." diff --git a/packages/i18n/locales/pl/messages.po b/packages/i18n/locales/pl/messages.po index 8b37f1d8bfd..ec7096833ee 100644 --- a/packages/i18n/locales/pl/messages.po +++ b/packages/i18n/locales/pl/messages.po @@ -2605,6 +2605,9 @@ msgstr "Wystąpił nieznany błąd" msgid "An update is ready to install." msgstr "Aktualizacja jest gotowa do zainstalowania." +msgid "Analytics cookies" +msgstr "Analityczne pliki cookie" + msgid "Android is on the way. Be first to know when it ships." msgstr "Android jest w drodze. Dowiedz się jako pierwszy, gdy się pojawi." diff --git a/packages/i18n/locales/pt-BR/messages.po b/packages/i18n/locales/pt-BR/messages.po index ddd9cfd3be0..411d8165bd4 100644 --- a/packages/i18n/locales/pt-BR/messages.po +++ b/packages/i18n/locales/pt-BR/messages.po @@ -2605,6 +2605,9 @@ msgstr "Ocorreu um erro desconhecido" msgid "An update is ready to install." msgstr "Há uma atualização pronta para instalar." +msgid "Analytics cookies" +msgstr "Cookies de análise" + msgid "Android is on the way. Be first to know when it ships." msgstr "O Android está a caminho. Seja o primeiro a saber quando for lançado." diff --git a/packages/i18n/locales/ru/messages.po b/packages/i18n/locales/ru/messages.po index 8e15944f429..10345852125 100644 --- a/packages/i18n/locales/ru/messages.po +++ b/packages/i18n/locales/ru/messages.po @@ -2605,6 +2605,9 @@ msgstr "Произошла неизвестная ошибка" msgid "An update is ready to install." msgstr "Обновление готово к установке." +msgid "Analytics cookies" +msgstr "Аналитические cookie" + msgid "Android is on the way. Be first to know when it ships." msgstr "Версия для Android уже в работе. Узнайте о выходе первыми." diff --git a/packages/i18n/locales/tr/messages.po b/packages/i18n/locales/tr/messages.po index faab983e052..94df7640609 100644 --- a/packages/i18n/locales/tr/messages.po +++ b/packages/i18n/locales/tr/messages.po @@ -2605,6 +2605,9 @@ msgstr "Bilinmeyen bir hata oluştu" msgid "An update is ready to install." msgstr "Yüklenmeye hazır bir güncelleme var." +msgid "Analytics cookies" +msgstr "Analiz çerezleri" + msgid "Android is on the way. Be first to know when it ships." msgstr "Android yolda. Çıktığında ilk siz haberdar olun." diff --git a/packages/i18n/locales/uk/messages.po b/packages/i18n/locales/uk/messages.po index 12efe9ddbc7..24b20de64fd 100644 --- a/packages/i18n/locales/uk/messages.po +++ b/packages/i18n/locales/uk/messages.po @@ -2599,6 +2599,9 @@ msgstr "Сталася невідома помилка" msgid "An update is ready to install." msgstr "Оновлення готове до встановлення." +msgid "Analytics cookies" +msgstr "Аналітичні cookie" + msgid "Android is on the way. Be first to know when it ships." msgstr "Версія для Android уже на підході. Дізнайтеся про вихід першими." diff --git a/packages/i18n/locales/vi/messages.po b/packages/i18n/locales/vi/messages.po index 2dbf9329937..e911f296b25 100644 --- a/packages/i18n/locales/vi/messages.po +++ b/packages/i18n/locales/vi/messages.po @@ -2605,6 +2605,9 @@ msgstr "Đã xảy ra lỗi không xác định" msgid "An update is ready to install." msgstr "Đã có bản cập nhật sẵn sàng để cài đặt." +msgid "Analytics cookies" +msgstr "Cookie phân tích" + msgid "Android is on the way. Be first to know when it ships." msgstr "Bản Android đang đến. Hãy là người đầu tiên biết khi nó ra mắt." diff --git a/packages/i18n/locales/zh-CN/messages.po b/packages/i18n/locales/zh-CN/messages.po index 5b8eb7d2d72..7b4f7bdd00a 100644 --- a/packages/i18n/locales/zh-CN/messages.po +++ b/packages/i18n/locales/zh-CN/messages.po @@ -2605,6 +2605,9 @@ msgstr "发生未知错误" msgid "An update is ready to install." msgstr "更新已准备好安装。" +msgid "Analytics cookies" +msgstr "分析 Cookie" + msgid "Android is on the way. Be first to know when it ships." msgstr "Android 版即将到来。发布时第一时间通知你。" diff --git a/packages/i18n/locales/zh-TW/messages.po b/packages/i18n/locales/zh-TW/messages.po index 09c4f4983aa..c43f04520e4 100644 --- a/packages/i18n/locales/zh-TW/messages.po +++ b/packages/i18n/locales/zh-TW/messages.po @@ -2605,6 +2605,9 @@ msgstr "發生未知錯誤" msgid "An update is ready to install." msgstr "更新已準備好安裝。" +msgid "Analytics cookies" +msgstr "分析 Cookie" + msgid "Android is on the way. Be first to know when it ships." msgstr "Android 版即將推出。發布時第一時間通知你。"