@pelatform/ui 2.0.0 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +360 -5
- package/dist/animation.d.ts +6 -4
- package/dist/animation.js +3 -1
- package/dist/base.d.ts +1 -1
- package/dist/base.js +3 -1
- package/dist/components.d.ts +1 -2987
- package/dist/components.js +2 -2318
- package/dist/css/color/gray.css +105 -0
- package/dist/css/color/neutral.css +105 -0
- package/dist/css/color/slate.css +105 -0
- package/dist/css/color/stone.css +105 -0
- package/dist/css/color/zinc.css +105 -0
- package/dist/css/styles/style-lyra.css +1335 -0
- package/dist/css/styles/style-maia.css +1360 -0
- package/dist/css/styles/style-mira.css +1362 -0
- package/dist/css/styles/style-nova.css +1360 -0
- package/dist/css/styles/style-vega.css +1356 -0
- package/dist/hooks.d.ts +1 -93
- package/dist/hooks.js +2 -7
- package/dist/index.d.ts +1 -68
- package/dist/index.js +2 -7
- package/dist/radix.d.ts +1 -0
- package/dist/radix.js +4 -0
- package/dist/style.css +2 -0
- package/package.json +74 -48
- package/LICENSE +0 -21
- package/css/components/apexcharts.css +0 -101
- package/css/components/book.css +0 -19
- package/css/components/extra.css +0 -12
- package/css/components/image-input.css +0 -51
- package/css/components/leaflet.css +0 -25
- package/css/components/patterns.css +0 -34
- package/css/components/rating.css +0 -89
- package/css/components/scrollable.css +0 -118
- package/css/components/theme-transition.css +0 -51
- package/css/source.css +0 -20
- package/css/theme.css +0 -237
- package/dist/aria.d.ts +0 -1
- package/dist/aria.js +0 -2
- package/dist/chunk-UEVIEY7W.js +0 -51
- package/dist/chunk-VZEE3GOC.js +0 -458
- package/dist/default.d.ts +0 -1
- package/dist/default.js +0 -2
package/dist/components.js
CHANGED
|
@@ -1,2320 +1,4 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import {
|
|
3
|
-
useMetaColor
|
|
4
|
-
} from "./chunk-UEVIEY7W.js";
|
|
5
|
-
import {
|
|
6
|
-
Icons
|
|
7
|
-
} from "./chunk-VZEE3GOC.js";
|
|
8
2
|
|
|
9
|
-
// src/components
|
|
10
|
-
|
|
11
|
-
CheckIcon,
|
|
12
|
-
CircleAlertIcon,
|
|
13
|
-
CircleCheckIcon,
|
|
14
|
-
CircleXIcon,
|
|
15
|
-
InfoIcon,
|
|
16
|
-
TriangleAlertIcon
|
|
17
|
-
} from "@pelatform/ui.core";
|
|
18
|
-
import { Alert, AlertIcon, AlertTitle } from "@pelatform/ui.default";
|
|
19
|
-
import { toast } from "@pelatform/ui.default/dep";
|
|
20
|
-
import { jsx, jsxs } from "react/jsx-runtime";
|
|
21
|
-
var iconMap = {
|
|
22
|
-
primary: /* @__PURE__ */ jsx(CircleAlertIcon, {}),
|
|
23
|
-
success: /* @__PURE__ */ jsx(CircleCheckIcon, {}),
|
|
24
|
-
info: /* @__PURE__ */ jsx(InfoIcon, {}),
|
|
25
|
-
warning: /* @__PURE__ */ jsx(TriangleAlertIcon, {}),
|
|
26
|
-
destructive: /* @__PURE__ */ jsx(CircleXIcon, {})
|
|
27
|
-
};
|
|
28
|
-
function AlertToast({
|
|
29
|
-
message = "This is a toast",
|
|
30
|
-
icon = "success",
|
|
31
|
-
variant = "mono"
|
|
32
|
-
}) {
|
|
33
|
-
toast.custom(
|
|
34
|
-
() => /* @__PURE__ */ jsxs(Alert, { variant, icon, children: [
|
|
35
|
-
/* @__PURE__ */ jsx(AlertIcon, { children: iconMap[icon ?? "success"] }),
|
|
36
|
-
/* @__PURE__ */ jsx(AlertTitle, { children: message })
|
|
37
|
-
] }),
|
|
38
|
-
{
|
|
39
|
-
// Auto-dismiss after 4 seconds
|
|
40
|
-
duration: 4e3,
|
|
41
|
-
// Generate unique ID to prevent duplicate toasts
|
|
42
|
-
id: `alert-toast-${Date.now()}`
|
|
43
|
-
}
|
|
44
|
-
);
|
|
45
|
-
}
|
|
46
|
-
function AlertNotification({ message, variant = "info" }) {
|
|
47
|
-
if (!message) return null;
|
|
48
|
-
const getIcon = () => {
|
|
49
|
-
switch (variant) {
|
|
50
|
-
case "destructive":
|
|
51
|
-
return /* @__PURE__ */ jsx(CircleAlertIcon, {});
|
|
52
|
-
case "success":
|
|
53
|
-
return /* @__PURE__ */ jsx(CheckIcon, {});
|
|
54
|
-
case "info":
|
|
55
|
-
return /* @__PURE__ */ jsx(InfoIcon, {});
|
|
56
|
-
case "warning":
|
|
57
|
-
return /* @__PURE__ */ jsx(TriangleAlertIcon, {});
|
|
58
|
-
default:
|
|
59
|
-
return /* @__PURE__ */ jsx(InfoIcon, {});
|
|
60
|
-
}
|
|
61
|
-
};
|
|
62
|
-
return /* @__PURE__ */ jsxs(Alert, { variant, children: [
|
|
63
|
-
/* @__PURE__ */ jsx(AlertIcon, { children: getIcon() }),
|
|
64
|
-
/* @__PURE__ */ jsx(AlertTitle, { children: message })
|
|
65
|
-
] });
|
|
66
|
-
}
|
|
67
|
-
var AlertComingsoon = ({
|
|
68
|
-
message = "This feature is coming soon.",
|
|
69
|
-
icon = "success",
|
|
70
|
-
variant = "mono"
|
|
71
|
-
} = {}) => {
|
|
72
|
-
toast.custom(
|
|
73
|
-
() => /* @__PURE__ */ jsxs(Alert, { variant, icon, children: [
|
|
74
|
-
/* @__PURE__ */ jsx(AlertIcon, { children: /* @__PURE__ */ jsx(CircleAlertIcon, {}) }),
|
|
75
|
-
/* @__PURE__ */ jsx(AlertTitle, { children: message })
|
|
76
|
-
] }),
|
|
77
|
-
{
|
|
78
|
-
// Toast configuration for better UX
|
|
79
|
-
position: "top-center",
|
|
80
|
-
duration: 3e3,
|
|
81
|
-
// Show for 3 seconds
|
|
82
|
-
id: `coming-soon-${Date.now()}`
|
|
83
|
-
// Prevent duplicate toasts
|
|
84
|
-
}
|
|
85
|
-
);
|
|
86
|
-
};
|
|
87
|
-
|
|
88
|
-
// src/components/feedback/dialog.tsx
|
|
89
|
-
import {
|
|
90
|
-
AlertDialog,
|
|
91
|
-
AlertDialogAction,
|
|
92
|
-
AlertDialogCancel,
|
|
93
|
-
AlertDialogContent,
|
|
94
|
-
AlertDialogDescription,
|
|
95
|
-
AlertDialogFooter,
|
|
96
|
-
AlertDialogHeader,
|
|
97
|
-
AlertDialogTitle
|
|
98
|
-
} from "@pelatform/ui.default";
|
|
99
|
-
import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
100
|
-
var ConfirmDismissDialog = ({
|
|
101
|
-
open,
|
|
102
|
-
onOpenChange,
|
|
103
|
-
onConfirm,
|
|
104
|
-
onCancel,
|
|
105
|
-
title = "Discard changes?",
|
|
106
|
-
description = "You have unsaved changes. Are you sure you want to close this dialog?",
|
|
107
|
-
confirmText = "Discard changes",
|
|
108
|
-
cancelText = "Cancel",
|
|
109
|
-
maxWidth = "md:max-w-[375px]"
|
|
110
|
-
}) => {
|
|
111
|
-
const handleCancel = () => {
|
|
112
|
-
if (onCancel) {
|
|
113
|
-
onCancel();
|
|
114
|
-
} else {
|
|
115
|
-
onOpenChange(false);
|
|
116
|
-
}
|
|
117
|
-
};
|
|
118
|
-
return /* @__PURE__ */ jsx2(AlertDialog, { open, onOpenChange, children: /* @__PURE__ */ jsxs2(AlertDialogContent, { className: maxWidth, children: [
|
|
119
|
-
/* @__PURE__ */ jsxs2(AlertDialogHeader, { children: [
|
|
120
|
-
/* @__PURE__ */ jsx2(AlertDialogTitle, { children: title }),
|
|
121
|
-
/* @__PURE__ */ jsx2(AlertDialogDescription, { children: description })
|
|
122
|
-
] }),
|
|
123
|
-
/* @__PURE__ */ jsxs2(AlertDialogFooter, { children: [
|
|
124
|
-
/* @__PURE__ */ jsx2(AlertDialogCancel, { onClick: handleCancel, children: cancelText }),
|
|
125
|
-
/* @__PURE__ */ jsx2(AlertDialogAction, { onClick: onConfirm, children: confirmText })
|
|
126
|
-
] })
|
|
127
|
-
] }) });
|
|
128
|
-
};
|
|
129
|
-
|
|
130
|
-
// src/components/feedback/screen-loader.tsx
|
|
131
|
-
import { cn, LoaderIcon } from "@pelatform/ui.core";
|
|
132
|
-
import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
133
|
-
function ScreenLoader({
|
|
134
|
-
loadingText = "Loading...",
|
|
135
|
-
className = "",
|
|
136
|
-
spinnerClassName = "size-6 animate-spin",
|
|
137
|
-
textClassName = "text-muted-foreground font-medium text-sm",
|
|
138
|
-
contentLoader = false
|
|
139
|
-
} = {}) {
|
|
140
|
-
if (contentLoader) {
|
|
141
|
-
return /* @__PURE__ */ jsx3("div", { className: cn("flex w-full grow items-center justify-center", className), children: /* @__PURE__ */ jsxs3("div", { className: "flex items-center gap-2.5", children: [
|
|
142
|
-
/* @__PURE__ */ jsx3(LoaderIcon, { className: spinnerClassName, "aria-hidden": "true" }),
|
|
143
|
-
/* @__PURE__ */ jsx3("span", { className: textClassName, children: loadingText })
|
|
144
|
-
] }) });
|
|
145
|
-
}
|
|
146
|
-
return /* @__PURE__ */ jsxs3(
|
|
147
|
-
"div",
|
|
148
|
-
{
|
|
149
|
-
className: cn(
|
|
150
|
-
"fixed inset-0 z-500 flex flex-col items-center justify-center gap-2 bg-background transition-opacity duration-700 ease-in-out",
|
|
151
|
-
className
|
|
152
|
-
),
|
|
153
|
-
role: "status",
|
|
154
|
-
"aria-live": "polite",
|
|
155
|
-
"aria-label": loadingText,
|
|
156
|
-
children: [
|
|
157
|
-
/* @__PURE__ */ jsx3(LoaderIcon, { className: spinnerClassName, "aria-hidden": "true" }),
|
|
158
|
-
/* @__PURE__ */ jsx3("div", { className: textClassName, children: loadingText })
|
|
159
|
-
]
|
|
160
|
-
}
|
|
161
|
-
);
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
// src/components/layout/auth.tsx
|
|
165
|
-
import { cn as cn2 } from "@pelatform/ui.core";
|
|
166
|
-
import { Card, CardContent } from "@pelatform/ui.default";
|
|
167
|
-
import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
168
|
-
function LayoutAuth({
|
|
169
|
-
children,
|
|
170
|
-
className,
|
|
171
|
-
logo
|
|
172
|
-
}) {
|
|
173
|
-
return /* @__PURE__ */ jsxs4(
|
|
174
|
-
"div",
|
|
175
|
-
{
|
|
176
|
-
className: cn2("flex min-h-screen grow flex-col items-center justify-center p-4", className),
|
|
177
|
-
children: [
|
|
178
|
-
logo && /* @__PURE__ */ jsx4("div", { className: "m-5", children: logo }),
|
|
179
|
-
/* @__PURE__ */ jsx4(Card, { className: "w-full max-w-md", children: /* @__PURE__ */ jsx4(CardContent, { className: "p-6", children }) })
|
|
180
|
-
]
|
|
181
|
-
}
|
|
182
|
-
);
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
// src/components/layout/blank.tsx
|
|
186
|
-
import { cn as cn4 } from "@pelatform/ui.core";
|
|
187
|
-
|
|
188
|
-
// src/components/layout/grid.tsx
|
|
189
|
-
import { useId } from "react";
|
|
190
|
-
import { cn as cn3 } from "@pelatform/ui.core";
|
|
191
|
-
import { jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
192
|
-
function Grid({
|
|
193
|
-
cellSize = 12,
|
|
194
|
-
strokeWidth = 1,
|
|
195
|
-
patternOffset = [0, 0],
|
|
196
|
-
className
|
|
197
|
-
}) {
|
|
198
|
-
const id = useId();
|
|
199
|
-
return /* @__PURE__ */ jsxs5(
|
|
200
|
-
"svg",
|
|
201
|
-
{
|
|
202
|
-
className: cn3("pointer-events-none absolute inset-0 text-foreground/10", className),
|
|
203
|
-
width: "100%",
|
|
204
|
-
height: "100%",
|
|
205
|
-
children: [
|
|
206
|
-
/* @__PURE__ */ jsx5("defs", { children: /* @__PURE__ */ jsx5(
|
|
207
|
-
"pattern",
|
|
208
|
-
{
|
|
209
|
-
id: `grid-${id}`,
|
|
210
|
-
x: patternOffset[0] - 1,
|
|
211
|
-
y: patternOffset[1] - 1,
|
|
212
|
-
width: cellSize,
|
|
213
|
-
height: cellSize,
|
|
214
|
-
patternUnits: "userSpaceOnUse",
|
|
215
|
-
children: /* @__PURE__ */ jsx5(
|
|
216
|
-
"path",
|
|
217
|
-
{
|
|
218
|
-
d: `M ${cellSize} 0 L 0 0 0 ${cellSize}`,
|
|
219
|
-
fill: "transparent",
|
|
220
|
-
stroke: "currentColor",
|
|
221
|
-
strokeWidth
|
|
222
|
-
}
|
|
223
|
-
)
|
|
224
|
-
}
|
|
225
|
-
) }),
|
|
226
|
-
/* @__PURE__ */ jsx5("rect", { fill: `url(#grid-${id})`, width: "100%", height: "100%" })
|
|
227
|
-
]
|
|
228
|
-
}
|
|
229
|
-
);
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
// src/components/layout/blank.tsx
|
|
233
|
-
import { Fragment, jsx as jsx6, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
234
|
-
function LayoutBlank({ children, footer, className, logo, logoHref }) {
|
|
235
|
-
return /* @__PURE__ */ jsxs6(Fragment, { children: [
|
|
236
|
-
/* @__PURE__ */ jsx6("div", { className: "absolute inset-0 isolate overflow-hidden bg-background", children: /* @__PURE__ */ jsx6(
|
|
237
|
-
"div",
|
|
238
|
-
{
|
|
239
|
-
className: cn4(
|
|
240
|
-
"-translate-x-1/2 absolute inset-y-0 start-1/2 w-[1200px]",
|
|
241
|
-
"mask-intersect mask-[linear-gradient(black,transparent_320px),linear-gradient(90deg,transparent,black_5%,black_95%,transparent)]"
|
|
242
|
-
),
|
|
243
|
-
children: /* @__PURE__ */ jsx6(Grid, { cellSize: 60, patternOffset: [0.75, 0], className: "text-foreground/15" })
|
|
244
|
-
}
|
|
245
|
-
) }),
|
|
246
|
-
/* @__PURE__ */ jsxs6(
|
|
247
|
-
"div",
|
|
248
|
-
{
|
|
249
|
-
className: cn4(
|
|
250
|
-
"relative flex min-h-screen w-full flex-col items-center justify-between",
|
|
251
|
-
className
|
|
252
|
-
),
|
|
253
|
-
children: [
|
|
254
|
-
/* @__PURE__ */ jsx6("div", { className: "grow basis-0", children: logo && /* @__PURE__ */ jsx6("div", { className: "pt-4", children: /* @__PURE__ */ jsx6("a", { href: logoHref ?? "#", target: "_blank", className: "block", children: logo }) }) }),
|
|
255
|
-
/* @__PURE__ */ jsx6("div", { className: "w-full max-w-4xl px-4 py-16", children }),
|
|
256
|
-
/* @__PURE__ */ jsx6("div", { className: "grow basis-0", children: footer })
|
|
257
|
-
]
|
|
258
|
-
}
|
|
259
|
-
)
|
|
260
|
-
] });
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
// src/components/layout/body.tsx
|
|
264
|
-
import { cn as cn5 } from "@pelatform/ui.core";
|
|
265
|
-
import { jsx as jsx7 } from "react/jsx-runtime";
|
|
266
|
-
function useMode(slug) {
|
|
267
|
-
return Array.isArray(slug) && slug.length > 0 ? slug[0] : void 0;
|
|
268
|
-
}
|
|
269
|
-
function Body({ slug, children, className }) {
|
|
270
|
-
const mode = useMode(slug);
|
|
271
|
-
return /* @__PURE__ */ jsx7("body", { className: cn5(mode, className), children });
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
// src/components/layout/comingsoon.tsx
|
|
275
|
-
import { HoverBackground } from "@pelatform/ui.animation";
|
|
276
|
-
import { cn as cn6 } from "@pelatform/ui.core";
|
|
277
|
-
import { jsx as jsx8, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
278
|
-
function ComingSoon({ className, title, description }) {
|
|
279
|
-
return /* @__PURE__ */ jsx8("div", { className: cn6("h-[calc(100vh-54px)] w-full overflow-hidden", className), children: /* @__PURE__ */ jsx8(
|
|
280
|
-
HoverBackground,
|
|
281
|
-
{
|
|
282
|
-
colors: {
|
|
283
|
-
background: "bg-gradient-to-br from-black via-gray-900 to-zinc-900",
|
|
284
|
-
objects: [
|
|
285
|
-
"bg-emerald-500/30",
|
|
286
|
-
"bg-teal-500/30",
|
|
287
|
-
"bg-green-500/30",
|
|
288
|
-
"bg-lime-500/30",
|
|
289
|
-
"bg-cyan-500/30",
|
|
290
|
-
"bg-blue-500/30"
|
|
291
|
-
],
|
|
292
|
-
glow: "shadow-emerald-400/70"
|
|
293
|
-
},
|
|
294
|
-
objectCount: 8,
|
|
295
|
-
children: /* @__PURE__ */ jsxs7("div", { className: "flex h-full flex-col items-center justify-center space-y-4 text-center", children: [
|
|
296
|
-
title && /* @__PURE__ */ jsx8("h2", { className: "font-bold text-4xl text-white/90", children: title }),
|
|
297
|
-
description && /* @__PURE__ */ jsx8("p", { className: "max-w-md text-emerald-100/80 text-lg", children: description })
|
|
298
|
-
] })
|
|
299
|
-
}
|
|
300
|
-
) });
|
|
301
|
-
}
|
|
302
|
-
|
|
303
|
-
// src/components/layout/error.tsx
|
|
304
|
-
import { cn as cn7, getAssetsUrl } from "@pelatform/ui.core";
|
|
305
|
-
import { Badge } from "@pelatform/ui.default";
|
|
306
|
-
import { jsx as jsx9, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
307
|
-
function ErrorComponents({
|
|
308
|
-
className,
|
|
309
|
-
type = "default",
|
|
310
|
-
textTitle,
|
|
311
|
-
textSubtitle,
|
|
312
|
-
button
|
|
313
|
-
}) {
|
|
314
|
-
if (type === "404") {
|
|
315
|
-
return /* @__PURE__ */ jsxs8("div", { className: cn7("flex h-[95%] grow flex-col items-center justify-center", className), children: [
|
|
316
|
-
/* @__PURE__ */ jsxs8("div", { className: "mb-10", children: [
|
|
317
|
-
/* @__PURE__ */ jsx9(
|
|
318
|
-
"img",
|
|
319
|
-
{
|
|
320
|
-
src: getAssetsUrl("media/illustrations/19.svg"),
|
|
321
|
-
className: "max-h-40 dark:hidden",
|
|
322
|
-
alt: "illustrations"
|
|
323
|
-
}
|
|
324
|
-
),
|
|
325
|
-
/* @__PURE__ */ jsx9(
|
|
326
|
-
"img",
|
|
327
|
-
{
|
|
328
|
-
src: getAssetsUrl("media/illustrations/19-dark.svg"),
|
|
329
|
-
className: "hidden max-h-40 dark:block",
|
|
330
|
-
alt: "illustrations"
|
|
331
|
-
}
|
|
332
|
-
)
|
|
333
|
-
] }),
|
|
334
|
-
/* @__PURE__ */ jsx9(Badge, { variant: "destructive", appearance: "outline", className: "mb-3", children: "404 Error" }),
|
|
335
|
-
/* @__PURE__ */ jsx9("h3", { className: "mb-2 text-center font-semibold text-2xl text-foreground", children: textTitle }),
|
|
336
|
-
/* @__PURE__ */ jsx9("div", { className: "mb-10 text-center text-base text-secondary-foreground", children: textSubtitle })
|
|
337
|
-
] });
|
|
338
|
-
}
|
|
339
|
-
if (type === "500") {
|
|
340
|
-
return /* @__PURE__ */ jsxs8("div", { className: cn7("flex h-[95%] grow flex-col items-center justify-center", className), children: [
|
|
341
|
-
/* @__PURE__ */ jsxs8("div", { className: "mb-10", children: [
|
|
342
|
-
/* @__PURE__ */ jsx9(
|
|
343
|
-
"img",
|
|
344
|
-
{
|
|
345
|
-
src: getAssetsUrl("media/illustrations/20.svg"),
|
|
346
|
-
className: "max-h-40 dark:hidden",
|
|
347
|
-
alt: "illustrations"
|
|
348
|
-
}
|
|
349
|
-
),
|
|
350
|
-
/* @__PURE__ */ jsx9(
|
|
351
|
-
"img",
|
|
352
|
-
{
|
|
353
|
-
src: getAssetsUrl("media/illustrations/20-dark.svg"),
|
|
354
|
-
className: "hidden max-h-40 dark:block",
|
|
355
|
-
alt: "illustrations"
|
|
356
|
-
}
|
|
357
|
-
)
|
|
358
|
-
] }),
|
|
359
|
-
/* @__PURE__ */ jsx9(Badge, { variant: "destructive", appearance: "outline", className: "mb-3", children: "500 Error" }),
|
|
360
|
-
/* @__PURE__ */ jsx9("h3", { className: "mb-2 text-center font-semibold text-2xl text-foreground", children: textTitle }),
|
|
361
|
-
/* @__PURE__ */ jsx9("div", { className: "mb-10 text-center text-base text-secondary-foreground", children: textSubtitle }),
|
|
362
|
-
button
|
|
363
|
-
] });
|
|
364
|
-
}
|
|
365
|
-
return /* @__PURE__ */ jsxs8("div", { className: cn7("flex h-[95%] grow flex-col items-center justify-center", className), children: [
|
|
366
|
-
/* @__PURE__ */ jsxs8("div", { className: "mb-10", children: [
|
|
367
|
-
/* @__PURE__ */ jsx9(
|
|
368
|
-
"img",
|
|
369
|
-
{
|
|
370
|
-
src: getAssetsUrl("media/illustrations/29.svg"),
|
|
371
|
-
className: "max-h-40 dark:hidden",
|
|
372
|
-
alt: "illustrations"
|
|
373
|
-
}
|
|
374
|
-
),
|
|
375
|
-
/* @__PURE__ */ jsx9(
|
|
376
|
-
"img",
|
|
377
|
-
{
|
|
378
|
-
src: getAssetsUrl("media/illustrations/29-dark.svg"),
|
|
379
|
-
className: "hidden max-h-40 dark:block",
|
|
380
|
-
alt: "illustrations"
|
|
381
|
-
}
|
|
382
|
-
)
|
|
383
|
-
] }),
|
|
384
|
-
/* @__PURE__ */ jsx9("h3", { className: "mb-2 text-center font-semibold text-2xl text-foreground", children: textTitle }),
|
|
385
|
-
/* @__PURE__ */ jsx9("div", { className: "mb-10 text-center text-base text-secondary-foreground", children: textSubtitle })
|
|
386
|
-
] });
|
|
387
|
-
}
|
|
388
|
-
|
|
389
|
-
// src/components/layout/section.tsx
|
|
390
|
-
import { cn as cn9, PlusIcon } from "@pelatform/ui.core";
|
|
391
|
-
|
|
392
|
-
// src/components/ui/grid-background.tsx
|
|
393
|
-
import { cn as cn8 } from "@pelatform/ui.core";
|
|
394
|
-
import { jsx as jsx10, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
395
|
-
var GridBackground = ({
|
|
396
|
-
columns = 4,
|
|
397
|
-
className = "",
|
|
398
|
-
maxWidthClass = "grid-container"
|
|
399
|
-
}) => {
|
|
400
|
-
const columnElements = Array.from({ length: columns }, (_, i) => /* @__PURE__ */ jsx10(
|
|
401
|
-
"div",
|
|
402
|
-
{
|
|
403
|
-
className: "h-full w-px",
|
|
404
|
-
style: {
|
|
405
|
-
backgroundColor: i === 0 ? "var(--grid-base-color)" : "transparent",
|
|
406
|
-
backgroundImage: i === 0 ? "none" : `linear-gradient(180deg, var(--grid-dots-color) 50%, transparent 50%)`,
|
|
407
|
-
backgroundSize: i === 0 ? "auto" : "1px 8px"
|
|
408
|
-
}
|
|
409
|
-
},
|
|
410
|
-
i
|
|
411
|
-
));
|
|
412
|
-
return /* @__PURE__ */ jsx10("div", { className: cn8("stripe-grid -z-50 absolute inset-0 h-full w-full", className), children: /* @__PURE__ */ jsx10("div", { className: "relative h-full w-full overflow-hidden", children: /* @__PURE__ */ jsx10("div", { className: "pointer-events-none absolute top-0 left-0 h-full w-full", "aria-hidden": "true", children: /* @__PURE__ */ jsxs9(
|
|
413
|
-
"div",
|
|
414
|
-
{
|
|
415
|
-
className: cn8("relative mx-auto grid h-full grid-cols-4 grid-rows-1", maxWidthClass),
|
|
416
|
-
children: [
|
|
417
|
-
columnElements,
|
|
418
|
-
/* @__PURE__ */ jsx10(
|
|
419
|
-
"div",
|
|
420
|
-
{
|
|
421
|
-
className: "absolute top-0 right-0 h-full w-px",
|
|
422
|
-
style: { backgroundColor: "var(--grid-base-color)" }
|
|
423
|
-
}
|
|
424
|
-
)
|
|
425
|
-
]
|
|
426
|
-
}
|
|
427
|
-
) }) }) });
|
|
428
|
-
};
|
|
429
|
-
|
|
430
|
-
// src/components/layout/section.tsx
|
|
431
|
-
import { jsx as jsx11, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
432
|
-
var Cross = () => /* @__PURE__ */ jsxs10("div", { className: "relative h-6 w-6", children: [
|
|
433
|
-
/* @__PURE__ */ jsx11("div", { className: "absolute left-3 h-6 w-px bg-background" }),
|
|
434
|
-
/* @__PURE__ */ jsx11("div", { className: "absolute top-3 h-px w-6 bg-background" }),
|
|
435
|
-
/* @__PURE__ */ jsx11("div", { className: "-translate-x-1/2 -translate-y-1/2 absolute top-1/2 left-1/2", children: /* @__PURE__ */ jsx11(PlusIcon, { size: 20, className: "text-border/70 dark:text-border" }) })
|
|
436
|
-
] });
|
|
437
|
-
var Section = ({ children, sectionClassName, className, ...props }) => /* @__PURE__ */ jsx11("section", { className: sectionClassName, ...props, children: /* @__PURE__ */ jsxs10("div", { className: "grid-container relative mx-auto", children: [
|
|
438
|
-
/* @__PURE__ */ jsx11(GridBackground, { maxWidthClass: "grid-container" }),
|
|
439
|
-
/* @__PURE__ */ jsx11("div", { className: cn9(className), children }),
|
|
440
|
-
/* @__PURE__ */ jsx11("div", { className: "-bottom-3 -left-3 absolute z-10 hidden h-6 sm:block", children: /* @__PURE__ */ jsx11(Cross, {}) }),
|
|
441
|
-
/* @__PURE__ */ jsx11("div", { className: "-bottom-3 -right-3 -translate-x-px absolute z-10 hidden h-6 sm:block", children: /* @__PURE__ */ jsx11(Cross, {}) })
|
|
442
|
-
] }) });
|
|
443
|
-
|
|
444
|
-
// src/components/layout/site-footer.tsx
|
|
445
|
-
import { cn as cn10 } from "@pelatform/ui.core";
|
|
446
|
-
import { jsx as jsx12 } from "react/jsx-runtime";
|
|
447
|
-
function SiteFooter({ children, className }) {
|
|
448
|
-
return /* @__PURE__ */ jsx12("footer", { className: cn10("border-border border-t py-5 md:py-0", className), children: /* @__PURE__ */ jsx12("div", { className: "container flex flex-col items-center justify-between gap-4 py-4 md:h-16 md:flex-row", children }) });
|
|
449
|
-
}
|
|
450
|
-
|
|
451
|
-
// src/components/layout/site-header.tsx
|
|
452
|
-
import { cn as cn11 } from "@pelatform/ui.core";
|
|
453
|
-
import { jsx as jsx13 } from "react/jsx-runtime";
|
|
454
|
-
function SiteHeader({ className, children }) {
|
|
455
|
-
return /* @__PURE__ */ jsx13(
|
|
456
|
-
"header",
|
|
457
|
-
{
|
|
458
|
-
className: cn11(
|
|
459
|
-
"sticky top-0 z-50 w-full border-border border-b bg-background/95 backdrop-blur-sm supports-backdrop-filter:bg-background/60",
|
|
460
|
-
className
|
|
461
|
-
),
|
|
462
|
-
children: /* @__PURE__ */ jsx13("div", { className: "container flex h-16 items-center justify-between gap-4", children })
|
|
463
|
-
}
|
|
464
|
-
);
|
|
465
|
-
}
|
|
466
|
-
|
|
467
|
-
// src/components/layout/wrapper.tsx
|
|
468
|
-
import { cn as cn12 } from "@pelatform/ui.core";
|
|
469
|
-
import { jsx as jsx14 } from "react/jsx-runtime";
|
|
470
|
-
function MaxWidthWrapper({ className, children }) {
|
|
471
|
-
return /* @__PURE__ */ jsx14("div", { className: cn12("mx-auto w-full max-w-7xl p-3 lg:px-10", className), children });
|
|
472
|
-
}
|
|
473
|
-
|
|
474
|
-
// src/components/mdx/code-display.tsx
|
|
475
|
-
import { jsx as jsx15, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
476
|
-
function CodeDisplay({
|
|
477
|
-
children,
|
|
478
|
-
component
|
|
479
|
-
}) {
|
|
480
|
-
return /* @__PURE__ */ jsxs11("div", { className: "my-6 grid grid-cols-1 gap-6 overflow-hidden md:grid-cols-2", children: [
|
|
481
|
-
/* @__PURE__ */ jsx15("div", { className: "w-full overflow-hidden", children }),
|
|
482
|
-
/* @__PURE__ */ jsx15("div", { className: "my-6 flex w-full items-center justify-center rounded-lg border bg-gray-50 dark:bg-gray-900", children: component })
|
|
483
|
-
] });
|
|
484
|
-
}
|
|
485
|
-
|
|
486
|
-
// src/components/mdx/download.tsx
|
|
487
|
-
import { cn as cn13, DownloadIcon } from "@pelatform/ui.core";
|
|
488
|
-
import { Button } from "@pelatform/ui.default";
|
|
489
|
-
import { jsx as jsx16, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
490
|
-
function DownloadFile({ children, className, href }) {
|
|
491
|
-
return /* @__PURE__ */ jsx16("div", { className: "inline-flex pb-4", children: /* @__PURE__ */ jsx16(Button, { size: "lg", className: cn13("rounded-full", className), children: /* @__PURE__ */ jsxs12("a", { href, target: "_blank", rel: "noopener noreferrer", children: [
|
|
492
|
-
/* @__PURE__ */ jsx16(DownloadIcon, { className: "mr-2 size-5" }),
|
|
493
|
-
children
|
|
494
|
-
] }) }) });
|
|
495
|
-
}
|
|
496
|
-
|
|
497
|
-
// src/components/mdx/link.tsx
|
|
498
|
-
import { cn as cn14 } from "@pelatform/ui.core";
|
|
499
|
-
|
|
500
|
-
// src/components/utils/shared.tsx
|
|
501
|
-
import { jsx as jsx17 } from "react/jsx-runtime";
|
|
502
|
-
var DefaultImage = ({ src, alt, className }) => /* @__PURE__ */ jsx17("img", { src, alt, className });
|
|
503
|
-
var DefaultLink = ({ href, className, children }) => /* @__PURE__ */ jsx17("a", { href, className, children });
|
|
504
|
-
var DefaultNavigate = (href) => {
|
|
505
|
-
window.location.href = href;
|
|
506
|
-
};
|
|
507
|
-
|
|
508
|
-
// src/components/mdx/link.tsx
|
|
509
|
-
import { jsx as jsx18 } from "react/jsx-runtime";
|
|
510
|
-
function ExtraLink({
|
|
511
|
-
Link = DefaultLink,
|
|
512
|
-
href,
|
|
513
|
-
target,
|
|
514
|
-
className,
|
|
515
|
-
children
|
|
516
|
-
}) {
|
|
517
|
-
return /* @__PURE__ */ jsx18(
|
|
518
|
-
Link,
|
|
519
|
-
{
|
|
520
|
-
href,
|
|
521
|
-
target,
|
|
522
|
-
className: cn14("font-medium underline underline-offset-4", className),
|
|
523
|
-
children
|
|
524
|
-
}
|
|
525
|
-
);
|
|
526
|
-
}
|
|
527
|
-
|
|
528
|
-
// src/components/mdx/video.tsx
|
|
529
|
-
import { cn as cn15 } from "@pelatform/ui.core";
|
|
530
|
-
import { jsx as jsx19 } from "react/jsx-runtime";
|
|
531
|
-
function Video({ className, ...props }) {
|
|
532
|
-
return /* @__PURE__ */ jsx19("video", { className: cn15("w-full rounded-lg border", className), controls: true, loop: true, ...props });
|
|
533
|
-
}
|
|
534
|
-
|
|
535
|
-
// src/components/mdx/wrapper.tsx
|
|
536
|
-
import { cn as cn16 } from "@pelatform/ui.core";
|
|
537
|
-
import { jsx as jsx20 } from "react/jsx-runtime";
|
|
538
|
-
function Wrapper({ children, className }) {
|
|
539
|
-
return /* @__PURE__ */ jsx20(
|
|
540
|
-
"div",
|
|
541
|
-
{
|
|
542
|
-
className: cn16(
|
|
543
|
-
"prose-no-margin rounded-lg border border-fd-primary/10 bg-radial-[at_bottom] from-blue-500/20 bg-origin-border p-4 dark:bg-black/20",
|
|
544
|
-
className
|
|
545
|
-
),
|
|
546
|
-
children
|
|
547
|
-
}
|
|
548
|
-
);
|
|
549
|
-
}
|
|
550
|
-
|
|
551
|
-
// src/components/mdx/youtube.tsx
|
|
552
|
-
import { jsx as jsx21 } from "react/jsx-runtime";
|
|
553
|
-
function Youtube({ id }) {
|
|
554
|
-
return /* @__PURE__ */ jsx21(
|
|
555
|
-
"iframe",
|
|
556
|
-
{
|
|
557
|
-
src: `https://www.youtube.com/embed/${id}`,
|
|
558
|
-
title: `YouTube video with ID ${id}`,
|
|
559
|
-
style: {
|
|
560
|
-
width: "100%",
|
|
561
|
-
height: "auto",
|
|
562
|
-
aspectRatio: "16/9",
|
|
563
|
-
border: "none",
|
|
564
|
-
borderRadius: ".75rem",
|
|
565
|
-
overflow: "hidden"
|
|
566
|
-
},
|
|
567
|
-
allowFullScreen: true
|
|
568
|
-
}
|
|
569
|
-
);
|
|
570
|
-
}
|
|
571
|
-
|
|
572
|
-
// src/components/navigation/back-link.tsx
|
|
573
|
-
import { ChevronLeftIcon, cn as cn17 } from "@pelatform/ui.core";
|
|
574
|
-
import { Button as Button2 } from "@pelatform/ui.default";
|
|
575
|
-
import { jsx as jsx22, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
576
|
-
function BackLink({ Link = DefaultLink, children, href, className }) {
|
|
577
|
-
return /* @__PURE__ */ jsxs13(
|
|
578
|
-
Link,
|
|
579
|
-
{
|
|
580
|
-
href,
|
|
581
|
-
className: cn17(
|
|
582
|
-
"group flex items-center gap-2 text-foreground transition-colors duration-100 hover:text-foreground/75",
|
|
583
|
-
className
|
|
584
|
-
),
|
|
585
|
-
children: [
|
|
586
|
-
/* @__PURE__ */ jsx22(
|
|
587
|
-
Button2,
|
|
588
|
-
{
|
|
589
|
-
variant: "secondary",
|
|
590
|
-
mode: "icon",
|
|
591
|
-
className: "group-hover:-translate-x-0.5 size-7.5! transition-transform duration-100",
|
|
592
|
-
children: /* @__PURE__ */ jsx22(ChevronLeftIcon, {})
|
|
593
|
-
}
|
|
594
|
-
),
|
|
595
|
-
/* @__PURE__ */ jsx22("span", { className: "font-semibold text-lg", children })
|
|
596
|
-
]
|
|
597
|
-
}
|
|
598
|
-
);
|
|
599
|
-
}
|
|
600
|
-
|
|
601
|
-
// src/components/navigation/command-menu.tsx
|
|
602
|
-
import * as React from "react";
|
|
603
|
-
import { cn as cn18, googleTrackEvent, SearchIcon } from "@pelatform/ui.core";
|
|
604
|
-
import { Button as Button3, CommandDialog, CommandInput, CommandList } from "@pelatform/ui.default";
|
|
605
|
-
import { Fragment as Fragment2, jsx as jsx23, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
606
|
-
function CommandMenu({
|
|
607
|
-
children,
|
|
608
|
-
classButton,
|
|
609
|
-
classDialog,
|
|
610
|
-
searchButtonText = "Search ...",
|
|
611
|
-
commandInputPlaceholder = "Type a command or search...",
|
|
612
|
-
keyHint = "\u2318K",
|
|
613
|
-
...props
|
|
614
|
-
}) {
|
|
615
|
-
const [open, setOpen] = React.useState(false);
|
|
616
|
-
React.useEffect(() => {
|
|
617
|
-
const handleKeyDown = (e) => {
|
|
618
|
-
const isCommandShortcut = e.key === "k" && (e.metaKey || e.ctrlKey) || e.key === "/";
|
|
619
|
-
if (isCommandShortcut) {
|
|
620
|
-
const isTypingInField = e.target instanceof HTMLElement && e.target.isContentEditable || e.target instanceof HTMLInputElement || e.target instanceof HTMLTextAreaElement || e.target instanceof HTMLSelectElement;
|
|
621
|
-
if (isTypingInField) {
|
|
622
|
-
return;
|
|
623
|
-
}
|
|
624
|
-
e.preventDefault();
|
|
625
|
-
setOpen((currentOpen) => {
|
|
626
|
-
const newState = !currentOpen;
|
|
627
|
-
if (newState) {
|
|
628
|
-
googleTrackEvent({
|
|
629
|
-
name: "site_header_search_trigger_shortcut",
|
|
630
|
-
properties: {
|
|
631
|
-
method: e.key === "/" ? "slash" : "cmd_k",
|
|
632
|
-
category: "search",
|
|
633
|
-
label: `Search Trigger - ${e.key === "/" ? "Slash" : "Cmd+K"}`,
|
|
634
|
-
timestamp: Date.now()
|
|
635
|
-
}
|
|
636
|
-
});
|
|
637
|
-
}
|
|
638
|
-
return newState;
|
|
639
|
-
});
|
|
640
|
-
}
|
|
641
|
-
};
|
|
642
|
-
document.addEventListener("keydown", handleKeyDown);
|
|
643
|
-
return () => document.removeEventListener("keydown", handleKeyDown);
|
|
644
|
-
}, []);
|
|
645
|
-
const handleButtonClick = React.useCallback(() => {
|
|
646
|
-
googleTrackEvent({
|
|
647
|
-
name: "site_header_search_trigger_click",
|
|
648
|
-
properties: {
|
|
649
|
-
method: "button_click",
|
|
650
|
-
category: "search",
|
|
651
|
-
label: "Search Trigger - Button Click",
|
|
652
|
-
timestamp: Date.now()
|
|
653
|
-
}
|
|
654
|
-
});
|
|
655
|
-
}, []);
|
|
656
|
-
const handleOpenMenu = React.useCallback(() => {
|
|
657
|
-
setOpen(true);
|
|
658
|
-
handleButtonClick();
|
|
659
|
-
}, [handleButtonClick]);
|
|
660
|
-
return /* @__PURE__ */ jsxs14(Fragment2, { children: [
|
|
661
|
-
/* @__PURE__ */ jsxs14(
|
|
662
|
-
Button3,
|
|
663
|
-
{
|
|
664
|
-
variant: "outline",
|
|
665
|
-
mode: "input",
|
|
666
|
-
size: "sm",
|
|
667
|
-
className: cn18("relative h-8 w-full py-0 pl-2 sm:w-40 sm:pr-12 lg:w-48", classButton),
|
|
668
|
-
onClick: handleOpenMenu,
|
|
669
|
-
"aria-label": `Open command menu (${keyHint})`,
|
|
670
|
-
...props,
|
|
671
|
-
children: [
|
|
672
|
-
/* @__PURE__ */ jsx23(SearchIcon, { className: "mr-2 h-4 w-4", "aria-hidden": "true" }),
|
|
673
|
-
/* @__PURE__ */ jsx23("span", { className: "inline-flex text-muted-foreground", children: searchButtonText }),
|
|
674
|
-
/* @__PURE__ */ jsx23(
|
|
675
|
-
"kbd",
|
|
676
|
-
{
|
|
677
|
-
className: "-translate-y-1/2 pointer-events-none absolute top-1/2 right-[5px] hidden h-5 select-none items-center gap-1 rounded border bg-muted px-1.5 font-medium font-mono text-[10px] opacity-100 sm:flex",
|
|
678
|
-
"aria-label": `Keyboard shortcut: ${keyHint}`,
|
|
679
|
-
children: keyHint
|
|
680
|
-
}
|
|
681
|
-
)
|
|
682
|
-
]
|
|
683
|
-
}
|
|
684
|
-
),
|
|
685
|
-
/* @__PURE__ */ jsxs14(
|
|
686
|
-
CommandDialog,
|
|
687
|
-
{
|
|
688
|
-
open,
|
|
689
|
-
onOpenChange: setOpen,
|
|
690
|
-
className: cn18(
|
|
691
|
-
"**:data-dialog-close:end-[0.925rem] **:data-dialog-close:top-[0.925rem]",
|
|
692
|
-
classDialog
|
|
693
|
-
),
|
|
694
|
-
children: [
|
|
695
|
-
/* @__PURE__ */ jsx23(CommandInput, { placeholder: commandInputPlaceholder, "aria-label": "Search commands" }),
|
|
696
|
-
/* @__PURE__ */ jsx23(CommandList, { children })
|
|
697
|
-
]
|
|
698
|
-
}
|
|
699
|
-
)
|
|
700
|
-
] });
|
|
701
|
-
}
|
|
702
|
-
|
|
703
|
-
// src/components/navigation/main-nav.tsx
|
|
704
|
-
import { ArrowUpRightIcon, ChevronDownIcon, cn as cn19, googleTrackEvent as googleTrackEvent2 } from "@pelatform/ui.core";
|
|
705
|
-
import {
|
|
706
|
-
DropdownMenu,
|
|
707
|
-
DropdownMenuContent,
|
|
708
|
-
DropdownMenuItem,
|
|
709
|
-
DropdownMenuSub,
|
|
710
|
-
DropdownMenuSubContent,
|
|
711
|
-
DropdownMenuSubTrigger,
|
|
712
|
-
DropdownMenuTrigger
|
|
713
|
-
} from "@pelatform/ui.default";
|
|
714
|
-
import { jsx as jsx24, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
715
|
-
function MainNav({ Link = DefaultLink, pathname, items, className }) {
|
|
716
|
-
return /* @__PURE__ */ jsx24("div", { className: cn19("mr-4 hidden items-center justify-center md:flex", className), children: /* @__PURE__ */ jsx24("nav", { className: "flex items-center gap-4 font-medium text-sm xl:gap-6", children: items.map((item) => /* @__PURE__ */ jsx24(NavItemRenderer, { Link, item, pathname, level: 1 }, item.title)) }) });
|
|
717
|
-
}
|
|
718
|
-
function NavItemRenderer({ Link = DefaultLink, item, pathname, level }) {
|
|
719
|
-
const hasChildren = item.children && item.children.length > 0;
|
|
720
|
-
const isActive = hasChildren ? item.children?.some(
|
|
721
|
-
(child) => child.href === pathname || child.href !== "/" && child.href && pathname?.startsWith(child.href) || (child.children?.some(
|
|
722
|
-
(grandchild) => grandchild.href === pathname || grandchild.href !== "/" && grandchild.href && pathname?.startsWith(grandchild.href)
|
|
723
|
-
) ?? false)
|
|
724
|
-
) ?? false : item.href === pathname || item.href !== "/" && item.href && pathname?.startsWith(item.href);
|
|
725
|
-
if (hasChildren && level <= 3) {
|
|
726
|
-
return /* @__PURE__ */ jsxs15(DropdownMenu, { children: [
|
|
727
|
-
/* @__PURE__ */ jsx24(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsxs15(
|
|
728
|
-
"button",
|
|
729
|
-
{
|
|
730
|
-
className: cn19(
|
|
731
|
-
"inline-flex cursor-pointer items-center gap-1 transition-colors hover:text-foreground/80 focus-visible:outline-0",
|
|
732
|
-
isActive ? "text-foreground" : "text-foreground/60"
|
|
733
|
-
),
|
|
734
|
-
children: [
|
|
735
|
-
item.icon && /* @__PURE__ */ jsx24(item.icon, {}),
|
|
736
|
-
item.title,
|
|
737
|
-
/* @__PURE__ */ jsx24(ChevronDownIcon, { className: "size-3.5" })
|
|
738
|
-
]
|
|
739
|
-
}
|
|
740
|
-
) }),
|
|
741
|
-
/* @__PURE__ */ jsx24(
|
|
742
|
-
DropdownMenuContent,
|
|
743
|
-
{
|
|
744
|
-
className: "min-w-[150px] overflow-visible",
|
|
745
|
-
side: "bottom",
|
|
746
|
-
align: "start",
|
|
747
|
-
sideOffset: 15,
|
|
748
|
-
alignOffset: -10,
|
|
749
|
-
children: item.children?.map((child) => /* @__PURE__ */ jsx24(
|
|
750
|
-
ChildNavItemRenderer,
|
|
751
|
-
{
|
|
752
|
-
item: child,
|
|
753
|
-
pathname,
|
|
754
|
-
level: level + 1
|
|
755
|
-
},
|
|
756
|
-
child.title
|
|
757
|
-
))
|
|
758
|
-
}
|
|
759
|
-
)
|
|
760
|
-
] });
|
|
761
|
-
}
|
|
762
|
-
return /* @__PURE__ */ jsxs15(
|
|
763
|
-
Link,
|
|
764
|
-
{
|
|
765
|
-
href: item.href ?? "#",
|
|
766
|
-
...item.external ? { target: "_blank", rel: "noopener noreferrer" } : {},
|
|
767
|
-
className: cn19(
|
|
768
|
-
"relative inline-flex items-center gap-1 transition-colors hover:text-foreground/80",
|
|
769
|
-
isActive ? "text-foreground" : "text-foreground/60"
|
|
770
|
-
),
|
|
771
|
-
onClick: () => handleMenuClick(item),
|
|
772
|
-
children: [
|
|
773
|
-
item.icon && /* @__PURE__ */ jsx24(item.icon, {}),
|
|
774
|
-
item.title,
|
|
775
|
-
item.external && /* @__PURE__ */ jsx24(ArrowUpRightIcon, { className: "size-3.5 opacity-60" })
|
|
776
|
-
]
|
|
777
|
-
}
|
|
778
|
-
);
|
|
779
|
-
}
|
|
780
|
-
function ChildNavItemRenderer({ Link = DefaultLink, item, pathname, level }) {
|
|
781
|
-
const hasChildren = item.children && item.children.length > 0;
|
|
782
|
-
const isChildActive = item.href === pathname || item.href !== "/" && item.href && pathname?.startsWith(item.href) || hasChildren && (item.children?.some(
|
|
783
|
-
(grandchild) => grandchild.href === pathname || grandchild.href !== "/" && grandchild.href && pathname?.startsWith(grandchild.href)
|
|
784
|
-
) ?? false);
|
|
785
|
-
if (hasChildren && level <= 3) {
|
|
786
|
-
return /* @__PURE__ */ jsxs15(DropdownMenuSub, { children: [
|
|
787
|
-
/* @__PURE__ */ jsxs15(
|
|
788
|
-
DropdownMenuSubTrigger,
|
|
789
|
-
{
|
|
790
|
-
className: cn19(
|
|
791
|
-
"flex w-full items-center justify-between text-muted-foreground hover:text-foreground",
|
|
792
|
-
isChildActive && "font-medium text-foreground"
|
|
793
|
-
),
|
|
794
|
-
children: [
|
|
795
|
-
item.icon && /* @__PURE__ */ jsx24(item.icon, {}),
|
|
796
|
-
item.title
|
|
797
|
-
]
|
|
798
|
-
}
|
|
799
|
-
),
|
|
800
|
-
/* @__PURE__ */ jsx24(DropdownMenuSubContent, { className: "min-w-[150px]", children: item.children?.map((child) => /* @__PURE__ */ jsx24(
|
|
801
|
-
ChildNavItemRenderer,
|
|
802
|
-
{
|
|
803
|
-
item: child,
|
|
804
|
-
pathname,
|
|
805
|
-
level: level + 1
|
|
806
|
-
},
|
|
807
|
-
child.title
|
|
808
|
-
)) })
|
|
809
|
-
] });
|
|
810
|
-
}
|
|
811
|
-
return /* @__PURE__ */ jsx24(DropdownMenuItem, { asChild: true, children: /* @__PURE__ */ jsxs15(
|
|
812
|
-
Link,
|
|
813
|
-
{
|
|
814
|
-
href: item.href || "",
|
|
815
|
-
...item.external ? { target: "_blank", rel: "noopener noreferrer" } : {},
|
|
816
|
-
className: cn19(
|
|
817
|
-
"block w-full cursor-pointer transition-colors",
|
|
818
|
-
isChildActive ? "font-medium text-foreground" : "text-muted-foreground hover:text-foreground"
|
|
819
|
-
),
|
|
820
|
-
onClick: () => handleMenuClick(item),
|
|
821
|
-
children: [
|
|
822
|
-
item.icon && /* @__PURE__ */ jsx24(item.icon, {}),
|
|
823
|
-
item.title,
|
|
824
|
-
item.external && /* @__PURE__ */ jsx24(ArrowUpRightIcon, { className: "size-3.5 opacity-60" })
|
|
825
|
-
]
|
|
826
|
-
}
|
|
827
|
-
) });
|
|
828
|
-
}
|
|
829
|
-
function handleMenuClick(item) {
|
|
830
|
-
googleTrackEvent2({
|
|
831
|
-
name: `site_header_menu_${item.title.toLowerCase().replace(/\s+/g, "_")}_link_click`,
|
|
832
|
-
properties: {
|
|
833
|
-
menu_item: item.title,
|
|
834
|
-
menu_path: item.href || "#",
|
|
835
|
-
is_external: !!item.external,
|
|
836
|
-
category: "navigation",
|
|
837
|
-
label: `Header Menu ${item.title} Click`
|
|
838
|
-
}
|
|
839
|
-
});
|
|
840
|
-
}
|
|
841
|
-
|
|
842
|
-
// src/components/navigation/mobile-nav.tsx
|
|
843
|
-
import { useCallback as useCallback2, useState as useState2 } from "react";
|
|
844
|
-
import {
|
|
845
|
-
ArrowUpRightIcon as ArrowUpRightIcon2,
|
|
846
|
-
ChevronDownIcon as ChevronDownIcon2,
|
|
847
|
-
cn as cn20,
|
|
848
|
-
MenuIcon
|
|
849
|
-
} from "@pelatform/ui.core";
|
|
850
|
-
import {
|
|
851
|
-
Button as Button4,
|
|
852
|
-
Collapsible,
|
|
853
|
-
CollapsibleContent,
|
|
854
|
-
CollapsibleTrigger,
|
|
855
|
-
Drawer,
|
|
856
|
-
DrawerContent,
|
|
857
|
-
DrawerDescription,
|
|
858
|
-
DrawerTitle,
|
|
859
|
-
DrawerTrigger
|
|
860
|
-
} from "@pelatform/ui.default";
|
|
861
|
-
import { jsx as jsx25, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
862
|
-
function MobileNav({ children, className }) {
|
|
863
|
-
const { setMetaColor, metaColor } = useMetaColor();
|
|
864
|
-
const [open, setOpen] = useState2(false);
|
|
865
|
-
const onOpenChange = useCallback2(
|
|
866
|
-
(open2) => {
|
|
867
|
-
setOpen(open2);
|
|
868
|
-
setMetaColor(open2 ? "#09090b" : metaColor);
|
|
869
|
-
},
|
|
870
|
-
[setMetaColor, metaColor]
|
|
871
|
-
);
|
|
872
|
-
return /* @__PURE__ */ jsx25("div", { className: cn20("flex items-center gap-2.5 md:hidden", className), children: /* @__PURE__ */ jsxs16(Drawer, { open, onOpenChange, children: [
|
|
873
|
-
/* @__PURE__ */ jsx25(DrawerTrigger, { asChild: true, children: /* @__PURE__ */ jsxs16(Button4, { variant: "ghost", className: "group/toggle size-8 px-0 text-foreground", children: [
|
|
874
|
-
/* @__PURE__ */ jsx25(MenuIcon, {}),
|
|
875
|
-
/* @__PURE__ */ jsx25("span", { className: "sr-only", children: "Toggle Menu" })
|
|
876
|
-
] }) }),
|
|
877
|
-
/* @__PURE__ */ jsxs16(DrawerContent, { className: "max-h-[60svh] p-0", children: [
|
|
878
|
-
/* @__PURE__ */ jsx25(DrawerTitle, { className: "sr-only", children: "Mobile menu" }),
|
|
879
|
-
/* @__PURE__ */ jsx25("div", { className: "overflow-auto p-6", children }),
|
|
880
|
-
/* @__PURE__ */ jsx25(DrawerDescription, { className: "sr-only", children: "Mobile menu" })
|
|
881
|
-
] })
|
|
882
|
-
] }) });
|
|
883
|
-
}
|
|
884
|
-
function MobileNavItemRenderer({
|
|
885
|
-
Link = DefaultLink,
|
|
886
|
-
navigate = DefaultNavigate,
|
|
887
|
-
item,
|
|
888
|
-
pathname,
|
|
889
|
-
level,
|
|
890
|
-
onOpenChange
|
|
891
|
-
}) {
|
|
892
|
-
const router = navigate;
|
|
893
|
-
const [isOpen, setIsOpen] = useState2(false);
|
|
894
|
-
const hasChildren = item.children && item.children.length > 0;
|
|
895
|
-
const isActive = hasChildren ? item.children?.some(
|
|
896
|
-
(child) => child.href === pathname || child.href !== "/" && child.href && pathname?.startsWith(child.href) || (child.children?.some(
|
|
897
|
-
(grandchild) => grandchild.href === pathname || grandchild.href !== "/" && grandchild.href && pathname?.startsWith(grandchild.href)
|
|
898
|
-
) ?? false)
|
|
899
|
-
) ?? false : item.href === pathname || item.href !== "/" && item.href && pathname?.startsWith(item.href);
|
|
900
|
-
if (hasChildren && level <= 3) {
|
|
901
|
-
console.log(item);
|
|
902
|
-
return /* @__PURE__ */ jsxs16(Collapsible, { open: isOpen, onOpenChange: setIsOpen, children: [
|
|
903
|
-
/* @__PURE__ */ jsxs16(
|
|
904
|
-
CollapsibleTrigger,
|
|
905
|
-
{
|
|
906
|
-
className: cn20(
|
|
907
|
-
"flex w-full cursor-pointer items-center gap-1 text-sm transition-colors",
|
|
908
|
-
isOpen ? "text-foreground" : "text-foreground/60"
|
|
909
|
-
),
|
|
910
|
-
children: [
|
|
911
|
-
item.icon && /* @__PURE__ */ jsx25(item.icon, {}),
|
|
912
|
-
item.title,
|
|
913
|
-
/* @__PURE__ */ jsx25(
|
|
914
|
-
ChevronDownIcon2,
|
|
915
|
-
{
|
|
916
|
-
className: cn20(
|
|
917
|
-
"ml-auto size-3.5 opacity-60 transition-transform",
|
|
918
|
-
isOpen && "rotate-180"
|
|
919
|
-
)
|
|
920
|
-
}
|
|
921
|
-
)
|
|
922
|
-
]
|
|
923
|
-
}
|
|
924
|
-
),
|
|
925
|
-
/* @__PURE__ */ jsx25(CollapsibleContent, { children: /* @__PURE__ */ jsx25("div", { className: cn20("flex flex-col space-y-2.5 pt-3", `ps-5`), children: item.children.map((child) => /* @__PURE__ */ jsx25(
|
|
926
|
-
MobileNavItemRenderer,
|
|
927
|
-
{
|
|
928
|
-
item: child,
|
|
929
|
-
pathname,
|
|
930
|
-
level: level + 1,
|
|
931
|
-
onOpenChange
|
|
932
|
-
},
|
|
933
|
-
child.title
|
|
934
|
-
)) }) })
|
|
935
|
-
] });
|
|
936
|
-
}
|
|
937
|
-
return /* @__PURE__ */ jsxs16(
|
|
938
|
-
Link,
|
|
939
|
-
{
|
|
940
|
-
href: item.href || "#",
|
|
941
|
-
...item.external ? { target: "_blank", rel: "noopener noreferrer" } : {},
|
|
942
|
-
onClick: () => {
|
|
943
|
-
if (!item.external && item.href) {
|
|
944
|
-
router(item.href.toString());
|
|
945
|
-
}
|
|
946
|
-
onOpenChange?.(false);
|
|
947
|
-
handleMenuClick(item);
|
|
948
|
-
},
|
|
949
|
-
className: cn20(
|
|
950
|
-
"inline-flex items-center gap-1 text-sm transition-colors",
|
|
951
|
-
isActive ? "text-foreground" : "text-foreground/60"
|
|
952
|
-
),
|
|
953
|
-
children: [
|
|
954
|
-
item.icon && /* @__PURE__ */ jsx25(item.icon, {}),
|
|
955
|
-
item.title,
|
|
956
|
-
item.external && /* @__PURE__ */ jsx25(ArrowUpRightIcon2, { className: "ml-1 size-3.5 opacity-60" })
|
|
957
|
-
]
|
|
958
|
-
}
|
|
959
|
-
);
|
|
960
|
-
}
|
|
961
|
-
|
|
962
|
-
// src/components/providers/query-provider.tsx
|
|
963
|
-
import { useState as useState3 } from "react";
|
|
964
|
-
import { QueryCache, QueryClient, QueryClientProvider } from "@tanstack/react-query";
|
|
965
|
-
import { CircleAlertIcon as CircleAlertIcon2 } from "@pelatform/ui.core";
|
|
966
|
-
import { Alert as Alert2, AlertIcon as AlertIcon2, AlertTitle as AlertTitle2 } from "@pelatform/ui.default";
|
|
967
|
-
import { toast as toast2 } from "@pelatform/ui.default/dep";
|
|
968
|
-
import { jsx as jsx26, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
969
|
-
var QueryProvider = ({
|
|
970
|
-
client: clientProps,
|
|
971
|
-
children
|
|
972
|
-
}) => {
|
|
973
|
-
const [queryClient] = useState3(
|
|
974
|
-
() => new QueryClient({
|
|
975
|
-
/** Global query defaults for all queries */
|
|
976
|
-
defaultOptions: {
|
|
977
|
-
queries: {
|
|
978
|
-
/** Time before data is considered stale (5 minutes) */
|
|
979
|
-
staleTime: 5 * 60 * 1e3,
|
|
980
|
-
/** Time before inactive queries are garbage collected (10 minutes) */
|
|
981
|
-
gcTime: 10 * 60 * 1e3,
|
|
982
|
-
/** Number of retry attempts on failure */
|
|
983
|
-
retry: (failureCount, error) => {
|
|
984
|
-
if (error?.status && error.status >= 400 && error.status < 500) {
|
|
985
|
-
return false;
|
|
986
|
-
}
|
|
987
|
-
return failureCount < 3;
|
|
988
|
-
},
|
|
989
|
-
/** Delay between retries (exponential backoff) */
|
|
990
|
-
retryDelay: (attemptIndex) => Math.min(1e3 * 2 ** attemptIndex, 3e4),
|
|
991
|
-
/** Refetch on window focus for fresh data */
|
|
992
|
-
refetchOnWindowFocus: true,
|
|
993
|
-
/** Refetch when network reconnects */
|
|
994
|
-
refetchOnReconnect: true
|
|
995
|
-
},
|
|
996
|
-
mutations: {
|
|
997
|
-
/** Number of retry attempts for mutations */
|
|
998
|
-
retry: 1,
|
|
999
|
-
/** Delay between mutation retries */
|
|
1000
|
-
retryDelay: 1e3
|
|
1001
|
-
}
|
|
1002
|
-
},
|
|
1003
|
-
/** Global query cache with error handling */
|
|
1004
|
-
queryCache: new QueryCache({
|
|
1005
|
-
onError: (error, query) => {
|
|
1006
|
-
const message = error?.response?.data?.message || error?.message || "Something went wrong. Please try again.";
|
|
1007
|
-
if (process.env.NODE_ENV === "development") {
|
|
1008
|
-
console.error("Query Error:", {
|
|
1009
|
-
error,
|
|
1010
|
-
queryKey: query.queryKey,
|
|
1011
|
-
message,
|
|
1012
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
1013
|
-
});
|
|
1014
|
-
}
|
|
1015
|
-
toast2.custom(
|
|
1016
|
-
() => /* @__PURE__ */ jsxs17(Alert2, { variant: "mono", icon: "destructive", close: false, children: [
|
|
1017
|
-
/* @__PURE__ */ jsx26(AlertIcon2, { children: /* @__PURE__ */ jsx26(CircleAlertIcon2, {}) }),
|
|
1018
|
-
/* @__PURE__ */ jsx26(AlertTitle2, { children: message })
|
|
1019
|
-
] }),
|
|
1020
|
-
{
|
|
1021
|
-
position: "top-center",
|
|
1022
|
-
duration: 5e3,
|
|
1023
|
-
// Show for 5 seconds
|
|
1024
|
-
id: `query-error-${query.queryHash}`
|
|
1025
|
-
// Prevent duplicate toasts
|
|
1026
|
-
}
|
|
1027
|
-
);
|
|
1028
|
-
}
|
|
1029
|
-
})
|
|
1030
|
-
})
|
|
1031
|
-
);
|
|
1032
|
-
return /* @__PURE__ */ jsx26(QueryClientProvider, { client: clientProps ?? queryClient, children });
|
|
1033
|
-
};
|
|
1034
|
-
|
|
1035
|
-
// src/components/providers/theme-provider.tsx
|
|
1036
|
-
import { DEFAULT_THEME_MODE, THEME_MODES } from "@pelatform/ui.core";
|
|
1037
|
-
import { TooltipProvider } from "@pelatform/ui.default";
|
|
1038
|
-
import { ThemeProvider as NextThemesProvider } from "@pelatform/ui.default/dep";
|
|
1039
|
-
import { jsx as jsx27 } from "react/jsx-runtime";
|
|
1040
|
-
function ThemeProvider({ children, ...props }) {
|
|
1041
|
-
return /* @__PURE__ */ jsx27(
|
|
1042
|
-
NextThemesProvider,
|
|
1043
|
-
{
|
|
1044
|
-
attribute: "class",
|
|
1045
|
-
defaultTheme: DEFAULT_THEME_MODE,
|
|
1046
|
-
enableSystem: true,
|
|
1047
|
-
disableTransitionOnChange: true,
|
|
1048
|
-
enableColorScheme: true,
|
|
1049
|
-
storageKey: "theme",
|
|
1050
|
-
themes: [THEME_MODES.LIGHT, THEME_MODES.DARK, THEME_MODES.SYSTEM],
|
|
1051
|
-
...props,
|
|
1052
|
-
children: /* @__PURE__ */ jsx27(TooltipProvider, { delayDuration: 0, children })
|
|
1053
|
-
}
|
|
1054
|
-
);
|
|
1055
|
-
}
|
|
1056
|
-
|
|
1057
|
-
// src/components/ui/announcement.tsx
|
|
1058
|
-
import { cn as cn21 } from "@pelatform/ui.core";
|
|
1059
|
-
import { Badge as Badge2 } from "@pelatform/ui.default";
|
|
1060
|
-
import { jsx as jsx28 } from "react/jsx-runtime";
|
|
1061
|
-
var Announcement = ({
|
|
1062
|
-
variant = "outline",
|
|
1063
|
-
themed = false,
|
|
1064
|
-
className,
|
|
1065
|
-
...props
|
|
1066
|
-
}) => /* @__PURE__ */ jsx28(
|
|
1067
|
-
Badge2,
|
|
1068
|
-
{
|
|
1069
|
-
variant,
|
|
1070
|
-
className: cn21(
|
|
1071
|
-
"group max-w-full gap-2 rounded-full bg-background px-3 py-0.5 font-medium shadow-sm transition-all",
|
|
1072
|
-
"hover:shadow-md",
|
|
1073
|
-
themed && "announcement-themed border-foreground/5",
|
|
1074
|
-
className
|
|
1075
|
-
),
|
|
1076
|
-
...props
|
|
1077
|
-
}
|
|
1078
|
-
);
|
|
1079
|
-
var AnnouncementTag = ({ className, ...props }) => /* @__PURE__ */ jsx28(
|
|
1080
|
-
"div",
|
|
1081
|
-
{
|
|
1082
|
-
className: cn21(
|
|
1083
|
-
"-ml-2.5 shrink-0 truncate rounded-full bg-foreground/5 px-2.5 py-1 text-xs",
|
|
1084
|
-
"group-[.announcement-themed]:bg-background/60",
|
|
1085
|
-
className
|
|
1086
|
-
),
|
|
1087
|
-
...props
|
|
1088
|
-
}
|
|
1089
|
-
);
|
|
1090
|
-
var AnnouncementTitle = ({ className, ...props }) => /* @__PURE__ */ jsx28("div", { className: cn21("flex items-center gap-1 truncate py-1", className), ...props });
|
|
1091
|
-
|
|
1092
|
-
// src/components/ui/background-paths.tsx
|
|
1093
|
-
import { motion } from "@pelatform/ui.animation";
|
|
1094
|
-
import { cn as cn22 } from "@pelatform/ui.core";
|
|
1095
|
-
import { jsx as jsx29, jsxs as jsxs18 } from "react/jsx-runtime";
|
|
1096
|
-
function FloatingPaths({
|
|
1097
|
-
position,
|
|
1098
|
-
color = "text-slate-950 dark:text-white"
|
|
1099
|
-
}) {
|
|
1100
|
-
const paths = Array.from({ length: 36 }, (_, i) => ({
|
|
1101
|
-
id: i,
|
|
1102
|
-
d: `M-${380 - i * 5 * position} -${189 + i * 6}C-${380 - i * 5 * position} -${189 + i * 6} -${312 - i * 5 * position} ${216 - i * 6} ${152 - i * 5 * position} ${343 - i * 6}C${616 - i * 5 * position} ${470 - i * 6} ${684 - i * 5 * position} ${875 - i * 6} ${684 - i * 5 * position} ${875 - i * 6}`,
|
|
1103
|
-
color: `rgba(15,23,42,${0.1 + i * 0.03})`,
|
|
1104
|
-
width: 0.5 + i * 0.03
|
|
1105
|
-
}));
|
|
1106
|
-
return /* @__PURE__ */ jsx29("div", { className: "-z-50 pointer-events-none absolute inset-0", children: /* @__PURE__ */ jsx29("svg", { className: cn22("h-full w-full", color), viewBox: "0 0 696 316", fill: "none", children: paths.map((path) => /* @__PURE__ */ jsx29(
|
|
1107
|
-
motion.path,
|
|
1108
|
-
{
|
|
1109
|
-
d: path.d,
|
|
1110
|
-
stroke: "currentColor",
|
|
1111
|
-
strokeWidth: path.width,
|
|
1112
|
-
strokeOpacity: 0.1 + path.id * 0.03,
|
|
1113
|
-
initial: { pathLength: 0.3, opacity: 0.6 },
|
|
1114
|
-
animate: {
|
|
1115
|
-
pathLength: 1,
|
|
1116
|
-
opacity: [0.3, 0.6, 0.3],
|
|
1117
|
-
pathOffset: [0, 1, 0]
|
|
1118
|
-
},
|
|
1119
|
-
transition: {
|
|
1120
|
-
duration: 20 + Math.random() * 10,
|
|
1121
|
-
repeat: Number.POSITIVE_INFINITY,
|
|
1122
|
-
ease: "linear"
|
|
1123
|
-
}
|
|
1124
|
-
},
|
|
1125
|
-
path.id
|
|
1126
|
-
)) }) });
|
|
1127
|
-
}
|
|
1128
|
-
function BackgroundPaths({ color = "text-slate-950 dark:text-white" }) {
|
|
1129
|
-
return /* @__PURE__ */ jsx29("div", { className: "relative flex min-h-screen w-full items-center justify-center overflow-hidden bg-white dark:bg-neutral-950", children: /* @__PURE__ */ jsxs18("div", { className: "absolute inset-0", children: [
|
|
1130
|
-
/* @__PURE__ */ jsx29(FloatingPaths, { position: 1, color }),
|
|
1131
|
-
/* @__PURE__ */ jsx29(FloatingPaths, { position: -1, color })
|
|
1132
|
-
] }) });
|
|
1133
|
-
}
|
|
1134
|
-
|
|
1135
|
-
// src/components/ui/book.tsx
|
|
1136
|
-
import { cn as cn23 } from "@pelatform/ui.core";
|
|
1137
|
-
import { jsx as jsx30, jsxs as jsxs19 } from "react/jsx-runtime";
|
|
1138
|
-
function Book(props) {
|
|
1139
|
-
const {
|
|
1140
|
-
children,
|
|
1141
|
-
color = "#f50537",
|
|
1142
|
-
depth,
|
|
1143
|
-
texture,
|
|
1144
|
-
variant = "default",
|
|
1145
|
-
textColor,
|
|
1146
|
-
illustration,
|
|
1147
|
-
width
|
|
1148
|
-
} = props;
|
|
1149
|
-
return /* @__PURE__ */ jsx30(
|
|
1150
|
-
"div",
|
|
1151
|
-
{
|
|
1152
|
-
className: cn23("group perspective-[900px] inline-block w-fit"),
|
|
1153
|
-
style: {
|
|
1154
|
-
"--book-color": color,
|
|
1155
|
-
"--text-color": textColor,
|
|
1156
|
-
"--book-depth": `${depth || 4}cqw`,
|
|
1157
|
-
"--book-width": `${width || 196}px`
|
|
1158
|
-
},
|
|
1159
|
-
children: /* @__PURE__ */ jsxs19("div", { className: "transform-3d group-hover:transform-[rotateY(-20deg)_scale(1.066)translateX(-8px)] relative aspect-49/60 w-fit min-w-[calc(var(--book-width))] rotate-0 transition-transform duration-500 ease-out contain-inline-size", children: [
|
|
1160
|
-
/* @__PURE__ */ jsxs19(
|
|
1161
|
-
Stack,
|
|
1162
|
-
{
|
|
1163
|
-
align: "stretch",
|
|
1164
|
-
className: "absolute size-full overflow-hidden rounded-r rounded-l border border-border bg-stone-100 shadow-book dark:bg-stone-800",
|
|
1165
|
-
children: [
|
|
1166
|
-
variant !== "simple" && /* @__PURE__ */ jsxs19(
|
|
1167
|
-
Stack,
|
|
1168
|
-
{
|
|
1169
|
-
shrink: true,
|
|
1170
|
-
grow: true,
|
|
1171
|
-
direction: "row",
|
|
1172
|
-
className: cn23(
|
|
1173
|
-
"relative min-w-[calc(var(--book-width))] overflow-hidden bg-(--book-color)"
|
|
1174
|
-
),
|
|
1175
|
-
children: [
|
|
1176
|
-
/* @__PURE__ */ jsx30("div", { className: "absolute inset-y-0 min-w-[8.2%] bg-book-bind-bg opacity-100 mix-blend-overlay" }),
|
|
1177
|
-
illustration && /* @__PURE__ */ jsx30("div", { className: "object-cover", children: illustration })
|
|
1178
|
-
]
|
|
1179
|
-
}
|
|
1180
|
-
),
|
|
1181
|
-
/* @__PURE__ */ jsxs19(Stack, { grow: variant === "simple", direction: "row", className: "h-fit", children: [
|
|
1182
|
-
/* @__PURE__ */ jsx30("div", { className: "h-full min-w-[8.2%] bg-book-bind-bg opacity-100 mix-blend-overlay" }),
|
|
1183
|
-
/* @__PURE__ */ jsx30("div", { className: "w-full contain-inline-size", children })
|
|
1184
|
-
] }),
|
|
1185
|
-
texture && /* @__PURE__ */ jsx30(
|
|
1186
|
-
"div",
|
|
1187
|
-
{
|
|
1188
|
-
"aria-hidden": true,
|
|
1189
|
-
className: "absolute inset-0 bg-ali bg-cover bg-no-repeat opacity-60 mix-blend-hard-light"
|
|
1190
|
-
}
|
|
1191
|
-
)
|
|
1192
|
-
]
|
|
1193
|
-
}
|
|
1194
|
-
),
|
|
1195
|
-
/* @__PURE__ */ jsx30(
|
|
1196
|
-
"div",
|
|
1197
|
-
{
|
|
1198
|
-
"aria-hidden": true,
|
|
1199
|
-
className: "absolute top-[3px] h-[calc(100%-2*6px)] w-[calc(var(--book-depth)-2px)] bg-book-pages",
|
|
1200
|
-
style: {
|
|
1201
|
-
transform: "translateX(calc(var(--book-width) - var(--book-depth) / 2 - 3px)) rotateY(90deg) translateX(calc(var(--book-depth) / 2))"
|
|
1202
|
-
}
|
|
1203
|
-
}
|
|
1204
|
-
),
|
|
1205
|
-
/* @__PURE__ */ jsx30(
|
|
1206
|
-
"div",
|
|
1207
|
-
{
|
|
1208
|
-
"aria-hidden": true,
|
|
1209
|
-
className: "book-bg absolute left-0 h-full w-full rounded-r rounded-l-md bg-(--book-color)",
|
|
1210
|
-
style: {
|
|
1211
|
-
transform: "translateZ(calc(-1 * var(--book-depth)))"
|
|
1212
|
-
}
|
|
1213
|
-
}
|
|
1214
|
-
)
|
|
1215
|
-
] })
|
|
1216
|
-
}
|
|
1217
|
-
);
|
|
1218
|
-
}
|
|
1219
|
-
function Stack(props) {
|
|
1220
|
-
const {
|
|
1221
|
-
children,
|
|
1222
|
-
shrink = false,
|
|
1223
|
-
grow = false,
|
|
1224
|
-
justify = "start",
|
|
1225
|
-
align = "start",
|
|
1226
|
-
wrap = false,
|
|
1227
|
-
padding = 0,
|
|
1228
|
-
gap = 0,
|
|
1229
|
-
direction = "column",
|
|
1230
|
-
className,
|
|
1231
|
-
...etc
|
|
1232
|
-
} = props;
|
|
1233
|
-
return /* @__PURE__ */ jsx30(
|
|
1234
|
-
"div",
|
|
1235
|
-
{
|
|
1236
|
-
className,
|
|
1237
|
-
style: {
|
|
1238
|
-
display: "flex",
|
|
1239
|
-
flex: "initial",
|
|
1240
|
-
flexDirection: direction,
|
|
1241
|
-
alignItems: align === "start" ? "flex-start" : align === "end" ? "flex-end" : align,
|
|
1242
|
-
justifyContent: justify === "start" ? "flex-start" : justify === "end" ? "flex-end" : justify,
|
|
1243
|
-
flexWrap: wrap ? "wrap" : "nowrap",
|
|
1244
|
-
flexGrow: grow ? 1 : 0,
|
|
1245
|
-
flexShrink: shrink ? 1 : 0,
|
|
1246
|
-
padding: `${padding * 4}px`,
|
|
1247
|
-
gap: `${gap * 4}px`
|
|
1248
|
-
},
|
|
1249
|
-
...etc,
|
|
1250
|
-
children
|
|
1251
|
-
}
|
|
1252
|
-
);
|
|
1253
|
-
}
|
|
1254
|
-
|
|
1255
|
-
// src/components/ui/dots-pattern.tsx
|
|
1256
|
-
import { useId as useId2 } from "react";
|
|
1257
|
-
import { cn as cn24 } from "@pelatform/ui.core";
|
|
1258
|
-
import { jsx as jsx31, jsxs as jsxs20 } from "react/jsx-runtime";
|
|
1259
|
-
function DotsPattern({
|
|
1260
|
-
dotSize = 2,
|
|
1261
|
-
gapSize = 10,
|
|
1262
|
-
patternOffset = [0, 0],
|
|
1263
|
-
className
|
|
1264
|
-
}) {
|
|
1265
|
-
const id = useId2();
|
|
1266
|
-
return /* @__PURE__ */ jsxs20(
|
|
1267
|
-
"svg",
|
|
1268
|
-
{
|
|
1269
|
-
className: cn24("pointer-events-none absolute inset-0 text-foreground/10", className),
|
|
1270
|
-
width: "100%",
|
|
1271
|
-
height: "100%",
|
|
1272
|
-
children: [
|
|
1273
|
-
/* @__PURE__ */ jsx31("defs", { children: /* @__PURE__ */ jsx31(
|
|
1274
|
-
"pattern",
|
|
1275
|
-
{
|
|
1276
|
-
id: `dots-${id}`,
|
|
1277
|
-
x: patternOffset[0] - 1,
|
|
1278
|
-
y: patternOffset[1] - 1,
|
|
1279
|
-
width: dotSize + gapSize,
|
|
1280
|
-
height: dotSize + gapSize,
|
|
1281
|
-
patternUnits: "userSpaceOnUse",
|
|
1282
|
-
children: /* @__PURE__ */ jsx31("rect", { x: 1, y: 1, width: dotSize, height: dotSize, fill: "currentColor" })
|
|
1283
|
-
}
|
|
1284
|
-
) }),
|
|
1285
|
-
/* @__PURE__ */ jsx31("rect", { fill: `url(#dots-${id})`, width: "100%", height: "100%" })
|
|
1286
|
-
]
|
|
1287
|
-
}
|
|
1288
|
-
);
|
|
1289
|
-
}
|
|
1290
|
-
|
|
1291
|
-
// src/components/ui/hexagon-badge.tsx
|
|
1292
|
-
import { cn as cn25 } from "@pelatform/ui.core";
|
|
1293
|
-
import { jsx as jsx32, jsxs as jsxs21 } from "react/jsx-runtime";
|
|
1294
|
-
var HexagonBadge = ({ children, classNames }) => {
|
|
1295
|
-
return /* @__PURE__ */ jsxs21("div", { className: cn25("relative shrink-0", classNames?.base), children: [
|
|
1296
|
-
/* @__PURE__ */ jsxs21(
|
|
1297
|
-
"svg",
|
|
1298
|
-
{
|
|
1299
|
-
className: cn25("h-full w-full", classNames?.svg),
|
|
1300
|
-
width: "44",
|
|
1301
|
-
height: "48",
|
|
1302
|
-
viewBox: "0 0 44 48",
|
|
1303
|
-
fill: "none",
|
|
1304
|
-
xmlns: "http://www.w3.org/2000/svg",
|
|
1305
|
-
children: [
|
|
1306
|
-
/* @__PURE__ */ jsx32(
|
|
1307
|
-
"path",
|
|
1308
|
-
{
|
|
1309
|
-
d: "M16 2.4641C19.7128 0.320509 24.2872 0.320508 28 2.4641L37.6506 8.0359C41.3634 10.1795 43.6506 14.141 43.6506 \n 18.4282V29.5718C43.6506 33.859 41.3634 37.8205 37.6506 39.9641L28 45.5359C24.2872 47.6795 19.7128 47.6795 16 45.5359L6.34937 \n 39.9641C2.63655 37.8205 0.349365 33.859 0.349365 29.5718V18.4282C0.349365 14.141 2.63655 10.1795 6.34937 8.0359L16 2.4641Z",
|
|
1310
|
-
fill: ""
|
|
1311
|
-
}
|
|
1312
|
-
),
|
|
1313
|
-
/* @__PURE__ */ jsx32(
|
|
1314
|
-
"path",
|
|
1315
|
-
{
|
|
1316
|
-
d: "M16.25 2.89711C19.8081 0.842838 24.1919 0.842837 27.75 2.89711L37.4006 8.46891C40.9587 10.5232 43.1506 14.3196 43.1506 \n 18.4282V29.5718C43.1506 33.6804 40.9587 37.4768 37.4006 39.5311L27.75 45.1029C24.1919 47.1572 19.8081 47.1572 16.25 45.1029L6.59937 \n 39.5311C3.04125 37.4768 0.849365 33.6803 0.849365 29.5718V18.4282C0.849365 14.3196 3.04125 10.5232 6.59937 8.46891L16.25 2.89711Z",
|
|
1317
|
-
stroke: ""
|
|
1318
|
-
}
|
|
1319
|
-
)
|
|
1320
|
-
]
|
|
1321
|
-
}
|
|
1322
|
-
),
|
|
1323
|
-
/* @__PURE__ */ jsx32(
|
|
1324
|
-
"div",
|
|
1325
|
-
{
|
|
1326
|
-
className: cn25(
|
|
1327
|
-
"-translate-y-2/4 -translate-x-2/4 absolute start-2/4 top-2/4 leading-none rtl:translate-x-2/4",
|
|
1328
|
-
classNames?.wraper
|
|
1329
|
-
),
|
|
1330
|
-
children
|
|
1331
|
-
}
|
|
1332
|
-
)
|
|
1333
|
-
] });
|
|
1334
|
-
};
|
|
1335
|
-
|
|
1336
|
-
// src/components/ui/image-input.tsx
|
|
1337
|
-
import {
|
|
1338
|
-
useCallback as useCallback3,
|
|
1339
|
-
useRef,
|
|
1340
|
-
useState as useState4
|
|
1341
|
-
} from "react";
|
|
1342
|
-
import { Fragment as Fragment3, jsx as jsx33, jsxs as jsxs22 } from "react/jsx-runtime";
|
|
1343
|
-
var DEFAULT_NULL_INDEX = -1;
|
|
1344
|
-
var DEFAULT_DATA_URL_KEY = "dataURL";
|
|
1345
|
-
var openFileDialog = (inputRef) => {
|
|
1346
|
-
if (!inputRef.current) {
|
|
1347
|
-
return;
|
|
1348
|
-
}
|
|
1349
|
-
inputRef.current.click();
|
|
1350
|
-
};
|
|
1351
|
-
var getAcceptTypeString = (acceptType, allowNonImageType) => {
|
|
1352
|
-
if (acceptType?.length) return acceptType.map((item) => `.${item}`).join(", ");
|
|
1353
|
-
if (allowNonImageType) return "";
|
|
1354
|
-
return "image/*";
|
|
1355
|
-
};
|
|
1356
|
-
var getBase64 = async (file) => {
|
|
1357
|
-
const reader = new FileReader();
|
|
1358
|
-
return await new Promise((resolve) => {
|
|
1359
|
-
reader.addEventListener("load", () => {
|
|
1360
|
-
resolve(String(reader.result));
|
|
1361
|
-
});
|
|
1362
|
-
reader.readAsDataURL(file);
|
|
1363
|
-
});
|
|
1364
|
-
};
|
|
1365
|
-
var getImage = async (file) => {
|
|
1366
|
-
const image = new Image();
|
|
1367
|
-
return await new Promise((resolve) => {
|
|
1368
|
-
image.addEventListener("load", () => {
|
|
1369
|
-
resolve(image);
|
|
1370
|
-
});
|
|
1371
|
-
image.src = URL.createObjectURL(file);
|
|
1372
|
-
});
|
|
1373
|
-
};
|
|
1374
|
-
var getListFiles = async (files, dataURLKey) => {
|
|
1375
|
-
const promiseFiles = [];
|
|
1376
|
-
for (let i = 0; i < files.length; i += 1) {
|
|
1377
|
-
promiseFiles.push(getBase64(files[i]));
|
|
1378
|
-
}
|
|
1379
|
-
return await Promise.all(promiseFiles).then((fileListBase64) => {
|
|
1380
|
-
const fileList = fileListBase64.map((base64, index) => ({
|
|
1381
|
-
[dataURLKey]: base64,
|
|
1382
|
-
file: files[index]
|
|
1383
|
-
}));
|
|
1384
|
-
return fileList;
|
|
1385
|
-
});
|
|
1386
|
-
};
|
|
1387
|
-
var ImageInput = ({
|
|
1388
|
-
value,
|
|
1389
|
-
acceptType,
|
|
1390
|
-
inputProps,
|
|
1391
|
-
multiple,
|
|
1392
|
-
children,
|
|
1393
|
-
onChange
|
|
1394
|
-
}) => {
|
|
1395
|
-
const inValue = value || [];
|
|
1396
|
-
const inputRef = useRef(null);
|
|
1397
|
-
const [keyUpdate, setKeyUpdate] = useState4(DEFAULT_NULL_INDEX);
|
|
1398
|
-
const [isDragging, setIsDragging] = useState4(false);
|
|
1399
|
-
const onImageRemoveAll = useCallback3(() => {
|
|
1400
|
-
onChange?.([]);
|
|
1401
|
-
}, [onChange]);
|
|
1402
|
-
const handleClickInput = useCallback3(() => {
|
|
1403
|
-
openFileDialog(inputRef);
|
|
1404
|
-
}, []);
|
|
1405
|
-
const onImageUpload = useCallback3(() => {
|
|
1406
|
-
handleClickInput();
|
|
1407
|
-
}, [handleClickInput]);
|
|
1408
|
-
const onInputChange = async (e) => {
|
|
1409
|
-
await handleChange(e.target.files);
|
|
1410
|
-
if (inputRef.current) inputRef.current.value = "";
|
|
1411
|
-
};
|
|
1412
|
-
const handleChange = async (files) => {
|
|
1413
|
-
if (!files) return;
|
|
1414
|
-
const fileList = await getListFiles(files, DEFAULT_DATA_URL_KEY);
|
|
1415
|
-
if (!fileList.length) return;
|
|
1416
|
-
let updatedFileList;
|
|
1417
|
-
const updatedIndexes = [];
|
|
1418
|
-
if (keyUpdate > DEFAULT_NULL_INDEX) {
|
|
1419
|
-
const [firstFile] = fileList;
|
|
1420
|
-
updatedFileList = [...inValue];
|
|
1421
|
-
updatedFileList[keyUpdate] = firstFile;
|
|
1422
|
-
updatedIndexes.push(keyUpdate);
|
|
1423
|
-
} else if (multiple) {
|
|
1424
|
-
updatedFileList = [...inValue, ...fileList];
|
|
1425
|
-
for (let i = inValue.length; i < updatedFileList.length; i += 1) {
|
|
1426
|
-
updatedIndexes.push(i);
|
|
1427
|
-
}
|
|
1428
|
-
} else {
|
|
1429
|
-
updatedFileList = [fileList[0]];
|
|
1430
|
-
updatedIndexes.push(0);
|
|
1431
|
-
}
|
|
1432
|
-
onChange?.(updatedFileList, updatedIndexes);
|
|
1433
|
-
};
|
|
1434
|
-
const onImageRemove = (index) => {
|
|
1435
|
-
const updatedList = [...inValue];
|
|
1436
|
-
if (Array.isArray(index)) {
|
|
1437
|
-
index.forEach((i) => {
|
|
1438
|
-
updatedList.splice(i, 1);
|
|
1439
|
-
});
|
|
1440
|
-
} else {
|
|
1441
|
-
updatedList.splice(index, 1);
|
|
1442
|
-
}
|
|
1443
|
-
onChange?.(updatedList);
|
|
1444
|
-
};
|
|
1445
|
-
const onImageUpdate = (index) => {
|
|
1446
|
-
setKeyUpdate(index);
|
|
1447
|
-
handleClickInput();
|
|
1448
|
-
};
|
|
1449
|
-
const handleDrag = (e) => {
|
|
1450
|
-
e.preventDefault();
|
|
1451
|
-
e.stopPropagation();
|
|
1452
|
-
};
|
|
1453
|
-
const handleDragIn = (e) => {
|
|
1454
|
-
e.preventDefault();
|
|
1455
|
-
e.stopPropagation();
|
|
1456
|
-
if (e.dataTransfer.items && e.dataTransfer.items.length > 0) {
|
|
1457
|
-
setIsDragging(true);
|
|
1458
|
-
}
|
|
1459
|
-
};
|
|
1460
|
-
const handleDragOut = (e) => {
|
|
1461
|
-
e.preventDefault();
|
|
1462
|
-
e.stopPropagation();
|
|
1463
|
-
setIsDragging(false);
|
|
1464
|
-
};
|
|
1465
|
-
const handleDrop = (e) => {
|
|
1466
|
-
e.preventDefault();
|
|
1467
|
-
e.stopPropagation();
|
|
1468
|
-
setIsDragging(false);
|
|
1469
|
-
if (e.dataTransfer.files && e.dataTransfer.files.length > 0) {
|
|
1470
|
-
handleChange(e.dataTransfer.files);
|
|
1471
|
-
}
|
|
1472
|
-
};
|
|
1473
|
-
const handleDragStart = (e) => {
|
|
1474
|
-
e.preventDefault();
|
|
1475
|
-
e.stopPropagation();
|
|
1476
|
-
e.dataTransfer.clearData();
|
|
1477
|
-
};
|
|
1478
|
-
return /* @__PURE__ */ jsxs22(Fragment3, { children: [
|
|
1479
|
-
/* @__PURE__ */ jsx33(
|
|
1480
|
-
"input",
|
|
1481
|
-
{
|
|
1482
|
-
ref: inputRef,
|
|
1483
|
-
type: "file",
|
|
1484
|
-
accept: getAcceptTypeString(acceptType),
|
|
1485
|
-
multiple,
|
|
1486
|
-
onChange: (e) => {
|
|
1487
|
-
onInputChange(e);
|
|
1488
|
-
},
|
|
1489
|
-
style: { display: "none" },
|
|
1490
|
-
...inputProps
|
|
1491
|
-
}
|
|
1492
|
-
),
|
|
1493
|
-
children?.({
|
|
1494
|
-
fileList: inValue,
|
|
1495
|
-
onImageUpload,
|
|
1496
|
-
onImageRemove,
|
|
1497
|
-
onImageUpdate,
|
|
1498
|
-
onImageRemoveAll,
|
|
1499
|
-
dragProps: {
|
|
1500
|
-
onDrop: handleDrop,
|
|
1501
|
-
onDragEnter: handleDragIn,
|
|
1502
|
-
onDragLeave: handleDragOut,
|
|
1503
|
-
onDragOver: handleDrag,
|
|
1504
|
-
onDragStart: handleDragStart
|
|
1505
|
-
},
|
|
1506
|
-
isDragging
|
|
1507
|
-
})
|
|
1508
|
-
] });
|
|
1509
|
-
};
|
|
1510
|
-
|
|
1511
|
-
// src/components/ui/language-switcher.tsx
|
|
1512
|
-
import { useTransition } from "react";
|
|
1513
|
-
import { cn as cn26, GlobeIcon, getFlagUrl, LanguagesIcon } from "@pelatform/ui.core";
|
|
1514
|
-
import {
|
|
1515
|
-
Badge as Badge3,
|
|
1516
|
-
Button as Button5,
|
|
1517
|
-
DropdownMenu as DropdownMenu2,
|
|
1518
|
-
DropdownMenuContent as DropdownMenuContent2,
|
|
1519
|
-
DropdownMenuItem as DropdownMenuItem2,
|
|
1520
|
-
DropdownMenuRadioGroup,
|
|
1521
|
-
DropdownMenuRadioItem,
|
|
1522
|
-
DropdownMenuSub as DropdownMenuSub2,
|
|
1523
|
-
DropdownMenuSubContent as DropdownMenuSubContent2,
|
|
1524
|
-
DropdownMenuSubTrigger as DropdownMenuSubTrigger2,
|
|
1525
|
-
DropdownMenuTrigger as DropdownMenuTrigger2
|
|
1526
|
-
} from "@pelatform/ui.default";
|
|
1527
|
-
import { jsx as jsx34, jsxs as jsxs23 } from "react/jsx-runtime";
|
|
1528
|
-
function LanguageSwitcher({
|
|
1529
|
-
className,
|
|
1530
|
-
type = "dropdown",
|
|
1531
|
-
variant = "ghost",
|
|
1532
|
-
size = "md",
|
|
1533
|
-
showNames = true,
|
|
1534
|
-
showFlags = true,
|
|
1535
|
-
label = "Language",
|
|
1536
|
-
i18nEnabled = true,
|
|
1537
|
-
currentLocale,
|
|
1538
|
-
locales,
|
|
1539
|
-
onLocaleChange,
|
|
1540
|
-
customFlagUrl = false,
|
|
1541
|
-
Image: Image2 = DefaultImage
|
|
1542
|
-
}) {
|
|
1543
|
-
const [isPending, startTransition] = useTransition();
|
|
1544
|
-
const languages = locales ?? [];
|
|
1545
|
-
const currentLanguage = languages.find((l) => l.code === currentLocale);
|
|
1546
|
-
function handleLanguageChange(newLocale) {
|
|
1547
|
-
if (newLocale === currentLocale) return;
|
|
1548
|
-
startTransition(() => {
|
|
1549
|
-
const maybePromise = onLocaleChange?.(newLocale);
|
|
1550
|
-
return maybePromise;
|
|
1551
|
-
});
|
|
1552
|
-
}
|
|
1553
|
-
if (!i18nEnabled && (languages?.length ?? 0) <= 1) {
|
|
1554
|
-
return null;
|
|
1555
|
-
}
|
|
1556
|
-
if (type === "dropdown") {
|
|
1557
|
-
return /* @__PURE__ */ jsxs23(DropdownMenu2, { children: [
|
|
1558
|
-
/* @__PURE__ */ jsx34(DropdownMenuTrigger2, { asChild: true, children: /* @__PURE__ */ jsxs23(
|
|
1559
|
-
Button5,
|
|
1560
|
-
{
|
|
1561
|
-
variant,
|
|
1562
|
-
size,
|
|
1563
|
-
className: cn26(
|
|
1564
|
-
"group/toggle size-8 px-0 text-foreground ring-0! focus:outline-none! focus:ring-0! focus-visible:outline-none! focus-visible:ring-0! focus-visible:ring-offset-0!",
|
|
1565
|
-
isPending && "cursor-not-allowed opacity-50",
|
|
1566
|
-
className
|
|
1567
|
-
),
|
|
1568
|
-
disabled: isPending,
|
|
1569
|
-
children: [
|
|
1570
|
-
/* @__PURE__ */ jsx34(LanguagesIcon, { className: "size-4" }),
|
|
1571
|
-
/* @__PURE__ */ jsx34("span", { className: "sr-only", children: isPending ? "Changing language..." : "Language dropdown" })
|
|
1572
|
-
]
|
|
1573
|
-
}
|
|
1574
|
-
) }),
|
|
1575
|
-
/* @__PURE__ */ jsx34(
|
|
1576
|
-
DropdownMenuContent2,
|
|
1577
|
-
{
|
|
1578
|
-
align: "end",
|
|
1579
|
-
className: "min-w-[150px]",
|
|
1580
|
-
onCloseAutoFocus: (e) => e.preventDefault(),
|
|
1581
|
-
children: languages.map((lang) => /* @__PURE__ */ jsxs23(
|
|
1582
|
-
DropdownMenuItem2,
|
|
1583
|
-
{
|
|
1584
|
-
onClick: () => handleLanguageChange(lang.code),
|
|
1585
|
-
className: cn26("gap-2", currentLocale === lang.code && "bg-accent"),
|
|
1586
|
-
children: [
|
|
1587
|
-
showFlags && lang.flag ? /* @__PURE__ */ jsx34(
|
|
1588
|
-
Image2,
|
|
1589
|
-
{
|
|
1590
|
-
src: customFlagUrl ? lang.flag : getFlagUrl(lang.flag),
|
|
1591
|
-
alt: `${lang.name} flag`,
|
|
1592
|
-
className: "size-4 rounded-full object-cover",
|
|
1593
|
-
width: 24,
|
|
1594
|
-
height: 24
|
|
1595
|
-
}
|
|
1596
|
-
) : showFlags ? /* @__PURE__ */ jsx34(GlobeIcon, { className: "size-4" }) : null,
|
|
1597
|
-
showNames && /* @__PURE__ */ jsx34("span", { className: "text-sm", children: lang.name }),
|
|
1598
|
-
currentLocale === lang.code && /* @__PURE__ */ jsx34("span", { className: "ms-auto text-muted-foreground text-xs", children: "\u2713" })
|
|
1599
|
-
]
|
|
1600
|
-
},
|
|
1601
|
-
lang.code
|
|
1602
|
-
))
|
|
1603
|
-
}
|
|
1604
|
-
)
|
|
1605
|
-
] });
|
|
1606
|
-
}
|
|
1607
|
-
return /* @__PURE__ */ jsxs23(DropdownMenuSub2, { children: [
|
|
1608
|
-
/* @__PURE__ */ jsxs23(
|
|
1609
|
-
DropdownMenuSubTrigger2,
|
|
1610
|
-
{
|
|
1611
|
-
className: cn26(
|
|
1612
|
-
"flex items-center gap-2 data-[state=open]:**:data-[slot=badge]:border-input **:data-[slot=dropdown-menu-sub-trigger-indicator]:hidden hover:**:data-[slot=badge]:border-input",
|
|
1613
|
-
className
|
|
1614
|
-
),
|
|
1615
|
-
children: [
|
|
1616
|
-
/* @__PURE__ */ jsx34(GlobeIcon, { className: "size-4" }),
|
|
1617
|
-
/* @__PURE__ */ jsxs23("span", { className: "relative flex grow items-center justify-between gap-2", children: [
|
|
1618
|
-
label,
|
|
1619
|
-
currentLanguage && /* @__PURE__ */ jsxs23(Badge3, { appearance: "outline", className: "-translate-y-1/2 absolute end-0 top-1/2", children: [
|
|
1620
|
-
currentLanguage.name,
|
|
1621
|
-
showFlags && currentLanguage.flag && /* @__PURE__ */ jsx34(
|
|
1622
|
-
Image2,
|
|
1623
|
-
{
|
|
1624
|
-
src: customFlagUrl ? currentLanguage.flag : getFlagUrl(currentLanguage.flag),
|
|
1625
|
-
alt: currentLanguage.name,
|
|
1626
|
-
className: "ms-1 size-3.5 rounded-full",
|
|
1627
|
-
width: 24,
|
|
1628
|
-
height: 24
|
|
1629
|
-
}
|
|
1630
|
-
)
|
|
1631
|
-
] })
|
|
1632
|
-
] })
|
|
1633
|
-
]
|
|
1634
|
-
}
|
|
1635
|
-
),
|
|
1636
|
-
/* @__PURE__ */ jsx34(DropdownMenuSubContent2, { className: "w-48", children: /* @__PURE__ */ jsx34(
|
|
1637
|
-
DropdownMenuRadioGroup,
|
|
1638
|
-
{
|
|
1639
|
-
value: currentLocale,
|
|
1640
|
-
onValueChange: (value) => handleLanguageChange(value),
|
|
1641
|
-
children: languages.map((item) => /* @__PURE__ */ jsxs23(
|
|
1642
|
-
DropdownMenuRadioItem,
|
|
1643
|
-
{
|
|
1644
|
-
value: item.code,
|
|
1645
|
-
className: "flex items-center gap-2",
|
|
1646
|
-
children: [
|
|
1647
|
-
showFlags && item.flag ? /* @__PURE__ */ jsx34(
|
|
1648
|
-
Image2,
|
|
1649
|
-
{
|
|
1650
|
-
src: customFlagUrl ? item.flag : getFlagUrl(item.flag),
|
|
1651
|
-
alt: `${item.name} flag`,
|
|
1652
|
-
className: "size-4 rounded-full object-cover",
|
|
1653
|
-
width: 24,
|
|
1654
|
-
height: 24
|
|
1655
|
-
}
|
|
1656
|
-
) : showFlags ? /* @__PURE__ */ jsx34(GlobeIcon, { className: "size-4" }) : null,
|
|
1657
|
-
/* @__PURE__ */ jsx34("span", { children: item.name })
|
|
1658
|
-
]
|
|
1659
|
-
},
|
|
1660
|
-
item.code
|
|
1661
|
-
))
|
|
1662
|
-
}
|
|
1663
|
-
) })
|
|
1664
|
-
] });
|
|
1665
|
-
}
|
|
1666
|
-
|
|
1667
|
-
// src/components/ui/logo.tsx
|
|
1668
|
-
import { cn as cn27 } from "@pelatform/ui.core";
|
|
1669
|
-
import { jsx as jsx35 } from "react/jsx-runtime";
|
|
1670
|
-
function Logo({ className }) {
|
|
1671
|
-
return /* @__PURE__ */ jsx35(
|
|
1672
|
-
"svg",
|
|
1673
|
-
{
|
|
1674
|
-
xmlns: "http://www.w3.org/2000/svg",
|
|
1675
|
-
viewBox: "0 0 300 300",
|
|
1676
|
-
className: cn27("size-8 text-primary", className),
|
|
1677
|
-
children: /* @__PURE__ */ jsx35(
|
|
1678
|
-
"path",
|
|
1679
|
-
{
|
|
1680
|
-
fill: "currentColor",
|
|
1681
|
-
d: "M128.522 1.522c-32.588 5.306-62.029 20.107-84.303 42.38C11.915 76.206-4.329 122.766 1.097 167.5c7.82 64.464 55.004 115.796 119.215 129.692 13.77 2.981 43.538 3.228 57.152.476 55.106-11.142 98.806-49.775 115.475-102.085 9.652-30.288 9.28-64.659-1.019-94.282-13.203-37.974-41.238-69.366-77.545-86.829-9.214-4.432-22.787-8.877-35.198-11.527-12.922-2.76-38.101-3.467-50.655-1.423m45.43 23.051c25.127 4.747 47.405 16.665 66.107 35.368 18.907 18.906 30.066 39.63 35.57 66.059 2.173 10.433 2.429 35.004.478 46-1.644 9.273-7.255 26.356-11.31 34.44-12.206 24.332-34.074 46.206-58.297 58.317-37.669 18.832-85.803 16.865-121.763-4.977-32.079-19.483-53.841-50.921-60.419-87.28-2.115-11.696-2.107-33.116.019-45 5.217-29.172 20.878-56.039 43.866-75.257C88.177 35.545 110.634 25.946 136.5 23.05c9.765-1.094 27.393-.377 37.452 1.523M132.5 32.582c-17.187 2.652-35.032 9.653-49.67 19.487-9.019 6.061-25.684 23.052-31.743 32.367-19.802 30.442-24.936 66.068-14.488 100.534 10.763 35.502 38.905 64.97 73.472 76.934 37.229 12.886 76.705 7.51 108.412-14.763 36.802-25.851 55.968-71.116 48.91-115.511-4.458-28.042-18.237-52.604-40.544-72.276-10.285-9.071-26.471-18.003-40.349-22.267-18.878-5.802-36.218-7.248-54-4.505m89.497 40.668c-.003 1.59-4.605 18.817-6.612 24.75-.837 2.475-2.503 5.57-3.703 6.879-4.588 5.002-5.729 5.121-49.15 5.121-22.293 0-40.532.218-40.532.484 0 .677-10.97 43.679-11.611 45.516-.541 1.551-1.105 1.021-12.792-12.019C86.59 131.698 78 118.349 78 113.527c0-3.566 7.168-32.105 8.856-35.259.622-1.162 2.32-3.048 3.773-4.19C93.24 72.023 93.983 72 157.635 72c50.827 0 64.364.263 64.362 1.25m-37.204 62.319c6.763 8.973 10.207 15.902 10.207 20.535 0 4.848-7.331 31.946-9.565 35.355-3.203 4.888-6.075 5.579-25.942 6.24l-18.441.613-.976 3.094c-.537 1.702-3.299 11.644-6.139 22.094s-5.486 19.351-5.879 19.779c-.394.429-4.574-3.222-9.288-8.112-14.649-15.196-22.751-27.719-22.75-35.167 0-1.925 1.971-10.681 4.38-19.457 3.804-13.856 4.792-16.325 7.506-18.75l3.126-2.793h19.505c19.297 0 19.515-.024 20.398-2.25.491-1.238 2.559-8.55 4.596-16.25s4.641-17.333 5.786-21.407l2.083-7.407 8.084 8.476c4.447 4.662 10.436 11.595 13.309 15.407"
|
|
1682
|
-
}
|
|
1683
|
-
)
|
|
1684
|
-
}
|
|
1685
|
-
);
|
|
1686
|
-
}
|
|
1687
|
-
|
|
1688
|
-
// src/components/ui/mode-switcher.tsx
|
|
1689
|
-
import * as React2 from "react";
|
|
1690
|
-
import {
|
|
1691
|
-
cn as cn28,
|
|
1692
|
-
MonitorIcon,
|
|
1693
|
-
MoonIcon,
|
|
1694
|
-
SunIcon,
|
|
1695
|
-
THEME_MODES as THEME_MODES2
|
|
1696
|
-
} from "@pelatform/ui.core";
|
|
1697
|
-
import {
|
|
1698
|
-
Button as Button6,
|
|
1699
|
-
DropdownMenu as DropdownMenu3,
|
|
1700
|
-
DropdownMenuContent as DropdownMenuContent3,
|
|
1701
|
-
DropdownMenuItem as DropdownMenuItem3,
|
|
1702
|
-
DropdownMenuTrigger as DropdownMenuTrigger3
|
|
1703
|
-
} from "@pelatform/ui.default";
|
|
1704
|
-
import { useTheme } from "@pelatform/ui.default/dep";
|
|
1705
|
-
import { Fragment as Fragment4, jsx as jsx36, jsxs as jsxs24 } from "react/jsx-runtime";
|
|
1706
|
-
function ModeSwitcher({
|
|
1707
|
-
className,
|
|
1708
|
-
variant = "ghost",
|
|
1709
|
-
size = "md",
|
|
1710
|
-
cycleOrder = [THEME_MODES2.SYSTEM, THEME_MODES2.LIGHT, THEME_MODES2.DARK],
|
|
1711
|
-
type = "toogle",
|
|
1712
|
-
label = {
|
|
1713
|
-
system: "System",
|
|
1714
|
-
dark: "Dark",
|
|
1715
|
-
light: "Light"
|
|
1716
|
-
}
|
|
1717
|
-
}) {
|
|
1718
|
-
const { setTheme, theme } = useTheme();
|
|
1719
|
-
const toggleTheme = React2.useCallback(() => {
|
|
1720
|
-
const currentIndex = cycleOrder.indexOf(theme);
|
|
1721
|
-
const nextIndex = (currentIndex + 1) % cycleOrder.length;
|
|
1722
|
-
const nextTheme = cycleOrder[nextIndex];
|
|
1723
|
-
setTheme(nextTheme);
|
|
1724
|
-
}, [theme, setTheme, cycleOrder]);
|
|
1725
|
-
const getCurrentIcon = (withLabel = false) => {
|
|
1726
|
-
if (theme === THEME_MODES2.SYSTEM) {
|
|
1727
|
-
return /* @__PURE__ */ jsxs24(Fragment4, { children: [
|
|
1728
|
-
/* @__PURE__ */ jsx36(MonitorIcon, {}),
|
|
1729
|
-
" ",
|
|
1730
|
-
withLabel && /* @__PURE__ */ jsx36("span", { children: label.system })
|
|
1731
|
-
] });
|
|
1732
|
-
}
|
|
1733
|
-
if (theme === THEME_MODES2.DARK) {
|
|
1734
|
-
return /* @__PURE__ */ jsxs24(Fragment4, { children: [
|
|
1735
|
-
/* @__PURE__ */ jsx36(MoonIcon, {}),
|
|
1736
|
-
" ",
|
|
1737
|
-
withLabel && /* @__PURE__ */ jsx36("span", { children: label.dark })
|
|
1738
|
-
] });
|
|
1739
|
-
}
|
|
1740
|
-
return /* @__PURE__ */ jsxs24(Fragment4, { children: [
|
|
1741
|
-
/* @__PURE__ */ jsx36(SunIcon, {}),
|
|
1742
|
-
" ",
|
|
1743
|
-
withLabel && /* @__PURE__ */ jsx36("span", { children: label.light })
|
|
1744
|
-
] });
|
|
1745
|
-
};
|
|
1746
|
-
const isActive = (val) => theme === val;
|
|
1747
|
-
if (type === "toogle") {
|
|
1748
|
-
return /* @__PURE__ */ jsxs24(
|
|
1749
|
-
Button6,
|
|
1750
|
-
{
|
|
1751
|
-
variant,
|
|
1752
|
-
size,
|
|
1753
|
-
className: cn28("group/toggle size-8 px-0 text-foreground", className),
|
|
1754
|
-
onClick: toggleTheme,
|
|
1755
|
-
"aria-label": "Switch theme",
|
|
1756
|
-
children: [
|
|
1757
|
-
getCurrentIcon(),
|
|
1758
|
-
/* @__PURE__ */ jsx36("span", { className: "sr-only", children: "Toggle theme" })
|
|
1759
|
-
]
|
|
1760
|
-
}
|
|
1761
|
-
);
|
|
1762
|
-
}
|
|
1763
|
-
if (type === "dropdown") {
|
|
1764
|
-
return /* @__PURE__ */ jsxs24(DropdownMenu3, { children: [
|
|
1765
|
-
/* @__PURE__ */ jsx36(DropdownMenuTrigger3, { asChild: true, children: /* @__PURE__ */ jsxs24(
|
|
1766
|
-
Button6,
|
|
1767
|
-
{
|
|
1768
|
-
variant,
|
|
1769
|
-
size,
|
|
1770
|
-
className: cn28(
|
|
1771
|
-
"group/toggle size-8 px-0 text-foreground ring-0! focus:outline-none! focus:ring-0! focus-visible:outline-none! focus-visible:ring-0! focus-visible:ring-offset-0!",
|
|
1772
|
-
className
|
|
1773
|
-
),
|
|
1774
|
-
children: [
|
|
1775
|
-
getCurrentIcon(),
|
|
1776
|
-
/* @__PURE__ */ jsx36("span", { className: "sr-only", children: "Toggle theme" })
|
|
1777
|
-
]
|
|
1778
|
-
}
|
|
1779
|
-
) }),
|
|
1780
|
-
/* @__PURE__ */ jsxs24(DropdownMenuContent3, { align: "end", onCloseAutoFocus: (e) => e.preventDefault(), children: [
|
|
1781
|
-
/* @__PURE__ */ jsxs24(
|
|
1782
|
-
DropdownMenuItem3,
|
|
1783
|
-
{
|
|
1784
|
-
className: isActive("light") ? "bg-accent" : "",
|
|
1785
|
-
onClick: () => setTheme("light"),
|
|
1786
|
-
children: [
|
|
1787
|
-
/* @__PURE__ */ jsx36(SunIcon, {}),
|
|
1788
|
-
label.light
|
|
1789
|
-
]
|
|
1790
|
-
}
|
|
1791
|
-
),
|
|
1792
|
-
/* @__PURE__ */ jsxs24(
|
|
1793
|
-
DropdownMenuItem3,
|
|
1794
|
-
{
|
|
1795
|
-
className: isActive("dark") ? "bg-accent" : "",
|
|
1796
|
-
onClick: () => setTheme("dark"),
|
|
1797
|
-
children: [
|
|
1798
|
-
/* @__PURE__ */ jsx36(MoonIcon, {}),
|
|
1799
|
-
label.dark
|
|
1800
|
-
]
|
|
1801
|
-
}
|
|
1802
|
-
),
|
|
1803
|
-
/* @__PURE__ */ jsxs24(
|
|
1804
|
-
DropdownMenuItem3,
|
|
1805
|
-
{
|
|
1806
|
-
className: isActive("system") ? "bg-accent" : "",
|
|
1807
|
-
onClick: () => setTheme("system"),
|
|
1808
|
-
children: [
|
|
1809
|
-
/* @__PURE__ */ jsx36(MonitorIcon, {}),
|
|
1810
|
-
label.system
|
|
1811
|
-
]
|
|
1812
|
-
}
|
|
1813
|
-
)
|
|
1814
|
-
] })
|
|
1815
|
-
] });
|
|
1816
|
-
}
|
|
1817
|
-
return /* @__PURE__ */ jsx36(
|
|
1818
|
-
DropdownMenuItem3,
|
|
1819
|
-
{
|
|
1820
|
-
className,
|
|
1821
|
-
onSelect: (e) => {
|
|
1822
|
-
e.preventDefault();
|
|
1823
|
-
toggleTheme();
|
|
1824
|
-
},
|
|
1825
|
-
children: getCurrentIcon(true)
|
|
1826
|
-
}
|
|
1827
|
-
);
|
|
1828
|
-
}
|
|
1829
|
-
|
|
1830
|
-
// src/components/ui/moving-border.tsx
|
|
1831
|
-
import { useRef as useRef2 } from "react";
|
|
1832
|
-
import {
|
|
1833
|
-
motion as motion2,
|
|
1834
|
-
useAnimationFrame,
|
|
1835
|
-
useMotionTemplate,
|
|
1836
|
-
useMotionValue,
|
|
1837
|
-
useTransform
|
|
1838
|
-
} from "@pelatform/ui.animation";
|
|
1839
|
-
import { cn as cn29 } from "@pelatform/ui.core";
|
|
1840
|
-
import { Fragment as Fragment5, jsx as jsx37, jsxs as jsxs25 } from "react/jsx-runtime";
|
|
1841
|
-
function MovingLabel({
|
|
1842
|
-
borderRadius = "1.75rem",
|
|
1843
|
-
children,
|
|
1844
|
-
as: Component = "button",
|
|
1845
|
-
containerClassName,
|
|
1846
|
-
borderClassName,
|
|
1847
|
-
duration,
|
|
1848
|
-
className,
|
|
1849
|
-
...otherProps
|
|
1850
|
-
}) {
|
|
1851
|
-
return /* @__PURE__ */ jsxs25(
|
|
1852
|
-
Component,
|
|
1853
|
-
{
|
|
1854
|
-
className: cn29("relative h-9 overflow-hidden bg-transparent p-px text-xl", containerClassName),
|
|
1855
|
-
style: {
|
|
1856
|
-
borderRadius
|
|
1857
|
-
},
|
|
1858
|
-
...otherProps,
|
|
1859
|
-
children: [
|
|
1860
|
-
/* @__PURE__ */ jsx37("div", { className: "absolute inset-0", style: { borderRadius: `calc(${borderRadius} * 0.96)` }, children: /* @__PURE__ */ jsx37(MovingBorder, { duration, rx: "30%", ry: "30%", children: /* @__PURE__ */ jsx37(
|
|
1861
|
-
"div",
|
|
1862
|
-
{
|
|
1863
|
-
className: cn29(
|
|
1864
|
-
"h-12 w-20 bg-[radial-gradient(#24B47E_15%,transparent_60%)] opacity-[0.6]",
|
|
1865
|
-
borderClassName
|
|
1866
|
-
)
|
|
1867
|
-
}
|
|
1868
|
-
) }) }),
|
|
1869
|
-
/* @__PURE__ */ jsx37(
|
|
1870
|
-
"div",
|
|
1871
|
-
{
|
|
1872
|
-
className: cn29(
|
|
1873
|
-
"relative flex h-full w-full items-center justify-center border border-slate-800 bg-slate-900/50 text-sm text-white antialiased backdrop-blur-xl",
|
|
1874
|
-
className
|
|
1875
|
-
),
|
|
1876
|
-
style: {
|
|
1877
|
-
borderRadius: `calc(${borderRadius} * 1)`
|
|
1878
|
-
},
|
|
1879
|
-
children
|
|
1880
|
-
}
|
|
1881
|
-
)
|
|
1882
|
-
]
|
|
1883
|
-
}
|
|
1884
|
-
);
|
|
1885
|
-
}
|
|
1886
|
-
var MovingBorder = ({
|
|
1887
|
-
children,
|
|
1888
|
-
duration = 2e3,
|
|
1889
|
-
rx,
|
|
1890
|
-
ry,
|
|
1891
|
-
...otherProps
|
|
1892
|
-
}) => {
|
|
1893
|
-
const pathRef = useRef2(null);
|
|
1894
|
-
const progress = useMotionValue(0);
|
|
1895
|
-
useAnimationFrame((time) => {
|
|
1896
|
-
const length = pathRef.current?.getTotalLength();
|
|
1897
|
-
if (length) {
|
|
1898
|
-
const pxPerMillisecond = length / duration;
|
|
1899
|
-
progress.set(time * pxPerMillisecond % length);
|
|
1900
|
-
}
|
|
1901
|
-
});
|
|
1902
|
-
const x = useTransform(progress, (val) => pathRef.current?.getPointAtLength(val).x);
|
|
1903
|
-
const y = useTransform(progress, (val) => pathRef.current?.getPointAtLength(val).y);
|
|
1904
|
-
const transform = useMotionTemplate`translateX(${x}px) translateY(${y}px) translateX(-50%) translateY(-50%)`;
|
|
1905
|
-
return /* @__PURE__ */ jsxs25(Fragment5, { children: [
|
|
1906
|
-
/* @__PURE__ */ jsx37(
|
|
1907
|
-
"svg",
|
|
1908
|
-
{
|
|
1909
|
-
preserveAspectRatio: "none",
|
|
1910
|
-
className: "absolute h-full w-full",
|
|
1911
|
-
width: "100%",
|
|
1912
|
-
height: "100%",
|
|
1913
|
-
...otherProps,
|
|
1914
|
-
children: /* @__PURE__ */ jsx37("rect", { fill: "none", width: "100%", height: "100%", rx, ry, ref: pathRef })
|
|
1915
|
-
}
|
|
1916
|
-
),
|
|
1917
|
-
/* @__PURE__ */ jsx37(
|
|
1918
|
-
motion2.div,
|
|
1919
|
-
{
|
|
1920
|
-
style: {
|
|
1921
|
-
position: "absolute",
|
|
1922
|
-
top: 0,
|
|
1923
|
-
left: 0,
|
|
1924
|
-
display: "inline-block",
|
|
1925
|
-
transform
|
|
1926
|
-
},
|
|
1927
|
-
children
|
|
1928
|
-
}
|
|
1929
|
-
)
|
|
1930
|
-
] });
|
|
1931
|
-
};
|
|
1932
|
-
|
|
1933
|
-
// src/components/ui/subscribe.tsx
|
|
1934
|
-
import { useState as useState5 } from "react";
|
|
1935
|
-
import { CircleAlertIcon as CircleAlertIcon4, CircleCheckIcon as CircleCheckIcon2, googleTrackEvent as googleTrackEvent3 } from "@pelatform/ui.core";
|
|
1936
|
-
import { Alert as Alert4, AlertIcon as AlertIcon4, AlertTitle as AlertTitle4, Button as Button8, Input } from "@pelatform/ui.default";
|
|
1937
|
-
import { toast as toast4 } from "@pelatform/ui.default/dep";
|
|
1938
|
-
|
|
1939
|
-
// src/components/utils/recaptcha-popover.tsx
|
|
1940
|
-
import { CircleAlertIcon as CircleAlertIcon3 } from "@pelatform/ui.core";
|
|
1941
|
-
import { Alert as Alert3, AlertIcon as AlertIcon3, AlertTitle as AlertTitle3, Button as Button7 } from "@pelatform/ui.default";
|
|
1942
|
-
import { Popover, toast as toast3 } from "@pelatform/ui.default/dep";
|
|
1943
|
-
import { useRecaptchaV2 } from "@pelatform/ui.hook";
|
|
1944
|
-
import { jsx as jsx38, jsxs as jsxs26 } from "react/jsx-runtime";
|
|
1945
|
-
function RecaptchaPopover({
|
|
1946
|
-
open,
|
|
1947
|
-
onOpenChange,
|
|
1948
|
-
onVerify,
|
|
1949
|
-
trigger,
|
|
1950
|
-
verifyButtonText = "Verify & Submit"
|
|
1951
|
-
}) {
|
|
1952
|
-
const { containerRef, getToken, resetCaptcha, initializeRecaptcha } = useRecaptchaV2(
|
|
1953
|
-
process.env.NEXT_PUBLIC_RECAPTCHA_SITE_KEY || ""
|
|
1954
|
-
);
|
|
1955
|
-
const handleOpenChange = (newOpen) => {
|
|
1956
|
-
onOpenChange(newOpen);
|
|
1957
|
-
if (newOpen) {
|
|
1958
|
-
resetCaptcha();
|
|
1959
|
-
setTimeout(() => {
|
|
1960
|
-
initializeRecaptcha();
|
|
1961
|
-
}, 100);
|
|
1962
|
-
}
|
|
1963
|
-
};
|
|
1964
|
-
const handleVerify = () => {
|
|
1965
|
-
try {
|
|
1966
|
-
const token = getToken();
|
|
1967
|
-
if (!token) {
|
|
1968
|
-
toast3.custom(
|
|
1969
|
-
() => /* @__PURE__ */ jsxs26(Alert3, { variant: "mono", icon: "destructive", children: [
|
|
1970
|
-
/* @__PURE__ */ jsx38(AlertIcon3, { children: /* @__PURE__ */ jsx38(CircleAlertIcon3, {}) }),
|
|
1971
|
-
/* @__PURE__ */ jsx38(AlertTitle3, { children: "Please complete the reCAPTCHA verification." })
|
|
1972
|
-
] }),
|
|
1973
|
-
{
|
|
1974
|
-
position: "top-center"
|
|
1975
|
-
}
|
|
1976
|
-
);
|
|
1977
|
-
return;
|
|
1978
|
-
}
|
|
1979
|
-
onVerify(token);
|
|
1980
|
-
} catch (error) {
|
|
1981
|
-
console.error("Error getting reCAPTCHA token:", error);
|
|
1982
|
-
toast3.custom(
|
|
1983
|
-
() => /* @__PURE__ */ jsxs26(Alert3, { variant: "mono", icon: "destructive", children: [
|
|
1984
|
-
/* @__PURE__ */ jsx38(AlertIcon3, { children: /* @__PURE__ */ jsx38(CircleAlertIcon3, {}) }),
|
|
1985
|
-
/* @__PURE__ */ jsx38(AlertTitle3, { children: "Please complete the reCAPTCHA verification." })
|
|
1986
|
-
] }),
|
|
1987
|
-
{
|
|
1988
|
-
position: "top-center"
|
|
1989
|
-
}
|
|
1990
|
-
);
|
|
1991
|
-
return;
|
|
1992
|
-
}
|
|
1993
|
-
};
|
|
1994
|
-
return /* @__PURE__ */ jsxs26(Popover.Root, { open, onOpenChange: handleOpenChange, children: [
|
|
1995
|
-
/* @__PURE__ */ jsx38(Popover.Trigger, { asChild: true, children: trigger }),
|
|
1996
|
-
/* @__PURE__ */ jsx38(Popover.Portal, { children: /* @__PURE__ */ jsxs26(
|
|
1997
|
-
Popover.Content,
|
|
1998
|
-
{
|
|
1999
|
-
className: "z-50 rounded-lg bg-white p-4 shadow-lg",
|
|
2000
|
-
sideOffset: 5,
|
|
2001
|
-
align: "end",
|
|
2002
|
-
onInteractOutside: (e) => {
|
|
2003
|
-
if (e.target.tagName === "IFRAME") {
|
|
2004
|
-
e.preventDefault();
|
|
2005
|
-
}
|
|
2006
|
-
},
|
|
2007
|
-
children: [
|
|
2008
|
-
/* @__PURE__ */ jsxs26("div", { className: "flex flex-col gap-4", children: [
|
|
2009
|
-
/* @__PURE__ */ jsx38("div", { ref: containerRef, className: "min-h-[78px]" }),
|
|
2010
|
-
/* @__PURE__ */ jsx38(Button7, { type: "button", variant: "mono", onClick: handleVerify, className: "w-full", children: verifyButtonText })
|
|
2011
|
-
] }),
|
|
2012
|
-
/* @__PURE__ */ jsx38(Popover.Arrow, { className: "fill-white" })
|
|
2013
|
-
]
|
|
2014
|
-
}
|
|
2015
|
-
) })
|
|
2016
|
-
] });
|
|
2017
|
-
}
|
|
2018
|
-
|
|
2019
|
-
// src/components/ui/subscribe.tsx
|
|
2020
|
-
import { jsx as jsx39, jsxs as jsxs27 } from "react/jsx-runtime";
|
|
2021
|
-
function Subscribe({
|
|
2022
|
-
heading = "Stay notified on every new release",
|
|
2023
|
-
subheading = "Only the updates worth knowing",
|
|
2024
|
-
buttonText = "Subscribe",
|
|
2025
|
-
loadingButtonText = "Subscribing...",
|
|
2026
|
-
inputPlaceholder = "Your email address",
|
|
2027
|
-
successMessage = "Thank you for your subscription. Expect amazing stuff soon!",
|
|
2028
|
-
invalidEmailMessage = "Invalid email address. Please check and try again.",
|
|
2029
|
-
recaptchaMessage = "Please complete the reCAPTCHA verification.",
|
|
2030
|
-
errorMessage = "Oops! Something unexpected happened. Please try again later.",
|
|
2031
|
-
apiEndpoint = "/api/subscribe",
|
|
2032
|
-
verifyButtonText = "Verify & Subscribe",
|
|
2033
|
-
className
|
|
2034
|
-
} = {}) {
|
|
2035
|
-
const [email, setEmail] = useState5("");
|
|
2036
|
-
const [loading, setLoading] = useState5(false);
|
|
2037
|
-
const [showRecaptcha, setShowRecaptcha] = useState5(false);
|
|
2038
|
-
const validateEmail = () => {
|
|
2039
|
-
if (!email.match(/^[^\s@]+@[^\s@]+\.[^\s@]+$/)) {
|
|
2040
|
-
toast4.custom(
|
|
2041
|
-
() => /* @__PURE__ */ jsxs27(Alert4, { variant: "mono", icon: "destructive", children: [
|
|
2042
|
-
/* @__PURE__ */ jsx39(AlertIcon4, { children: /* @__PURE__ */ jsx39(CircleAlertIcon4, {}) }),
|
|
2043
|
-
/* @__PURE__ */ jsx39(AlertTitle4, { children: invalidEmailMessage })
|
|
2044
|
-
] }),
|
|
2045
|
-
{
|
|
2046
|
-
position: "top-center"
|
|
2047
|
-
}
|
|
2048
|
-
);
|
|
2049
|
-
return false;
|
|
2050
|
-
}
|
|
2051
|
-
return true;
|
|
2052
|
-
};
|
|
2053
|
-
const handleSubmit = async (e) => {
|
|
2054
|
-
e.preventDefault();
|
|
2055
|
-
if (!validateEmail()) {
|
|
2056
|
-
setShowRecaptcha(false);
|
|
2057
|
-
return;
|
|
2058
|
-
}
|
|
2059
|
-
setShowRecaptcha(true);
|
|
2060
|
-
};
|
|
2061
|
-
const handleVerifiedSubmit = async (token) => {
|
|
2062
|
-
if (!token) {
|
|
2063
|
-
toast4.custom(
|
|
2064
|
-
() => /* @__PURE__ */ jsxs27(Alert4, { variant: "mono", icon: "destructive", children: [
|
|
2065
|
-
/* @__PURE__ */ jsx39(AlertIcon4, { children: /* @__PURE__ */ jsx39(CircleAlertIcon4, {}) }),
|
|
2066
|
-
/* @__PURE__ */ jsx39(AlertTitle4, { children: recaptchaMessage })
|
|
2067
|
-
] }),
|
|
2068
|
-
{
|
|
2069
|
-
position: "top-center"
|
|
2070
|
-
}
|
|
2071
|
-
);
|
|
2072
|
-
return;
|
|
2073
|
-
}
|
|
2074
|
-
setLoading(true);
|
|
2075
|
-
setShowRecaptcha(false);
|
|
2076
|
-
try {
|
|
2077
|
-
googleTrackEvent3({
|
|
2078
|
-
name: "site_newsletter_subscribe_submit",
|
|
2079
|
-
properties: {
|
|
2080
|
-
category: "conversion",
|
|
2081
|
-
label: "Newsletter Subscribe Submit",
|
|
2082
|
-
email
|
|
2083
|
-
}
|
|
2084
|
-
});
|
|
2085
|
-
const res = await fetch(apiEndpoint, {
|
|
2086
|
-
method: "POST",
|
|
2087
|
-
headers: {
|
|
2088
|
-
"Content-Type": "application/json",
|
|
2089
|
-
"x-recaptcha-token": token
|
|
2090
|
-
},
|
|
2091
|
-
body: JSON.stringify({ email })
|
|
2092
|
-
});
|
|
2093
|
-
const data = await res.json();
|
|
2094
|
-
if (res.ok) {
|
|
2095
|
-
toast4.custom(
|
|
2096
|
-
() => /* @__PURE__ */ jsxs27(Alert4, { variant: "mono", icon: "success", children: [
|
|
2097
|
-
/* @__PURE__ */ jsx39(AlertIcon4, { children: /* @__PURE__ */ jsx39(CircleCheckIcon2, {}) }),
|
|
2098
|
-
/* @__PURE__ */ jsx39(AlertTitle4, { children: successMessage })
|
|
2099
|
-
] }),
|
|
2100
|
-
{
|
|
2101
|
-
position: "top-center"
|
|
2102
|
-
}
|
|
2103
|
-
);
|
|
2104
|
-
googleTrackEvent3({
|
|
2105
|
-
name: "site_newsletter_subscribe_success",
|
|
2106
|
-
properties: {
|
|
2107
|
-
category: "conversion",
|
|
2108
|
-
label: "Newsletter Subscribe Success",
|
|
2109
|
-
email
|
|
2110
|
-
}
|
|
2111
|
-
});
|
|
2112
|
-
setEmail("");
|
|
2113
|
-
} else {
|
|
2114
|
-
toast4.custom(
|
|
2115
|
-
() => /* @__PURE__ */ jsxs27(Alert4, { variant: "mono", icon: "destructive", children: [
|
|
2116
|
-
/* @__PURE__ */ jsx39(AlertIcon4, { children: /* @__PURE__ */ jsx39(CircleAlertIcon4, {}) }),
|
|
2117
|
-
/* @__PURE__ */ jsx39(AlertTitle4, { children: data.message || errorMessage })
|
|
2118
|
-
] }),
|
|
2119
|
-
{
|
|
2120
|
-
position: "top-center"
|
|
2121
|
-
}
|
|
2122
|
-
);
|
|
2123
|
-
}
|
|
2124
|
-
} catch (err) {
|
|
2125
|
-
console.error("Newsletter subscription error:", err);
|
|
2126
|
-
toast4.custom(
|
|
2127
|
-
() => /* @__PURE__ */ jsxs27(Alert4, { variant: "mono", icon: "destructive", children: [
|
|
2128
|
-
/* @__PURE__ */ jsx39(AlertIcon4, { children: /* @__PURE__ */ jsx39(CircleAlertIcon4, {}) }),
|
|
2129
|
-
/* @__PURE__ */ jsx39(AlertTitle4, { children: errorMessage })
|
|
2130
|
-
] }),
|
|
2131
|
-
{
|
|
2132
|
-
position: "top-center"
|
|
2133
|
-
}
|
|
2134
|
-
);
|
|
2135
|
-
} finally {
|
|
2136
|
-
setLoading(false);
|
|
2137
|
-
}
|
|
2138
|
-
};
|
|
2139
|
-
const style = {
|
|
2140
|
-
backgroundImage: `linear-gradient(0deg, transparent 0%, transparent 60%, rgba(183, 183, 183, 0.05) 60%, rgba(183, 183, 183, 0.05) 93%, transparent 93%, transparent 100%), linear-gradient(135deg, transparent 0%, transparent 55%, rgba(183, 183, 183, 0.05) 55%, rgba(183, 183, 183, 0.05) 84%, transparent 84%, transparent 100%), linear-gradient(0deg, transparent 0%, transparent 80%, rgba(183, 183, 183, 0.05) 80%, rgba(183, 183, 183, 0.05) 94%, transparent 94%, transparent 100%), linear-gradient(90deg, rgb(0,0,0), rgb(0,0,0))`
|
|
2141
|
-
};
|
|
2142
|
-
return /* @__PURE__ */ jsx39("footer", { children: /* @__PURE__ */ jsx39("div", { className: "container pt-10", children: /* @__PURE__ */ jsxs27(
|
|
2143
|
-
"div",
|
|
2144
|
-
{
|
|
2145
|
-
className: `mt-10 mb-8 flex flex-wrap items-center justify-between gap-7 rounded-xl px-10 py-16 md:px-20 ${className || ""}`,
|
|
2146
|
-
style,
|
|
2147
|
-
children: [
|
|
2148
|
-
/* @__PURE__ */ jsxs27("div", { className: "flex flex-col gap-1.5", children: [
|
|
2149
|
-
/* @__PURE__ */ jsx39("h2", { className: "font-medium text-3xl text-white", children: heading }),
|
|
2150
|
-
/* @__PURE__ */ jsx39("div", { className: "font-medium text-2xl text-white/50", children: subheading })
|
|
2151
|
-
] }),
|
|
2152
|
-
/* @__PURE__ */ jsxs27("form", { onSubmit: handleSubmit, className: "flex gap-2.5", children: [
|
|
2153
|
-
/* @__PURE__ */ jsx39(
|
|
2154
|
-
Input,
|
|
2155
|
-
{
|
|
2156
|
-
type: "email",
|
|
2157
|
-
value: email,
|
|
2158
|
-
onChange: (e) => {
|
|
2159
|
-
setEmail(e.target.value);
|
|
2160
|
-
setShowRecaptcha(false);
|
|
2161
|
-
},
|
|
2162
|
-
placeholder: inputPlaceholder,
|
|
2163
|
-
className: "h-auto rounded-lg border border-input/20 bg-white/5 px-5 py-3 text-white/80 placeholder:text-white/50 focus:outline-none focus:ring md:min-w-64",
|
|
2164
|
-
required: true
|
|
2165
|
-
}
|
|
2166
|
-
),
|
|
2167
|
-
/* @__PURE__ */ jsx39(
|
|
2168
|
-
RecaptchaPopover,
|
|
2169
|
-
{
|
|
2170
|
-
open: showRecaptcha,
|
|
2171
|
-
onOpenChange: (open) => {
|
|
2172
|
-
if (!open) {
|
|
2173
|
-
setShowRecaptcha(false);
|
|
2174
|
-
}
|
|
2175
|
-
},
|
|
2176
|
-
onVerify: handleVerifiedSubmit,
|
|
2177
|
-
verifyButtonText,
|
|
2178
|
-
trigger: /* @__PURE__ */ jsx39(
|
|
2179
|
-
Button8,
|
|
2180
|
-
{
|
|
2181
|
-
type: "submit",
|
|
2182
|
-
className: "h-auto rounded-lg bg-white px-5 py-3 font-semibold text-black/80 hover:bg-white hover:text-black",
|
|
2183
|
-
disabled: loading,
|
|
2184
|
-
children: loading ? loadingButtonText : buttonText
|
|
2185
|
-
}
|
|
2186
|
-
)
|
|
2187
|
-
}
|
|
2188
|
-
)
|
|
2189
|
-
] })
|
|
2190
|
-
]
|
|
2191
|
-
}
|
|
2192
|
-
) }) });
|
|
2193
|
-
}
|
|
2194
|
-
|
|
2195
|
-
// src/components/ui/toolbar.tsx
|
|
2196
|
-
import { cn as cn30 } from "@pelatform/ui.core";
|
|
2197
|
-
import { jsx as jsx40 } from "react/jsx-runtime";
|
|
2198
|
-
var Toolbar = ({ children }) => {
|
|
2199
|
-
return /* @__PURE__ */ jsx40("div", { className: "flex grow items-center justify-between gap-2.5 pb-5", children });
|
|
2200
|
-
};
|
|
2201
|
-
var ToolbarHeading = ({ children, className }) => {
|
|
2202
|
-
return /* @__PURE__ */ jsx40("div", { className: cn30("flex flex-col flex-wrap gap-px", className), children });
|
|
2203
|
-
};
|
|
2204
|
-
var ToolbarTitle = ({ className, children }) => {
|
|
2205
|
-
return /* @__PURE__ */ jsx40("h1", { className: cn30("font-semibold text-foreground text-lg", className), children });
|
|
2206
|
-
};
|
|
2207
|
-
var ToolbarActions = ({ children }) => {
|
|
2208
|
-
return /* @__PURE__ */ jsx40("div", { className: "flex flex-wrap items-center gap-1.5 lg:gap-3.5", children });
|
|
2209
|
-
};
|
|
2210
|
-
|
|
2211
|
-
// src/components/ui/user-avatar.tsx
|
|
2212
|
-
import {
|
|
2213
|
-
Avatar,
|
|
2214
|
-
AvatarFallback,
|
|
2215
|
-
AvatarImage,
|
|
2216
|
-
AvatarIndicator,
|
|
2217
|
-
AvatarStatus
|
|
2218
|
-
} from "@pelatform/ui.default";
|
|
2219
|
-
import { jsx as jsx41, jsxs as jsxs28 } from "react/jsx-runtime";
|
|
2220
|
-
function UserAvatar({ className, indicator = false, src, alt }) {
|
|
2221
|
-
const name = alt ?? "User";
|
|
2222
|
-
const initial = getInitials(name);
|
|
2223
|
-
return /* @__PURE__ */ jsxs28(Avatar, { className, children: [
|
|
2224
|
-
/* @__PURE__ */ jsx41(AvatarImage, { src: src ?? void 0, alt: name }),
|
|
2225
|
-
/* @__PURE__ */ jsx41(AvatarFallback, { children: initial }),
|
|
2226
|
-
indicator && /* @__PURE__ */ jsx41(AvatarIndicator, { className: "-end-2 -top-2", children: /* @__PURE__ */ jsx41(AvatarStatus, { variant: "online", className: "size-2.5" }) })
|
|
2227
|
-
] });
|
|
2228
|
-
}
|
|
2229
|
-
var getInitials = (name, count) => {
|
|
2230
|
-
if (!name || typeof name !== "string") {
|
|
2231
|
-
return "";
|
|
2232
|
-
}
|
|
2233
|
-
const initials = name.split(" ").filter(Boolean).map((part) => part[0].toUpperCase());
|
|
2234
|
-
return count && count > 0 ? initials.slice(0, count).join("") : initials.join("");
|
|
2235
|
-
};
|
|
2236
|
-
|
|
2237
|
-
// src/components/utils/fonts.tsx
|
|
2238
|
-
import { jsx as jsx42 } from "react/jsx-runtime";
|
|
2239
|
-
var satoshiFontUrl = "https://assets.pelatform.com/fonts/satoshi/Satoshi-Variable.woff2";
|
|
2240
|
-
var cssFontFace = `
|
|
2241
|
-
@font-face {
|
|
2242
|
-
font-family: 'Satoshi';
|
|
2243
|
-
src: url('${satoshiFontUrl}') format('woff2');
|
|
2244
|
-
font-weight: 300 900;
|
|
2245
|
-
font-style: normal;
|
|
2246
|
-
font-display: swap;
|
|
2247
|
-
}
|
|
2248
|
-
`;
|
|
2249
|
-
function SatoshiFontCSS() {
|
|
2250
|
-
return /* @__PURE__ */ jsx42("style", { dangerouslySetInnerHTML: { __html: cssFontFace } });
|
|
2251
|
-
}
|
|
2252
|
-
export {
|
|
2253
|
-
AlertComingsoon,
|
|
2254
|
-
AlertNotification,
|
|
2255
|
-
AlertToast,
|
|
2256
|
-
Announcement,
|
|
2257
|
-
AnnouncementTag,
|
|
2258
|
-
AnnouncementTitle,
|
|
2259
|
-
BackLink,
|
|
2260
|
-
BackgroundPaths,
|
|
2261
|
-
Body,
|
|
2262
|
-
Book,
|
|
2263
|
-
CodeDisplay,
|
|
2264
|
-
ComingSoon,
|
|
2265
|
-
CommandMenu,
|
|
2266
|
-
ConfirmDismissDialog,
|
|
2267
|
-
DEFAULT_DATA_URL_KEY,
|
|
2268
|
-
DEFAULT_NULL_INDEX,
|
|
2269
|
-
DefaultImage,
|
|
2270
|
-
DefaultLink,
|
|
2271
|
-
DefaultNavigate,
|
|
2272
|
-
DotsPattern,
|
|
2273
|
-
DownloadFile,
|
|
2274
|
-
ErrorComponents,
|
|
2275
|
-
ExtraLink,
|
|
2276
|
-
FloatingPaths,
|
|
2277
|
-
Grid,
|
|
2278
|
-
GridBackground,
|
|
2279
|
-
HexagonBadge,
|
|
2280
|
-
Icons,
|
|
2281
|
-
ImageInput,
|
|
2282
|
-
LanguageSwitcher,
|
|
2283
|
-
LayoutAuth,
|
|
2284
|
-
LayoutBlank,
|
|
2285
|
-
Logo,
|
|
2286
|
-
MainNav,
|
|
2287
|
-
MaxWidthWrapper,
|
|
2288
|
-
MobileNav,
|
|
2289
|
-
MobileNavItemRenderer,
|
|
2290
|
-
ModeSwitcher,
|
|
2291
|
-
MovingBorder,
|
|
2292
|
-
MovingLabel,
|
|
2293
|
-
QueryProvider,
|
|
2294
|
-
RecaptchaPopover,
|
|
2295
|
-
SatoshiFontCSS,
|
|
2296
|
-
ScreenLoader,
|
|
2297
|
-
Section,
|
|
2298
|
-
SiteFooter,
|
|
2299
|
-
SiteHeader,
|
|
2300
|
-
Stack,
|
|
2301
|
-
Subscribe,
|
|
2302
|
-
ThemeProvider,
|
|
2303
|
-
Toolbar,
|
|
2304
|
-
ToolbarActions,
|
|
2305
|
-
ToolbarHeading,
|
|
2306
|
-
ToolbarTitle,
|
|
2307
|
-
UserAvatar,
|
|
2308
|
-
Video,
|
|
2309
|
-
Wrapper,
|
|
2310
|
-
Youtube,
|
|
2311
|
-
cssFontFace,
|
|
2312
|
-
getAcceptTypeString,
|
|
2313
|
-
getBase64,
|
|
2314
|
-
getImage,
|
|
2315
|
-
getInitials,
|
|
2316
|
-
getListFiles,
|
|
2317
|
-
handleMenuClick,
|
|
2318
|
-
openFileDialog,
|
|
2319
|
-
satoshiFontUrl
|
|
2320
|
-
};
|
|
3
|
+
// src/components.ts
|
|
4
|
+
export * from "pelatform-ui/components";
|