@mission-studio/puck 1.0.1 → 1.0.3
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/ResponsiveToggleField-CVhKzDAT.d.mts +183 -0
- package/dist/ResponsiveToggleField-CVhKzDAT.d.ts +183 -0
- package/dist/{chunk-SRFEJJIW.mjs → chunk-F47J7QDM.mjs} +153 -41
- package/dist/chunk-OZYZPWP7.mjs +6288 -0
- package/dist/chunk-TTKY3YGP.mjs +262 -0
- package/dist/chunk-UJTTHDZA.mjs +16 -0
- package/dist/config-entry.d.mts +5 -0
- package/dist/config-entry.d.ts +5 -0
- package/dist/config-entry.js +9353 -0
- package/dist/config-entry.mjs +1075 -0
- package/dist/editor.d.mts +135 -0
- package/dist/editor.d.ts +135 -0
- package/dist/editor.js +7046 -0
- package/dist/editor.mjs +509 -0
- package/dist/index.d.mts +287 -0
- package/dist/index.d.ts +287 -0
- package/dist/index.js +2300 -0
- package/dist/index.mjs +82 -0
- package/dist/styles.css +2 -0
- package/package.json +2 -1
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import { ReactNode } from 'react';
|
|
3
|
+
|
|
4
|
+
type ColorValue = {
|
|
5
|
+
color: string;
|
|
6
|
+
opacity: number;
|
|
7
|
+
};
|
|
8
|
+
type CustomFieldProps<T> = {
|
|
9
|
+
value: T;
|
|
10
|
+
onChangeAction: (value: T) => void;
|
|
11
|
+
disabled?: boolean;
|
|
12
|
+
label: string;
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
type ThemeColors = {
|
|
16
|
+
primary: ColorValue;
|
|
17
|
+
secondary: ColorValue;
|
|
18
|
+
accent: ColorValue;
|
|
19
|
+
background: ColorValue;
|
|
20
|
+
foreground: ColorValue;
|
|
21
|
+
muted: ColorValue;
|
|
22
|
+
};
|
|
23
|
+
type ThemeTypography = {
|
|
24
|
+
fontFamily: {
|
|
25
|
+
heading: string;
|
|
26
|
+
body: string;
|
|
27
|
+
};
|
|
28
|
+
fontSize: {
|
|
29
|
+
base: string;
|
|
30
|
+
heading: string;
|
|
31
|
+
};
|
|
32
|
+
fontWeight: {
|
|
33
|
+
normal: number;
|
|
34
|
+
heading: number;
|
|
35
|
+
};
|
|
36
|
+
};
|
|
37
|
+
type ThemeSpacing = {
|
|
38
|
+
xs: number;
|
|
39
|
+
sm: number;
|
|
40
|
+
md: number;
|
|
41
|
+
lg: number;
|
|
42
|
+
xl: number;
|
|
43
|
+
};
|
|
44
|
+
type ThemeBorders = {
|
|
45
|
+
radiusSmall: number;
|
|
46
|
+
radiusMedium: number;
|
|
47
|
+
radiusLarge: number;
|
|
48
|
+
};
|
|
49
|
+
type ThemeShadows = {
|
|
50
|
+
small: string;
|
|
51
|
+
medium: string;
|
|
52
|
+
large: string;
|
|
53
|
+
};
|
|
54
|
+
type PageTheme = {
|
|
55
|
+
id: string;
|
|
56
|
+
name: string;
|
|
57
|
+
colors: ThemeColors;
|
|
58
|
+
typography: ThemeTypography;
|
|
59
|
+
spacing: ThemeSpacing;
|
|
60
|
+
borders: ThemeBorders;
|
|
61
|
+
shadows: ThemeShadows;
|
|
62
|
+
};
|
|
63
|
+
type ThemeColorKey = keyof ThemeColors;
|
|
64
|
+
type ThemeSpacingKey = keyof ThemeSpacing;
|
|
65
|
+
type ThemeBorderKey = keyof ThemeBorders;
|
|
66
|
+
type ThemeShadowKey = keyof ThemeShadows;
|
|
67
|
+
type ThemeableColorValue = {
|
|
68
|
+
useTheme: true;
|
|
69
|
+
themeKey: ThemeColorKey;
|
|
70
|
+
} | {
|
|
71
|
+
useTheme: false;
|
|
72
|
+
value: ColorValue;
|
|
73
|
+
};
|
|
74
|
+
type ThemeableSpacingValue = {
|
|
75
|
+
useTheme: true;
|
|
76
|
+
themeKey: ThemeSpacingKey;
|
|
77
|
+
} | {
|
|
78
|
+
useTheme: false;
|
|
79
|
+
value: number;
|
|
80
|
+
};
|
|
81
|
+
type ThemeableBorderRadiusValue = {
|
|
82
|
+
useTheme: true;
|
|
83
|
+
themeKey: ThemeBorderKey;
|
|
84
|
+
} | {
|
|
85
|
+
useTheme: false;
|
|
86
|
+
value: number;
|
|
87
|
+
};
|
|
88
|
+
type ThemeableShadowValue = {
|
|
89
|
+
useTheme: true;
|
|
90
|
+
themeKey: ThemeShadowKey;
|
|
91
|
+
} | {
|
|
92
|
+
useTheme: false;
|
|
93
|
+
value: string;
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
type ThemeContextValue = {
|
|
97
|
+
theme: PageTheme;
|
|
98
|
+
resolveColor: (key: ThemeColorKey) => ColorValue;
|
|
99
|
+
resolveSpacing: (key: ThemeSpacingKey) => number;
|
|
100
|
+
resolveBorderRadius: (key: ThemeBorderKey) => number;
|
|
101
|
+
resolveShadow: (key: ThemeShadowKey) => string;
|
|
102
|
+
};
|
|
103
|
+
declare function ThemeProvider({ theme, children, }: {
|
|
104
|
+
theme: PageTheme | null;
|
|
105
|
+
children: ReactNode;
|
|
106
|
+
}): react_jsx_runtime.JSX.Element;
|
|
107
|
+
declare function useTheme(): ThemeContextValue;
|
|
108
|
+
|
|
109
|
+
declare const DEFAULT_THEME: PageTheme;
|
|
110
|
+
|
|
111
|
+
type BorderRadiusPreset = {
|
|
112
|
+
label: string;
|
|
113
|
+
value: number;
|
|
114
|
+
};
|
|
115
|
+
declare const borderRadiusScale: BorderRadiusPreset[];
|
|
116
|
+
declare const getClosestBorderRadiusValue: (value: number) => number;
|
|
117
|
+
declare const getBorderRadiusCSS: (value: number) => string;
|
|
118
|
+
|
|
119
|
+
type ColorPreset = {
|
|
120
|
+
label: string;
|
|
121
|
+
value: string;
|
|
122
|
+
};
|
|
123
|
+
declare const neutralColors: ColorPreset[];
|
|
124
|
+
declare const allColorPresets: ColorPreset[];
|
|
125
|
+
|
|
126
|
+
type ShadowPreset = {
|
|
127
|
+
label: string;
|
|
128
|
+
value: string;
|
|
129
|
+
css: string;
|
|
130
|
+
};
|
|
131
|
+
declare const shadowPresets: ShadowPreset[];
|
|
132
|
+
declare const getShadowCSS: (value: string) => string;
|
|
133
|
+
|
|
134
|
+
type SpacingPreset = {
|
|
135
|
+
label: string;
|
|
136
|
+
value: number;
|
|
137
|
+
};
|
|
138
|
+
declare const spacingScale: SpacingPreset[];
|
|
139
|
+
declare const getClosestSpacingValue: (value: number) => number;
|
|
140
|
+
|
|
141
|
+
type FontFamilyPreset = {
|
|
142
|
+
label: string;
|
|
143
|
+
value: string;
|
|
144
|
+
};
|
|
145
|
+
type FontSizePreset = {
|
|
146
|
+
label: string;
|
|
147
|
+
value: string;
|
|
148
|
+
css: string;
|
|
149
|
+
};
|
|
150
|
+
type FontWeightPreset = {
|
|
151
|
+
label: string;
|
|
152
|
+
value: number;
|
|
153
|
+
};
|
|
154
|
+
declare const fontFamilies: FontFamilyPreset[];
|
|
155
|
+
declare const fontSizes: FontSizePreset[];
|
|
156
|
+
declare const fontWeights: FontWeightPreset[];
|
|
157
|
+
declare const getFontSizeCSS: (value: string) => string;
|
|
158
|
+
|
|
159
|
+
type EntryContent = Record<string, string | number | boolean | null>;
|
|
160
|
+
type Entry = {
|
|
161
|
+
id: string;
|
|
162
|
+
venture_id: string;
|
|
163
|
+
name: string;
|
|
164
|
+
content: EntryContent;
|
|
165
|
+
created_at: string | null;
|
|
166
|
+
updated_at: string | null;
|
|
167
|
+
};
|
|
168
|
+
type EntryBoundValue<T> = {
|
|
169
|
+
useEntry: true;
|
|
170
|
+
entryName: string;
|
|
171
|
+
fieldKey: string;
|
|
172
|
+
} | {
|
|
173
|
+
useEntry: false;
|
|
174
|
+
value: T;
|
|
175
|
+
};
|
|
176
|
+
|
|
177
|
+
type ResponsiveVisibility = {
|
|
178
|
+
mobile: boolean;
|
|
179
|
+
desktop: boolean;
|
|
180
|
+
};
|
|
181
|
+
declare function ResponsiveToggleField({ value, onChangeAction, disabled, label, }: CustomFieldProps<ResponsiveVisibility>): react_jsx_runtime.JSX.Element;
|
|
182
|
+
|
|
183
|
+
export { getBorderRadiusCSS as A, type BorderRadiusPreset as B, type ColorValue as C, DEFAULT_THEME as D, type Entry as E, type FontFamilyPreset as F, getClosestBorderRadiusValue as G, getClosestSpacingValue as H, getFontSizeCSS as I, getShadowCSS as J, neutralColors as K, shadowPresets as L, spacingScale as M, useTheme as N, type PageTheme as P, type ResponsiveVisibility as R, type ShadowPreset as S, type ThemeableColorValue as T, type EntryBoundValue as a, type ThemeColorKey as b, type CustomFieldProps as c, type ColorPreset as d, type EntryContent as e, type FontSizePreset as f, type FontWeightPreset as g, ResponsiveToggleField as h, type SpacingPreset as i, type ThemeBorderKey as j, type ThemeBorders as k, type ThemeColors as l, ThemeProvider as m, type ThemeShadowKey as n, type ThemeShadows as o, type ThemeSpacing as p, type ThemeSpacingKey as q, type ThemeTypography as r, type ThemeableBorderRadiusValue as s, type ThemeableShadowValue as t, type ThemeableSpacingValue as u, allColorPresets as v, borderRadiusScale as w, fontFamilies as x, fontSizes as y, fontWeights as z };
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import { ReactNode } from 'react';
|
|
3
|
+
|
|
4
|
+
type ColorValue = {
|
|
5
|
+
color: string;
|
|
6
|
+
opacity: number;
|
|
7
|
+
};
|
|
8
|
+
type CustomFieldProps<T> = {
|
|
9
|
+
value: T;
|
|
10
|
+
onChangeAction: (value: T) => void;
|
|
11
|
+
disabled?: boolean;
|
|
12
|
+
label: string;
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
type ThemeColors = {
|
|
16
|
+
primary: ColorValue;
|
|
17
|
+
secondary: ColorValue;
|
|
18
|
+
accent: ColorValue;
|
|
19
|
+
background: ColorValue;
|
|
20
|
+
foreground: ColorValue;
|
|
21
|
+
muted: ColorValue;
|
|
22
|
+
};
|
|
23
|
+
type ThemeTypography = {
|
|
24
|
+
fontFamily: {
|
|
25
|
+
heading: string;
|
|
26
|
+
body: string;
|
|
27
|
+
};
|
|
28
|
+
fontSize: {
|
|
29
|
+
base: string;
|
|
30
|
+
heading: string;
|
|
31
|
+
};
|
|
32
|
+
fontWeight: {
|
|
33
|
+
normal: number;
|
|
34
|
+
heading: number;
|
|
35
|
+
};
|
|
36
|
+
};
|
|
37
|
+
type ThemeSpacing = {
|
|
38
|
+
xs: number;
|
|
39
|
+
sm: number;
|
|
40
|
+
md: number;
|
|
41
|
+
lg: number;
|
|
42
|
+
xl: number;
|
|
43
|
+
};
|
|
44
|
+
type ThemeBorders = {
|
|
45
|
+
radiusSmall: number;
|
|
46
|
+
radiusMedium: number;
|
|
47
|
+
radiusLarge: number;
|
|
48
|
+
};
|
|
49
|
+
type ThemeShadows = {
|
|
50
|
+
small: string;
|
|
51
|
+
medium: string;
|
|
52
|
+
large: string;
|
|
53
|
+
};
|
|
54
|
+
type PageTheme = {
|
|
55
|
+
id: string;
|
|
56
|
+
name: string;
|
|
57
|
+
colors: ThemeColors;
|
|
58
|
+
typography: ThemeTypography;
|
|
59
|
+
spacing: ThemeSpacing;
|
|
60
|
+
borders: ThemeBorders;
|
|
61
|
+
shadows: ThemeShadows;
|
|
62
|
+
};
|
|
63
|
+
type ThemeColorKey = keyof ThemeColors;
|
|
64
|
+
type ThemeSpacingKey = keyof ThemeSpacing;
|
|
65
|
+
type ThemeBorderKey = keyof ThemeBorders;
|
|
66
|
+
type ThemeShadowKey = keyof ThemeShadows;
|
|
67
|
+
type ThemeableColorValue = {
|
|
68
|
+
useTheme: true;
|
|
69
|
+
themeKey: ThemeColorKey;
|
|
70
|
+
} | {
|
|
71
|
+
useTheme: false;
|
|
72
|
+
value: ColorValue;
|
|
73
|
+
};
|
|
74
|
+
type ThemeableSpacingValue = {
|
|
75
|
+
useTheme: true;
|
|
76
|
+
themeKey: ThemeSpacingKey;
|
|
77
|
+
} | {
|
|
78
|
+
useTheme: false;
|
|
79
|
+
value: number;
|
|
80
|
+
};
|
|
81
|
+
type ThemeableBorderRadiusValue = {
|
|
82
|
+
useTheme: true;
|
|
83
|
+
themeKey: ThemeBorderKey;
|
|
84
|
+
} | {
|
|
85
|
+
useTheme: false;
|
|
86
|
+
value: number;
|
|
87
|
+
};
|
|
88
|
+
type ThemeableShadowValue = {
|
|
89
|
+
useTheme: true;
|
|
90
|
+
themeKey: ThemeShadowKey;
|
|
91
|
+
} | {
|
|
92
|
+
useTheme: false;
|
|
93
|
+
value: string;
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
type ThemeContextValue = {
|
|
97
|
+
theme: PageTheme;
|
|
98
|
+
resolveColor: (key: ThemeColorKey) => ColorValue;
|
|
99
|
+
resolveSpacing: (key: ThemeSpacingKey) => number;
|
|
100
|
+
resolveBorderRadius: (key: ThemeBorderKey) => number;
|
|
101
|
+
resolveShadow: (key: ThemeShadowKey) => string;
|
|
102
|
+
};
|
|
103
|
+
declare function ThemeProvider({ theme, children, }: {
|
|
104
|
+
theme: PageTheme | null;
|
|
105
|
+
children: ReactNode;
|
|
106
|
+
}): react_jsx_runtime.JSX.Element;
|
|
107
|
+
declare function useTheme(): ThemeContextValue;
|
|
108
|
+
|
|
109
|
+
declare const DEFAULT_THEME: PageTheme;
|
|
110
|
+
|
|
111
|
+
type BorderRadiusPreset = {
|
|
112
|
+
label: string;
|
|
113
|
+
value: number;
|
|
114
|
+
};
|
|
115
|
+
declare const borderRadiusScale: BorderRadiusPreset[];
|
|
116
|
+
declare const getClosestBorderRadiusValue: (value: number) => number;
|
|
117
|
+
declare const getBorderRadiusCSS: (value: number) => string;
|
|
118
|
+
|
|
119
|
+
type ColorPreset = {
|
|
120
|
+
label: string;
|
|
121
|
+
value: string;
|
|
122
|
+
};
|
|
123
|
+
declare const neutralColors: ColorPreset[];
|
|
124
|
+
declare const allColorPresets: ColorPreset[];
|
|
125
|
+
|
|
126
|
+
type ShadowPreset = {
|
|
127
|
+
label: string;
|
|
128
|
+
value: string;
|
|
129
|
+
css: string;
|
|
130
|
+
};
|
|
131
|
+
declare const shadowPresets: ShadowPreset[];
|
|
132
|
+
declare const getShadowCSS: (value: string) => string;
|
|
133
|
+
|
|
134
|
+
type SpacingPreset = {
|
|
135
|
+
label: string;
|
|
136
|
+
value: number;
|
|
137
|
+
};
|
|
138
|
+
declare const spacingScale: SpacingPreset[];
|
|
139
|
+
declare const getClosestSpacingValue: (value: number) => number;
|
|
140
|
+
|
|
141
|
+
type FontFamilyPreset = {
|
|
142
|
+
label: string;
|
|
143
|
+
value: string;
|
|
144
|
+
};
|
|
145
|
+
type FontSizePreset = {
|
|
146
|
+
label: string;
|
|
147
|
+
value: string;
|
|
148
|
+
css: string;
|
|
149
|
+
};
|
|
150
|
+
type FontWeightPreset = {
|
|
151
|
+
label: string;
|
|
152
|
+
value: number;
|
|
153
|
+
};
|
|
154
|
+
declare const fontFamilies: FontFamilyPreset[];
|
|
155
|
+
declare const fontSizes: FontSizePreset[];
|
|
156
|
+
declare const fontWeights: FontWeightPreset[];
|
|
157
|
+
declare const getFontSizeCSS: (value: string) => string;
|
|
158
|
+
|
|
159
|
+
type EntryContent = Record<string, string | number | boolean | null>;
|
|
160
|
+
type Entry = {
|
|
161
|
+
id: string;
|
|
162
|
+
venture_id: string;
|
|
163
|
+
name: string;
|
|
164
|
+
content: EntryContent;
|
|
165
|
+
created_at: string | null;
|
|
166
|
+
updated_at: string | null;
|
|
167
|
+
};
|
|
168
|
+
type EntryBoundValue<T> = {
|
|
169
|
+
useEntry: true;
|
|
170
|
+
entryName: string;
|
|
171
|
+
fieldKey: string;
|
|
172
|
+
} | {
|
|
173
|
+
useEntry: false;
|
|
174
|
+
value: T;
|
|
175
|
+
};
|
|
176
|
+
|
|
177
|
+
type ResponsiveVisibility = {
|
|
178
|
+
mobile: boolean;
|
|
179
|
+
desktop: boolean;
|
|
180
|
+
};
|
|
181
|
+
declare function ResponsiveToggleField({ value, onChangeAction, disabled, label, }: CustomFieldProps<ResponsiveVisibility>): react_jsx_runtime.JSX.Element;
|
|
182
|
+
|
|
183
|
+
export { getBorderRadiusCSS as A, type BorderRadiusPreset as B, type ColorValue as C, DEFAULT_THEME as D, type Entry as E, type FontFamilyPreset as F, getClosestBorderRadiusValue as G, getClosestSpacingValue as H, getFontSizeCSS as I, getShadowCSS as J, neutralColors as K, shadowPresets as L, spacingScale as M, useTheme as N, type PageTheme as P, type ResponsiveVisibility as R, type ShadowPreset as S, type ThemeableColorValue as T, type EntryBoundValue as a, type ThemeColorKey as b, type CustomFieldProps as c, type ColorPreset as d, type EntryContent as e, type FontSizePreset as f, type FontWeightPreset as g, ResponsiveToggleField as h, type SpacingPreset as i, type ThemeBorderKey as j, type ThemeBorders as k, type ThemeColors as l, ThemeProvider as m, type ThemeShadowKey as n, type ThemeShadows as o, type ThemeSpacing as p, type ThemeSpacingKey as q, type ThemeTypography as r, type ThemeableBorderRadiusValue as s, type ThemeableShadowValue as t, type ThemeableSpacingValue as u, allColorPresets as v, borderRadiusScale as w, fontFamilies as x, fontSizes as y, fontWeights as z };
|
|
@@ -158,21 +158,8 @@ function Paragraph({
|
|
|
158
158
|
return /* @__PURE__ */ jsx2("p", { id, style, children: resolvedText });
|
|
159
159
|
}
|
|
160
160
|
|
|
161
|
-
//
|
|
162
|
-
|
|
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
|
-
}
|
|
161
|
+
// components/page/Button.tsx
|
|
162
|
+
import { sendGTMEvent } from "@next/third-parties/google";
|
|
176
163
|
|
|
177
164
|
// hooks/useUtmParams.ts
|
|
178
165
|
import { useEffect, useState } from "react";
|
|
@@ -263,7 +250,6 @@ function Button({
|
|
|
263
250
|
}) {
|
|
264
251
|
const { resolveColor: resolveColor2 } = useTheme();
|
|
265
252
|
const { getEntryValue } = useEntries();
|
|
266
|
-
const sendEvent = useGtmEvent();
|
|
267
253
|
const utm = useUtmParams();
|
|
268
254
|
const resolvedText = (() => {
|
|
269
255
|
if (!text) return "Button";
|
|
@@ -277,11 +263,14 @@ function Button({
|
|
|
277
263
|
return "Button";
|
|
278
264
|
})();
|
|
279
265
|
const handleClick = () => {
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
266
|
+
sendGTMEvent({
|
|
267
|
+
event: "button_click",
|
|
268
|
+
value: {
|
|
269
|
+
text: resolvedText,
|
|
270
|
+
href: href || void 0,
|
|
271
|
+
variant,
|
|
272
|
+
...utm
|
|
273
|
+
}
|
|
285
274
|
});
|
|
286
275
|
};
|
|
287
276
|
const resolvedColor = (() => {
|
|
@@ -496,6 +485,7 @@ function Image({
|
|
|
496
485
|
|
|
497
486
|
// components/page/ImageCarousel.tsx
|
|
498
487
|
import { useState as useState2 } from "react";
|
|
488
|
+
import { sendGTMEvent as sendGTMEvent2 } from "@next/third-parties/google";
|
|
499
489
|
import { Fragment, jsx as jsx5, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
500
490
|
var aspectRatioMap2 = {
|
|
501
491
|
"16:9": "16 / 9",
|
|
@@ -524,6 +514,7 @@ function ImageCarousel({
|
|
|
524
514
|
}) {
|
|
525
515
|
const [currentIndex, setCurrentIndex] = useState2(0);
|
|
526
516
|
const { resolveColor: resolveColor2 } = useTheme();
|
|
517
|
+
const utm = useUtmParams();
|
|
527
518
|
const resolvedArrowColor = (() => {
|
|
528
519
|
if (!arrowColor) return { color: "#FFFFFF", opacity: 100 };
|
|
529
520
|
if (typeof arrowColor === "string")
|
|
@@ -544,13 +535,42 @@ function ImageCarousel({
|
|
|
544
535
|
return resolveColor2("primary");
|
|
545
536
|
})();
|
|
546
537
|
const goToPrevious = () => {
|
|
547
|
-
|
|
538
|
+
const newIndex = currentIndex === 0 ? images.length - 1 : currentIndex - 1;
|
|
539
|
+
setCurrentIndex(newIndex);
|
|
540
|
+
sendGTMEvent2({
|
|
541
|
+
event: "carousel_navigate",
|
|
542
|
+
value: {
|
|
543
|
+
direction: "previous",
|
|
544
|
+
slideIndex: newIndex,
|
|
545
|
+
totalSlides: images.length,
|
|
546
|
+
...utm
|
|
547
|
+
}
|
|
548
|
+
});
|
|
548
549
|
};
|
|
549
550
|
const goToNext = () => {
|
|
550
|
-
|
|
551
|
+
const newIndex = currentIndex === images.length - 1 ? 0 : currentIndex + 1;
|
|
552
|
+
setCurrentIndex(newIndex);
|
|
553
|
+
sendGTMEvent2({
|
|
554
|
+
event: "carousel_navigate",
|
|
555
|
+
value: {
|
|
556
|
+
direction: "next",
|
|
557
|
+
slideIndex: newIndex,
|
|
558
|
+
totalSlides: images.length,
|
|
559
|
+
...utm
|
|
560
|
+
}
|
|
561
|
+
});
|
|
551
562
|
};
|
|
552
563
|
const goToSlide = (index) => {
|
|
553
564
|
setCurrentIndex(index);
|
|
565
|
+
sendGTMEvent2({
|
|
566
|
+
event: "carousel_navigate",
|
|
567
|
+
value: {
|
|
568
|
+
direction: "direct",
|
|
569
|
+
slideIndex: index,
|
|
570
|
+
totalSlides: images.length,
|
|
571
|
+
...utm
|
|
572
|
+
}
|
|
573
|
+
});
|
|
554
574
|
};
|
|
555
575
|
if (images.length === 0) {
|
|
556
576
|
return /* @__PURE__ */ jsx5(
|
|
@@ -1643,6 +1663,7 @@ function FeatureGrid({
|
|
|
1643
1663
|
|
|
1644
1664
|
// components/page/Footer.tsx
|
|
1645
1665
|
import { Facebook, Instagram, Twitter } from "lucide-react";
|
|
1666
|
+
import { sendGTMEvent as sendGTMEvent3 } from "@next/third-parties/google";
|
|
1646
1667
|
import { jsx as jsx18, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
1647
1668
|
function Footer({
|
|
1648
1669
|
logo,
|
|
@@ -1655,11 +1676,31 @@ function Footer({
|
|
|
1655
1676
|
puck
|
|
1656
1677
|
}) {
|
|
1657
1678
|
const DropZone = puck?.renderDropZone;
|
|
1679
|
+
const utm = useUtmParams();
|
|
1680
|
+
const getSocialPlatform = (url) => {
|
|
1681
|
+
if (url.includes("facebook")) return "facebook";
|
|
1682
|
+
if (url.includes("instagram")) return "instagram";
|
|
1683
|
+
if (url.includes("twitter")) return "twitter";
|
|
1684
|
+
return "social";
|
|
1685
|
+
};
|
|
1686
|
+
const handleSocialClick = (url) => {
|
|
1687
|
+
const platform = getSocialPlatform(url);
|
|
1688
|
+
sendGTMEvent3({
|
|
1689
|
+
event: "social_click",
|
|
1690
|
+
value: {
|
|
1691
|
+
platform,
|
|
1692
|
+
url,
|
|
1693
|
+
...utm
|
|
1694
|
+
}
|
|
1695
|
+
});
|
|
1696
|
+
};
|
|
1658
1697
|
const socialLinks = [
|
|
1659
1698
|
{ url: facebookUrl, Icon: Facebook },
|
|
1660
1699
|
{ url: instagramUrl, Icon: Instagram },
|
|
1661
1700
|
{ url: twitterUrl, Icon: Twitter }
|
|
1662
|
-
].filter(
|
|
1701
|
+
].filter(
|
|
1702
|
+
(link) => !!link.url
|
|
1703
|
+
);
|
|
1663
1704
|
return /* @__PURE__ */ jsx18(
|
|
1664
1705
|
"footer",
|
|
1665
1706
|
{
|
|
@@ -1675,6 +1716,7 @@ function Footer({
|
|
|
1675
1716
|
target: "_blank",
|
|
1676
1717
|
rel: "noopener noreferrer",
|
|
1677
1718
|
className: "transition-opacity hover:opacity-80",
|
|
1719
|
+
onClick: () => handleSocialClick(url),
|
|
1678
1720
|
children: /* @__PURE__ */ jsx18(Icon3, { size: 24, style: { color: textColor } })
|
|
1679
1721
|
},
|
|
1680
1722
|
index
|
|
@@ -1689,6 +1731,7 @@ function Footer({
|
|
|
1689
1731
|
import { useState as useState3 } from "react";
|
|
1690
1732
|
import Link from "next/link";
|
|
1691
1733
|
import { Menu, X } from "lucide-react";
|
|
1734
|
+
import { sendGTMEvent as sendGTMEvent4 } from "@next/third-parties/google";
|
|
1692
1735
|
import { jsx as jsx19, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
1693
1736
|
function Topbar({
|
|
1694
1737
|
logo,
|
|
@@ -1701,6 +1744,29 @@ function Topbar({
|
|
|
1701
1744
|
}) {
|
|
1702
1745
|
const DropZone = puck?.renderDropZone;
|
|
1703
1746
|
const [mobileMenuOpen, setMobileMenuOpen] = useState3(false);
|
|
1747
|
+
const utm = useUtmParams();
|
|
1748
|
+
const handleNavClick = (item) => {
|
|
1749
|
+
sendGTMEvent4({
|
|
1750
|
+
event: "nav_click",
|
|
1751
|
+
value: {
|
|
1752
|
+
name: item.name,
|
|
1753
|
+
url: item.url,
|
|
1754
|
+
linkType: item.linkType || "internal",
|
|
1755
|
+
...utm
|
|
1756
|
+
}
|
|
1757
|
+
});
|
|
1758
|
+
};
|
|
1759
|
+
const handleMobileMenuToggle = () => {
|
|
1760
|
+
const newState = !mobileMenuOpen;
|
|
1761
|
+
setMobileMenuOpen(newState);
|
|
1762
|
+
sendGTMEvent4({
|
|
1763
|
+
event: "mobile_menu_toggle",
|
|
1764
|
+
value: {
|
|
1765
|
+
open: newState,
|
|
1766
|
+
...utm
|
|
1767
|
+
}
|
|
1768
|
+
});
|
|
1769
|
+
};
|
|
1704
1770
|
const renderLink = (item, index) => {
|
|
1705
1771
|
const className = "hover:opacity-80 transition-opacity";
|
|
1706
1772
|
if (item.linkType === "external") {
|
|
@@ -1711,15 +1777,34 @@ function Topbar({
|
|
|
1711
1777
|
target: "_blank",
|
|
1712
1778
|
rel: "noopener noreferrer",
|
|
1713
1779
|
className,
|
|
1780
|
+
onClick: () => handleNavClick(item),
|
|
1714
1781
|
children: item.name
|
|
1715
1782
|
},
|
|
1716
1783
|
index
|
|
1717
1784
|
);
|
|
1718
1785
|
}
|
|
1719
1786
|
if (item.linkType === "scrollTo") {
|
|
1720
|
-
return /* @__PURE__ */ jsx19(
|
|
1787
|
+
return /* @__PURE__ */ jsx19(
|
|
1788
|
+
"a",
|
|
1789
|
+
{
|
|
1790
|
+
href: item.url,
|
|
1791
|
+
className,
|
|
1792
|
+
onClick: () => handleNavClick(item),
|
|
1793
|
+
children: item.name
|
|
1794
|
+
},
|
|
1795
|
+
index
|
|
1796
|
+
);
|
|
1721
1797
|
}
|
|
1722
|
-
return /* @__PURE__ */ jsx19(
|
|
1798
|
+
return /* @__PURE__ */ jsx19(
|
|
1799
|
+
Link,
|
|
1800
|
+
{
|
|
1801
|
+
href: item.url,
|
|
1802
|
+
className,
|
|
1803
|
+
onClick: () => handleNavClick(item),
|
|
1804
|
+
children: item.name
|
|
1805
|
+
},
|
|
1806
|
+
index
|
|
1807
|
+
);
|
|
1723
1808
|
};
|
|
1724
1809
|
return /* @__PURE__ */ jsxs8(
|
|
1725
1810
|
"nav",
|
|
@@ -1733,19 +1818,28 @@ function Topbar({
|
|
|
1733
1818
|
className: "mx-auto flex items-center justify-between",
|
|
1734
1819
|
style: { maxWidth },
|
|
1735
1820
|
children: [
|
|
1736
|
-
/* @__PURE__ */ jsx19(
|
|
1821
|
+
/* @__PURE__ */ jsx19(
|
|
1822
|
+
Link,
|
|
1823
|
+
{
|
|
1824
|
+
href: logoUrl,
|
|
1825
|
+
className: "flex-shrink-0",
|
|
1826
|
+
onClick: () => sendGTMEvent4({
|
|
1827
|
+
event: "nav_click",
|
|
1828
|
+
value: {
|
|
1829
|
+
name: "logo",
|
|
1830
|
+
url: logoUrl,
|
|
1831
|
+
linkType: "internal",
|
|
1832
|
+
...utm
|
|
1833
|
+
}
|
|
1834
|
+
}),
|
|
1835
|
+
children: logo ? /* @__PURE__ */ jsx19("img", { src: logo, alt: "Logo", className: "h-8" }) : /* @__PURE__ */ jsx19("span", { className: "text-xl font-bold", children: "Logo" })
|
|
1836
|
+
}
|
|
1837
|
+
),
|
|
1737
1838
|
/* @__PURE__ */ jsxs8("div", { className: "hidden items-center gap-8 md:flex", children: [
|
|
1738
1839
|
navItems.map(renderLink),
|
|
1739
1840
|
DropZone && /* @__PURE__ */ jsx19(DropZone, { zone: "cta" })
|
|
1740
1841
|
] }),
|
|
1741
|
-
/* @__PURE__ */ jsx19(
|
|
1742
|
-
"button",
|
|
1743
|
-
{
|
|
1744
|
-
className: "md:hidden",
|
|
1745
|
-
onClick: () => setMobileMenuOpen(!mobileMenuOpen),
|
|
1746
|
-
children: mobileMenuOpen ? /* @__PURE__ */ jsx19(X, { size: 24 }) : /* @__PURE__ */ jsx19(Menu, { size: 24 })
|
|
1747
|
-
}
|
|
1748
|
-
)
|
|
1842
|
+
/* @__PURE__ */ jsx19("button", { className: "md:hidden", onClick: handleMobileMenuToggle, children: mobileMenuOpen ? /* @__PURE__ */ jsx19(X, { size: 24 }) : /* @__PURE__ */ jsx19(Menu, { size: 24 }) })
|
|
1749
1843
|
]
|
|
1750
1844
|
}
|
|
1751
1845
|
),
|
|
@@ -1768,6 +1862,7 @@ function Topbar({
|
|
|
1768
1862
|
// components/page/Popup.tsx
|
|
1769
1863
|
import { useState as useState4 } from "react";
|
|
1770
1864
|
import { icons as icons4, X as X2 } from "lucide-react";
|
|
1865
|
+
import { sendGTMEvent as sendGTMEvent5 } from "@next/third-parties/google";
|
|
1771
1866
|
import { Fragment as Fragment2, jsx as jsx20, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
1772
1867
|
function Icon2({ name, ...props }) {
|
|
1773
1868
|
const formatted = name.charAt(0).toUpperCase() + name.slice(1);
|
|
@@ -1797,10 +1892,29 @@ function Popup({
|
|
|
1797
1892
|
puck
|
|
1798
1893
|
}) {
|
|
1799
1894
|
const [isOpen, setIsOpen] = useState4(false);
|
|
1895
|
+
const utm = useUtmParams();
|
|
1896
|
+
const handleOpen = () => {
|
|
1897
|
+
setIsOpen(true);
|
|
1898
|
+
sendGTMEvent5({
|
|
1899
|
+
event: "popup_open",
|
|
1900
|
+
value: {
|
|
1901
|
+
ctaText,
|
|
1902
|
+
type: textLink ? "link" : "button",
|
|
1903
|
+
...utm
|
|
1904
|
+
}
|
|
1905
|
+
});
|
|
1906
|
+
};
|
|
1907
|
+
const handleClose = () => {
|
|
1908
|
+
setIsOpen(false);
|
|
1909
|
+
sendGTMEvent5({
|
|
1910
|
+
event: "popup_close",
|
|
1911
|
+
value: { ctaText, ...utm }
|
|
1912
|
+
});
|
|
1913
|
+
};
|
|
1800
1914
|
const trigger = textLink ? /* @__PURE__ */ jsx20(
|
|
1801
1915
|
"button",
|
|
1802
1916
|
{
|
|
1803
|
-
onClick:
|
|
1917
|
+
onClick: handleOpen,
|
|
1804
1918
|
className: "underline hover:opacity-80",
|
|
1805
1919
|
style: { color: buttonColor },
|
|
1806
1920
|
children: ctaText
|
|
@@ -1808,7 +1922,7 @@ function Popup({
|
|
|
1808
1922
|
) : /* @__PURE__ */ jsxs9(
|
|
1809
1923
|
"button",
|
|
1810
1924
|
{
|
|
1811
|
-
onClick:
|
|
1925
|
+
onClick: handleOpen,
|
|
1812
1926
|
className: cn(
|
|
1813
1927
|
"flex items-center gap-2 rounded-full font-medium",
|
|
1814
1928
|
sizeMap8[size]
|
|
@@ -1827,7 +1941,7 @@ function Popup({
|
|
|
1827
1941
|
"div",
|
|
1828
1942
|
{
|
|
1829
1943
|
className: "fixed inset-0 z-50 flex items-center justify-center bg-black/50 p-4",
|
|
1830
|
-
onClick:
|
|
1944
|
+
onClick: handleClose,
|
|
1831
1945
|
children: /* @__PURE__ */ jsxs9(
|
|
1832
1946
|
"div",
|
|
1833
1947
|
{
|
|
@@ -1840,7 +1954,7 @@ function Popup({
|
|
|
1840
1954
|
/* @__PURE__ */ jsx20(
|
|
1841
1955
|
"button",
|
|
1842
1956
|
{
|
|
1843
|
-
onClick:
|
|
1957
|
+
onClick: handleClose,
|
|
1844
1958
|
className: "absolute top-4 right-4 text-gray-500 hover:text-gray-700",
|
|
1845
1959
|
children: /* @__PURE__ */ jsx20(X2, { size: 24 })
|
|
1846
1960
|
}
|
|
@@ -1857,8 +1971,6 @@ function Popup({
|
|
|
1857
1971
|
export {
|
|
1858
1972
|
Heading,
|
|
1859
1973
|
Paragraph,
|
|
1860
|
-
useGtmEvent,
|
|
1861
|
-
useUtmParams,
|
|
1862
1974
|
Button,
|
|
1863
1975
|
Image,
|
|
1864
1976
|
ImageCarousel,
|