@mission-studio/puck 1.0.2 → 1.0.5
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/dist/chunk-QSWQDR6M.mjs +67 -0
- package/dist/{chunk-RVOG4KFI.mjs → chunk-R7TH6TWG.mjs} +91 -123
- package/dist/config-entry.js +83 -63
- package/dist/config-entry.mjs +2 -1
- package/dist/hooks/index.d.mts +32 -0
- package/dist/hooks/index.d.ts +32 -0
- package/dist/hooks/index.js +94 -0
- package/dist/hooks/index.mjs +8 -0
- package/dist/index.js +83 -63
- package/dist/index.mjs +2 -1
- package/package.json +7 -1
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
// hooks/useGtmEvent.ts
|
|
2
|
+
function useGtmEvent() {
|
|
3
|
+
return (eventName, data) => {
|
|
4
|
+
if (typeof window === "undefined") return;
|
|
5
|
+
if (typeof window.gtag === "function") {
|
|
6
|
+
window.gtag("event", eventName, data || {});
|
|
7
|
+
}
|
|
8
|
+
};
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
// hooks/useUtmParams.ts
|
|
12
|
+
import { useEffect, useState } from "react";
|
|
13
|
+
function useUtmParams() {
|
|
14
|
+
const [utmParams, setUtmParams] = useState({});
|
|
15
|
+
useEffect(() => {
|
|
16
|
+
if (typeof window === "undefined") return;
|
|
17
|
+
const urlParams = new URLSearchParams(window.location.search);
|
|
18
|
+
const source = urlParams.get("utm_source");
|
|
19
|
+
const medium = urlParams.get("utm_medium");
|
|
20
|
+
const campaign = urlParams.get("utm_campaign");
|
|
21
|
+
const content = urlParams.get("utm_content");
|
|
22
|
+
const term = urlParams.get("utm_term");
|
|
23
|
+
const params = {};
|
|
24
|
+
if (source) {
|
|
25
|
+
params.source = source;
|
|
26
|
+
sessionStorage.setItem("utm_source", source);
|
|
27
|
+
} else {
|
|
28
|
+
const stored = sessionStorage.getItem("utm_source");
|
|
29
|
+
if (stored) params.source = stored;
|
|
30
|
+
}
|
|
31
|
+
if (medium) {
|
|
32
|
+
params.medium = medium;
|
|
33
|
+
sessionStorage.setItem("utm_medium", medium);
|
|
34
|
+
} else {
|
|
35
|
+
const stored = sessionStorage.getItem("utm_medium");
|
|
36
|
+
if (stored) params.medium = stored;
|
|
37
|
+
}
|
|
38
|
+
if (campaign) {
|
|
39
|
+
params.campaign = campaign;
|
|
40
|
+
sessionStorage.setItem("utm_campaign", campaign);
|
|
41
|
+
} else {
|
|
42
|
+
const stored = sessionStorage.getItem("utm_campaign");
|
|
43
|
+
if (stored) params.campaign = stored;
|
|
44
|
+
}
|
|
45
|
+
if (content) {
|
|
46
|
+
params.content = content;
|
|
47
|
+
sessionStorage.setItem("utm_content", content);
|
|
48
|
+
} else {
|
|
49
|
+
const stored = sessionStorage.getItem("utm_content");
|
|
50
|
+
if (stored) params.content = stored;
|
|
51
|
+
}
|
|
52
|
+
if (term) {
|
|
53
|
+
params.term = term;
|
|
54
|
+
sessionStorage.setItem("utm_term", term);
|
|
55
|
+
} else {
|
|
56
|
+
const stored = sessionStorage.getItem("utm_term");
|
|
57
|
+
if (stored) params.term = stored;
|
|
58
|
+
}
|
|
59
|
+
setUtmParams(params);
|
|
60
|
+
}, []);
|
|
61
|
+
return utmParams;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export {
|
|
65
|
+
useGtmEvent,
|
|
66
|
+
useUtmParams
|
|
67
|
+
};
|
|
@@ -5,6 +5,9 @@ import {
|
|
|
5
5
|
useEntries,
|
|
6
6
|
useTheme
|
|
7
7
|
} from "./chunk-TTKY3YGP.mjs";
|
|
8
|
+
import {
|
|
9
|
+
useUtmParams
|
|
10
|
+
} from "./chunk-QSWQDR6M.mjs";
|
|
8
11
|
|
|
9
12
|
// components/page/Heading.tsx
|
|
10
13
|
import { jsx } from "react/jsx-runtime";
|
|
@@ -158,76 +161,8 @@ function Paragraph({
|
|
|
158
161
|
return /* @__PURE__ */ jsx2("p", { id, style, children: resolvedText });
|
|
159
162
|
}
|
|
160
163
|
|
|
161
|
-
// hooks/useGtmEvent.ts
|
|
162
|
-
function useGtmEvent() {
|
|
163
|
-
return (eventName, data) => {
|
|
164
|
-
if (typeof window === "undefined") return;
|
|
165
|
-
if (typeof window.gtag !== "function") {
|
|
166
|
-
console.warn("GTM not initialized. Make sure @next/third-parties/google GoogleTagManager is added to your layout.");
|
|
167
|
-
return;
|
|
168
|
-
}
|
|
169
|
-
const eventData = {
|
|
170
|
-
event: eventName,
|
|
171
|
-
...data && { value: data }
|
|
172
|
-
};
|
|
173
|
-
window.gtag("event", eventName, data || {});
|
|
174
|
-
};
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
// hooks/useUtmParams.ts
|
|
178
|
-
import { useEffect, useState } from "react";
|
|
179
|
-
function useUtmParams() {
|
|
180
|
-
const [utmParams, setUtmParams] = useState({});
|
|
181
|
-
useEffect(() => {
|
|
182
|
-
if (typeof window === "undefined") return;
|
|
183
|
-
const urlParams = new URLSearchParams(window.location.search);
|
|
184
|
-
const source = urlParams.get("utm_source");
|
|
185
|
-
const medium = urlParams.get("utm_medium");
|
|
186
|
-
const campaign = urlParams.get("utm_campaign");
|
|
187
|
-
const content = urlParams.get("utm_content");
|
|
188
|
-
const term = urlParams.get("utm_term");
|
|
189
|
-
const params = {};
|
|
190
|
-
if (source) {
|
|
191
|
-
params.source = source;
|
|
192
|
-
sessionStorage.setItem("utm_source", source);
|
|
193
|
-
} else {
|
|
194
|
-
const stored = sessionStorage.getItem("utm_source");
|
|
195
|
-
if (stored) params.source = stored;
|
|
196
|
-
}
|
|
197
|
-
if (medium) {
|
|
198
|
-
params.medium = medium;
|
|
199
|
-
sessionStorage.setItem("utm_medium", medium);
|
|
200
|
-
} else {
|
|
201
|
-
const stored = sessionStorage.getItem("utm_medium");
|
|
202
|
-
if (stored) params.medium = stored;
|
|
203
|
-
}
|
|
204
|
-
if (campaign) {
|
|
205
|
-
params.campaign = campaign;
|
|
206
|
-
sessionStorage.setItem("utm_campaign", campaign);
|
|
207
|
-
} else {
|
|
208
|
-
const stored = sessionStorage.getItem("utm_campaign");
|
|
209
|
-
if (stored) params.campaign = stored;
|
|
210
|
-
}
|
|
211
|
-
if (content) {
|
|
212
|
-
params.content = content;
|
|
213
|
-
sessionStorage.setItem("utm_content", content);
|
|
214
|
-
} else {
|
|
215
|
-
const stored = sessionStorage.getItem("utm_content");
|
|
216
|
-
if (stored) params.content = stored;
|
|
217
|
-
}
|
|
218
|
-
if (term) {
|
|
219
|
-
params.term = term;
|
|
220
|
-
sessionStorage.setItem("utm_term", term);
|
|
221
|
-
} else {
|
|
222
|
-
const stored = sessionStorage.getItem("utm_term");
|
|
223
|
-
if (stored) params.term = stored;
|
|
224
|
-
}
|
|
225
|
-
setUtmParams(params);
|
|
226
|
-
}, []);
|
|
227
|
-
return utmParams;
|
|
228
|
-
}
|
|
229
|
-
|
|
230
164
|
// components/page/Button.tsx
|
|
165
|
+
import { sendGTMEvent } from "@next/third-parties/google";
|
|
231
166
|
import { jsx as jsx3 } from "react/jsx-runtime";
|
|
232
167
|
var sizeStyles = {
|
|
233
168
|
sm: { padding: "8px 16px", fontSize: "0.875rem" },
|
|
@@ -263,7 +198,6 @@ function Button({
|
|
|
263
198
|
}) {
|
|
264
199
|
const { resolveColor: resolveColor2 } = useTheme();
|
|
265
200
|
const { getEntryValue } = useEntries();
|
|
266
|
-
const sendEvent = useGtmEvent();
|
|
267
201
|
const utm = useUtmParams();
|
|
268
202
|
const resolvedText = (() => {
|
|
269
203
|
if (!text) return "Button";
|
|
@@ -277,11 +211,16 @@ function Button({
|
|
|
277
211
|
return "Button";
|
|
278
212
|
})();
|
|
279
213
|
const handleClick = () => {
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
214
|
+
const sessionId = typeof window !== "undefined" ? sessionStorage.getItem("session_id") : null;
|
|
215
|
+
sendGTMEvent({
|
|
216
|
+
event: "button_click",
|
|
217
|
+
value: {
|
|
218
|
+
text: resolvedText,
|
|
219
|
+
href: href || void 0,
|
|
220
|
+
variant,
|
|
221
|
+
session_id: sessionId,
|
|
222
|
+
...utm
|
|
223
|
+
}
|
|
285
224
|
});
|
|
286
225
|
};
|
|
287
226
|
const resolvedColor = (() => {
|
|
@@ -495,7 +434,8 @@ function Image({
|
|
|
495
434
|
}
|
|
496
435
|
|
|
497
436
|
// components/page/ImageCarousel.tsx
|
|
498
|
-
import { useState
|
|
437
|
+
import { useState } from "react";
|
|
438
|
+
import { sendGTMEvent as sendGTMEvent2 } from "@next/third-parties/google";
|
|
499
439
|
import { Fragment, jsx as jsx5, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
500
440
|
var aspectRatioMap2 = {
|
|
501
441
|
"16:9": "16 / 9",
|
|
@@ -522,9 +462,8 @@ function ImageCarousel({
|
|
|
522
462
|
dotColor,
|
|
523
463
|
id
|
|
524
464
|
}) {
|
|
525
|
-
const [currentIndex, setCurrentIndex] =
|
|
465
|
+
const [currentIndex, setCurrentIndex] = useState(0);
|
|
526
466
|
const { resolveColor: resolveColor2 } = useTheme();
|
|
527
|
-
const sendEvent = useGtmEvent();
|
|
528
467
|
const utm = useUtmParams();
|
|
529
468
|
const resolvedArrowColor = (() => {
|
|
530
469
|
if (!arrowColor) return { color: "#FFFFFF", opacity: 100 };
|
|
@@ -548,30 +487,39 @@ function ImageCarousel({
|
|
|
548
487
|
const goToPrevious = () => {
|
|
549
488
|
const newIndex = currentIndex === 0 ? images.length - 1 : currentIndex - 1;
|
|
550
489
|
setCurrentIndex(newIndex);
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
490
|
+
sendGTMEvent2({
|
|
491
|
+
event: "carousel_navigate",
|
|
492
|
+
value: {
|
|
493
|
+
direction: "previous",
|
|
494
|
+
slideIndex: newIndex,
|
|
495
|
+
totalSlides: images.length,
|
|
496
|
+
...utm
|
|
497
|
+
}
|
|
556
498
|
});
|
|
557
499
|
};
|
|
558
500
|
const goToNext = () => {
|
|
559
501
|
const newIndex = currentIndex === images.length - 1 ? 0 : currentIndex + 1;
|
|
560
502
|
setCurrentIndex(newIndex);
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
503
|
+
sendGTMEvent2({
|
|
504
|
+
event: "carousel_navigate",
|
|
505
|
+
value: {
|
|
506
|
+
direction: "next",
|
|
507
|
+
slideIndex: newIndex,
|
|
508
|
+
totalSlides: images.length,
|
|
509
|
+
...utm
|
|
510
|
+
}
|
|
566
511
|
});
|
|
567
512
|
};
|
|
568
513
|
const goToSlide = (index) => {
|
|
569
514
|
setCurrentIndex(index);
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
515
|
+
sendGTMEvent2({
|
|
516
|
+
event: "carousel_navigate",
|
|
517
|
+
value: {
|
|
518
|
+
direction: "direct",
|
|
519
|
+
slideIndex: index,
|
|
520
|
+
totalSlides: images.length,
|
|
521
|
+
...utm
|
|
522
|
+
}
|
|
575
523
|
});
|
|
576
524
|
};
|
|
577
525
|
if (images.length === 0) {
|
|
@@ -1665,6 +1613,7 @@ function FeatureGrid({
|
|
|
1665
1613
|
|
|
1666
1614
|
// components/page/Footer.tsx
|
|
1667
1615
|
import { Facebook, Instagram, Twitter } from "lucide-react";
|
|
1616
|
+
import { sendGTMEvent as sendGTMEvent3 } from "@next/third-parties/google";
|
|
1668
1617
|
import { jsx as jsx18, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
1669
1618
|
function Footer({
|
|
1670
1619
|
logo,
|
|
@@ -1677,7 +1626,6 @@ function Footer({
|
|
|
1677
1626
|
puck
|
|
1678
1627
|
}) {
|
|
1679
1628
|
const DropZone = puck?.renderDropZone;
|
|
1680
|
-
const sendEvent = useGtmEvent();
|
|
1681
1629
|
const utm = useUtmParams();
|
|
1682
1630
|
const getSocialPlatform = (url) => {
|
|
1683
1631
|
if (url.includes("facebook")) return "facebook";
|
|
@@ -1687,17 +1635,22 @@ function Footer({
|
|
|
1687
1635
|
};
|
|
1688
1636
|
const handleSocialClick = (url) => {
|
|
1689
1637
|
const platform = getSocialPlatform(url);
|
|
1690
|
-
|
|
1691
|
-
|
|
1692
|
-
|
|
1693
|
-
|
|
1638
|
+
sendGTMEvent3({
|
|
1639
|
+
event: "social_click",
|
|
1640
|
+
value: {
|
|
1641
|
+
platform,
|
|
1642
|
+
url,
|
|
1643
|
+
...utm
|
|
1644
|
+
}
|
|
1694
1645
|
});
|
|
1695
1646
|
};
|
|
1696
1647
|
const socialLinks = [
|
|
1697
1648
|
{ url: facebookUrl, Icon: Facebook },
|
|
1698
1649
|
{ url: instagramUrl, Icon: Instagram },
|
|
1699
1650
|
{ url: twitterUrl, Icon: Twitter }
|
|
1700
|
-
].filter(
|
|
1651
|
+
].filter(
|
|
1652
|
+
(link) => !!link.url
|
|
1653
|
+
);
|
|
1701
1654
|
return /* @__PURE__ */ jsx18(
|
|
1702
1655
|
"footer",
|
|
1703
1656
|
{
|
|
@@ -1725,9 +1678,10 @@ function Footer({
|
|
|
1725
1678
|
}
|
|
1726
1679
|
|
|
1727
1680
|
// components/page/Topbar.tsx
|
|
1728
|
-
import { useState as
|
|
1681
|
+
import { useState as useState2 } from "react";
|
|
1729
1682
|
import Link from "next/link";
|
|
1730
1683
|
import { Menu, X } from "lucide-react";
|
|
1684
|
+
import { sendGTMEvent as sendGTMEvent4 } from "@next/third-parties/google";
|
|
1731
1685
|
import { jsx as jsx19, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
1732
1686
|
function Topbar({
|
|
1733
1687
|
logo,
|
|
@@ -1739,23 +1693,28 @@ function Topbar({
|
|
|
1739
1693
|
puck
|
|
1740
1694
|
}) {
|
|
1741
1695
|
const DropZone = puck?.renderDropZone;
|
|
1742
|
-
const [mobileMenuOpen, setMobileMenuOpen] =
|
|
1743
|
-
const sendEvent = useGtmEvent();
|
|
1696
|
+
const [mobileMenuOpen, setMobileMenuOpen] = useState2(false);
|
|
1744
1697
|
const utm = useUtmParams();
|
|
1745
1698
|
const handleNavClick = (item) => {
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
|
|
1699
|
+
sendGTMEvent4({
|
|
1700
|
+
event: "nav_click",
|
|
1701
|
+
value: {
|
|
1702
|
+
name: item.name,
|
|
1703
|
+
url: item.url,
|
|
1704
|
+
linkType: item.linkType || "internal",
|
|
1705
|
+
...utm
|
|
1706
|
+
}
|
|
1751
1707
|
});
|
|
1752
1708
|
};
|
|
1753
1709
|
const handleMobileMenuToggle = () => {
|
|
1754
1710
|
const newState = !mobileMenuOpen;
|
|
1755
1711
|
setMobileMenuOpen(newState);
|
|
1756
|
-
|
|
1757
|
-
|
|
1758
|
-
|
|
1712
|
+
sendGTMEvent4({
|
|
1713
|
+
event: "mobile_menu_toggle",
|
|
1714
|
+
value: {
|
|
1715
|
+
open: newState,
|
|
1716
|
+
...utm
|
|
1717
|
+
}
|
|
1759
1718
|
});
|
|
1760
1719
|
};
|
|
1761
1720
|
const renderLink = (item, index) => {
|
|
@@ -1814,11 +1773,14 @@ function Topbar({
|
|
|
1814
1773
|
{
|
|
1815
1774
|
href: logoUrl,
|
|
1816
1775
|
className: "flex-shrink-0",
|
|
1817
|
-
onClick: () =>
|
|
1818
|
-
|
|
1819
|
-
|
|
1820
|
-
|
|
1821
|
-
|
|
1776
|
+
onClick: () => sendGTMEvent4({
|
|
1777
|
+
event: "nav_click",
|
|
1778
|
+
value: {
|
|
1779
|
+
name: "logo",
|
|
1780
|
+
url: logoUrl,
|
|
1781
|
+
linkType: "internal",
|
|
1782
|
+
...utm
|
|
1783
|
+
}
|
|
1822
1784
|
}),
|
|
1823
1785
|
children: logo ? /* @__PURE__ */ jsx19("img", { src: logo, alt: "Logo", className: "h-8" }) : /* @__PURE__ */ jsx19("span", { className: "text-xl font-bold", children: "Logo" })
|
|
1824
1786
|
}
|
|
@@ -1848,8 +1810,9 @@ function Topbar({
|
|
|
1848
1810
|
}
|
|
1849
1811
|
|
|
1850
1812
|
// components/page/Popup.tsx
|
|
1851
|
-
import { useState as
|
|
1813
|
+
import { useState as useState3 } from "react";
|
|
1852
1814
|
import { icons as icons4, X as X2 } from "lucide-react";
|
|
1815
|
+
import { sendGTMEvent as sendGTMEvent5 } from "@next/third-parties/google";
|
|
1853
1816
|
import { Fragment as Fragment2, jsx as jsx20, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
1854
1817
|
function Icon2({ name, ...props }) {
|
|
1855
1818
|
const formatted = name.charAt(0).toUpperCase() + name.slice(1);
|
|
@@ -1878,20 +1841,25 @@ function Popup({
|
|
|
1878
1841
|
textLink = false,
|
|
1879
1842
|
puck
|
|
1880
1843
|
}) {
|
|
1881
|
-
const [isOpen, setIsOpen] =
|
|
1882
|
-
const sendEvent = useGtmEvent();
|
|
1844
|
+
const [isOpen, setIsOpen] = useState3(false);
|
|
1883
1845
|
const utm = useUtmParams();
|
|
1884
1846
|
const handleOpen = () => {
|
|
1885
1847
|
setIsOpen(true);
|
|
1886
|
-
|
|
1887
|
-
|
|
1888
|
-
|
|
1889
|
-
|
|
1848
|
+
sendGTMEvent5({
|
|
1849
|
+
event: "popup_open",
|
|
1850
|
+
value: {
|
|
1851
|
+
ctaText,
|
|
1852
|
+
type: textLink ? "link" : "button",
|
|
1853
|
+
...utm
|
|
1854
|
+
}
|
|
1890
1855
|
});
|
|
1891
1856
|
};
|
|
1892
1857
|
const handleClose = () => {
|
|
1893
1858
|
setIsOpen(false);
|
|
1894
|
-
|
|
1859
|
+
sendGTMEvent5({
|
|
1860
|
+
event: "popup_close",
|
|
1861
|
+
value: { ctaText, ...utm }
|
|
1862
|
+
});
|
|
1895
1863
|
};
|
|
1896
1864
|
const trigger = textLink ? /* @__PURE__ */ jsx20(
|
|
1897
1865
|
"button",
|
package/dist/config-entry.js
CHANGED
|
@@ -292,21 +292,8 @@ function Paragraph({
|
|
|
292
292
|
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { id, style, children: resolvedText });
|
|
293
293
|
}
|
|
294
294
|
|
|
295
|
-
//
|
|
296
|
-
|
|
297
|
-
return (eventName, data) => {
|
|
298
|
-
if (typeof window === "undefined") return;
|
|
299
|
-
if (typeof window.gtag !== "function") {
|
|
300
|
-
console.warn("GTM not initialized. Make sure @next/third-parties/google GoogleTagManager is added to your layout.");
|
|
301
|
-
return;
|
|
302
|
-
}
|
|
303
|
-
const eventData = {
|
|
304
|
-
event: eventName,
|
|
305
|
-
...data && { value: data }
|
|
306
|
-
};
|
|
307
|
-
window.gtag("event", eventName, data || {});
|
|
308
|
-
};
|
|
309
|
-
}
|
|
295
|
+
// components/page/Button.tsx
|
|
296
|
+
var import_google = require("@next/third-parties/google");
|
|
310
297
|
|
|
311
298
|
// hooks/useUtmParams.ts
|
|
312
299
|
var import_react3 = require("react");
|
|
@@ -397,7 +384,6 @@ function Button({
|
|
|
397
384
|
}) {
|
|
398
385
|
const { resolveColor: resolveColor2 } = useTheme();
|
|
399
386
|
const { getEntryValue } = useEntries();
|
|
400
|
-
const sendEvent = useGtmEvent();
|
|
401
387
|
const utm = useUtmParams();
|
|
402
388
|
const resolvedText = (() => {
|
|
403
389
|
if (!text) return "Button";
|
|
@@ -411,11 +397,16 @@ function Button({
|
|
|
411
397
|
return "Button";
|
|
412
398
|
})();
|
|
413
399
|
const handleClick = () => {
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
400
|
+
const sessionId = typeof window !== "undefined" ? sessionStorage.getItem("session_id") : null;
|
|
401
|
+
(0, import_google.sendGTMEvent)({
|
|
402
|
+
event: "button_click",
|
|
403
|
+
value: {
|
|
404
|
+
text: resolvedText,
|
|
405
|
+
href: href || void 0,
|
|
406
|
+
variant,
|
|
407
|
+
session_id: sessionId,
|
|
408
|
+
...utm
|
|
409
|
+
}
|
|
419
410
|
});
|
|
420
411
|
};
|
|
421
412
|
const resolvedColor = (() => {
|
|
@@ -630,6 +621,7 @@ function Image({
|
|
|
630
621
|
|
|
631
622
|
// components/page/ImageCarousel.tsx
|
|
632
623
|
var import_react4 = require("react");
|
|
624
|
+
var import_google2 = require("@next/third-parties/google");
|
|
633
625
|
var import_jsx_runtime7 = require("react/jsx-runtime");
|
|
634
626
|
var aspectRatioMap2 = {
|
|
635
627
|
"16:9": "16 / 9",
|
|
@@ -658,7 +650,6 @@ function ImageCarousel({
|
|
|
658
650
|
}) {
|
|
659
651
|
const [currentIndex, setCurrentIndex] = (0, import_react4.useState)(0);
|
|
660
652
|
const { resolveColor: resolveColor2 } = useTheme();
|
|
661
|
-
const sendEvent = useGtmEvent();
|
|
662
653
|
const utm = useUtmParams();
|
|
663
654
|
const resolvedArrowColor = (() => {
|
|
664
655
|
if (!arrowColor) return { color: "#FFFFFF", opacity: 100 };
|
|
@@ -682,30 +673,39 @@ function ImageCarousel({
|
|
|
682
673
|
const goToPrevious = () => {
|
|
683
674
|
const newIndex = currentIndex === 0 ? images.length - 1 : currentIndex - 1;
|
|
684
675
|
setCurrentIndex(newIndex);
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
676
|
+
(0, import_google2.sendGTMEvent)({
|
|
677
|
+
event: "carousel_navigate",
|
|
678
|
+
value: {
|
|
679
|
+
direction: "previous",
|
|
680
|
+
slideIndex: newIndex,
|
|
681
|
+
totalSlides: images.length,
|
|
682
|
+
...utm
|
|
683
|
+
}
|
|
690
684
|
});
|
|
691
685
|
};
|
|
692
686
|
const goToNext = () => {
|
|
693
687
|
const newIndex = currentIndex === images.length - 1 ? 0 : currentIndex + 1;
|
|
694
688
|
setCurrentIndex(newIndex);
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
689
|
+
(0, import_google2.sendGTMEvent)({
|
|
690
|
+
event: "carousel_navigate",
|
|
691
|
+
value: {
|
|
692
|
+
direction: "next",
|
|
693
|
+
slideIndex: newIndex,
|
|
694
|
+
totalSlides: images.length,
|
|
695
|
+
...utm
|
|
696
|
+
}
|
|
700
697
|
});
|
|
701
698
|
};
|
|
702
699
|
const goToSlide = (index2) => {
|
|
703
700
|
setCurrentIndex(index2);
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
701
|
+
(0, import_google2.sendGTMEvent)({
|
|
702
|
+
event: "carousel_navigate",
|
|
703
|
+
value: {
|
|
704
|
+
direction: "direct",
|
|
705
|
+
slideIndex: index2,
|
|
706
|
+
totalSlides: images.length,
|
|
707
|
+
...utm
|
|
708
|
+
}
|
|
709
709
|
});
|
|
710
710
|
};
|
|
711
711
|
if (images.length === 0) {
|
|
@@ -1835,6 +1835,7 @@ function FeatureGrid({
|
|
|
1835
1835
|
|
|
1836
1836
|
// components/page/Footer.tsx
|
|
1837
1837
|
var import_lucide_react3 = require("lucide-react");
|
|
1838
|
+
var import_google3 = require("@next/third-parties/google");
|
|
1838
1839
|
var import_jsx_runtime20 = require("react/jsx-runtime");
|
|
1839
1840
|
function Footer({
|
|
1840
1841
|
logo,
|
|
@@ -1847,7 +1848,6 @@ function Footer({
|
|
|
1847
1848
|
puck
|
|
1848
1849
|
}) {
|
|
1849
1850
|
const DropZone = puck?.renderDropZone;
|
|
1850
|
-
const sendEvent = useGtmEvent();
|
|
1851
1851
|
const utm = useUtmParams();
|
|
1852
1852
|
const getSocialPlatform = (url) => {
|
|
1853
1853
|
if (url.includes("facebook")) return "facebook";
|
|
@@ -1857,17 +1857,22 @@ function Footer({
|
|
|
1857
1857
|
};
|
|
1858
1858
|
const handleSocialClick = (url) => {
|
|
1859
1859
|
const platform2 = getSocialPlatform(url);
|
|
1860
|
-
|
|
1861
|
-
|
|
1862
|
-
|
|
1863
|
-
|
|
1860
|
+
(0, import_google3.sendGTMEvent)({
|
|
1861
|
+
event: "social_click",
|
|
1862
|
+
value: {
|
|
1863
|
+
platform: platform2,
|
|
1864
|
+
url,
|
|
1865
|
+
...utm
|
|
1866
|
+
}
|
|
1864
1867
|
});
|
|
1865
1868
|
};
|
|
1866
1869
|
const socialLinks = [
|
|
1867
1870
|
{ url: facebookUrl, Icon: import_lucide_react3.Facebook },
|
|
1868
1871
|
{ url: instagramUrl, Icon: import_lucide_react3.Instagram },
|
|
1869
1872
|
{ url: twitterUrl, Icon: import_lucide_react3.Twitter }
|
|
1870
|
-
].filter(
|
|
1873
|
+
].filter(
|
|
1874
|
+
(link) => !!link.url
|
|
1875
|
+
);
|
|
1871
1876
|
return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
1872
1877
|
"footer",
|
|
1873
1878
|
{
|
|
@@ -1898,6 +1903,7 @@ function Footer({
|
|
|
1898
1903
|
var import_react5 = require("react");
|
|
1899
1904
|
var import_link = __toESM(require("next/link"));
|
|
1900
1905
|
var import_lucide_react4 = require("lucide-react");
|
|
1906
|
+
var import_google4 = require("@next/third-parties/google");
|
|
1901
1907
|
var import_jsx_runtime21 = require("react/jsx-runtime");
|
|
1902
1908
|
function Topbar({
|
|
1903
1909
|
logo,
|
|
@@ -1910,22 +1916,27 @@ function Topbar({
|
|
|
1910
1916
|
}) {
|
|
1911
1917
|
const DropZone = puck?.renderDropZone;
|
|
1912
1918
|
const [mobileMenuOpen, setMobileMenuOpen] = (0, import_react5.useState)(false);
|
|
1913
|
-
const sendEvent = useGtmEvent();
|
|
1914
1919
|
const utm = useUtmParams();
|
|
1915
1920
|
const handleNavClick = (item) => {
|
|
1916
|
-
|
|
1917
|
-
|
|
1918
|
-
|
|
1919
|
-
|
|
1920
|
-
|
|
1921
|
+
(0, import_google4.sendGTMEvent)({
|
|
1922
|
+
event: "nav_click",
|
|
1923
|
+
value: {
|
|
1924
|
+
name: item.name,
|
|
1925
|
+
url: item.url,
|
|
1926
|
+
linkType: item.linkType || "internal",
|
|
1927
|
+
...utm
|
|
1928
|
+
}
|
|
1921
1929
|
});
|
|
1922
1930
|
};
|
|
1923
1931
|
const handleMobileMenuToggle = () => {
|
|
1924
1932
|
const newState = !mobileMenuOpen;
|
|
1925
1933
|
setMobileMenuOpen(newState);
|
|
1926
|
-
|
|
1927
|
-
|
|
1928
|
-
|
|
1934
|
+
(0, import_google4.sendGTMEvent)({
|
|
1935
|
+
event: "mobile_menu_toggle",
|
|
1936
|
+
value: {
|
|
1937
|
+
open: newState,
|
|
1938
|
+
...utm
|
|
1939
|
+
}
|
|
1929
1940
|
});
|
|
1930
1941
|
};
|
|
1931
1942
|
const renderLink = (item, index2) => {
|
|
@@ -1984,11 +1995,14 @@ function Topbar({
|
|
|
1984
1995
|
{
|
|
1985
1996
|
href: logoUrl,
|
|
1986
1997
|
className: "flex-shrink-0",
|
|
1987
|
-
onClick: () =>
|
|
1988
|
-
|
|
1989
|
-
|
|
1990
|
-
|
|
1991
|
-
|
|
1998
|
+
onClick: () => (0, import_google4.sendGTMEvent)({
|
|
1999
|
+
event: "nav_click",
|
|
2000
|
+
value: {
|
|
2001
|
+
name: "logo",
|
|
2002
|
+
url: logoUrl,
|
|
2003
|
+
linkType: "internal",
|
|
2004
|
+
...utm
|
|
2005
|
+
}
|
|
1992
2006
|
}),
|
|
1993
2007
|
children: logo ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("img", { src: logo, alt: "Logo", className: "h-8" }) : /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "text-xl font-bold", children: "Logo" })
|
|
1994
2008
|
}
|
|
@@ -2020,6 +2034,7 @@ function Topbar({
|
|
|
2020
2034
|
// components/page/Popup.tsx
|
|
2021
2035
|
var import_react6 = require("react");
|
|
2022
2036
|
var import_lucide_react5 = require("lucide-react");
|
|
2037
|
+
var import_google5 = require("@next/third-parties/google");
|
|
2023
2038
|
var import_jsx_runtime22 = require("react/jsx-runtime");
|
|
2024
2039
|
function Icon2({ name, ...props }) {
|
|
2025
2040
|
const formatted = name.charAt(0).toUpperCase() + name.slice(1);
|
|
@@ -2049,19 +2064,24 @@ function Popup({
|
|
|
2049
2064
|
puck
|
|
2050
2065
|
}) {
|
|
2051
2066
|
const [isOpen, setIsOpen] = (0, import_react6.useState)(false);
|
|
2052
|
-
const sendEvent = useGtmEvent();
|
|
2053
2067
|
const utm = useUtmParams();
|
|
2054
2068
|
const handleOpen = () => {
|
|
2055
2069
|
setIsOpen(true);
|
|
2056
|
-
|
|
2057
|
-
|
|
2058
|
-
|
|
2059
|
-
|
|
2070
|
+
(0, import_google5.sendGTMEvent)({
|
|
2071
|
+
event: "popup_open",
|
|
2072
|
+
value: {
|
|
2073
|
+
ctaText,
|
|
2074
|
+
type: textLink ? "link" : "button",
|
|
2075
|
+
...utm
|
|
2076
|
+
}
|
|
2060
2077
|
});
|
|
2061
2078
|
};
|
|
2062
2079
|
const handleClose = () => {
|
|
2063
2080
|
setIsOpen(false);
|
|
2064
|
-
|
|
2081
|
+
(0, import_google5.sendGTMEvent)({
|
|
2082
|
+
event: "popup_close",
|
|
2083
|
+
value: { ctaText, ...utm }
|
|
2084
|
+
});
|
|
2065
2085
|
};
|
|
2066
2086
|
const trigger = textLink ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
2067
2087
|
"button",
|
package/dist/config-entry.mjs
CHANGED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Hook to send events to Google Tag Manager
|
|
3
|
+
* Assumes GTM is initialized in the parent app via @next/third-parties/google
|
|
4
|
+
* @example
|
|
5
|
+
* const sendEvent = useGtmEvent();
|
|
6
|
+
* sendEvent('button_click', { text: 'Sign Up', href: '/signup' });
|
|
7
|
+
*/
|
|
8
|
+
declare function useGtmEvent(): (eventName: string, data?: Record<string, any>) => void;
|
|
9
|
+
declare global {
|
|
10
|
+
interface Window {
|
|
11
|
+
gtag?: (...args: any[]) => void;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* UTM parameter object
|
|
17
|
+
*/
|
|
18
|
+
interface UtmParams {
|
|
19
|
+
source?: string;
|
|
20
|
+
medium?: string;
|
|
21
|
+
campaign?: string;
|
|
22
|
+
content?: string;
|
|
23
|
+
term?: string;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Hook to capture and persist UTM parameters from URL
|
|
27
|
+
* Stores in sessionStorage so they persist across navigation
|
|
28
|
+
* @returns Current UTM parameters
|
|
29
|
+
*/
|
|
30
|
+
declare function useUtmParams(): UtmParams;
|
|
31
|
+
|
|
32
|
+
export { type UtmParams, useGtmEvent, useUtmParams };
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Hook to send events to Google Tag Manager
|
|
3
|
+
* Assumes GTM is initialized in the parent app via @next/third-parties/google
|
|
4
|
+
* @example
|
|
5
|
+
* const sendEvent = useGtmEvent();
|
|
6
|
+
* sendEvent('button_click', { text: 'Sign Up', href: '/signup' });
|
|
7
|
+
*/
|
|
8
|
+
declare function useGtmEvent(): (eventName: string, data?: Record<string, any>) => void;
|
|
9
|
+
declare global {
|
|
10
|
+
interface Window {
|
|
11
|
+
gtag?: (...args: any[]) => void;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* UTM parameter object
|
|
17
|
+
*/
|
|
18
|
+
interface UtmParams {
|
|
19
|
+
source?: string;
|
|
20
|
+
medium?: string;
|
|
21
|
+
campaign?: string;
|
|
22
|
+
content?: string;
|
|
23
|
+
term?: string;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Hook to capture and persist UTM parameters from URL
|
|
27
|
+
* Stores in sessionStorage so they persist across navigation
|
|
28
|
+
* @returns Current UTM parameters
|
|
29
|
+
*/
|
|
30
|
+
declare function useUtmParams(): UtmParams;
|
|
31
|
+
|
|
32
|
+
export { type UtmParams, useGtmEvent, useUtmParams };
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// hooks/index.ts
|
|
21
|
+
var hooks_exports = {};
|
|
22
|
+
__export(hooks_exports, {
|
|
23
|
+
useGtmEvent: () => useGtmEvent,
|
|
24
|
+
useUtmParams: () => useUtmParams
|
|
25
|
+
});
|
|
26
|
+
module.exports = __toCommonJS(hooks_exports);
|
|
27
|
+
|
|
28
|
+
// hooks/useGtmEvent.ts
|
|
29
|
+
function useGtmEvent() {
|
|
30
|
+
return (eventName, data) => {
|
|
31
|
+
if (typeof window === "undefined") return;
|
|
32
|
+
if (typeof window.gtag === "function") {
|
|
33
|
+
window.gtag("event", eventName, data || {});
|
|
34
|
+
}
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// hooks/useUtmParams.ts
|
|
39
|
+
var import_react = require("react");
|
|
40
|
+
function useUtmParams() {
|
|
41
|
+
const [utmParams, setUtmParams] = (0, import_react.useState)({});
|
|
42
|
+
(0, import_react.useEffect)(() => {
|
|
43
|
+
if (typeof window === "undefined") return;
|
|
44
|
+
const urlParams = new URLSearchParams(window.location.search);
|
|
45
|
+
const source = urlParams.get("utm_source");
|
|
46
|
+
const medium = urlParams.get("utm_medium");
|
|
47
|
+
const campaign = urlParams.get("utm_campaign");
|
|
48
|
+
const content = urlParams.get("utm_content");
|
|
49
|
+
const term = urlParams.get("utm_term");
|
|
50
|
+
const params = {};
|
|
51
|
+
if (source) {
|
|
52
|
+
params.source = source;
|
|
53
|
+
sessionStorage.setItem("utm_source", source);
|
|
54
|
+
} else {
|
|
55
|
+
const stored = sessionStorage.getItem("utm_source");
|
|
56
|
+
if (stored) params.source = stored;
|
|
57
|
+
}
|
|
58
|
+
if (medium) {
|
|
59
|
+
params.medium = medium;
|
|
60
|
+
sessionStorage.setItem("utm_medium", medium);
|
|
61
|
+
} else {
|
|
62
|
+
const stored = sessionStorage.getItem("utm_medium");
|
|
63
|
+
if (stored) params.medium = stored;
|
|
64
|
+
}
|
|
65
|
+
if (campaign) {
|
|
66
|
+
params.campaign = campaign;
|
|
67
|
+
sessionStorage.setItem("utm_campaign", campaign);
|
|
68
|
+
} else {
|
|
69
|
+
const stored = sessionStorage.getItem("utm_campaign");
|
|
70
|
+
if (stored) params.campaign = stored;
|
|
71
|
+
}
|
|
72
|
+
if (content) {
|
|
73
|
+
params.content = content;
|
|
74
|
+
sessionStorage.setItem("utm_content", content);
|
|
75
|
+
} else {
|
|
76
|
+
const stored = sessionStorage.getItem("utm_content");
|
|
77
|
+
if (stored) params.content = stored;
|
|
78
|
+
}
|
|
79
|
+
if (term) {
|
|
80
|
+
params.term = term;
|
|
81
|
+
sessionStorage.setItem("utm_term", term);
|
|
82
|
+
} else {
|
|
83
|
+
const stored = sessionStorage.getItem("utm_term");
|
|
84
|
+
if (stored) params.term = stored;
|
|
85
|
+
}
|
|
86
|
+
setUtmParams(params);
|
|
87
|
+
}, []);
|
|
88
|
+
return utmParams;
|
|
89
|
+
}
|
|
90
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
91
|
+
0 && (module.exports = {
|
|
92
|
+
useGtmEvent,
|
|
93
|
+
useUtmParams
|
|
94
|
+
});
|
package/dist/index.js
CHANGED
|
@@ -332,21 +332,8 @@ function Paragraph({
|
|
|
332
332
|
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { id, style, children: resolvedText });
|
|
333
333
|
}
|
|
334
334
|
|
|
335
|
-
//
|
|
336
|
-
|
|
337
|
-
return (eventName, data) => {
|
|
338
|
-
if (typeof window === "undefined") return;
|
|
339
|
-
if (typeof window.gtag !== "function") {
|
|
340
|
-
console.warn("GTM not initialized. Make sure @next/third-parties/google GoogleTagManager is added to your layout.");
|
|
341
|
-
return;
|
|
342
|
-
}
|
|
343
|
-
const eventData = {
|
|
344
|
-
event: eventName,
|
|
345
|
-
...data && { value: data }
|
|
346
|
-
};
|
|
347
|
-
window.gtag("event", eventName, data || {});
|
|
348
|
-
};
|
|
349
|
-
}
|
|
335
|
+
// components/page/Button.tsx
|
|
336
|
+
var import_google = require("@next/third-parties/google");
|
|
350
337
|
|
|
351
338
|
// hooks/useUtmParams.ts
|
|
352
339
|
var import_react3 = require("react");
|
|
@@ -437,7 +424,6 @@ function Button({
|
|
|
437
424
|
}) {
|
|
438
425
|
const { resolveColor: resolveColor2 } = useTheme();
|
|
439
426
|
const { getEntryValue } = useEntries();
|
|
440
|
-
const sendEvent = useGtmEvent();
|
|
441
427
|
const utm = useUtmParams();
|
|
442
428
|
const resolvedText = (() => {
|
|
443
429
|
if (!text) return "Button";
|
|
@@ -451,11 +437,16 @@ function Button({
|
|
|
451
437
|
return "Button";
|
|
452
438
|
})();
|
|
453
439
|
const handleClick = () => {
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
440
|
+
const sessionId = typeof window !== "undefined" ? sessionStorage.getItem("session_id") : null;
|
|
441
|
+
(0, import_google.sendGTMEvent)({
|
|
442
|
+
event: "button_click",
|
|
443
|
+
value: {
|
|
444
|
+
text: resolvedText,
|
|
445
|
+
href: href || void 0,
|
|
446
|
+
variant,
|
|
447
|
+
session_id: sessionId,
|
|
448
|
+
...utm
|
|
449
|
+
}
|
|
459
450
|
});
|
|
460
451
|
};
|
|
461
452
|
const resolvedColor = (() => {
|
|
@@ -670,6 +661,7 @@ function Image({
|
|
|
670
661
|
|
|
671
662
|
// components/page/ImageCarousel.tsx
|
|
672
663
|
var import_react4 = require("react");
|
|
664
|
+
var import_google2 = require("@next/third-parties/google");
|
|
673
665
|
var import_jsx_runtime7 = require("react/jsx-runtime");
|
|
674
666
|
var aspectRatioMap2 = {
|
|
675
667
|
"16:9": "16 / 9",
|
|
@@ -698,7 +690,6 @@ function ImageCarousel({
|
|
|
698
690
|
}) {
|
|
699
691
|
const [currentIndex, setCurrentIndex] = (0, import_react4.useState)(0);
|
|
700
692
|
const { resolveColor: resolveColor2 } = useTheme();
|
|
701
|
-
const sendEvent = useGtmEvent();
|
|
702
693
|
const utm = useUtmParams();
|
|
703
694
|
const resolvedArrowColor = (() => {
|
|
704
695
|
if (!arrowColor) return { color: "#FFFFFF", opacity: 100 };
|
|
@@ -722,30 +713,39 @@ function ImageCarousel({
|
|
|
722
713
|
const goToPrevious = () => {
|
|
723
714
|
const newIndex = currentIndex === 0 ? images.length - 1 : currentIndex - 1;
|
|
724
715
|
setCurrentIndex(newIndex);
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
716
|
+
(0, import_google2.sendGTMEvent)({
|
|
717
|
+
event: "carousel_navigate",
|
|
718
|
+
value: {
|
|
719
|
+
direction: "previous",
|
|
720
|
+
slideIndex: newIndex,
|
|
721
|
+
totalSlides: images.length,
|
|
722
|
+
...utm
|
|
723
|
+
}
|
|
730
724
|
});
|
|
731
725
|
};
|
|
732
726
|
const goToNext = () => {
|
|
733
727
|
const newIndex = currentIndex === images.length - 1 ? 0 : currentIndex + 1;
|
|
734
728
|
setCurrentIndex(newIndex);
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
729
|
+
(0, import_google2.sendGTMEvent)({
|
|
730
|
+
event: "carousel_navigate",
|
|
731
|
+
value: {
|
|
732
|
+
direction: "next",
|
|
733
|
+
slideIndex: newIndex,
|
|
734
|
+
totalSlides: images.length,
|
|
735
|
+
...utm
|
|
736
|
+
}
|
|
740
737
|
});
|
|
741
738
|
};
|
|
742
739
|
const goToSlide = (index) => {
|
|
743
740
|
setCurrentIndex(index);
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
741
|
+
(0, import_google2.sendGTMEvent)({
|
|
742
|
+
event: "carousel_navigate",
|
|
743
|
+
value: {
|
|
744
|
+
direction: "direct",
|
|
745
|
+
slideIndex: index,
|
|
746
|
+
totalSlides: images.length,
|
|
747
|
+
...utm
|
|
748
|
+
}
|
|
749
749
|
});
|
|
750
750
|
};
|
|
751
751
|
if (images.length === 0) {
|
|
@@ -1875,6 +1875,7 @@ function FeatureGrid({
|
|
|
1875
1875
|
|
|
1876
1876
|
// components/page/Footer.tsx
|
|
1877
1877
|
var import_lucide_react3 = require("lucide-react");
|
|
1878
|
+
var import_google3 = require("@next/third-parties/google");
|
|
1878
1879
|
var import_jsx_runtime20 = require("react/jsx-runtime");
|
|
1879
1880
|
function Footer({
|
|
1880
1881
|
logo,
|
|
@@ -1887,7 +1888,6 @@ function Footer({
|
|
|
1887
1888
|
puck
|
|
1888
1889
|
}) {
|
|
1889
1890
|
const DropZone = puck?.renderDropZone;
|
|
1890
|
-
const sendEvent = useGtmEvent();
|
|
1891
1891
|
const utm = useUtmParams();
|
|
1892
1892
|
const getSocialPlatform = (url) => {
|
|
1893
1893
|
if (url.includes("facebook")) return "facebook";
|
|
@@ -1897,17 +1897,22 @@ function Footer({
|
|
|
1897
1897
|
};
|
|
1898
1898
|
const handleSocialClick = (url) => {
|
|
1899
1899
|
const platform = getSocialPlatform(url);
|
|
1900
|
-
|
|
1901
|
-
|
|
1902
|
-
|
|
1903
|
-
|
|
1900
|
+
(0, import_google3.sendGTMEvent)({
|
|
1901
|
+
event: "social_click",
|
|
1902
|
+
value: {
|
|
1903
|
+
platform,
|
|
1904
|
+
url,
|
|
1905
|
+
...utm
|
|
1906
|
+
}
|
|
1904
1907
|
});
|
|
1905
1908
|
};
|
|
1906
1909
|
const socialLinks = [
|
|
1907
1910
|
{ url: facebookUrl, Icon: import_lucide_react3.Facebook },
|
|
1908
1911
|
{ url: instagramUrl, Icon: import_lucide_react3.Instagram },
|
|
1909
1912
|
{ url: twitterUrl, Icon: import_lucide_react3.Twitter }
|
|
1910
|
-
].filter(
|
|
1913
|
+
].filter(
|
|
1914
|
+
(link) => !!link.url
|
|
1915
|
+
);
|
|
1911
1916
|
return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
1912
1917
|
"footer",
|
|
1913
1918
|
{
|
|
@@ -1938,6 +1943,7 @@ function Footer({
|
|
|
1938
1943
|
var import_react5 = require("react");
|
|
1939
1944
|
var import_link = __toESM(require("next/link"));
|
|
1940
1945
|
var import_lucide_react4 = require("lucide-react");
|
|
1946
|
+
var import_google4 = require("@next/third-parties/google");
|
|
1941
1947
|
var import_jsx_runtime21 = require("react/jsx-runtime");
|
|
1942
1948
|
function Topbar({
|
|
1943
1949
|
logo,
|
|
@@ -1950,22 +1956,27 @@ function Topbar({
|
|
|
1950
1956
|
}) {
|
|
1951
1957
|
const DropZone = puck?.renderDropZone;
|
|
1952
1958
|
const [mobileMenuOpen, setMobileMenuOpen] = (0, import_react5.useState)(false);
|
|
1953
|
-
const sendEvent = useGtmEvent();
|
|
1954
1959
|
const utm = useUtmParams();
|
|
1955
1960
|
const handleNavClick = (item) => {
|
|
1956
|
-
|
|
1957
|
-
|
|
1958
|
-
|
|
1959
|
-
|
|
1960
|
-
|
|
1961
|
+
(0, import_google4.sendGTMEvent)({
|
|
1962
|
+
event: "nav_click",
|
|
1963
|
+
value: {
|
|
1964
|
+
name: item.name,
|
|
1965
|
+
url: item.url,
|
|
1966
|
+
linkType: item.linkType || "internal",
|
|
1967
|
+
...utm
|
|
1968
|
+
}
|
|
1961
1969
|
});
|
|
1962
1970
|
};
|
|
1963
1971
|
const handleMobileMenuToggle = () => {
|
|
1964
1972
|
const newState = !mobileMenuOpen;
|
|
1965
1973
|
setMobileMenuOpen(newState);
|
|
1966
|
-
|
|
1967
|
-
|
|
1968
|
-
|
|
1974
|
+
(0, import_google4.sendGTMEvent)({
|
|
1975
|
+
event: "mobile_menu_toggle",
|
|
1976
|
+
value: {
|
|
1977
|
+
open: newState,
|
|
1978
|
+
...utm
|
|
1979
|
+
}
|
|
1969
1980
|
});
|
|
1970
1981
|
};
|
|
1971
1982
|
const renderLink = (item, index) => {
|
|
@@ -2024,11 +2035,14 @@ function Topbar({
|
|
|
2024
2035
|
{
|
|
2025
2036
|
href: logoUrl,
|
|
2026
2037
|
className: "flex-shrink-0",
|
|
2027
|
-
onClick: () =>
|
|
2028
|
-
|
|
2029
|
-
|
|
2030
|
-
|
|
2031
|
-
|
|
2038
|
+
onClick: () => (0, import_google4.sendGTMEvent)({
|
|
2039
|
+
event: "nav_click",
|
|
2040
|
+
value: {
|
|
2041
|
+
name: "logo",
|
|
2042
|
+
url: logoUrl,
|
|
2043
|
+
linkType: "internal",
|
|
2044
|
+
...utm
|
|
2045
|
+
}
|
|
2032
2046
|
}),
|
|
2033
2047
|
children: logo ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("img", { src: logo, alt: "Logo", className: "h-8" }) : /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "text-xl font-bold", children: "Logo" })
|
|
2034
2048
|
}
|
|
@@ -2060,6 +2074,7 @@ function Topbar({
|
|
|
2060
2074
|
// components/page/Popup.tsx
|
|
2061
2075
|
var import_react6 = require("react");
|
|
2062
2076
|
var import_lucide_react5 = require("lucide-react");
|
|
2077
|
+
var import_google5 = require("@next/third-parties/google");
|
|
2063
2078
|
var import_jsx_runtime22 = require("react/jsx-runtime");
|
|
2064
2079
|
function Icon2({ name, ...props }) {
|
|
2065
2080
|
const formatted = name.charAt(0).toUpperCase() + name.slice(1);
|
|
@@ -2089,19 +2104,24 @@ function Popup({
|
|
|
2089
2104
|
puck
|
|
2090
2105
|
}) {
|
|
2091
2106
|
const [isOpen, setIsOpen] = (0, import_react6.useState)(false);
|
|
2092
|
-
const sendEvent = useGtmEvent();
|
|
2093
2107
|
const utm = useUtmParams();
|
|
2094
2108
|
const handleOpen = () => {
|
|
2095
2109
|
setIsOpen(true);
|
|
2096
|
-
|
|
2097
|
-
|
|
2098
|
-
|
|
2099
|
-
|
|
2110
|
+
(0, import_google5.sendGTMEvent)({
|
|
2111
|
+
event: "popup_open",
|
|
2112
|
+
value: {
|
|
2113
|
+
ctaText,
|
|
2114
|
+
type: textLink ? "link" : "button",
|
|
2115
|
+
...utm
|
|
2116
|
+
}
|
|
2100
2117
|
});
|
|
2101
2118
|
};
|
|
2102
2119
|
const handleClose = () => {
|
|
2103
2120
|
setIsOpen(false);
|
|
2104
|
-
|
|
2121
|
+
(0, import_google5.sendGTMEvent)({
|
|
2122
|
+
event: "popup_close",
|
|
2123
|
+
value: { ctaText, ...utm }
|
|
2124
|
+
});
|
|
2105
2125
|
};
|
|
2106
2126
|
const trigger = textLink ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
2107
2127
|
"button",
|
package/dist/index.mjs
CHANGED
|
@@ -20,7 +20,7 @@ import {
|
|
|
20
20
|
Topbar,
|
|
21
21
|
VideoEmbed,
|
|
22
22
|
availableIcons
|
|
23
|
-
} from "./chunk-
|
|
23
|
+
} from "./chunk-R7TH6TWG.mjs";
|
|
24
24
|
import {
|
|
25
25
|
allColorPresets,
|
|
26
26
|
neutralColors
|
|
@@ -41,6 +41,7 @@ import {
|
|
|
41
41
|
spacingScale,
|
|
42
42
|
useTheme
|
|
43
43
|
} from "./chunk-TTKY3YGP.mjs";
|
|
44
|
+
import "./chunk-QSWQDR6M.mjs";
|
|
44
45
|
export {
|
|
45
46
|
Button,
|
|
46
47
|
Card,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mission-studio/puck",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.5",
|
|
4
4
|
"description": "A collection of puck components and configurations for internal use at Mission Studio.",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -37,6 +37,11 @@
|
|
|
37
37
|
"import": "./dist/config-entry.mjs",
|
|
38
38
|
"require": "./dist/config-entry.js"
|
|
39
39
|
},
|
|
40
|
+
"./hooks": {
|
|
41
|
+
"types": "./dist/hooks/index.d.ts",
|
|
42
|
+
"import": "./dist/hooks/index.mjs",
|
|
43
|
+
"require": "./dist/hooks/index.js"
|
|
44
|
+
},
|
|
40
45
|
"./styles.css": "./dist/styles.css"
|
|
41
46
|
},
|
|
42
47
|
"scripts": {
|
|
@@ -52,6 +57,7 @@
|
|
|
52
57
|
},
|
|
53
58
|
"dependencies": {
|
|
54
59
|
"@measured/puck": "^0.20.2",
|
|
60
|
+
"@next/third-parties": "^16.1.6",
|
|
55
61
|
"@radix-ui/react-label": "^2.1.8",
|
|
56
62
|
"@radix-ui/react-slot": "^1.2.4",
|
|
57
63
|
"@tailwindcss/postcss": "^4.1.18",
|