@vadimcomanescu/nadicode-design-system 4.0.3 → 4.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (69) hide show
  1. package/.agents/skills/seed/SKILL.md +24 -3
  2. package/dist/catalog/catalog.d.ts +186 -0
  3. package/dist/catalog/catalog.js +194 -0
  4. package/dist/catalog/components.d.ts +26 -0
  5. package/dist/catalog/components.js +71 -40
  6. package/dist/{chunk-RMGDDOCD.js → chunk-3ZPNIY2Z.js} +2 -2
  7. package/dist/chunk-4KZLCCIR.js +88 -0
  8. package/dist/{chunk-AWZFQQGN.js → chunk-6NCLYJAI.js} +2 -2
  9. package/dist/{chunk-K4U67BVG.js → chunk-7ALMTY6W.js} +1 -1
  10. package/dist/chunk-CZ7NGW7N.js +60 -0
  11. package/dist/chunk-FRGZSR2P.js +86 -0
  12. package/dist/{chunk-LGW7FVG5.js → chunk-HMFIUUYC.js} +1 -1
  13. package/dist/chunk-IC3BMFHV.js +86 -0
  14. package/dist/chunk-JVIRZNQ6.js +37 -0
  15. package/dist/chunk-K5AFXZDL.js +30 -0
  16. package/dist/{chunk-LK2L3C7D.js → chunk-LCMAB2BX.js} +3 -3
  17. package/dist/chunk-LIJYUSSE.js +152 -0
  18. package/dist/chunk-MB6TIORE.js +103 -0
  19. package/dist/chunk-PTJPPKDR.js +115 -0
  20. package/dist/chunk-PV62D7H6.js +75 -0
  21. package/dist/chunk-QVAV4MA2.js +60 -0
  22. package/dist/chunk-RPVG37RB.js +24 -0
  23. package/dist/{chunk-QW5II6YK.js → chunk-TEWCCMRH.js} +2 -2
  24. package/dist/chunk-W74WK3HB.js +184 -0
  25. package/dist/chunk-WVKJNHQM.js +120 -0
  26. package/dist/chunk-XAAJBX6R.js +100 -0
  27. package/dist/chunk-ZXVDDZZL.js +96 -0
  28. package/dist/components/blocks/ApiKeysBlock.d.ts +18 -0
  29. package/dist/components/blocks/ApiKeysBlock.js +128 -0
  30. package/dist/components/blocks/BenchmarksBlock.d.ts +20 -0
  31. package/dist/components/blocks/BenchmarksBlock.js +11 -0
  32. package/dist/components/blocks/CheckEmailBlock.d.ts +9 -0
  33. package/dist/components/blocks/CheckEmailBlock.js +13 -0
  34. package/dist/components/blocks/CommandPaletteBlock.d.ts +9 -0
  35. package/dist/components/blocks/CommandPaletteBlock.js +125 -0
  36. package/dist/components/blocks/EmailVerifiedBlock.d.ts +10 -0
  37. package/dist/components/blocks/EmailVerifiedBlock.js +10 -0
  38. package/dist/components/blocks/ForgotPasswordBlock.d.ts +14 -0
  39. package/dist/components/blocks/ForgotPasswordBlock.js +15 -0
  40. package/dist/components/blocks/IntegrationsBlock.js +4 -4
  41. package/dist/components/blocks/MagicLinkBlock.d.ts +12 -0
  42. package/dist/components/blocks/MagicLinkBlock.js +18 -0
  43. package/dist/components/blocks/OTPBlock.d.ts +10 -0
  44. package/dist/components/blocks/OTPBlock.js +121 -0
  45. package/dist/components/blocks/PasswordChangedBlock.d.ts +10 -0
  46. package/dist/components/blocks/PasswordChangedBlock.js +10 -0
  47. package/dist/components/blocks/PricingTableBlock.d.ts +19 -0
  48. package/dist/components/blocks/PricingTableBlock.js +12 -0
  49. package/dist/components/blocks/SavingsCalculatorBlock.d.ts +30 -0
  50. package/dist/components/blocks/SavingsCalculatorBlock.js +22 -0
  51. package/dist/components/blocks/TimezonePickerBlock.d.ts +11 -0
  52. package/dist/components/blocks/TimezonePickerBlock.js +126 -0
  53. package/dist/components/blocks/WorkspaceSwitcherBlock.d.ts +11 -0
  54. package/dist/components/blocks/WorkspaceSwitcherBlock.js +129 -0
  55. package/dist/components/logos/index.js +3 -3
  56. package/dist/components/page-kits/BlogContentPageKit.js +4 -4
  57. package/dist/components/page-kits/CheckoutPageKit.js +3 -3
  58. package/dist/components/page-kits/CompanySuitePageKit.js +4 -4
  59. package/dist/components/page-kits/LandingPageKit.js +5 -5
  60. package/dist/components/page-kits/MarketingShellPageKit.js +2 -2
  61. package/dist/components/page-kits/PricingPageKit.js +4 -4
  62. package/dist/components/page-kits/ServiceSuitePageKit.js +3 -3
  63. package/dist/components/ui/SearchCommand.js +4 -152
  64. package/dist/hooks/useHotkey.js +1 -37
  65. package/dist/lib/timezones.d.ts +14 -0
  66. package/dist/lib/timezones.js +1 -0
  67. package/package.json +6 -2
  68. package/dist/{chunk-6HGSU24S.js → chunk-4TUJJ3UI.js} +3 -3
  69. package/dist/{chunk-Z233ZQZE.js → chunk-E4L6LR6P.js} +1 -1
@@ -0,0 +1,60 @@
1
+ import { Card, CardHeader, CardTitle, CardDescription, CardContent } from './chunk-AH6YSYYT.js';
2
+ import { Button } from './chunk-7KIDDF3I.js';
3
+ import { useMotionConfig, m, scaleIn, motionSpring } from './chunk-PD2YEH3H.js';
4
+ import { ShieldCheckIcon } from './chunk-BFLN54VR.js';
5
+ import { cn } from './chunk-QYZT24TS.js';
6
+ import * as React from 'react';
7
+ import { jsx, jsxs } from 'react/jsx-runtime';
8
+
9
+ function PasswordChangedBlock({
10
+ className,
11
+ onContinue,
12
+ autoRedirectSeconds,
13
+ title = "Password changed!",
14
+ description = "Your password has been successfully updated.",
15
+ buttonLabel = "Continue to login"
16
+ }) {
17
+ const motionConfig = useMotionConfig();
18
+ const [countdown, setCountdown] = React.useState(autoRedirectSeconds ?? 0);
19
+ React.useEffect(() => {
20
+ if (!autoRedirectSeconds) return;
21
+ setCountdown(autoRedirectSeconds);
22
+ const interval = setInterval(() => {
23
+ setCountdown((prev) => {
24
+ if (prev <= 1) {
25
+ clearInterval(interval);
26
+ onContinue?.();
27
+ return 0;
28
+ }
29
+ return prev - 1;
30
+ });
31
+ }, 1e3);
32
+ return () => clearInterval(interval);
33
+ }, [autoRedirectSeconds, onContinue]);
34
+ return /* @__PURE__ */ jsx(m.div, { ...scaleIn, className: cn("w-full max-w-sm mx-auto", className), children: /* @__PURE__ */ jsxs(Card, { children: [
35
+ /* @__PURE__ */ jsxs(CardHeader, { className: "text-center", children: [
36
+ /* @__PURE__ */ jsx(
37
+ m.div,
38
+ {
39
+ className: "mx-auto mb-2",
40
+ initial: { scale: 0.8, opacity: 0 },
41
+ animate: { scale: 1, opacity: 1 },
42
+ transition: { ...motionSpring.bouncy, ...motionConfig },
43
+ children: /* @__PURE__ */ jsx("div", { className: "flex h-16 w-16 items-center justify-center rounded-full bg-success/10 shadow-[0_0_24px_rgba(61,214,140,0.2)]", children: /* @__PURE__ */ jsx(ShieldCheckIcon, { size: 32, className: "text-success" }) })
44
+ }
45
+ ),
46
+ /* @__PURE__ */ jsx(CardTitle, { className: "text-2xl", children: title }),
47
+ /* @__PURE__ */ jsx(CardDescription, { children: description })
48
+ ] }),
49
+ /* @__PURE__ */ jsxs(CardContent, { className: "grid gap-4", children: [
50
+ autoRedirectSeconds !== void 0 && countdown > 0 && /* @__PURE__ */ jsxs("p", { className: "text-center text-sm text-text-tertiary tabular-nums", children: [
51
+ "Redirecting in ",
52
+ countdown,
53
+ "..."
54
+ ] }),
55
+ /* @__PURE__ */ jsx(Button, { variant: "accent", className: "w-full", onClick: onContinue, children: buttonLabel })
56
+ ] })
57
+ ] }) });
58
+ }
59
+
60
+ export { PasswordChangedBlock };
@@ -0,0 +1,24 @@
1
+ import { SidebarMenu, SidebarMenuItem, SidebarMenuButton } from './chunk-J2DCQDXO.js';
2
+ import { LayoutDashboardIcon } from './chunk-O74AEVHW.js';
3
+ import { cn } from './chunk-QYZT24TS.js';
4
+ import { jsx, jsxs } from 'react/jsx-runtime';
5
+
6
+ var DEFAULT_NAME = "My Workspace";
7
+ var DEFAULT_PLAN = "Free Plan";
8
+ var DEFAULT_HREF = "/dashboard";
9
+ function WorkspaceSwitcherBlock({
10
+ name = DEFAULT_NAME,
11
+ plan = DEFAULT_PLAN,
12
+ href = DEFAULT_HREF,
13
+ className
14
+ }) {
15
+ return /* @__PURE__ */ jsx(SidebarMenu, { className: cn(className), children: /* @__PURE__ */ jsx(SidebarMenuItem, { children: /* @__PURE__ */ jsx(SidebarMenuButton, { size: "lg", asChild: true, children: /* @__PURE__ */ jsxs("a", { href, children: [
16
+ /* @__PURE__ */ jsx("div", { className: "flex aspect-square size-8 items-center justify-center rounded-lg bg-primary text-primary-foreground", children: /* @__PURE__ */ jsx(LayoutDashboardIcon, { size: 16 }) }),
17
+ /* @__PURE__ */ jsxs("div", { className: "grid flex-1 text-left text-sm leading-tight", children: [
18
+ /* @__PURE__ */ jsx("span", { className: "truncate font-semibold text-text-primary", children: name }),
19
+ /* @__PURE__ */ jsx("span", { className: "truncate text-xs text-text-tertiary", children: plan })
20
+ ] })
21
+ ] }) }) }) });
22
+ }
23
+
24
+ export { WorkspaceSwitcherBlock };
@@ -1,7 +1,7 @@
1
- import { MarketingShellPageKit } from './chunk-Z233ZQZE.js';
1
+ import { MarketingShellPageKit } from './chunk-E4L6LR6P.js';
2
2
  import { TeamBlock } from './chunk-VBZQ4DBE.js';
3
- import { ContactBlock } from './chunk-U4GYSYGN.js';
4
3
  import { FAQBlock } from './chunk-NEHCPO53.js';
4
+ import { ContactBlock } from './chunk-U4GYSYGN.js';
5
5
  import { CallToActionBlock } from './chunk-GJPTPLCQ.js';
6
6
  import { Typography } from './chunk-N53OMWW2.js';
7
7
  import { Card, CardHeader, CardTitle, CardContent } from './chunk-AH6YSYYT.js';
@@ -0,0 +1,184 @@
1
+ import { Heading } from './chunk-WI547C47.js';
2
+ import { Table, TableHeader, TableRow, TableHead, TableBody, TableCell } from './chunk-PXDHNGTG.js';
3
+ import { Dialog, DialogTrigger, DialogContent, DialogHeader, DialogTitle, DialogDescription, DialogFooter } from './chunk-W73JAOHW.js';
4
+ import { Input } from './chunk-AP3XXYAY.js';
5
+ import { Card, CardContent } from './chunk-AH6YSYYT.js';
6
+ import { Button } from './chunk-7KIDDF3I.js';
7
+ import { Trash2Icon } from './chunk-S4GKGKON.js';
8
+ import { PlusIcon } from './chunk-E7RBK6ML.js';
9
+ import { KeyIcon } from './chunk-QSU23VYZ.js';
10
+ import { Badge } from './chunk-S4JAHKOP.js';
11
+ import { CopyIcon } from './chunk-TV4RSQH4.js';
12
+ import { cn } from './chunk-QYZT24TS.js';
13
+ import { useState, useMemo } from 'react';
14
+ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
15
+
16
+ var DEFAULT_KEYS = [];
17
+ function ApiKeysBlock({
18
+ keys = DEFAULT_KEYS,
19
+ onCreate,
20
+ onRevoke,
21
+ title = "API Keys",
22
+ description = "Manage your API keys",
23
+ className
24
+ }) {
25
+ const [dialogOpen, setDialogOpen] = useState(false);
26
+ const [newKeyName, setNewKeyName] = useState("");
27
+ const [creating, setCreating] = useState(false);
28
+ const [createdKey, setCreatedKey] = useState(null);
29
+ const [copied, setCopied] = useState(false);
30
+ const sortedKeys = useMemo(() => {
31
+ const active = keys.filter((k) => !k.revokedAt);
32
+ const revoked = keys.filter((k) => k.revokedAt);
33
+ return [...active, ...revoked];
34
+ }, [keys]);
35
+ const handleCreate = async () => {
36
+ if (!newKeyName.trim() || !onCreate) return;
37
+ setCreating(true);
38
+ try {
39
+ const result = await onCreate(newKeyName.trim());
40
+ if (typeof result === "string") {
41
+ setCreatedKey(result);
42
+ } else {
43
+ handleDialogClose();
44
+ }
45
+ } finally {
46
+ setCreating(false);
47
+ setNewKeyName("");
48
+ }
49
+ };
50
+ const handleCopy = async (text) => {
51
+ await navigator.clipboard.writeText(text);
52
+ setCopied(true);
53
+ setTimeout(() => setCopied(false), 2e3);
54
+ };
55
+ const handleDialogClose = () => {
56
+ setDialogOpen(false);
57
+ setCreatedKey(null);
58
+ setNewKeyName("");
59
+ };
60
+ return /* @__PURE__ */ jsx("section", { className: cn("py-16 md:py-24", className), children: /* @__PURE__ */ jsxs("div", { className: "mx-auto max-w-4xl px-6", children: [
61
+ /* @__PURE__ */ jsxs("div", { className: "mb-8 flex items-center justify-between", children: [
62
+ /* @__PURE__ */ jsxs("div", { children: [
63
+ !!title && /* @__PURE__ */ jsx(Heading, { level: 2, size: "section", className: "text-text-primary", children: title }),
64
+ !!description && /* @__PURE__ */ jsx("p", { className: "mt-1 text-text-secondary", children: description })
65
+ ] }),
66
+ /* @__PURE__ */ jsxs(
67
+ Dialog,
68
+ {
69
+ open: dialogOpen,
70
+ onOpenChange: (open) => {
71
+ if (!open) handleDialogClose();
72
+ else setDialogOpen(true);
73
+ },
74
+ children: [
75
+ /* @__PURE__ */ jsx(DialogTrigger, { asChild: true, children: /* @__PURE__ */ jsxs(Button, { children: [
76
+ /* @__PURE__ */ jsx(PlusIcon, { size: 16, className: "mr-2" }),
77
+ "Create API Key"
78
+ ] }) }),
79
+ /* @__PURE__ */ jsx(DialogContent, { children: createdKey ? /* @__PURE__ */ jsxs(Fragment, { children: [
80
+ /* @__PURE__ */ jsxs(DialogHeader, { children: [
81
+ /* @__PURE__ */ jsx(DialogTitle, { children: "API Key Created" }),
82
+ /* @__PURE__ */ jsxs(DialogDescription, { children: [
83
+ "Copy this key now. You won",
84
+ "'",
85
+ "t be able to see it again."
86
+ ] })
87
+ ] }),
88
+ /* @__PURE__ */ jsxs("div", { className: "space-y-4", children: [
89
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 rounded-lg border border-border bg-surface/80 p-3 font-mono text-sm break-all", children: [
90
+ /* @__PURE__ */ jsx("span", { className: "flex-1", children: createdKey }),
91
+ /* @__PURE__ */ jsxs(
92
+ Button,
93
+ {
94
+ size: "sm",
95
+ variant: "outline",
96
+ onClick: () => handleCopy(createdKey),
97
+ children: [
98
+ /* @__PURE__ */ jsx(CopyIcon, { size: 14, className: "mr-1" }),
99
+ copied ? "Copied!" : "Copy"
100
+ ]
101
+ }
102
+ )
103
+ ] }),
104
+ /* @__PURE__ */ jsx("p", { className: "text-sm text-destructive/80", children: "This key will not be shown again. Store it securely." })
105
+ ] }),
106
+ /* @__PURE__ */ jsx(DialogFooter, { children: /* @__PURE__ */ jsx(Button, { onClick: handleDialogClose, children: "Done" }) })
107
+ ] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
108
+ /* @__PURE__ */ jsxs(DialogHeader, { children: [
109
+ /* @__PURE__ */ jsx(DialogTitle, { children: "Create API Key" }),
110
+ /* @__PURE__ */ jsx(DialogDescription, { children: "Give your key a name to identify it later." })
111
+ ] }),
112
+ /* @__PURE__ */ jsx("div", { className: "space-y-4 py-4", children: /* @__PURE__ */ jsx(
113
+ Input,
114
+ {
115
+ name: "name",
116
+ placeholder: "e.g., Production server",
117
+ value: newKeyName,
118
+ onChange: (e) => setNewKeyName(e.target.value),
119
+ onKeyDown: (e) => {
120
+ if (e.key === "Enter") handleCreate();
121
+ }
122
+ }
123
+ ) }),
124
+ /* @__PURE__ */ jsxs(DialogFooter, { children: [
125
+ /* @__PURE__ */ jsx(Button, { variant: "outline", onClick: handleDialogClose, children: "Cancel" }),
126
+ /* @__PURE__ */ jsx(
127
+ Button,
128
+ {
129
+ onClick: handleCreate,
130
+ disabled: creating || !newKeyName.trim(),
131
+ children: creating ? "Creating..." : "Create"
132
+ }
133
+ )
134
+ ] })
135
+ ] }) })
136
+ ]
137
+ }
138
+ )
139
+ ] }),
140
+ /* @__PURE__ */ jsx(Card, { children: /* @__PURE__ */ jsx(CardContent, { className: "pt-6", children: keys.length === 0 ? /* @__PURE__ */ jsxs("div", { className: "space-y-4 py-12 text-center", children: [
141
+ /* @__PURE__ */ jsx(KeyIcon, { size: 40, className: "mx-auto text-text-tertiary" }),
142
+ /* @__PURE__ */ jsx(Heading, { level: 3, size: "label", className: "text-text-primary", children: "No API keys yet" }),
143
+ /* @__PURE__ */ jsx("p", { className: "text-text-secondary", children: "Create your first API key to get started." })
144
+ ] }) : /* @__PURE__ */ jsxs(Table, { children: [
145
+ /* @__PURE__ */ jsx(TableHeader, { children: /* @__PURE__ */ jsxs(TableRow, { children: [
146
+ /* @__PURE__ */ jsx(TableHead, { children: "Name" }),
147
+ /* @__PURE__ */ jsx(TableHead, { children: "Key" }),
148
+ /* @__PURE__ */ jsx(TableHead, { className: "hidden md:table-cell", children: "Created" }),
149
+ /* @__PURE__ */ jsx(TableHead, { className: "hidden md:table-cell", children: "Last Used" }),
150
+ /* @__PURE__ */ jsx(TableHead, { children: "Status" }),
151
+ /* @__PURE__ */ jsx(TableHead, { className: "text-right", children: "Action" })
152
+ ] }) }),
153
+ /* @__PURE__ */ jsx(TableBody, { children: sortedKeys.map((key) => /* @__PURE__ */ jsxs(TableRow, { children: [
154
+ /* @__PURE__ */ jsx(TableCell, { className: "font-medium", children: key.name }),
155
+ /* @__PURE__ */ jsx(TableCell, { className: "font-mono text-xs text-text-tertiary", children: key.prefix }),
156
+ /* @__PURE__ */ jsx(TableCell, { className: "hidden text-text-secondary md:table-cell", children: new Date(key.createdAt).toLocaleDateString() }),
157
+ /* @__PURE__ */ jsx(TableCell, { className: "hidden text-text-secondary md:table-cell", children: key.lastUsedAt ? new Date(key.lastUsedAt).toLocaleDateString() : "Never" }),
158
+ /* @__PURE__ */ jsx(TableCell, { children: key.revokedAt ? /* @__PURE__ */ jsx(
159
+ Badge,
160
+ {
161
+ variant: "outline",
162
+ className: "text-destructive/80",
163
+ children: "Revoked"
164
+ }
165
+ ) : /* @__PURE__ */ jsx(Badge, { variant: "outline", className: "text-chart-4", children: "Active" }) }),
166
+ /* @__PURE__ */ jsx(TableCell, { className: "text-right", children: !key.revokedAt && onRevoke && /* @__PURE__ */ jsxs(
167
+ Button,
168
+ {
169
+ size: "sm",
170
+ variant: "outline",
171
+ className: "text-destructive/80 hover:text-destructive",
172
+ onClick: () => onRevoke(key.id),
173
+ children: [
174
+ /* @__PURE__ */ jsx(Trash2Icon, { size: 14, className: "mr-1" }),
175
+ "Revoke"
176
+ ]
177
+ }
178
+ ) })
179
+ ] }, key.id)) })
180
+ ] }) }) })
181
+ ] }) });
182
+ }
183
+
184
+ export { ApiKeysBlock };
@@ -0,0 +1,120 @@
1
+ import { Spinner } from './chunk-ZLSWCV55.js';
2
+ import { Field, FieldLabel } from './chunk-RX5EUODB.js';
3
+ import { Separator } from './chunk-CUZJIDU7.js';
4
+ import { Input } from './chunk-AP3XXYAY.js';
5
+ import { Card, CardHeader, CardTitle, CardDescription, CardContent, CardFooter } from './chunk-AH6YSYYT.js';
6
+ import { Alert, AlertDescription } from './chunk-GJUR6HT3.js';
7
+ import { Button } from './chunk-7KIDDF3I.js';
8
+ import { m, scaleIn } from './chunk-PD2YEH3H.js';
9
+ import { SparklesIcon } from './chunk-CGUCH322.js';
10
+ import { MailIcon } from './chunk-XQ2UDMPO.js';
11
+ import { CheckIcon } from './chunk-CXACRCZ4.js';
12
+ import { cn } from './chunk-QYZT24TS.js';
13
+ import * as React from 'react';
14
+ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
15
+
16
+ function MagicLinkBlock({
17
+ className,
18
+ onSubmit,
19
+ onBackToLogin,
20
+ title = "Sign in with magic link",
21
+ subtitle = "No password needed",
22
+ successTitle = "Check your email",
23
+ expiryMinutes = 15,
24
+ placeholder = "name@example.com"
25
+ }) {
26
+ const [email, setEmail] = React.useState("");
27
+ const [state, setState] = React.useState("idle");
28
+ const handleSubmit = (e) => {
29
+ e.preventDefault();
30
+ if (!email) return;
31
+ setState("loading");
32
+ onSubmit?.(email);
33
+ setTimeout(() => setState("success"), 1500);
34
+ };
35
+ if (state === "success") {
36
+ return /* @__PURE__ */ jsx(m.div, { ...scaleIn, className: cn("w-full max-w-sm mx-auto", className), children: /* @__PURE__ */ jsxs(Card, { children: [
37
+ /* @__PURE__ */ jsxs(CardHeader, { className: "text-center", children: [
38
+ /* @__PURE__ */ jsx("div", { className: "mx-auto mb-2", children: /* @__PURE__ */ jsx(MailIcon, { size: 48, className: "text-accent" }) }),
39
+ /* @__PURE__ */ jsx(CardTitle, { className: "text-2xl", children: successTitle }),
40
+ /* @__PURE__ */ jsxs(CardDescription, { children: [
41
+ "We sent a magic link to ",
42
+ /* @__PURE__ */ jsx("span", { className: "font-mono text-text-primary", children: email })
43
+ ] })
44
+ ] }),
45
+ /* @__PURE__ */ jsx(CardContent, { className: "grid gap-4", children: /* @__PURE__ */ jsxs("ul", { className: "space-y-2 text-sm text-text-secondary", children: [
46
+ /* @__PURE__ */ jsxs("li", { className: "flex items-start gap-2", children: [
47
+ /* @__PURE__ */ jsx(CheckIcon, { size: 16, className: "text-success mt-0.5 shrink-0" }),
48
+ /* @__PURE__ */ jsx("span", { children: "Click the link in the email to sign in" })
49
+ ] }),
50
+ /* @__PURE__ */ jsxs("li", { className: "flex items-start gap-2", children: [
51
+ /* @__PURE__ */ jsx(CheckIcon, { size: 16, className: "text-success mt-0.5 shrink-0" }),
52
+ /* @__PURE__ */ jsxs("span", { children: [
53
+ "The link expires in ",
54
+ expiryMinutes,
55
+ " minutes"
56
+ ] })
57
+ ] })
58
+ ] }) }),
59
+ /* @__PURE__ */ jsx(CardFooter, { className: "justify-center", children: /* @__PURE__ */ jsx(
60
+ "button",
61
+ {
62
+ type: "button",
63
+ onClick: onBackToLogin,
64
+ className: "text-sm text-text-tertiary hover:text-text-primary transition-colors",
65
+ children: "Back to login"
66
+ }
67
+ ) })
68
+ ] }) });
69
+ }
70
+ return /* @__PURE__ */ jsx(m.div, { ...scaleIn, className: cn("w-full max-w-sm mx-auto", className), children: /* @__PURE__ */ jsxs(Card, { children: [
71
+ /* @__PURE__ */ jsxs(CardHeader, { className: "text-center", children: [
72
+ /* @__PURE__ */ jsx("div", { className: "mx-auto mb-2", children: /* @__PURE__ */ jsx(SparklesIcon, { size: 32, className: "text-accent" }) }),
73
+ /* @__PURE__ */ jsx(CardTitle, { className: "text-2xl", children: title }),
74
+ /* @__PURE__ */ jsx(CardDescription, { children: subtitle })
75
+ ] }),
76
+ /* @__PURE__ */ jsxs(CardContent, { children: [
77
+ /* @__PURE__ */ jsxs("form", { noValidate: true, onSubmit: handleSubmit, className: "grid gap-4", children: [
78
+ /* @__PURE__ */ jsxs(Field, { children: [
79
+ /* @__PURE__ */ jsx(FieldLabel, { htmlFor: "magic-email", children: "Email" }),
80
+ /* @__PURE__ */ jsx(
81
+ Input,
82
+ {
83
+ id: "magic-email",
84
+ name: "email",
85
+ type: "email",
86
+ placeholder,
87
+ value: email,
88
+ onChange: (e) => setEmail(e.target.value),
89
+ autoComplete: "email",
90
+ required: true
91
+ }
92
+ )
93
+ ] }),
94
+ /* @__PURE__ */ jsx(Alert, { children: /* @__PURE__ */ jsxs(AlertDescription, { className: "text-xs text-text-tertiary", children: [
95
+ "We",
96
+ "'",
97
+ "ll send you a link that expires in ",
98
+ expiryMinutes,
99
+ " minutes."
100
+ ] }) }),
101
+ /* @__PURE__ */ jsx(Button, { variant: "accent", className: "w-full", disabled: state === "loading", children: state === "loading" ? /* @__PURE__ */ jsxs(Fragment, { children: [
102
+ /* @__PURE__ */ jsx(Spinner, { className: "mr-2" }),
103
+ "Sending..."
104
+ ] }) : "Send magic link" })
105
+ ] }),
106
+ /* @__PURE__ */ jsx(Separator, { className: "my-4" }),
107
+ /* @__PURE__ */ jsx("div", { className: "text-center", children: /* @__PURE__ */ jsx(
108
+ "button",
109
+ {
110
+ type: "button",
111
+ onClick: onBackToLogin,
112
+ className: "text-sm text-text-tertiary hover:text-text-primary transition-colors",
113
+ children: "Prefer password? Sign in normally"
114
+ }
115
+ ) })
116
+ ] })
117
+ ] }) });
118
+ }
119
+
120
+ export { MagicLinkBlock };
@@ -0,0 +1,100 @@
1
+ import { Heading } from './chunk-WI547C47.js';
2
+ import { Card, CardHeader, CardTitle, CardDescription, CardContent, CardFooter } from './chunk-AH6YSYYT.js';
3
+ import { Button } from './chunk-7KIDDF3I.js';
4
+ import { CheckIcon } from './chunk-CXACRCZ4.js';
5
+ import { Badge } from './chunk-S4JAHKOP.js';
6
+ import { cn } from './chunk-QYZT24TS.js';
7
+ import { jsx, jsxs } from 'react/jsx-runtime';
8
+
9
+ var DEFAULT_PLANS = [
10
+ {
11
+ name: "Free",
12
+ price: "$0",
13
+ period: "mo",
14
+ description: "Per editor",
15
+ features: ["Basic Analytics Dashboard", "5GB Cloud Storage", "Email and Chat Support"],
16
+ buttonVariant: "outline"
17
+ },
18
+ {
19
+ name: "Pro",
20
+ price: "$19",
21
+ period: "mo",
22
+ description: "Per editor",
23
+ features: [
24
+ "Everything in Free Plan",
25
+ "5GB Cloud Storage",
26
+ "Email and Chat Support",
27
+ "Access to Community Forum",
28
+ "Single User Access",
29
+ "Access to Basic Templates",
30
+ "Mobile App Access",
31
+ "1 Custom Report Per Month",
32
+ "Monthly Product Updates",
33
+ "Standard Security Features"
34
+ ],
35
+ highlighted: true,
36
+ badge: "Popular"
37
+ },
38
+ {
39
+ name: "Startup",
40
+ price: "$29",
41
+ period: "mo",
42
+ description: "Per editor",
43
+ features: ["Everything in Pro Plan", "5GB Cloud Storage", "Email and Chat Support"],
44
+ buttonVariant: "outline"
45
+ }
46
+ ];
47
+ function PricingTableBlock({
48
+ heading = "Pricing that Scales with You",
49
+ subheading = "Gemini is evolving to be more than just the models. It supports an entire to the APIs and platforms helping developers and businesses innovate.",
50
+ plans = DEFAULT_PLANS,
51
+ onSelectPlan,
52
+ className
53
+ }) {
54
+ return /* @__PURE__ */ jsx("section", { className: cn("py-16 md:py-32", className), children: /* @__PURE__ */ jsxs("div", { className: "mx-auto max-w-6xl px-6", children: [
55
+ /* @__PURE__ */ jsxs("div", { className: "mx-auto max-w-2xl space-y-6 text-center", children: [
56
+ /* @__PURE__ */ jsx(Heading, { level: 2, className: "text-center", children: heading }),
57
+ /* @__PURE__ */ jsx("p", { children: subheading })
58
+ ] }),
59
+ /* @__PURE__ */ jsx("div", { className: "mt-8 grid gap-6 md:mt-20 md:grid-cols-3", children: plans.map((plan) => /* @__PURE__ */ jsxs(
60
+ Card,
61
+ {
62
+ className: plan.highlighted ? "relative" : "flex flex-col",
63
+ interactive: true,
64
+ children: [
65
+ !!plan.badge && /* @__PURE__ */ jsx(Badge, { className: "absolute inset-x-0 -top-3 mx-auto w-fit", children: plan.badge }),
66
+ /* @__PURE__ */ jsxs("div", { className: plan.highlighted ? "flex flex-col" : void 0, children: [
67
+ /* @__PURE__ */ jsxs(CardHeader, { children: [
68
+ /* @__PURE__ */ jsx(CardTitle, { className: "font-medium", children: plan.name }),
69
+ /* @__PURE__ */ jsxs("span", { className: "my-3 block text-2xl font-semibold tabular-nums", children: [
70
+ plan.price,
71
+ " / ",
72
+ plan.period
73
+ ] }),
74
+ /* @__PURE__ */ jsx(CardDescription, { className: "text-sm", children: plan.description })
75
+ ] }),
76
+ /* @__PURE__ */ jsxs(CardContent, { className: "space-y-4", children: [
77
+ /* @__PURE__ */ jsx("hr", { className: "border-dashed" }),
78
+ /* @__PURE__ */ jsx("ul", { className: "list-outside space-y-3 text-sm", children: plan.features.map((feature, index) => /* @__PURE__ */ jsxs("li", { className: "flex items-center gap-2", children: [
79
+ /* @__PURE__ */ jsx(CheckIcon, { size: 12 }),
80
+ feature
81
+ ] }, index)) })
82
+ ] }),
83
+ /* @__PURE__ */ jsx(CardFooter, { className: plan.highlighted ? void 0 : "mt-auto", children: /* @__PURE__ */ jsx(
84
+ Button,
85
+ {
86
+ variant: plan.buttonVariant ?? "primary",
87
+ className: "w-full",
88
+ onClick: () => onSelectPlan?.(plan.name),
89
+ children: "Get Started"
90
+ }
91
+ ) })
92
+ ] })
93
+ ]
94
+ },
95
+ plan.name
96
+ )) })
97
+ ] }) });
98
+ }
99
+
100
+ export { PricingTableBlock };
@@ -0,0 +1,96 @@
1
+ import { getTimezoneGroups } from './chunk-PTJPPKDR.js';
2
+ import { Popover, PopoverTrigger, PopoverContent } from './chunk-UYT33NG6.js';
3
+ import { Command } from './chunk-2HDB6MDK.js';
4
+ import { Button } from './chunk-7KIDDF3I.js';
5
+ import { Badge } from './chunk-S4JAHKOP.js';
6
+ import { cn } from './chunk-QYZT24TS.js';
7
+ import { useState, useMemo } from 'react';
8
+ import { Command as Command$1 } from 'cmdk';
9
+ import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
10
+
11
+ var DEFAULT_GROUPS = getTimezoneGroups();
12
+ function TimezonePickerBlock({
13
+ id,
14
+ value,
15
+ onChange,
16
+ name,
17
+ className,
18
+ groups = DEFAULT_GROUPS
19
+ }) {
20
+ const [open, setOpen] = useState(false);
21
+ const entries = useMemo(() => groups.flatMap((group) => group.timezones), [groups]);
22
+ const selectedTimezone = useMemo(
23
+ () => entries.find((timezone) => timezone.value === value) ?? null,
24
+ [entries, value]
25
+ );
26
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
27
+ name ? /* @__PURE__ */ jsx("input", { type: "hidden", name, value: value ?? "" }) : null,
28
+ /* @__PURE__ */ jsxs(Popover, { modal: false, open, onOpenChange: setOpen, children: [
29
+ /* @__PURE__ */ jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxs(
30
+ Button,
31
+ {
32
+ id,
33
+ type: "button",
34
+ variant: "outline",
35
+ role: "combobox",
36
+ "aria-expanded": open,
37
+ "aria-label": "Select timezone",
38
+ className: cn("w-full justify-between text-left", className),
39
+ children: [
40
+ /* @__PURE__ */ jsx("span", { className: "truncate", children: selectedTimezone ? `${selectedTimezone.value} (${selectedTimezone.offset})` : "Select timezone" }),
41
+ /* @__PURE__ */ jsx("span", { className: "ml-2 shrink-0 opacity-50", "aria-hidden": "true", children: /* @__PURE__ */ jsxs("svg", { viewBox: "0 0 20 20", width: "14", height: "14", fill: "none", stroke: "currentColor", children: [
42
+ /* @__PURE__ */ jsx("path", { d: "M6 8l4-4 4 4", strokeWidth: "1.8", strokeLinecap: "round", strokeLinejoin: "round" }),
43
+ /* @__PURE__ */ jsx("path", { d: "M6 12l4 4 4-4", strokeWidth: "1.8", strokeLinecap: "round", strokeLinejoin: "round" })
44
+ ] }) })
45
+ ]
46
+ }
47
+ ) }),
48
+ /* @__PURE__ */ jsx(PopoverContent, { align: "start", className: "w-[min(90vw,32rem)] p-0", children: /* @__PURE__ */ jsxs(Command, { children: [
49
+ /* @__PURE__ */ jsx("div", { className: "flex items-center border-b px-4", children: /* @__PURE__ */ jsx(
50
+ Command$1.Input,
51
+ {
52
+ className: "h-11 w-full rounded-md bg-transparent py-3 text-sm outline-none placeholder:text-text-tertiary focus-visible:ring-2 focus-visible:ring-accent focus-visible:ring-offset-2 focus-visible:ring-offset-background",
53
+ placeholder: "Search timezone by city, region, or offset..."
54
+ }
55
+ ) }),
56
+ /* @__PURE__ */ jsxs(Command$1.List, { className: "max-h-80 overflow-y-auto overflow-x-hidden", children: [
57
+ /* @__PURE__ */ jsx(Command$1.Empty, { className: "py-6 text-center text-sm", children: "No timezone found." }),
58
+ groups.map((group) => /* @__PURE__ */ jsx(
59
+ Command$1.Group,
60
+ {
61
+ heading: /* @__PURE__ */ jsx(Badge, { variant: "secondary", children: group.region }),
62
+ className: "overflow-hidden p-1.5 text-text-primary [&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:py-1.5",
63
+ children: group.timezones.map((timezone) => /* @__PURE__ */ jsxs(
64
+ Command$1.Item,
65
+ {
66
+ value: `${timezone.value} ${timezone.label} ${timezone.region} ${timezone.offset}`,
67
+ onSelect: () => {
68
+ onChange?.(timezone.value);
69
+ setOpen(false);
70
+ },
71
+ className: "relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none focus-visible:ring-2 focus-visible:ring-accent focus-visible:ring-offset-2 focus-visible:ring-offset-background data-[disabled=true]:pointer-events-none data-[selected='true']:bg-surface-active data-[selected=true]:text-text-primary data-[disabled=true]:opacity-50",
72
+ children: [
73
+ /* @__PURE__ */ jsx(
74
+ "span",
75
+ {
76
+ className: cn("mr-2 shrink-0 text-xs", value === timezone.value ? "opacity-100" : "opacity-0"),
77
+ "aria-hidden": "true",
78
+ children: "\u2713"
79
+ }
80
+ ),
81
+ /* @__PURE__ */ jsx("span", { className: "truncate", children: timezone.value }),
82
+ /* @__PURE__ */ jsx("span", { className: "ml-auto pl-2 text-xs text-text-tertiary", children: timezone.offset })
83
+ ]
84
+ },
85
+ timezone.value
86
+ ))
87
+ },
88
+ group.region
89
+ ))
90
+ ] })
91
+ ] }) })
92
+ ] })
93
+ ] });
94
+ }
95
+
96
+ export { TimezonePickerBlock };
@@ -0,0 +1,18 @@
1
+ interface ApiKey {
2
+ id: string;
3
+ name: string;
4
+ prefix: string;
5
+ createdAt: string;
6
+ lastUsedAt: string | null;
7
+ revokedAt: string | null;
8
+ }
9
+ interface ApiKeysBlockProps {
10
+ keys?: ApiKey[];
11
+ onCreate?: (name: string) => Promise<string | void> | string | void;
12
+ onRevoke?: (keyId: string) => void | Promise<void>;
13
+ title?: string;
14
+ description?: string;
15
+ className?: string;
16
+ }
17
+ export declare function ApiKeysBlock({ keys, onCreate, onRevoke, title, description, className, }: ApiKeysBlockProps): import("react/jsx-runtime").JSX.Element;
18
+ export {};