@rxdrag/website-lib 0.0.151 → 0.0.153
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/components/AnimationNumber.astro +217 -217
- package/components/Background.astro +140 -114
- package/components/BackgroundGroup.astro +20 -26
- package/components/BaseFooter.astro +24 -39
- package/components/BaseHeader.astro +22 -25
- package/components/Box.astro +20 -22
- package/components/Button.astro +80 -0
- package/components/Carousel.astro +456 -315
- package/components/CarouselPagination.astro +97 -76
- package/components/CarouselSlide.astro +10 -16
- package/components/Collapse.astro +125 -125
- package/components/CollapseIndicator.astro +20 -20
- package/components/Container.astro +27 -32
- package/components/Content.astro +20 -0
- package/components/CookieConsent.astro +47 -47
- package/components/CookieConsent.css +52 -52
- package/components/CookieConsentConfig.ts +208 -208
- package/components/Dialog.astro +342 -338
- package/components/DialogTrigger.astro +32 -32
- package/components/Document.astro +240 -225
- package/components/Frame.astro +32 -0
- package/components/GlassBorder.astro +104 -0
- package/components/GlassRefraction.astro +85 -0
- package/components/GradientBorder.astro +80 -0
- package/components/Grid.astro +32 -34
- package/components/GridCell.astro +28 -32
- package/components/Heading.astro +24 -24
- package/components/Icon.astro +29 -29
- package/components/Image.astro +100 -100
- package/components/Image.md +14 -14
- package/components/Link.astro +89 -99
- package/components/Main.astro +17 -17
- package/components/Meta.astro +65 -65
- package/components/Popover.astro +189 -189
- package/components/RichTextView.astro +28 -28
- package/components/Section.astro +26 -44
- package/components/TabButton.astro +32 -16
- package/components/TabPanel.astro +20 -19
- package/components/Tabs.astro +220 -147
- package/components/Video.astro +6 -4
- package/components/YearsSince.astro +20 -20
- package/components//344/270/211/345/261/202/346/250/241/345/236/213.md +5 -5
- package/components//344/270/273/351/242/230Token.md +198 -198
- package/components//345/216/237/345/255/220/345/206/273/347/273/223/346/270/205/345/215/225.md +270 -260
- package/components//347/211/251/346/226/231/346/270/205/345/215/225.md +599 -567
- package/index.ts +5 -5
- package/package.json +7 -7
- package/components/BaseBlock.astro +0 -34
- package/components/Motion.astro +0 -77
- package/components/Stack.astro +0 -31
|
@@ -1,47 +1,47 @@
|
|
|
1
|
-
---
|
|
2
|
-
import "vanilla-cookieconsent/dist/cookieconsent.css";
|
|
3
|
-
import "./CookieConsent.css";
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
<script>
|
|
7
|
-
import { run } from "vanilla-cookieconsent";
|
|
8
|
-
import { config } from "./CookieConsentConfig";
|
|
9
|
-
|
|
10
|
-
// 设计模式下跳过执行(sandbox 环境 document.cookie 不可用)
|
|
11
|
-
const isDesignMode = typeof window !== 'undefined' && window.top !== window && (window as any).__ASTRO_SANDBOX_MODULES__;
|
|
12
|
-
if (isDesignMode) {
|
|
13
|
-
//console.log('[CookieConsent] skip in design mode');
|
|
14
|
-
} else {
|
|
15
|
-
// 异步初始化Cookie同意逻辑
|
|
16
|
-
async function initializeCookieConsent() {
|
|
17
|
-
try {
|
|
18
|
-
// 始终显示Cookie同意UI
|
|
19
|
-
document.body.classList.add("cc--elegant-black");
|
|
20
|
-
run(config);
|
|
21
|
-
|
|
22
|
-
// 显示偏好设置按钮
|
|
23
|
-
const preferencesBtn = document.getElementById("show-preferences-btn");
|
|
24
|
-
if (preferencesBtn) {
|
|
25
|
-
preferencesBtn.style.display = "block";
|
|
26
|
-
}
|
|
27
|
-
} catch (error) {
|
|
28
|
-
console.error("Cookie同意初始化失败:", error);
|
|
29
|
-
// 出错时默认显示同意UI(安全策略)
|
|
30
|
-
document.body.classList.add("cc--elegant-black");
|
|
31
|
-
run(config);
|
|
32
|
-
|
|
33
|
-
const preferencesBtn = document.getElementById("show-preferences-btn");
|
|
34
|
-
if (preferencesBtn) {
|
|
35
|
-
preferencesBtn.style.display = "block";
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
// 页面加载完成后初始化
|
|
41
|
-
if (document.readyState === "loading") {
|
|
42
|
-
document.addEventListener("DOMContentLoaded", initializeCookieConsent);
|
|
43
|
-
} else {
|
|
44
|
-
initializeCookieConsent();
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
</script>
|
|
1
|
+
---
|
|
2
|
+
import "vanilla-cookieconsent/dist/cookieconsent.css";
|
|
3
|
+
import "./CookieConsent.css";
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
<script>
|
|
7
|
+
import { run } from "vanilla-cookieconsent";
|
|
8
|
+
import { config } from "./CookieConsentConfig";
|
|
9
|
+
|
|
10
|
+
// 设计模式下跳过执行(sandbox 环境 document.cookie 不可用)
|
|
11
|
+
const isDesignMode = typeof window !== 'undefined' && window.top !== window && (window as any).__ASTRO_SANDBOX_MODULES__;
|
|
12
|
+
if (isDesignMode) {
|
|
13
|
+
//console.log('[CookieConsent] skip in design mode');
|
|
14
|
+
} else {
|
|
15
|
+
// 异步初始化Cookie同意逻辑
|
|
16
|
+
async function initializeCookieConsent() {
|
|
17
|
+
try {
|
|
18
|
+
// 始终显示Cookie同意UI
|
|
19
|
+
document.body.classList.add("cc--elegant-black");
|
|
20
|
+
run(config);
|
|
21
|
+
|
|
22
|
+
// 显示偏好设置按钮
|
|
23
|
+
const preferencesBtn = document.getElementById("show-preferences-btn");
|
|
24
|
+
if (preferencesBtn) {
|
|
25
|
+
preferencesBtn.style.display = "block";
|
|
26
|
+
}
|
|
27
|
+
} catch (error) {
|
|
28
|
+
console.error("Cookie同意初始化失败:", error);
|
|
29
|
+
// 出错时默认显示同意UI(安全策略)
|
|
30
|
+
document.body.classList.add("cc--elegant-black");
|
|
31
|
+
run(config);
|
|
32
|
+
|
|
33
|
+
const preferencesBtn = document.getElementById("show-preferences-btn");
|
|
34
|
+
if (preferencesBtn) {
|
|
35
|
+
preferencesBtn.style.display = "block";
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// 页面加载完成后初始化
|
|
41
|
+
if (document.readyState === "loading") {
|
|
42
|
+
document.addEventListener("DOMContentLoaded", initializeCookieConsent);
|
|
43
|
+
} else {
|
|
44
|
+
initializeCookieConsent();
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
</script>
|
|
@@ -1,52 +1,52 @@
|
|
|
1
|
-
.cc--elegant-black {
|
|
2
|
-
--cc-bg: #000;
|
|
3
|
-
--cc-primary-color: rgb(239, 244, 246);
|
|
4
|
-
--cc-secondary-color: #b1bdc3 !important;
|
|
5
|
-
|
|
6
|
-
--cc-btn-primary-bg: #ffffff;
|
|
7
|
-
--cc-btn-primary-color: #000;
|
|
8
|
-
--cc-btn-primary-hover-bg: #ccd4d8;
|
|
9
|
-
--cc-btn-primary-hover-color: #000;
|
|
10
|
-
--cc-btn-primary-border-color: var(--cc-btn-primary-bg);
|
|
11
|
-
|
|
12
|
-
--cc-btn-secondary-bg: rgba(255, 255, 255, 0.039);
|
|
13
|
-
--cc-btn-secondary-color: var(--cc-primary-color);
|
|
14
|
-
--cc-btn-secondary-border-color: #252729;
|
|
15
|
-
--cc-btn-secondary-hover-bg: #252729;
|
|
16
|
-
--cc-btn-secondary-hover-color: #fff;
|
|
17
|
-
--cc-btn-secondary-hover-border-color: #252729;
|
|
18
|
-
|
|
19
|
-
--cc-cookie-category-block-bg: #101111;
|
|
20
|
-
--cc-cookie-category-block-border: #1d1e1f;
|
|
21
|
-
--cc-cookie-category-block-hover-bg: #151516;
|
|
22
|
-
--cc-cookie-category-block-hover-border: #1d1e1f;
|
|
23
|
-
--cc-cookie-category-expanded-block-hover-bg: #1d1e1f;
|
|
24
|
-
--cc-cookie-category-expanded-block-bg: #101111;
|
|
25
|
-
--cc-toggle-readonly-bg: #2f3132;
|
|
26
|
-
--cc-overlay-bg: rgba(0, 0, 0, 0.9) !important;
|
|
27
|
-
|
|
28
|
-
--cc-toggle-on-bg: var(--cc-btn-primary-bg);
|
|
29
|
-
--cc-toggle-off-bg: #525f6b;
|
|
30
|
-
--cc-toggle-on-knob-bg: var(--cc-bg);
|
|
31
|
-
--cc-toggle-off-knob-bg: var(--cc-btn-primary-color);
|
|
32
|
-
--cc-toggle-readonly-knob-bg: var(--cc-cookie-category-block-bg);
|
|
33
|
-
--cc-toggle-enabled-icon-color: var(--cc-btn-primary-color);
|
|
34
|
-
--cc-toggle-disabled-icon-color: var(--cc-btn-primary-color);
|
|
35
|
-
--cc-toggle-readonly-knob-icon-color: var(--cc-toggle-readonly-bg);
|
|
36
|
-
--cc-section-category-border: #1e2428;
|
|
37
|
-
|
|
38
|
-
--cc-webkit-scrollbar-bg: var(--cc-section-category-border);
|
|
39
|
-
--cc-webkit-scrollbar-hover-bg: var(--cc-btn-primary-hover-bg);
|
|
40
|
-
|
|
41
|
-
--cc-separator-border-color: #252729;
|
|
42
|
-
|
|
43
|
-
--cc-footer-bg: #000;
|
|
44
|
-
--cc-footer-color: var(--cc-secondary-color);
|
|
45
|
-
--cc-footer-border-color: #212529;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
.cc--elegant-black #cc-main .cm,
|
|
49
|
-
.cc--elegant-black #cc-main .pm {
|
|
50
|
-
color-scheme: dark;
|
|
51
|
-
border: 1px solid var(--cc-separator-border-color);
|
|
52
|
-
}
|
|
1
|
+
.cc--elegant-black {
|
|
2
|
+
--cc-bg: #000;
|
|
3
|
+
--cc-primary-color: rgb(239, 244, 246);
|
|
4
|
+
--cc-secondary-color: #b1bdc3 !important;
|
|
5
|
+
|
|
6
|
+
--cc-btn-primary-bg: #ffffff;
|
|
7
|
+
--cc-btn-primary-color: #000;
|
|
8
|
+
--cc-btn-primary-hover-bg: #ccd4d8;
|
|
9
|
+
--cc-btn-primary-hover-color: #000;
|
|
10
|
+
--cc-btn-primary-border-color: var(--cc-btn-primary-bg);
|
|
11
|
+
|
|
12
|
+
--cc-btn-secondary-bg: rgba(255, 255, 255, 0.039);
|
|
13
|
+
--cc-btn-secondary-color: var(--cc-primary-color);
|
|
14
|
+
--cc-btn-secondary-border-color: #252729;
|
|
15
|
+
--cc-btn-secondary-hover-bg: #252729;
|
|
16
|
+
--cc-btn-secondary-hover-color: #fff;
|
|
17
|
+
--cc-btn-secondary-hover-border-color: #252729;
|
|
18
|
+
|
|
19
|
+
--cc-cookie-category-block-bg: #101111;
|
|
20
|
+
--cc-cookie-category-block-border: #1d1e1f;
|
|
21
|
+
--cc-cookie-category-block-hover-bg: #151516;
|
|
22
|
+
--cc-cookie-category-block-hover-border: #1d1e1f;
|
|
23
|
+
--cc-cookie-category-expanded-block-hover-bg: #1d1e1f;
|
|
24
|
+
--cc-cookie-category-expanded-block-bg: #101111;
|
|
25
|
+
--cc-toggle-readonly-bg: #2f3132;
|
|
26
|
+
--cc-overlay-bg: rgba(0, 0, 0, 0.9) !important;
|
|
27
|
+
|
|
28
|
+
--cc-toggle-on-bg: var(--cc-btn-primary-bg);
|
|
29
|
+
--cc-toggle-off-bg: #525f6b;
|
|
30
|
+
--cc-toggle-on-knob-bg: var(--cc-bg);
|
|
31
|
+
--cc-toggle-off-knob-bg: var(--cc-btn-primary-color);
|
|
32
|
+
--cc-toggle-readonly-knob-bg: var(--cc-cookie-category-block-bg);
|
|
33
|
+
--cc-toggle-enabled-icon-color: var(--cc-btn-primary-color);
|
|
34
|
+
--cc-toggle-disabled-icon-color: var(--cc-btn-primary-color);
|
|
35
|
+
--cc-toggle-readonly-knob-icon-color: var(--cc-toggle-readonly-bg);
|
|
36
|
+
--cc-section-category-border: #1e2428;
|
|
37
|
+
|
|
38
|
+
--cc-webkit-scrollbar-bg: var(--cc-section-category-border);
|
|
39
|
+
--cc-webkit-scrollbar-hover-bg: var(--cc-btn-primary-hover-bg);
|
|
40
|
+
|
|
41
|
+
--cc-separator-border-color: #252729;
|
|
42
|
+
|
|
43
|
+
--cc-footer-bg: #000;
|
|
44
|
+
--cc-footer-color: var(--cc-secondary-color);
|
|
45
|
+
--cc-footer-border-color: #212529;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
.cc--elegant-black #cc-main .cm,
|
|
49
|
+
.cc--elegant-black #cc-main .pm {
|
|
50
|
+
color-scheme: dark;
|
|
51
|
+
border: 1px solid var(--cc-separator-border-color);
|
|
52
|
+
}
|
|
@@ -1,208 +1,208 @@
|
|
|
1
|
-
import type { CookieConsentConfig } from "vanilla-cookieconsent";
|
|
2
|
-
|
|
3
|
-
const GA_MEASUREMENT_ID = (import.meta.env.PUBLIC_GA_MEASUREMENT_ID as string) || "";
|
|
4
|
-
const ANONYMIZE_IP = (import.meta.env.PUBLIC_GA_ANONYMIZE_IP as string) === "false" ? false : true;
|
|
5
|
-
const COOKIE_FLAGS = (import.meta.env.PUBLIC_GA_COOKIE_FLAGS as string) || "SameSite=None;Secure";
|
|
6
|
-
|
|
7
|
-
// 声明全局 gtag 函数类型
|
|
8
|
-
declare global {
|
|
9
|
-
function gtag(...args: any[]): void;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
function updateConsent(consent: {
|
|
13
|
-
analytics_storage: "granted" | "denied";
|
|
14
|
-
ad_storage: "granted" | "denied";
|
|
15
|
-
}) {
|
|
16
|
-
console.log("[CookieConsent] updateConsent", consent);
|
|
17
|
-
if (typeof gtag !== "undefined") {
|
|
18
|
-
gtag("consent", "update", consent);
|
|
19
|
-
} else {
|
|
20
|
-
console.log("gtag 未定义,无法更新 consent", consent);
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
// 加载 Google Analytics 脚本
|
|
25
|
-
function loadGA4() {
|
|
26
|
-
if (!GA_MEASUREMENT_ID) {
|
|
27
|
-
console.log("GA_MEASUREMENT_ID 为空,跳过 GA4 config");
|
|
28
|
-
return;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
console.log("[CookieConsent] loadGA4 GA_MEASUREMENT_ID:", GA_MEASUREMENT_ID);
|
|
32
|
-
|
|
33
|
-
console.log("Loading Google Analytics with ID:", GA_MEASUREMENT_ID);
|
|
34
|
-
|
|
35
|
-
// 复用 HeadCode.astro 中的全局 gtag(不要再创建第二套 dataLayer/gtag)
|
|
36
|
-
if (typeof gtag !== "undefined") {
|
|
37
|
-
gtag("config", GA_MEASUREMENT_ID, {
|
|
38
|
-
anonymize_ip: ANONYMIZE_IP,
|
|
39
|
-
cookie_flags: COOKIE_FLAGS,
|
|
40
|
-
});
|
|
41
|
-
} else {
|
|
42
|
-
console.log("gtag 未定义,跳过 GA4 config");
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
// 直接加载 Google Analytics(非欧洲地区使用)
|
|
47
|
-
export function loadGA4Directly() {
|
|
48
|
-
if (!GA_MEASUREMENT_ID) {
|
|
49
|
-
console.log("GA_MEASUREMENT_ID 为空,跳过直接 GA4 config");
|
|
50
|
-
return;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
console.log(
|
|
54
|
-
"[CookieConsent] loadGA4Directly GA_MEASUREMENT_ID:",
|
|
55
|
-
GA_MEASUREMENT_ID
|
|
56
|
-
);
|
|
57
|
-
|
|
58
|
-
console.log("直接加载 Google Analytics (无需用户同意):", GA_MEASUREMENT_ID);
|
|
59
|
-
|
|
60
|
-
// 复用 HeadCode.astro 中的全局 gtag(不要再创建第二套 dataLayer/gtag)
|
|
61
|
-
if (typeof gtag !== "undefined") {
|
|
62
|
-
gtag("config", GA_MEASUREMENT_ID, {
|
|
63
|
-
anonymize_ip: ANONYMIZE_IP,
|
|
64
|
-
cookie_flags: COOKIE_FLAGS,
|
|
65
|
-
});
|
|
66
|
-
} else {
|
|
67
|
-
console.log("gtag 未定义,跳过 GA4 direct config");
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
// 清除 Google Analytics cookies
|
|
72
|
-
function clearGA4Cookies() {
|
|
73
|
-
const gaCookies = document.cookie
|
|
74
|
-
.split(";")
|
|
75
|
-
.filter((cookie) => cookie.trim().startsWith("_ga"));
|
|
76
|
-
|
|
77
|
-
gaCookies.forEach((cookie) => {
|
|
78
|
-
const cookieName = cookie.split("=")[0].trim();
|
|
79
|
-
document.cookie = `${cookieName}=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/; domain=.${window.location.hostname}`;
|
|
80
|
-
document.cookie = `${cookieName}=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/`;
|
|
81
|
-
});
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
export const config: CookieConsentConfig = {
|
|
85
|
-
guiOptions: {
|
|
86
|
-
consentModal: {
|
|
87
|
-
layout: "box inline",
|
|
88
|
-
position: "bottom left",
|
|
89
|
-
},
|
|
90
|
-
preferencesModal: {
|
|
91
|
-
layout: "box",
|
|
92
|
-
position: "right",
|
|
93
|
-
equalWeightButtons: true,
|
|
94
|
-
flipButtons: false,
|
|
95
|
-
},
|
|
96
|
-
},
|
|
97
|
-
categories: {
|
|
98
|
-
necessary: {
|
|
99
|
-
readOnly: true,
|
|
100
|
-
},
|
|
101
|
-
functionality: {},
|
|
102
|
-
analytics: {
|
|
103
|
-
services: {
|
|
104
|
-
ga4: {
|
|
105
|
-
label:
|
|
106
|
-
'<a href="https://marketingplatform.google.com/about/analytics/terms/us/" target="_blank">Google Analytics 4</a>',
|
|
107
|
-
onAccept: () => {
|
|
108
|
-
console.log("Google Analytics 4 accepted");
|
|
109
|
-
console.log(
|
|
110
|
-
"[CookieConsent] onAccept, GA_MEASUREMENT_ID:",
|
|
111
|
-
GA_MEASUREMENT_ID
|
|
112
|
-
);
|
|
113
|
-
updateConsent({
|
|
114
|
-
analytics_storage: "granted",
|
|
115
|
-
ad_storage: "granted",
|
|
116
|
-
});
|
|
117
|
-
loadGA4();
|
|
118
|
-
},
|
|
119
|
-
onReject: () => {
|
|
120
|
-
console.log("Google Analytics 4 rejected");
|
|
121
|
-
console.log(
|
|
122
|
-
"[CookieConsent] onReject, GA_MEASUREMENT_ID:",
|
|
123
|
-
GA_MEASUREMENT_ID
|
|
124
|
-
);
|
|
125
|
-
clearGA4Cookies();
|
|
126
|
-
|
|
127
|
-
// 禁用 Google Analytics
|
|
128
|
-
updateConsent({
|
|
129
|
-
analytics_storage: "denied",
|
|
130
|
-
ad_storage: "denied",
|
|
131
|
-
});
|
|
132
|
-
},
|
|
133
|
-
cookies: [
|
|
134
|
-
{
|
|
135
|
-
name: /^_ga/,
|
|
136
|
-
},
|
|
137
|
-
{
|
|
138
|
-
name: /^_gid/,
|
|
139
|
-
},
|
|
140
|
-
{
|
|
141
|
-
name: /^_gat/,
|
|
142
|
-
},
|
|
143
|
-
],
|
|
144
|
-
},
|
|
145
|
-
another: {
|
|
146
|
-
label: "Another one (dummy)",
|
|
147
|
-
},
|
|
148
|
-
},
|
|
149
|
-
},
|
|
150
|
-
},
|
|
151
|
-
language: {
|
|
152
|
-
default: "en",
|
|
153
|
-
autoDetect: "browser",
|
|
154
|
-
translations: {
|
|
155
|
-
en: {
|
|
156
|
-
consentModal: {
|
|
157
|
-
title: "Your Privacy Matters",
|
|
158
|
-
description:
|
|
159
|
-
"We use cookies to enhance your browsing experience, provide personalized content, and analyze our traffic. You can manage your preferences or accept all cookies. For more information, please see our Privacy Policy.",
|
|
160
|
-
acceptAllBtn: "Accept all",
|
|
161
|
-
acceptNecessaryBtn: "Reject all",
|
|
162
|
-
showPreferencesBtn: "Manage preferences",
|
|
163
|
-
footer:
|
|
164
|
-
'<a href="/privacy-policy" target="_blank" rel="noopener">Privacy Policy</a>\n<a href="/terms" target="_blank" rel="noopener">Terms and Conditions</a>',
|
|
165
|
-
},
|
|
166
|
-
preferencesModal: {
|
|
167
|
-
title: "Consent Preferences Center",
|
|
168
|
-
acceptAllBtn: "Accept all",
|
|
169
|
-
acceptNecessaryBtn: "Reject all",
|
|
170
|
-
savePreferencesBtn: "Save preferences",
|
|
171
|
-
closeIconLabel: "Close modal",
|
|
172
|
-
serviceCounterLabel: "Service|Services",
|
|
173
|
-
sections: [
|
|
174
|
-
{
|
|
175
|
-
title: "How We Use Cookies",
|
|
176
|
-
description:
|
|
177
|
-
"Cookies help us provide, protect and improve our services. You can choose which categories you want to allow. Some cookies are necessary for the website to function and cannot be switched off.",
|
|
178
|
-
},
|
|
179
|
-
{
|
|
180
|
-
title:
|
|
181
|
-
'Strictly Necessary Cookies <span class="pm__badge">Always Enabled</span>',
|
|
182
|
-
description:
|
|
183
|
-
"These cookies are essential for the website to operate properly. They enable basic functions like page navigation and access to secure areas of the website. The website cannot function properly without these cookies.",
|
|
184
|
-
linkedCategory: "necessary",
|
|
185
|
-
},
|
|
186
|
-
{
|
|
187
|
-
title: "Functionality Cookies",
|
|
188
|
-
description:
|
|
189
|
-
"Functionality cookies allow the website to remember choices you make (such as your language or the region you are in) and provide enhanced, more personal features.",
|
|
190
|
-
linkedCategory: "functionality",
|
|
191
|
-
},
|
|
192
|
-
{
|
|
193
|
-
title: "Analytics Cookies",
|
|
194
|
-
description:
|
|
195
|
-
"Analytics cookies help us understand how visitors interact with our website by collecting and reporting information anonymously. This helps us improve our services and your experience.",
|
|
196
|
-
linkedCategory: "analytics",
|
|
197
|
-
},
|
|
198
|
-
{
|
|
199
|
-
title: "More Information",
|
|
200
|
-
description:
|
|
201
|
-
'For any query in relation to my policy on cookies and your choices, please <a class="cc__link" href="#yourdomain.com">contact me</a>.',
|
|
202
|
-
},
|
|
203
|
-
],
|
|
204
|
-
},
|
|
205
|
-
},
|
|
206
|
-
},
|
|
207
|
-
},
|
|
208
|
-
};
|
|
1
|
+
import type { CookieConsentConfig } from "vanilla-cookieconsent";
|
|
2
|
+
|
|
3
|
+
const GA_MEASUREMENT_ID = (import.meta.env.PUBLIC_GA_MEASUREMENT_ID as string) || "";
|
|
4
|
+
const ANONYMIZE_IP = (import.meta.env.PUBLIC_GA_ANONYMIZE_IP as string) === "false" ? false : true;
|
|
5
|
+
const COOKIE_FLAGS = (import.meta.env.PUBLIC_GA_COOKIE_FLAGS as string) || "SameSite=None;Secure";
|
|
6
|
+
|
|
7
|
+
// 声明全局 gtag 函数类型
|
|
8
|
+
declare global {
|
|
9
|
+
function gtag(...args: any[]): void;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
function updateConsent(consent: {
|
|
13
|
+
analytics_storage: "granted" | "denied";
|
|
14
|
+
ad_storage: "granted" | "denied";
|
|
15
|
+
}) {
|
|
16
|
+
console.log("[CookieConsent] updateConsent", consent);
|
|
17
|
+
if (typeof gtag !== "undefined") {
|
|
18
|
+
gtag("consent", "update", consent);
|
|
19
|
+
} else {
|
|
20
|
+
console.log("gtag 未定义,无法更新 consent", consent);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// 加载 Google Analytics 脚本
|
|
25
|
+
function loadGA4() {
|
|
26
|
+
if (!GA_MEASUREMENT_ID) {
|
|
27
|
+
console.log("GA_MEASUREMENT_ID 为空,跳过 GA4 config");
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
console.log("[CookieConsent] loadGA4 GA_MEASUREMENT_ID:", GA_MEASUREMENT_ID);
|
|
32
|
+
|
|
33
|
+
console.log("Loading Google Analytics with ID:", GA_MEASUREMENT_ID);
|
|
34
|
+
|
|
35
|
+
// 复用 HeadCode.astro 中的全局 gtag(不要再创建第二套 dataLayer/gtag)
|
|
36
|
+
if (typeof gtag !== "undefined") {
|
|
37
|
+
gtag("config", GA_MEASUREMENT_ID, {
|
|
38
|
+
anonymize_ip: ANONYMIZE_IP,
|
|
39
|
+
cookie_flags: COOKIE_FLAGS,
|
|
40
|
+
});
|
|
41
|
+
} else {
|
|
42
|
+
console.log("gtag 未定义,跳过 GA4 config");
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// 直接加载 Google Analytics(非欧洲地区使用)
|
|
47
|
+
export function loadGA4Directly() {
|
|
48
|
+
if (!GA_MEASUREMENT_ID) {
|
|
49
|
+
console.log("GA_MEASUREMENT_ID 为空,跳过直接 GA4 config");
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
console.log(
|
|
54
|
+
"[CookieConsent] loadGA4Directly GA_MEASUREMENT_ID:",
|
|
55
|
+
GA_MEASUREMENT_ID
|
|
56
|
+
);
|
|
57
|
+
|
|
58
|
+
console.log("直接加载 Google Analytics (无需用户同意):", GA_MEASUREMENT_ID);
|
|
59
|
+
|
|
60
|
+
// 复用 HeadCode.astro 中的全局 gtag(不要再创建第二套 dataLayer/gtag)
|
|
61
|
+
if (typeof gtag !== "undefined") {
|
|
62
|
+
gtag("config", GA_MEASUREMENT_ID, {
|
|
63
|
+
anonymize_ip: ANONYMIZE_IP,
|
|
64
|
+
cookie_flags: COOKIE_FLAGS,
|
|
65
|
+
});
|
|
66
|
+
} else {
|
|
67
|
+
console.log("gtag 未定义,跳过 GA4 direct config");
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// 清除 Google Analytics cookies
|
|
72
|
+
function clearGA4Cookies() {
|
|
73
|
+
const gaCookies = document.cookie
|
|
74
|
+
.split(";")
|
|
75
|
+
.filter((cookie) => cookie.trim().startsWith("_ga"));
|
|
76
|
+
|
|
77
|
+
gaCookies.forEach((cookie) => {
|
|
78
|
+
const cookieName = cookie.split("=")[0].trim();
|
|
79
|
+
document.cookie = `${cookieName}=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/; domain=.${window.location.hostname}`;
|
|
80
|
+
document.cookie = `${cookieName}=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/`;
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
export const config: CookieConsentConfig = {
|
|
85
|
+
guiOptions: {
|
|
86
|
+
consentModal: {
|
|
87
|
+
layout: "box inline",
|
|
88
|
+
position: "bottom left",
|
|
89
|
+
},
|
|
90
|
+
preferencesModal: {
|
|
91
|
+
layout: "box",
|
|
92
|
+
position: "right",
|
|
93
|
+
equalWeightButtons: true,
|
|
94
|
+
flipButtons: false,
|
|
95
|
+
},
|
|
96
|
+
},
|
|
97
|
+
categories: {
|
|
98
|
+
necessary: {
|
|
99
|
+
readOnly: true,
|
|
100
|
+
},
|
|
101
|
+
functionality: {},
|
|
102
|
+
analytics: {
|
|
103
|
+
services: {
|
|
104
|
+
ga4: {
|
|
105
|
+
label:
|
|
106
|
+
'<a href="https://marketingplatform.google.com/about/analytics/terms/us/" target="_blank">Google Analytics 4</a>',
|
|
107
|
+
onAccept: () => {
|
|
108
|
+
console.log("Google Analytics 4 accepted");
|
|
109
|
+
console.log(
|
|
110
|
+
"[CookieConsent] onAccept, GA_MEASUREMENT_ID:",
|
|
111
|
+
GA_MEASUREMENT_ID
|
|
112
|
+
);
|
|
113
|
+
updateConsent({
|
|
114
|
+
analytics_storage: "granted",
|
|
115
|
+
ad_storage: "granted",
|
|
116
|
+
});
|
|
117
|
+
loadGA4();
|
|
118
|
+
},
|
|
119
|
+
onReject: () => {
|
|
120
|
+
console.log("Google Analytics 4 rejected");
|
|
121
|
+
console.log(
|
|
122
|
+
"[CookieConsent] onReject, GA_MEASUREMENT_ID:",
|
|
123
|
+
GA_MEASUREMENT_ID
|
|
124
|
+
);
|
|
125
|
+
clearGA4Cookies();
|
|
126
|
+
|
|
127
|
+
// 禁用 Google Analytics
|
|
128
|
+
updateConsent({
|
|
129
|
+
analytics_storage: "denied",
|
|
130
|
+
ad_storage: "denied",
|
|
131
|
+
});
|
|
132
|
+
},
|
|
133
|
+
cookies: [
|
|
134
|
+
{
|
|
135
|
+
name: /^_ga/,
|
|
136
|
+
},
|
|
137
|
+
{
|
|
138
|
+
name: /^_gid/,
|
|
139
|
+
},
|
|
140
|
+
{
|
|
141
|
+
name: /^_gat/,
|
|
142
|
+
},
|
|
143
|
+
],
|
|
144
|
+
},
|
|
145
|
+
another: {
|
|
146
|
+
label: "Another one (dummy)",
|
|
147
|
+
},
|
|
148
|
+
},
|
|
149
|
+
},
|
|
150
|
+
},
|
|
151
|
+
language: {
|
|
152
|
+
default: "en",
|
|
153
|
+
autoDetect: "browser",
|
|
154
|
+
translations: {
|
|
155
|
+
en: {
|
|
156
|
+
consentModal: {
|
|
157
|
+
title: "Your Privacy Matters",
|
|
158
|
+
description:
|
|
159
|
+
"We use cookies to enhance your browsing experience, provide personalized content, and analyze our traffic. You can manage your preferences or accept all cookies. For more information, please see our Privacy Policy.",
|
|
160
|
+
acceptAllBtn: "Accept all",
|
|
161
|
+
acceptNecessaryBtn: "Reject all",
|
|
162
|
+
showPreferencesBtn: "Manage preferences",
|
|
163
|
+
footer:
|
|
164
|
+
'<a href="/privacy-policy" target="_blank" rel="noopener">Privacy Policy</a>\n<a href="/terms" target="_blank" rel="noopener">Terms and Conditions</a>',
|
|
165
|
+
},
|
|
166
|
+
preferencesModal: {
|
|
167
|
+
title: "Consent Preferences Center",
|
|
168
|
+
acceptAllBtn: "Accept all",
|
|
169
|
+
acceptNecessaryBtn: "Reject all",
|
|
170
|
+
savePreferencesBtn: "Save preferences",
|
|
171
|
+
closeIconLabel: "Close modal",
|
|
172
|
+
serviceCounterLabel: "Service|Services",
|
|
173
|
+
sections: [
|
|
174
|
+
{
|
|
175
|
+
title: "How We Use Cookies",
|
|
176
|
+
description:
|
|
177
|
+
"Cookies help us provide, protect and improve our services. You can choose which categories you want to allow. Some cookies are necessary for the website to function and cannot be switched off.",
|
|
178
|
+
},
|
|
179
|
+
{
|
|
180
|
+
title:
|
|
181
|
+
'Strictly Necessary Cookies <span class="pm__badge">Always Enabled</span>',
|
|
182
|
+
description:
|
|
183
|
+
"These cookies are essential for the website to operate properly. They enable basic functions like page navigation and access to secure areas of the website. The website cannot function properly without these cookies.",
|
|
184
|
+
linkedCategory: "necessary",
|
|
185
|
+
},
|
|
186
|
+
{
|
|
187
|
+
title: "Functionality Cookies",
|
|
188
|
+
description:
|
|
189
|
+
"Functionality cookies allow the website to remember choices you make (such as your language or the region you are in) and provide enhanced, more personal features.",
|
|
190
|
+
linkedCategory: "functionality",
|
|
191
|
+
},
|
|
192
|
+
{
|
|
193
|
+
title: "Analytics Cookies",
|
|
194
|
+
description:
|
|
195
|
+
"Analytics cookies help us understand how visitors interact with our website by collecting and reporting information anonymously. This helps us improve our services and your experience.",
|
|
196
|
+
linkedCategory: "analytics",
|
|
197
|
+
},
|
|
198
|
+
{
|
|
199
|
+
title: "More Information",
|
|
200
|
+
description:
|
|
201
|
+
'For any query in relation to my policy on cookies and your choices, please <a class="cc__link" href="#yourdomain.com">contact me</a>.',
|
|
202
|
+
},
|
|
203
|
+
],
|
|
204
|
+
},
|
|
205
|
+
},
|
|
206
|
+
},
|
|
207
|
+
},
|
|
208
|
+
};
|