@rxdrag/website-lib-core 0.0.127 → 0.0.129

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.
Files changed (138) hide show
  1. package/README.md +1 -1
  2. package/index.ts +1 -1
  3. package/package.json +4 -4
  4. package/src/astro/animation.ts +146 -146
  5. package/src/astro/background.ts +82 -86
  6. package/src/astro/base.ts +7 -0
  7. package/src/astro/business.ts +13 -0
  8. package/src/astro/grid/consts.ts +80 -80
  9. package/src/astro/grid/index.ts +2 -2
  10. package/src/astro/grid/types.ts +35 -35
  11. package/src/astro/image.ts +239 -239
  12. package/src/astro/index.ts +12 -10
  13. package/src/astro/link.ts +20 -21
  14. package/src/astro/media.ts +123 -123
  15. package/src/astro/nav.ts +13 -13
  16. package/src/astro/section/index.ts +7 -12
  17. package/src/component-logic/index.ts +1 -1
  18. package/src/component-logic/link-client.ts +32 -32
  19. package/src/component-logic/link.ts +61 -61
  20. package/src/design-tokens.ts +160 -160
  21. package/src/entify/Entify.ts +111 -101
  22. package/src/entify/IEntify.ts +157 -177
  23. package/src/entify/index.ts +4 -4
  24. package/src/entify/lib/collectCategoryIds.ts +20 -20
  25. package/src/entify/lib/fulltextSearch.ts +63 -62
  26. package/src/entify/lib/langFields.ts +14 -14
  27. package/src/entify/lib/listToTree.ts +23 -23
  28. package/src/entify/lib/newAvatarQueryOptions.ts +4 -4
  29. package/src/entify/lib/newOgImageQueryOptions.ts +5 -5
  30. package/src/entify/lib/newQueryPostOptions.ts +42 -45
  31. package/src/entify/lib/newQueryProductOptions.ts +96 -98
  32. package/src/entify/lib/newQueryProductsMediaOptions.ts +28 -28
  33. package/src/entify/lib/queryAllProducts.ts +40 -40
  34. package/src/entify/lib/queryBulletin.ts +28 -16
  35. package/src/entify/lib/queryEntityList.ts +41 -41
  36. package/src/entify/lib/queryFeaturedProducts.ts +69 -68
  37. package/src/entify/lib/queryLangs.ts +36 -60
  38. package/src/entify/lib/queryLatestPosts.ts +92 -91
  39. package/src/entify/lib/queryOneEntity.ts +63 -63
  40. package/src/entify/lib/queryOneMedia.ts +27 -27
  41. package/src/entify/lib/queryOnePostById.ts +21 -21
  42. package/src/entify/lib/queryOnePostBySlug.ts +40 -39
  43. package/src/entify/lib/queryOnePostCategoryBySlug.ts +35 -35
  44. package/src/entify/lib/queryOneProductById.ts +20 -20
  45. package/src/entify/lib/queryOneProductBySlug.ts +53 -52
  46. package/src/entify/lib/queryOneProductCategoryBySlug.ts +50 -49
  47. package/src/entify/lib/queryOneTheme.ts +54 -72
  48. package/src/entify/lib/queryOneUser.ts +38 -38
  49. package/src/entify/lib/queryPostCategories.ts +67 -67
  50. package/src/entify/lib/queryPostSlugs.ts +37 -37
  51. package/src/entify/lib/queryPosts.ts +175 -174
  52. package/src/entify/lib/queryProductCategories.ts +59 -59
  53. package/src/entify/lib/queryProducts.ts +145 -144
  54. package/src/entify/lib/queryProductsInMenu.ts +45 -45
  55. package/src/entify/lib/queryTagCategories.ts +58 -58
  56. package/src/entify/lib/queryTags.ts +57 -57
  57. package/src/entify/lib/queryUserIds.ts +24 -24
  58. package/src/entify/lib/queryUserPosts.ts +80 -79
  59. package/src/entify/lib/queryWebSiteSettings.ts +28 -28
  60. package/src/entify/lib/queryWebsite.ts +43 -43
  61. package/src/entify/lib/sendEmail.ts +7 -7
  62. package/src/entify/lib/toQueryOptions.ts +19 -19
  63. package/src/entify/lib/upsertEntity.ts +8 -8
  64. package/src/entify/types/index.ts +1 -1
  65. package/src/entify/types/utils.ts +11 -6
  66. package/src/entify/types/variables.ts +0 -1
  67. package/src/entify/view-model/funcs.ts +230 -230
  68. package/src/entify/view-model/index.ts +1 -1
  69. package/src/entify/view-model/models.ts +135 -135
  70. package/src/global.d.ts +7 -7
  71. package/src/index.ts +8 -8
  72. package/src/lib/formatDate.ts +15 -15
  73. package/src/lib/index.ts +3 -3
  74. package/src/lib/pagination.ts +114 -114
  75. package/src/lib/utils.ts +135 -135
  76. package/src/react/components/Analytics/eventHandlers.ts +173 -173
  77. package/src/react/components/Analytics/index.tsx +21 -21
  78. package/src/react/components/Analytics/singleton.ts +214 -214
  79. package/src/react/components/Analytics/tracking.ts +221 -221
  80. package/src/react/components/Analytics/types.ts +60 -60
  81. package/src/react/components/Analytics/utils.ts +95 -95
  82. package/src/react/components/AttachmentIcon/index.tsx +53 -53
  83. package/src/react/components/BackgroundHlsVideoPlayer.tsx +97 -97
  84. package/src/react/components/BackgroundVideoPlayer.tsx +32 -32
  85. package/src/react/components/Bulletin.tsx +30 -30
  86. package/src/react/components/ContactForm/ContactForm.tsx +289 -289
  87. package/src/react/components/ContactForm/Input.tsx +48 -48
  88. package/src/react/components/ContactForm/Input2.tsx +59 -59
  89. package/src/react/components/ContactForm/Submit.tsx +48 -48
  90. package/src/react/components/ContactForm/TelInput.tsx +215 -215
  91. package/src/react/components/ContactForm/Textarea.tsx +48 -48
  92. package/src/react/components/ContactForm/Textarea2.tsx +89 -89
  93. package/src/react/components/ContactForm/funcs.ts +64 -64
  94. package/src/react/components/ContactForm/index.ts +7 -7
  95. package/src/react/components/ContactForm/types.ts +68 -68
  96. package/src/react/components/GoogleConsent/CookieItemPanel.tsx +80 -80
  97. package/src/react/components/GoogleConsent/CumtomizedModal.tsx +148 -148
  98. package/src/react/components/GoogleConsent/GoogleConsent.tsx +100 -100
  99. package/src/react/components/GoogleConsent/gtags.ts +67 -67
  100. package/src/react/components/GoogleConsent/index.ts +2 -2
  101. package/src/react/components/GoogleConsent/types.ts +18 -18
  102. package/src/react/components/GoogleConsent//345/217/202/350/200/203.md +4 -4
  103. package/src/react/components/Icon/index.tsx +19 -19
  104. package/src/react/components/Medias/MainMedia.tsx +257 -257
  105. package/src/react/components/Medias/Thumbnail.tsx +62 -62
  106. package/src/react/components/Medias/VideoPlayer.tsx +114 -114
  107. package/src/react/components/Medias/index.tsx +271 -271
  108. package/src/react/components/ProductCard/ProductCard.tsx +24 -24
  109. package/src/react/components/ProductCard/ProductCta/index.tsx +28 -28
  110. package/src/react/components/ProductCard/ProductCta/style.css +3 -3
  111. package/src/react/components/ProductCard/ProductDescription/index.tsx +12 -12
  112. package/src/react/components/ProductCard/ProductDescription/style.css +5 -5
  113. package/src/react/components/ProductCard/ProductMedia/index.tsx +35 -35
  114. package/src/react/components/ProductCard/ProductMedia/style.css +5 -5
  115. package/src/react/components/ProductCard/ProductTitle/index.tsx +7 -7
  116. package/src/react/components/ProductCard/ProductTitle/style.css +3 -3
  117. package/src/react/components/ProductCard/ProductView.tsx +36 -36
  118. package/src/react/components/ProductCard/index.ts +4 -4
  119. package/src/react/components/ProductCard/useQueryProduct.ts +32 -32
  120. package/src/react/components/ReactModalTrigger.tsx +28 -28
  121. package/src/react/components/ReactVideoPlayer.tsx +29 -52
  122. package/src/react/components/RichTextOutline/index.tsx +75 -75
  123. package/src/react/components/RichTextOutline/useAnchorScroll.ts +23 -23
  124. package/src/react/components/Scroller.tsx +39 -39
  125. package/src/react/components/SearchInput.tsx +21 -21
  126. package/src/react/components/Share/index.tsx +86 -86
  127. package/src/react/components/Share/socials.tsx +79 -77
  128. package/src/react/components/Share//350/265/204/346/226/231.md +7 -7
  129. package/src/react/components/ToTop.tsx +72 -72
  130. package/src/react/components/VideoPlayIcon.tsx +43 -0
  131. package/src/react/components/all.ts +38 -38
  132. package/src/react/components/index.ts +16 -16
  133. package/src/robots.ts +4 -4
  134. package/src/entify/lib/newPageMetaOptions.ts +0 -18
  135. package/src/entify/lib/newQueryPageOptions.ts +0 -14
  136. package/src/entify/lib/queryOneIcon.ts +0 -27
  137. package/src/entify/lib/queryPageBySlug.ts +0 -43
  138. package/src/entify/lib/queryPageByType.ts +0 -44
@@ -1,81 +1,81 @@
1
- import type { CookieItem } from "./types";
2
- import clsx from "clsx";
3
- import { motion } from "framer-motion";
4
-
5
- export function CookieItemPanel(props: {
6
- item: CookieItem,
7
- openedItem?: string,
8
- onToggle: (value: string) => void,
9
- checked?: boolean
10
- onChange?: (checked: boolean) => void
11
- }) {
12
- const { item, openedItem, checked, onChange, onToggle } = props;
13
-
14
- const opened = openedItem === item.checkbox.valueName;
15
- return (
16
- <div className="p-4 bg-gray-100 rounded-md">
17
- <div className="flex justify-between">
18
- <h2
19
- className="flex text-sm font-bold items-center gap-2 cursor-pointer select-none"
20
- onClick={() => onToggle(item.checkbox.valueName)}
21
- >
22
- <span
23
- className={
24
- clsx(
25
- "rounded-full h-7 w-7 p-1 bg-gray-200 transition-transform duration-200 ease-in-out",
26
- opened ? "transform rotate-[-180deg]" : ""
27
- )
28
- }>
29
- <svg
30
- xmlns="http://www.w3.org/2000/svg"
31
- fill="none"
32
- viewBox="0 0 24 24"
33
- strokeWidth="1.5"
34
- stroke="currentColor">
35
- <path
36
- strokeLinecap="round"
37
- strokeLinejoin="round"
38
- d="M19.5 8.25l-7.5 7.5-7.5-7.5" />
39
- </svg>
40
- </span>
41
- <span>
42
- {item.title}
43
- </span>
44
- </h2>
45
- <div className="flex items-center gap-2">
46
- <span className="text-sm">
47
- {item.checkbox.alwaysActive ? item.checkbox.label : (checked ? "Active" : "")}
48
- </span>
49
- <label className="relative inline-flex cursor-pointer items-center">
50
- <input
51
- id="switch"
52
- checked={item.checkbox.alwaysActive || checked}
53
- type="checkbox" className="peer sr-only"
54
- onChange={() => {
55
- onChange?.(!checked);
56
- }}
57
- />
58
- <label htmlFor="switch" className="hidden"></label>
59
- <div className="peer h-6 w-11 rounded-full border bg-slate-200 after:absolute after:left-[2px] after:top-0.5 after:h-5 after:w-5 after:rounded-full after:border after:border-gray-300 after:bg-white after:transition-all after:content-[''] peer-checked:bg-slate-800 peer-checked:after:translate-x-full peer-checked:after:border-white peer-focus:ring-green-300"></div>
60
- </label>
61
- </div>
62
- </div>
63
-
64
- <p className={clsx(opened ? "" : "hidden")}>
65
- <motion.div
66
- initial="hidden"
67
- className={
68
- clsx("text-sm pt-4")
69
- }
70
- animate={{
71
- opacity: opened ? "1" : "0",
72
- height: opened ? "auto" : "0",
73
- transition: opened ? { duration: 0.2, } : {}
74
- }}
75
- >
76
- {item.content}
77
- </motion.div>
78
- </p>
79
- </div >
80
- )
1
+ import type { CookieItem } from "./types";
2
+ import clsx from "clsx";
3
+ import { motion } from "framer-motion";
4
+
5
+ export function CookieItemPanel(props: {
6
+ item: CookieItem,
7
+ openedItem?: string,
8
+ onToggle: (value: string) => void,
9
+ checked?: boolean
10
+ onChange?: (checked: boolean) => void
11
+ }) {
12
+ const { item, openedItem, checked, onChange, onToggle } = props;
13
+
14
+ const opened = openedItem === item.checkbox.valueName;
15
+ return (
16
+ <div className="p-4 bg-gray-100 rounded-md">
17
+ <div className="flex justify-between">
18
+ <h2
19
+ className="flex text-sm font-bold items-center gap-2 cursor-pointer select-none"
20
+ onClick={() => onToggle(item.checkbox.valueName)}
21
+ >
22
+ <span
23
+ className={
24
+ clsx(
25
+ "rounded-full h-7 w-7 p-1 bg-gray-200 transition-transform duration-200 ease-in-out",
26
+ opened ? "transform rotate-[-180deg]" : ""
27
+ )
28
+ }>
29
+ <svg
30
+ xmlns="http://www.w3.org/2000/svg"
31
+ fill="none"
32
+ viewBox="0 0 24 24"
33
+ strokeWidth="1.5"
34
+ stroke="currentColor">
35
+ <path
36
+ strokeLinecap="round"
37
+ strokeLinejoin="round"
38
+ d="M19.5 8.25l-7.5 7.5-7.5-7.5" />
39
+ </svg>
40
+ </span>
41
+ <span>
42
+ {item.title}
43
+ </span>
44
+ </h2>
45
+ <div className="flex items-center gap-2">
46
+ <span className="text-sm">
47
+ {item.checkbox.alwaysActive ? item.checkbox.label : (checked ? "Active" : "")}
48
+ </span>
49
+ <label className="relative inline-flex cursor-pointer items-center">
50
+ <input
51
+ id="switch"
52
+ checked={item.checkbox.alwaysActive || checked}
53
+ type="checkbox" className="peer sr-only"
54
+ onChange={() => {
55
+ onChange?.(!checked);
56
+ }}
57
+ />
58
+ <label htmlFor="switch" className="hidden"></label>
59
+ <div className="peer h-6 w-11 rounded-full border bg-slate-200 after:absolute after:left-[2px] after:top-0.5 after:h-5 after:w-5 after:rounded-full after:border after:border-gray-300 after:bg-white after:transition-all after:content-[''] peer-checked:bg-slate-800 peer-checked:after:translate-x-full peer-checked:after:border-white peer-focus:ring-green-300"></div>
60
+ </label>
61
+ </div>
62
+ </div>
63
+
64
+ <p className={clsx(opened ? "" : "hidden")}>
65
+ <motion.div
66
+ initial="hidden"
67
+ className={
68
+ clsx("text-sm pt-4")
69
+ }
70
+ animate={{
71
+ opacity: opened ? "1" : "0",
72
+ height: opened ? "auto" : "0",
73
+ transition: opened ? { duration: 0.2, } : {}
74
+ }}
75
+ >
76
+ {item.content}
77
+ </motion.div>
78
+ </p>
79
+ </div >
80
+ )
81
81
  }
@@ -1,149 +1,149 @@
1
- import type { ConsentSettings, CookieItem } from "./types"
2
- import { CookieItemPanel } from "./CookieItemPanel"
3
- import { useState } from "react"
4
- import { XModal } from "../XModal/XModal"
5
- import { XModalAction } from "../XModalAction"
6
- import { XModalOverlay } from "../XModalOverlay"
7
- import { XModalContent } from "../XModalContent"
8
- import { XModalClose } from "../XModalClose"
9
-
10
- const items: CookieItem[] = [
11
- {
12
- title: "Strictly Necessary Cookies",
13
- content: "These cookies are necessary for the website to function and cannot be switched off in our systems. They are usually only set in response to actions made by you which amount to a request for services, such as setting your privacy preferences or filling in forms.",
14
- checkbox: {
15
- valueName: "strictlyNecessary",
16
- label: "Always Active",
17
- alwaysActive: true,
18
- }
19
- },
20
- {
21
- title: "Analytics Cookies",
22
- content: "These cookies allow us to track analytics by counting visits and traffic sources so we can measure and improve the performance of our website. They may be set by us or by third party providers to help us to know which pages are the most and least popular and see how visitors move around the website.",
23
- checkbox: {
24
- valueName: "analytics",
25
- }
26
- },
27
- {
28
- title: "Functionality Cookies",
29
- content: "These cookies enable the website to provide enhanced functionality and personalization based on your interaction with the website. They may be set by us or by third party providers whose services we have added to our pages.",
30
- checkbox: {
31
- valueName: "functionality",
32
- }
33
- },
34
- {
35
- title: "Advertisement Cookies",
36
- content: "These cookies may be set through our site by our advertising partners. They may be used by those partners to build a profile of your interests and show you relevant advertisements on other websites.",
37
- checkbox: {
38
- valueName: "advertisement",
39
- }
40
- }
41
- ]
42
-
43
- export function CumtomizedModal(
44
- props: {
45
- onAcceptAll?: () => void,
46
- onRejectAll?: () => void,
47
- onSavePreferences?: (consent: ConsentSettings) => void
48
- }
49
- ) {
50
- const { onAcceptAll, onRejectAll, onSavePreferences } = props;
51
- const [openedItem, setOpenedItem] = useState<string>();
52
- const [consent, setConsent] = useState<ConsentSettings>({
53
- strictlyNecessary: true,
54
- analytics: false,
55
- functionality: false,
56
- advertisement: false,
57
- });
58
-
59
-
60
- const handleSavePreferences = () => {
61
- onSavePreferences?.(consent);
62
- }
63
-
64
- return (
65
- <XModal
66
- className="col-span-2 "
67
- action={
68
- <XModalAction
69
- className="w-full text-white py-2 px-2 rounded bg-gray-700 hover:bg-gray-800"
70
- >
71
- Custimized Settings
72
- </XModalAction>
73
- }
74
- overlay={
75
- <XModalOverlay
76
- initial={{ opacity: 0 }}
77
- animate={{ opacity: 1 }}
78
- exit={{ opacity: 0 }}
79
- className="fixed inset-0 bg-black/30 backdrop-blur-md"
80
- />
81
- }
82
- content={
83
- <div className="fixed inset-0 flex w-screen items-center justify-center p-4">
84
- <XModalContent
85
- initial={{ opacity: 0, scale: 0.95 }}
86
- animate={{ opacity: 1, scale: 1 }}
87
- exit={{ opacity: 0, scale: 0.95 }}
88
- className="relative max-w-2xl space-y-4 bg-white pb-4 pt-0 px-4 rounded-lg w-full overflow-hidden"
89
- >
90
- <XModalClose className="absolute right-4 top-4 ">
91
- <svg className="h-6 w-6" fill="none" viewBox="0 0 24 24" strokeWidth="1.5" stroke="currentColor" aria-hidden="true">
92
- <path strokeLinecap="round" strokeLinejoin="round" d="M6 18L18 6M6 6l12 12" />
93
- </svg>
94
- </XModalClose>
95
- <div className="text-xl font-bold px-2">Privacy Preference Center</div>
96
- <div className="h-[420px] overflow-y-scroll flex flex-col gap-2 px-2">
97
- <h2 className="text-md font-bold">Cookie Usage</h2>
98
- <p className="text-sm">
99
- These cookies allow us to track analytics by counting visits and traffic sources so we can measure and improve the performance of our website. They may be set by us or by third party providers to help us to know which pages are the most and least popular and see how visitors move around the website.
100
- </p>
101
- {
102
- items.map((item, index) => (
103
- <CookieItemPanel
104
- key={index}
105
- item={item}
106
- openedItem={openedItem}
107
- checked={consent[item.checkbox.valueName as keyof ConsentSettings]}
108
- onToggle={(value) => {
109
- setOpenedItem(openedItem === value ? undefined : value);
110
- }}
111
- onChange={(checked) => {
112
- setConsent((prev) => ({
113
- ...prev,
114
- [item.checkbox.valueName]: checked
115
- }))
116
- }}
117
- />
118
- ))
119
- }
120
- </div>
121
- <div className="flex items-center justify-between text-sm">
122
- <div className="flex gap-4">
123
- <button
124
- className="bg-gray-700 hover:bg-gray-800 text-white py-2 px-3 rounded"
125
- onClick={onAcceptAll}
126
- >
127
- Accept All Cookies
128
- </button>
129
- <button
130
- className="bg-gray-700 hover:bg-gray-800 text-white py-2 px-3 rounded"
131
- onClick={onRejectAll}
132
- >
133
- Reject All
134
- </button>
135
- </div>
136
- <button
137
- className="bg-green-500 hover:bg-green-600 text-white py-2 px-3 rounded"
138
- onClick={handleSavePreferences}
139
- >
140
- Save Preferences
141
- </button>
142
- </div>
143
- </XModalContent>
144
- </div>
145
- }
146
-
147
- />
148
- )
1
+ import type { ConsentSettings, CookieItem } from "./types"
2
+ import { CookieItemPanel } from "./CookieItemPanel"
3
+ import { useState } from "react"
4
+ import { XModal } from "../XModal/XModal"
5
+ import { XModalAction } from "../XModalAction"
6
+ import { XModalOverlay } from "../XModalOverlay"
7
+ import { XModalContent } from "../XModalContent"
8
+ import { XModalClose } from "../XModalClose"
9
+
10
+ const items: CookieItem[] = [
11
+ {
12
+ title: "Strictly Necessary Cookies",
13
+ content: "These cookies are necessary for the website to function and cannot be switched off in our systems. They are usually only set in response to actions made by you which amount to a request for services, such as setting your privacy preferences or filling in forms.",
14
+ checkbox: {
15
+ valueName: "strictlyNecessary",
16
+ label: "Always Active",
17
+ alwaysActive: true,
18
+ }
19
+ },
20
+ {
21
+ title: "Analytics Cookies",
22
+ content: "These cookies allow us to track analytics by counting visits and traffic sources so we can measure and improve the performance of our website. They may be set by us or by third party providers to help us to know which pages are the most and least popular and see how visitors move around the website.",
23
+ checkbox: {
24
+ valueName: "analytics",
25
+ }
26
+ },
27
+ {
28
+ title: "Functionality Cookies",
29
+ content: "These cookies enable the website to provide enhanced functionality and personalization based on your interaction with the website. They may be set by us or by third party providers whose services we have added to our pages.",
30
+ checkbox: {
31
+ valueName: "functionality",
32
+ }
33
+ },
34
+ {
35
+ title: "Advertisement Cookies",
36
+ content: "These cookies may be set through our site by our advertising partners. They may be used by those partners to build a profile of your interests and show you relevant advertisements on other websites.",
37
+ checkbox: {
38
+ valueName: "advertisement",
39
+ }
40
+ }
41
+ ]
42
+
43
+ export function CumtomizedModal(
44
+ props: {
45
+ onAcceptAll?: () => void,
46
+ onRejectAll?: () => void,
47
+ onSavePreferences?: (consent: ConsentSettings) => void
48
+ }
49
+ ) {
50
+ const { onAcceptAll, onRejectAll, onSavePreferences } = props;
51
+ const [openedItem, setOpenedItem] = useState<string>();
52
+ const [consent, setConsent] = useState<ConsentSettings>({
53
+ strictlyNecessary: true,
54
+ analytics: false,
55
+ functionality: false,
56
+ advertisement: false,
57
+ });
58
+
59
+
60
+ const handleSavePreferences = () => {
61
+ onSavePreferences?.(consent);
62
+ }
63
+
64
+ return (
65
+ <XModal
66
+ className="col-span-2 "
67
+ action={
68
+ <XModalAction
69
+ className="w-full text-white py-2 px-2 rounded bg-gray-700 hover:bg-gray-800"
70
+ >
71
+ Custimized Settings
72
+ </XModalAction>
73
+ }
74
+ overlay={
75
+ <XModalOverlay
76
+ initial={{ opacity: 0 }}
77
+ animate={{ opacity: 1 }}
78
+ exit={{ opacity: 0 }}
79
+ className="fixed inset-0 bg-black/30 backdrop-blur-md"
80
+ />
81
+ }
82
+ content={
83
+ <div className="fixed inset-0 flex w-screen items-center justify-center p-4">
84
+ <XModalContent
85
+ initial={{ opacity: 0, scale: 0.95 }}
86
+ animate={{ opacity: 1, scale: 1 }}
87
+ exit={{ opacity: 0, scale: 0.95 }}
88
+ className="relative max-w-2xl space-y-4 bg-white pb-4 pt-0 px-4 rounded-lg w-full overflow-hidden"
89
+ >
90
+ <XModalClose className="absolute right-4 top-4 ">
91
+ <svg className="h-6 w-6" fill="none" viewBox="0 0 24 24" strokeWidth="1.5" stroke="currentColor" aria-hidden="true">
92
+ <path strokeLinecap="round" strokeLinejoin="round" d="M6 18L18 6M6 6l12 12" />
93
+ </svg>
94
+ </XModalClose>
95
+ <div className="text-xl font-bold px-2">Privacy Preference Center</div>
96
+ <div className="h-[420px] overflow-y-scroll flex flex-col gap-2 px-2">
97
+ <h2 className="text-md font-bold">Cookie Usage</h2>
98
+ <p className="text-sm">
99
+ These cookies allow us to track analytics by counting visits and traffic sources so we can measure and improve the performance of our website. They may be set by us or by third party providers to help us to know which pages are the most and least popular and see how visitors move around the website.
100
+ </p>
101
+ {
102
+ items.map((item, index) => (
103
+ <CookieItemPanel
104
+ key={index}
105
+ item={item}
106
+ openedItem={openedItem}
107
+ checked={consent[item.checkbox.valueName as keyof ConsentSettings]}
108
+ onToggle={(value) => {
109
+ setOpenedItem(openedItem === value ? undefined : value);
110
+ }}
111
+ onChange={(checked) => {
112
+ setConsent((prev) => ({
113
+ ...prev,
114
+ [item.checkbox.valueName]: checked
115
+ }))
116
+ }}
117
+ />
118
+ ))
119
+ }
120
+ </div>
121
+ <div className="flex items-center justify-between text-sm">
122
+ <div className="flex gap-4">
123
+ <button
124
+ className="bg-gray-700 hover:bg-gray-800 text-white py-2 px-3 rounded"
125
+ onClick={onAcceptAll}
126
+ >
127
+ Accept All Cookies
128
+ </button>
129
+ <button
130
+ className="bg-gray-700 hover:bg-gray-800 text-white py-2 px-3 rounded"
131
+ onClick={onRejectAll}
132
+ >
133
+ Reject All
134
+ </button>
135
+ </div>
136
+ <button
137
+ className="bg-green-500 hover:bg-green-600 text-white py-2 px-3 rounded"
138
+ onClick={handleSavePreferences}
139
+ >
140
+ Save Preferences
141
+ </button>
142
+ </div>
143
+ </XModalContent>
144
+ </div>
145
+ }
146
+
147
+ />
148
+ )
149
149
  }
@@ -1,101 +1,101 @@
1
- import { useEffect, useMemo, useState } from "react";
2
- import { CumtomizedModal } from "./CumtomizedModal";
3
- import Cookies from "universal-cookie"
4
- import { ConsentSettings } from "./types";
5
- import { Container } from "../Container";
6
- import { gtag } from "./gtags";
7
-
8
- const COOKIE_NAME = "gdpr-consent";
9
-
10
- const DEINED_ALL: ConsentSettings = {
11
- strictlyNecessary: true,
12
- analytics: false,
13
- functionality: false,
14
- advertisement: false,
15
- }
16
-
17
- export function XGoogleConsent(props: {
18
- domain?: string
19
- }) {
20
- const { domain } = props;
21
-
22
- const [decisionMade, setDecisionMade] = useState(true) // start with true to avoid flashing
23
- const cookies = useMemo(() => new Cookies(), []);
24
-
25
- useEffect(() => {
26
- const consent = cookies.get(COOKIE_NAME);
27
- if (consent !== undefined) {
28
- setDecisionMade(true)
29
- sendConsent(consent)
30
- } else {
31
- setDecisionMade(false)
32
- // 默认设置
33
- gtag.consent(DEINED_ALL);
34
- }
35
- }, [cookies, setDecisionMade])
36
-
37
- const handleSavePreferences = (consent: ConsentSettings) => {
38
- saveDecision(consent)
39
- };
40
-
41
- const handleDeclineAll = () => {
42
- saveDecision(DEINED_ALL)
43
- };
44
-
45
- const saveDecision = (consent: ConsentSettings) => {
46
- sendConsent(consent);
47
-
48
- cookies.set(COOKIE_NAME, consent, {
49
- expires: new Date(new Date().setFullYear(new Date().getFullYear() + 1)),
50
- path: "/",
51
- domain: domain
52
- })
53
-
54
- setDecisionMade(true)
55
- }
56
-
57
- const sendConsent = (consent: ConsentSettings) => {
58
- gtag.consent(consent);
59
- }
60
-
61
- const handleAcceptAll = () => {
62
- saveDecision({
63
- advertisement: true,
64
- analytics: true,
65
- functionality: true,
66
- strictlyNecessary: true
67
- })
68
- };
69
-
70
- if (decisionMade) {
71
- return null;
72
- }
73
-
74
- return (
75
- <div className="fixed left-0 bottom-0 w-full shadow-lg bg-gray-600">
76
- <Container>
77
- <div className="text-white p-6 w-full">
78
- <div className="flex flex-1 items-center gap-8 justify-between">
79
- <div className="text-sm">
80
- <h2 className="text-md font-bold pb-2">We Value Your Privacy</h2>
81
- We use cookies for site improvement, personalization, and ads. Accepting enhances your experience, but you can manage preferences or decline non-essential cookies. See our <a className="text-blue-500" target="_blank" href="/privacy-policy">Cookie Policy</a> for details.
82
- </div>
83
- <div className="grid grid-cols-2 w-[300px] gap-2 text-sm">
84
- <button onClick={handleAcceptAll} className="bg-green-400 hover:bg-green-500 text-white py-2 px-2 rounded">
85
- Accept All
86
- </button>
87
- <button onClick={handleDeclineAll} className="text-white py-2 px-2 rounded bg-gray-700 hover:bg-gray-800">
88
- Decline All
89
- </button>
90
- <CumtomizedModal
91
- onAcceptAll={handleAcceptAll}
92
- onRejectAll={handleDeclineAll}
93
- onSavePreferences={handleSavePreferences}
94
- />
95
- </div>
96
- </div>
97
- </div>
98
- </Container>
99
- </div>
100
- );
1
+ import { useEffect, useMemo, useState } from "react";
2
+ import { CumtomizedModal } from "./CumtomizedModal";
3
+ import Cookies from "universal-cookie"
4
+ import { ConsentSettings } from "./types";
5
+ import { Container } from "../Container";
6
+ import { gtag } from "./gtags";
7
+
8
+ const COOKIE_NAME = "gdpr-consent";
9
+
10
+ const DEINED_ALL: ConsentSettings = {
11
+ strictlyNecessary: true,
12
+ analytics: false,
13
+ functionality: false,
14
+ advertisement: false,
15
+ }
16
+
17
+ export function XGoogleConsent(props: {
18
+ domain?: string
19
+ }) {
20
+ const { domain } = props;
21
+
22
+ const [decisionMade, setDecisionMade] = useState(true) // start with true to avoid flashing
23
+ const cookies = useMemo(() => new Cookies(), []);
24
+
25
+ useEffect(() => {
26
+ const consent = cookies.get(COOKIE_NAME);
27
+ if (consent !== undefined) {
28
+ setDecisionMade(true)
29
+ sendConsent(consent)
30
+ } else {
31
+ setDecisionMade(false)
32
+ // 默认设置
33
+ gtag.consent(DEINED_ALL);
34
+ }
35
+ }, [cookies, setDecisionMade])
36
+
37
+ const handleSavePreferences = (consent: ConsentSettings) => {
38
+ saveDecision(consent)
39
+ };
40
+
41
+ const handleDeclineAll = () => {
42
+ saveDecision(DEINED_ALL)
43
+ };
44
+
45
+ const saveDecision = (consent: ConsentSettings) => {
46
+ sendConsent(consent);
47
+
48
+ cookies.set(COOKIE_NAME, consent, {
49
+ expires: new Date(new Date().setFullYear(new Date().getFullYear() + 1)),
50
+ path: "/",
51
+ domain: domain
52
+ })
53
+
54
+ setDecisionMade(true)
55
+ }
56
+
57
+ const sendConsent = (consent: ConsentSettings) => {
58
+ gtag.consent(consent);
59
+ }
60
+
61
+ const handleAcceptAll = () => {
62
+ saveDecision({
63
+ advertisement: true,
64
+ analytics: true,
65
+ functionality: true,
66
+ strictlyNecessary: true
67
+ })
68
+ };
69
+
70
+ if (decisionMade) {
71
+ return null;
72
+ }
73
+
74
+ return (
75
+ <div className="fixed left-0 bottom-0 w-full shadow-lg bg-gray-600">
76
+ <Container>
77
+ <div className="text-white p-6 w-full">
78
+ <div className="flex flex-1 items-center gap-8 justify-between">
79
+ <div className="text-sm">
80
+ <h2 className="text-md font-bold pb-2">We Value Your Privacy</h2>
81
+ We use cookies for site improvement, personalization, and ads. Accepting enhances your experience, but you can manage preferences or decline non-essential cookies. See our <a className="text-blue-500" target="_blank" href="/privacy-policy">Cookie Policy</a> for details.
82
+ </div>
83
+ <div className="grid grid-cols-2 w-[300px] gap-2 text-sm">
84
+ <button onClick={handleAcceptAll} className="bg-green-400 hover:bg-green-500 text-white py-2 px-2 rounded">
85
+ Accept All
86
+ </button>
87
+ <button onClick={handleDeclineAll} className="text-white py-2 px-2 rounded bg-gray-700 hover:bg-gray-800">
88
+ Decline All
89
+ </button>
90
+ <CumtomizedModal
91
+ onAcceptAll={handleAcceptAll}
92
+ onRejectAll={handleDeclineAll}
93
+ onSavePreferences={handleSavePreferences}
94
+ />
95
+ </div>
96
+ </div>
97
+ </div>
98
+ </Container>
99
+ </div>
100
+ );
101
101
  }