@pagehub/sdk 0.1.4 → 0.1.6

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 (141) hide show
  1. package/README.md +1 -1
  2. package/dist/chrome/viewport/Viewport/hooks/usePageLoadIndicator.d.ts +2 -2
  3. package/dist/chrome/viewport/design-system/hooks/useDesignSystem.d.ts +2 -2
  4. package/dist/chrome/viewport/design-system/hooks/usePaletteState.d.ts +2 -2
  5. package/dist/chunks/ActionEditorPanel-9v50QUwu.js +89 -0
  6. package/dist/chunks/ActionInput-CTt7sOs6.js +929 -0
  7. package/dist/chunks/ActionsAddPicker-BeTPUUor.js +51 -0
  8. package/dist/chunks/ActionsInput-D0h-zLYj.js +174 -0
  9. package/dist/chunks/AnchoredPopover-CckPTxXu.js +2676 -0
  10. package/dist/chunks/AnimationEditorPanel-CXNmsTqV.js +26 -0
  11. package/dist/chunks/AnimationsInput-Djyz0uXG.js +292 -0
  12. package/dist/chunks/AnimationsInputPopover-B2-oNebx.js +71 -0
  13. package/dist/chunks/AnimationsPanel-DungA9qb.js +25 -0
  14. package/dist/chunks/Audio.render-CsR69fZ9.js +22 -0
  15. package/dist/chunks/AudioMainTab-BljM2NMQ.js +70 -0
  16. package/dist/chunks/BackdropEditorPanel-CA2k-6SR.js +26 -0
  17. package/dist/chunks/BackgroundImageInputPopover-vB_217Ig.js +94 -0
  18. package/dist/chunks/BackgroundImagePanel-BvMhF9eU.js +100 -0
  19. package/dist/chunks/BackgroundMainTab-CI4c5DEF.js +10 -0
  20. package/dist/chunks/BundleRowPanel-BcYfyfGQ.js +33 -0
  21. package/dist/chunks/ButtonMainTab-Civy_DoA.js +43 -0
  22. package/dist/chunks/CSSEditorInput-C1ITwAh3.js +73 -0
  23. package/dist/chunks/ClassNameInput-Ce0fGQES.js +720 -0
  24. package/dist/chunks/CodeEditor-axBXmPH8.js +33370 -0
  25. package/dist/chunks/ColorInput-BSfMNt86.js +187 -0
  26. package/dist/chunks/ColorPanel-DOLrT-gS.js +562 -0
  27. package/dist/chunks/ComponentImportExportPanel-DVcnGhGx.js +161 -0
  28. package/dist/chunks/ComponentImportExportPopover-BY1_oxU8.js +26 -0
  29. package/dist/chunks/ConditionEditorPanel-DLbqYaSF.js +43 -0
  30. package/dist/chunks/ConditionsAddPicker-SsHJlc1E.js +54 -0
  31. package/dist/chunks/ConditionsInput-B_5Nge8o.js +474 -0
  32. package/dist/chunks/ContainerMainTab-kkktm1Ns.js +1107 -0
  33. package/dist/chunks/ContainerOverflowSectionPanel-ibKXf-1N.js +120 -0
  34. package/dist/chunks/ContainerOverflowSectionPopover-CRQ9EPsn.js +24 -0
  35. package/dist/chunks/ContainerPaddingOverlay-Cd3xOv-S.js +340 -0
  36. package/dist/chunks/ContainerScrollEffectSection-Dbztqdnr.js +123 -0
  37. package/dist/chunks/ContainerStateSection-DY_gjBJL.js +478 -0
  38. package/dist/chunks/ConversionFields-Bpfl-SGP.js +135 -0
  39. package/dist/chunks/CraftListEditor-_TIy1ogW.js +73 -0
  40. package/dist/chunks/CreateTokenDialog-DNWtWqJd.js +147 -0
  41. package/dist/chunks/Data.render-DTmaqSyz.js +10 -0
  42. package/dist/chunks/DataAttributesPanel-mYhisO_O.js +125 -0
  43. package/dist/chunks/DataMainTab-Batm515E.js +23 -0
  44. package/dist/chunks/DataSourceSectionSlot-BKoO6Vxn.js +10 -0
  45. package/dist/chunks/EditorEmptyLeafHintView-D3E3UN_0.js +78 -0
  46. package/dist/chunks/EffectRowInputPopover-CYhfjFwJ.js +323 -0
  47. package/dist/chunks/EffectsClassInput-Yujuchwy.js +315 -0
  48. package/dist/chunks/Embed.render-BgKpUV8n.js +17 -0
  49. package/dist/chunks/EmbedMainTab-d_-Bnkug.js +225 -0
  50. package/dist/chunks/FilterEditorPanel-CRa0IpLr.js +26 -0
  51. package/dist/chunks/FlexDirectionInput-C5gYjk5W.js +78 -0
  52. package/dist/chunks/FloatingPanel-DJP5Vhua.js +553 -0
  53. package/dist/chunks/FontFamilyInput-CVNnVylt.js +111 -0
  54. package/dist/chunks/Form.render-6GjcmL2u.js +54 -0
  55. package/dist/chunks/FormElement.render-DWrG-2ID.js +36 -0
  56. package/dist/chunks/FormElementMainTab-DSbF3F6e.js +470 -0
  57. package/dist/chunks/FormMainTab-SHny1HxF.js +240 -0
  58. package/dist/chunks/GradientInputPopover-1K6O9jBq.js +103 -0
  59. package/dist/chunks/GradientPanel-DSRQKkaB.js +194 -0
  60. package/dist/chunks/HTMLCodeInput-CCe4Bj5z.js +69 -0
  61. package/dist/chunks/HandlerEditorPanel-DiOXobsl.js +93 -0
  62. package/dist/chunks/HandlersAddPicker-DWTgjKgo.js +101 -0
  63. package/dist/chunks/HandlersInput-p49STTn8.js +132 -0
  64. package/dist/chunks/IconDialogInput-C-81_L2n.js +105 -0
  65. package/dist/chunks/IconInput-D2Gy7Hvf.js +182 -0
  66. package/dist/chunks/IconMainTab-CNrVjDWP.js +26 -0
  67. package/dist/chunks/IconPickerPanel-BjNOlCh6.js +670 -0
  68. package/dist/chunks/ImageMainTab-C4O7RjX0.js +66 -0
  69. package/dist/chunks/ImageSettingsPanel-dvOmGg3C.js +485 -0
  70. package/dist/chunks/LayoutPresetPanel-CNAVAcvw.js +81 -0
  71. package/dist/chunks/LayoutPresetSlot-BqMTdE33.js +16 -0
  72. package/dist/chunks/LinkMainTab-BfFZx0AU.js +13 -0
  73. package/dist/chunks/ListEditor-mD-CmRNE.js +178 -0
  74. package/dist/chunks/Map.render-DFkmncHz.js +82 -0
  75. package/dist/chunks/MapLeaflet-DOfmZ3Pk.js +6588 -0
  76. package/dist/chunks/MapMainTab-CxI7IS1_.js +165 -0
  77. package/dist/chunks/MapPoint.render-0OAfCZTp.js +16 -0
  78. package/dist/chunks/MapPointMainTab-CmLcaSR5.js +60 -0
  79. package/dist/chunks/MediaInput-DHs3D8TJ.js +672 -0
  80. package/dist/chunks/MediaManagerModal-Dc5PK3dn.js +240 -0
  81. package/dist/chunks/MiniPreviewTile-B4zxTj9Y.js +32 -0
  82. package/dist/chunks/ModifierChipList-CwsWklih.js +33 -0
  83. package/dist/chunks/ModifiersAddPicker-D-vSYw7O.js +74 -0
  84. package/dist/chunks/ModifiersPickerPanel-CTefidBx.js +243 -0
  85. package/dist/chunks/NodeAiContextInputPopover-D5bn5o_T.js +66 -0
  86. package/dist/chunks/NodeAiContextPanel-Bx4rcjiM.js +81 -0
  87. package/dist/chunks/NumberSettingsPanel-DASi_l6V.js +56 -0
  88. package/dist/chunks/PageSettingsModal-D6o450IR.js +2678 -0
  89. package/dist/chunks/PatternInputPopover-qMWBv_nl.js +100 -0
  90. package/dist/chunks/PatternPanel-D2fgWDd-.js +352 -0
  91. package/dist/chunks/PeekTargetButton-ClrJX7zh.js +26 -0
  92. package/dist/chunks/PermissionsSection-DwobrV40.js +82 -0
  93. package/dist/chunks/PresetAddChildList-D6a0xdt8.js +35 -0
  94. package/dist/chunks/PropertiesInput-9O39ngbb.js +125 -0
  95. package/dist/chunks/PropertiesPanel-DO0RlalO.js +76 -0
  96. package/dist/chunks/SaveModifierPanel-B6mjKyrT.js +130 -0
  97. package/dist/chunks/ScrollEffectEditorPanel-CllGUhui.js +26 -0
  98. package/dist/chunks/SearchInput-DRUztbM0.js +76 -0
  99. package/dist/chunks/SearchableMenuPopover-DZKVXiEl.js +1251 -0
  100. package/dist/chunks/SlotRenderer-CaLf_2_C.js +38 -0
  101. package/dist/chunks/StateBindingEditorPanel-DKdcG5py.js +101 -0
  102. package/dist/chunks/StateBindingsAddPicker-DxMNAWAD.js +91 -0
  103. package/dist/chunks/StateBindingsInput-iWiqvAVB.js +103 -0
  104. package/dist/chunks/TailwindInput-660FZtyK.js +24 -0
  105. package/dist/chunks/TextEditor-B2O7DlN8.js +22032 -0
  106. package/dist/chunks/TextMainTab-B5udsXsk.js +260 -0
  107. package/dist/chunks/TextStyleEditorPanel-GRNPGzUL.js +381 -0
  108. package/dist/chunks/TextStylePickerPanel-l108SmGQ.js +140 -0
  109. package/dist/chunks/TextareaSettingsPanel-C1rQuF1O.js +50 -0
  110. package/dist/chunks/TokenPicker-Q0LToF_p.js +291 -0
  111. package/dist/chunks/ToolbarDashedButton-DbUxGmDg.js +23 -0
  112. package/dist/chunks/TransformEditorPanel-BGwyznZ6.js +26 -0
  113. package/dist/chunks/TransitionEditorPanel-BSvk58Ow.js +26 -0
  114. package/dist/chunks/TypographyPresetInput-DqnGSgR2.js +296 -0
  115. package/dist/chunks/ValidationPanel-CmA9SfoF.js +56 -0
  116. package/dist/chunks/Video.render-Dg6xvis4.js +21 -0
  117. package/dist/chunks/VideoMainTab-v5UFhUm-.js +174 -0
  118. package/dist/chunks/YouTube.esm-EbHnLU1Z.js +744 -0
  119. package/dist/chunks/dialogAtoms-CeQ2G05l.js +59 -0
  120. package/dist/chunks/extends-hS2Bh-Yp.js +12 -0
  121. package/dist/chunks/formatStorage-C3o2s3dk.js +22 -0
  122. package/dist/chunks/googleFonts-Dj4AntNi.js +323 -0
  123. package/dist/chunks/helpers-Cll72tMn.js +18 -0
  124. package/dist/chunks/index-B-GJd039.js +2875 -0
  125. package/dist/chunks/index-C66dAl3Q.js +32177 -0
  126. package/dist/chunks/index.esm-mqFx3NOs.js +644 -0
  127. package/dist/chunks/popoverOpenRequestAtom-hBS_siXv.js +22 -0
  128. package/dist/chunks/propertyRegistry-CMhVNOgl.js +38 -0
  129. package/dist/chunks/resolveAnchorsViaCraft-Cixm6ZyJ.js +31 -0
  130. package/dist/chunks/toolboxUtils-DjTMslSn.js +370 -0
  131. package/dist/chunks/uiPrimitives-BtohldWg.js +15 -0
  132. package/dist/chunks/use-event-listener-DO3Sk7g0.js +15 -0
  133. package/dist/chunks/useElementPicker-DoNuXNMQ.js +41 -0
  134. package/dist/chunks/useLayoutPreset-wOMV5YnO.js +528 -0
  135. package/dist/chunks/useMediaManager-CmKDbFfw.js +4629 -0
  136. package/dist/chunks/usePopoverAutoOpen-CxIjt0ez.js +25 -0
  137. package/dist/chunks/usePopoverPosition-83Vti7Aw.js +15 -0
  138. package/dist/render/static/index.js +9 -0
  139. package/package.json +22 -13
  140. package/dist/pagehub-viewer.umd.cjs +0 -574
  141. package/dist/pagehub.umd.cjs +0 -1130
@@ -0,0 +1,2678 @@
1
+ import { jsxs as c, jsx as e } from "react/jsx-runtime";
2
+ import { useEditor as ee } from "@craftjs/core";
3
+ import Re, { useState as P, useMemo as E, useRef as O, useEffect as R, useCallback as H } from "react";
4
+ import { c as Ee, d as Oe, s as fe } from "./useMediaManager-CmKDbFfw.js";
5
+ import { P as Ue, aA as Ie, al as De, G as $, u as qe, b$ as He, _ as _e, aR as Me, dd as Ve, dm as ze, a0 as ye, aB as j, de as $e, R as je, bY as ke, bV as ve, ca as xe, Q as te, ct as Be, dp as Ne, fj as we, c5 as Ge, fk as Je, aF as We, fl as Ke, fm as Qe, fn as Ye, di as Xe, a_ as X, fo as Ze, fp as et, bZ as tt, dJ as at } from "./index-C66dAl3Q.js";
6
+ import { M as nt, S as rt } from "./MediaManagerModal-Dc5PK3dn.js";
7
+ import { u as lt } from "./useElementPicker-DoNuXNMQ.js";
8
+ import { b as st, d as it } from "./ConditionsInput-B_5Nge8o.js";
9
+ import { T as de } from "./ToolbarDashedButton-DbUxGmDg.js";
10
+ import { C as ot } from "./CodeEditor-axBXmPH8.js";
11
+ import { createPortal as dt } from "react-dom";
12
+ import { a as ct } from "./FloatingPanel-DJP5Vhua.js";
13
+ import { ROOT_NODE as ce } from "@craftjs/utils";
14
+ function ut(t, a = []) {
15
+ const n = /* @__PURE__ */ new Set(), l = [], o = (i, p) => {
16
+ var u;
17
+ for (const h of i) {
18
+ const r = (u = h == null ? void 0 : h.key) == null ? void 0 : u.trim();
19
+ r && (n.has(r) || (n.add(r), l.push({ tab: h, source: p, index: l.length })));
20
+ }
21
+ };
22
+ return o(t, "built-in"), o(a, "injected"), l.sort((i, p) => {
23
+ const u = Number.isFinite(i.tab.order) ? i.tab.order : 1e3, h = Number.isFinite(p.tab.order) ? p.tab.order : 1e3;
24
+ return u !== h ? u - h : i.index - p.index;
25
+ }).map((i) => i.tab);
26
+ }
27
+ function pt(t, a) {
28
+ return t.filter((n) => n.isVisible ? n.isVisible(a) : !0);
29
+ }
30
+ const mt = "input w-full placeholder:text-neutral-content", ht = "select w-full", Ce = "textarea w-full min-h-[4.5rem] resize-y placeholder:text-neutral-content";
31
+ function gt(t) {
32
+ return t.map((a) => ({
33
+ key: a.key,
34
+ label: a.label,
35
+ order: Number.isFinite(a.order) ? a.order : 350,
36
+ render: (n) => a.render({
37
+ inputClass: n.inputClass,
38
+ selectClass: n.selectClass,
39
+ query: n.query,
40
+ actions: n.actions,
41
+ pageId: n.pageId,
42
+ allowCustom404Page: n.allowCustom404Page,
43
+ draft: n.draft,
44
+ setDraft: n.setDraft,
45
+ updateField: (l, o) => n.updateField(l, o),
46
+ requestSave: n.requestSave,
47
+ flushSave: n.flushSave
48
+ }),
49
+ onSave: (n) => {
50
+ var l;
51
+ return (l = a.onSave) == null ? void 0 : l.call(a, {
52
+ pageId: n.pageId,
53
+ setProp: n.setProp,
54
+ draft: n.draft,
55
+ query: n.query,
56
+ actions: n.actions
57
+ });
58
+ }
59
+ }));
60
+ }
61
+ const q = "mx-auto flex w-full max-w-3xl flex-col gap-6", bt = "flex w-full flex-1 flex-col gap-4 min-h-0";
62
+ function I({ title: t, description: a }) {
63
+ return /* @__PURE__ */ c("header", { className: "space-y-1.5", children: [
64
+ /* @__PURE__ */ e("h2", { className: "text-base-content text-lg font-semibold tracking-tight", children: t }),
65
+ /* @__PURE__ */ e("p", { className: "text-neutral-content text-sm leading-relaxed", children: a })
66
+ ] });
67
+ }
68
+ function L({
69
+ title: t,
70
+ children: a,
71
+ className: n = "",
72
+ variant: l = "section"
73
+ }) {
74
+ return l === "card" ? /* @__PURE__ */ c(
75
+ "section",
76
+ {
77
+ className: `border-base-300 bg-base-200/25 rounded-xl border p-5 shadow-sm ${n}`.trim(),
78
+ children: [
79
+ t ? /* @__PURE__ */ e("h3", { className: "text-base-content mb-4 text-base font-semibold tracking-tight", children: t }) : null,
80
+ /* @__PURE__ */ e("div", { className: "space-y-4", children: a })
81
+ ]
82
+ }
83
+ ) : /* @__PURE__ */ c(
84
+ "section",
85
+ {
86
+ className: `border-base-300 border-t pt-6 first-of-type:border-t-0 first-of-type:pt-0 ${n}`.trim(),
87
+ children: [
88
+ t ? /* @__PURE__ */ e("h3", { className: "text-base-content mb-4 text-base font-semibold tracking-tight", children: t }) : null,
89
+ /* @__PURE__ */ e("div", { className: "space-y-4", children: a })
90
+ ]
91
+ }
92
+ );
93
+ }
94
+ function N({
95
+ label: t,
96
+ htmlFor: a,
97
+ hint: n,
98
+ variable: l,
99
+ children: o
100
+ }) {
101
+ return /* @__PURE__ */ c("div", { className: "space-y-2", children: [
102
+ /* @__PURE__ */ c("div", { className: "flex items-center justify-between gap-3", children: [
103
+ /* @__PURE__ */ e(
104
+ "label",
105
+ {
106
+ htmlFor: a,
107
+ className: "text-base-content block text-sm font-semibold tracking-tight",
108
+ children: t
109
+ }
110
+ ),
111
+ l ? /* @__PURE__ */ e(ft, { variable: l }) : null
112
+ ] }),
113
+ o,
114
+ n ? /* @__PURE__ */ e("p", { className: "text-neutral-content text-xs leading-relaxed", children: n }) : null
115
+ ] });
116
+ }
117
+ function ft({ variable: t }) {
118
+ const [a, n] = P(!1), l = `{{${t}}}`;
119
+ return /* @__PURE__ */ c(
120
+ "button",
121
+ {
122
+ type: "button",
123
+ onClick: async () => {
124
+ try {
125
+ await navigator.clipboard.writeText(l), n(!0), setTimeout(() => n(!1), 1500);
126
+ } catch {
127
+ }
128
+ },
129
+ "data-tooltip-id": Ue,
130
+ "data-tooltip-content": a ? "Copied" : "Click to copy",
131
+ className: "border-base-300 bg-base-200 text-neutral-content hover:border-primary hover:text-base-content flex max-w-[60%] min-w-0 items-center gap-1 rounded-md border px-2 py-0.5 font-mono text-xs transition-colors",
132
+ children: [
133
+ a ? /* @__PURE__ */ e(Ie, { className: "text-success size-3 shrink-0" }) : /* @__PURE__ */ e(De, { className: "size-3 shrink-0" }),
134
+ /* @__PURE__ */ e("span", { className: "min-w-0 truncate", children: l })
135
+ ]
136
+ }
137
+ );
138
+ }
139
+ function Se({
140
+ icon: t,
141
+ title: a,
142
+ children: n
143
+ }) {
144
+ return /* @__PURE__ */ e("aside", { className: "border-base-300 bg-base-200/35 rounded-xl border p-4", children: /* @__PURE__ */ c("div", { className: "flex gap-3", children: [
145
+ t ? /* @__PURE__ */ e("span", { className: "text-primary mt-0.5 shrink-0 [&>svg]:size-5", "aria-hidden": !0, children: t }) : null,
146
+ /* @__PURE__ */ c("div", { className: "min-w-0 space-y-1 text-sm leading-relaxed", children: [
147
+ a ? /* @__PURE__ */ e("p", { className: "text-base-content font-semibold", children: a }) : null,
148
+ /* @__PURE__ */ e("div", { className: "text-neutral-content", children: n })
149
+ ] })
150
+ ] }) });
151
+ }
152
+ function yt() {
153
+ return [];
154
+ }
155
+ function kt({
156
+ inputClass: t,
157
+ selectClass: a,
158
+ conditionGroups: n,
159
+ setConditionGroups: l,
160
+ pageConditionFailAction: o,
161
+ setPageConditionFailAction: i,
162
+ pageConditionRedirectUrl: p,
163
+ setPageConditionRedirectUrl: u,
164
+ pageConditionFallbackPageId: h,
165
+ setPageConditionFallbackPageId: r,
166
+ pages: s
167
+ }) {
168
+ const g = lt("all"), d = Array.isArray(g) ? g : [], m = yt(), f = a, b = n != null && n.length ? n : [], S = (k, x) => {
169
+ const v = [...b];
170
+ v[k] = x, l(v);
171
+ }, w = (k) => {
172
+ l(b.filter((x, v) => v !== k));
173
+ }, F = () => {
174
+ l([...b, { conditions: [it("auth")], logic: "all" }]);
175
+ };
176
+ return /* @__PURE__ */ c("div", { className: q, children: [
177
+ /* @__PURE__ */ e(
178
+ I,
179
+ {
180
+ title: "Access",
181
+ description: "Gate this page behind auth, form state, or connector rules. With no conditions, the page stays public."
182
+ }
183
+ ),
184
+ /* @__PURE__ */ c(L, { title: "Conditions", children: [
185
+ b.length === 0 ? /* @__PURE__ */ e("p", { className: "text-neutral-content text-sm", children: "No conditions — everyone can view this page." }) : null,
186
+ b.map((k, x) => /* @__PURE__ */ c("div", { children: [
187
+ x > 0 ? /* @__PURE__ */ c("div", { className: "my-3 flex items-center gap-2", children: [
188
+ /* @__PURE__ */ e("div", { className: "bg-base-300 h-px flex-1" }),
189
+ /* @__PURE__ */ e("span", { className: "text-neutral-content text-[10px] font-bold tracking-wider uppercase", children: "Or" }),
190
+ /* @__PURE__ */ e("div", { className: "bg-base-300 h-px flex-1" })
191
+ ] }) : null,
192
+ /* @__PURE__ */ e(
193
+ st,
194
+ {
195
+ group: k,
196
+ groupIndex: x,
197
+ onChange: (v) => S(x, v),
198
+ onRemove: () => w(x),
199
+ formElements: d,
200
+ connectorOptions: m
201
+ }
202
+ )
203
+ ] }, x)),
204
+ /* @__PURE__ */ e("div", { className: "pt-1", children: b.length === 0 ? /* @__PURE__ */ e(de, { onClick: F, children: "Add condition" }) : /* @__PURE__ */ e(de, { onClick: F, icon: /* @__PURE__ */ e($, { size: 12 }), children: "Add condition group (OR)" }) })
205
+ ] }),
206
+ b.length > 0 ? /* @__PURE__ */ c(L, { title: "When access is denied", children: [
207
+ /* @__PURE__ */ e(N, { label: "Action", htmlFor: "page-condition-fail", children: /* @__PURE__ */ c(
208
+ "select",
209
+ {
210
+ id: "page-condition-fail",
211
+ value: o,
212
+ onChange: (k) => i(k.target.value),
213
+ className: f,
214
+ children: [
215
+ /* @__PURE__ */ e("option", { value: "", children: "Hide page content" }),
216
+ /* @__PURE__ */ e("option", { value: "redirect", children: "Redirect to URL" }),
217
+ /* @__PURE__ */ e("option", { value: "show-page", children: "Show another page" })
218
+ ]
219
+ }
220
+ ) }),
221
+ o === "redirect" ? /* @__PURE__ */ e(N, { label: "Redirect URL", htmlFor: "page-condition-redirect", children: /* @__PURE__ */ e(
222
+ "input",
223
+ {
224
+ id: "page-condition-redirect",
225
+ type: "text",
226
+ value: p,
227
+ onChange: (k) => u(k.target.value),
228
+ placeholder: "/login or https://…",
229
+ className: t
230
+ }
231
+ ) }) : null,
232
+ o === "show-page" ? /* @__PURE__ */ e(N, { label: "Fallback page", htmlFor: "page-condition-fallback", children: /* @__PURE__ */ c(
233
+ "select",
234
+ {
235
+ id: "page-condition-fallback",
236
+ value: h,
237
+ onChange: (k) => r(k.target.value),
238
+ className: f,
239
+ children: [
240
+ /* @__PURE__ */ e("option", { value: "", children: "Select a page…" }),
241
+ s.map((k) => /* @__PURE__ */ e("option", { value: k.id, children: k.name }, k.id))
242
+ ]
243
+ }
244
+ ) }) : null
245
+ ] }) : null
246
+ ] });
247
+ }
248
+ async function vt(t) {
249
+ const n = new TextEncoder().encode(t), l = await crypto.subtle.digest("SHA-256", n);
250
+ return Array.from(new Uint8Array(l)).map((i) => i.toString(16).padStart(2, "0")).join("");
251
+ }
252
+ const ue = "font-mono text-xs";
253
+ function xt({
254
+ inputClass: t,
255
+ canonicalUrl: a,
256
+ setCanonicalUrl: n,
257
+ bodyClass: l,
258
+ setBodyClass: o,
259
+ pagePassword: i,
260
+ setPagePassword: p,
261
+ hideHeader: u,
262
+ setHideHeader: h,
263
+ hideFooter: r,
264
+ setHideFooter: s,
265
+ hideChrome: g,
266
+ setHideChrome: d
267
+ }) {
268
+ const [m, f] = P(""), b = async () => {
269
+ if (!m.trim()) {
270
+ p("");
271
+ return;
272
+ }
273
+ const w = await vt(m.trim());
274
+ p(w), f("");
275
+ }, S = () => {
276
+ p(""), f("");
277
+ };
278
+ return /* @__PURE__ */ c("div", { className: q, children: [
279
+ /* @__PURE__ */ e(
280
+ I,
281
+ {
282
+ title: "Advanced",
283
+ description: "Canonical URL, body class, and password protection. Custom head code, JSON-LD schema, and theme overrides each have their own tab."
284
+ }
285
+ ),
286
+ /* @__PURE__ */ c(L, { title: "URLs and body", children: [
287
+ /* @__PURE__ */ e(
288
+ N,
289
+ {
290
+ label: "Canonical URL",
291
+ htmlFor: "canonical-url",
292
+ hint: "Leave empty to use the auto-generated canonical for this page.",
293
+ children: /* @__PURE__ */ e(
294
+ "input",
295
+ {
296
+ id: "canonical-url",
297
+ type: "text",
298
+ value: a,
299
+ onChange: (w) => n(w.target.value),
300
+ className: t,
301
+ placeholder: "https://…"
302
+ }
303
+ )
304
+ }
305
+ ),
306
+ /* @__PURE__ */ e(
307
+ N,
308
+ {
309
+ label: "Body class",
310
+ htmlFor: "body-class",
311
+ hint: "Extra classes on the body element for this page only.",
312
+ children: /* @__PURE__ */ e(
313
+ "input",
314
+ {
315
+ id: "body-class",
316
+ type: "text",
317
+ value: l,
318
+ onChange: (w) => o(w.target.value),
319
+ className: `${t} ${ue}`,
320
+ placeholder: "e.g. dark overflow-hidden"
321
+ }
322
+ )
323
+ }
324
+ )
325
+ ] }),
326
+ /* @__PURE__ */ c(L, { title: "Site chrome", children: [
327
+ /* @__PURE__ */ c("p", { className: "text-neutral-content text-sm", children: [
328
+ "Hide the global header, footer, or all chrome on this page only. Use for ad landing pages or conversion-focused funnels. ",
329
+ /* @__PURE__ */ e("strong", { children: "Hide all chrome" }),
330
+ " also suppresses sticky CTAs, floating buttons, and mobile drawers — the right switch for Google Ads pages."
331
+ ] }),
332
+ /* @__PURE__ */ c("div", { className: "border-base-300 bg-base-200/20 flex items-center justify-between gap-3 rounded-xl border p-4", children: [
333
+ /* @__PURE__ */ c("div", { children: [
334
+ /* @__PURE__ */ e("p", { className: "text-base-content text-sm font-semibold", children: "Hide all chrome" }),
335
+ /* @__PURE__ */ e("p", { className: "text-neutral-content mt-1 text-xs", children: "Strip header, footer, and every other ROOT-level sibling. Supersedes hide header / hide footer." })
336
+ ] }),
337
+ /* @__PURE__ */ e(
338
+ "button",
339
+ {
340
+ type: "button",
341
+ onClick: () => d(!g),
342
+ className: `focus:ring-ring relative inline-flex h-6 w-11 shrink-0 items-center rounded-full transition-colors focus:ring-2 focus:ring-offset-2 focus:outline-none ${g ? "bg-primary" : "bg-base-300"}`,
343
+ "aria-pressed": g,
344
+ children: /* @__PURE__ */ e(
345
+ "span",
346
+ {
347
+ className: `bg-base-100 inline-block size-4 rounded-full transition-transform ${g ? "translate-x-6" : "translate-x-1"}`
348
+ }
349
+ )
350
+ }
351
+ )
352
+ ] }),
353
+ /* @__PURE__ */ c("div", { className: "grid gap-4 md:grid-cols-2", children: [
354
+ /* @__PURE__ */ c("div", { className: "border-base-300 bg-base-200/20 flex items-center justify-between gap-3 rounded-xl border p-4", children: [
355
+ /* @__PURE__ */ c("div", { children: [
356
+ /* @__PURE__ */ e("p", { className: "text-base-content text-sm font-semibold", children: "Hide header" }),
357
+ /* @__PURE__ */ e("p", { className: "text-neutral-content mt-1 text-xs", children: "Suppress the site header on this page." })
358
+ ] }),
359
+ /* @__PURE__ */ e(
360
+ "button",
361
+ {
362
+ type: "button",
363
+ onClick: () => h(!u),
364
+ className: `focus:ring-ring relative inline-flex h-6 w-11 shrink-0 items-center rounded-full transition-colors focus:ring-2 focus:ring-offset-2 focus:outline-none ${u ? "bg-primary" : "bg-base-300"}`,
365
+ "aria-pressed": u,
366
+ children: /* @__PURE__ */ e(
367
+ "span",
368
+ {
369
+ className: `bg-base-100 inline-block size-4 rounded-full transition-transform ${u ? "translate-x-6" : "translate-x-1"}`
370
+ }
371
+ )
372
+ }
373
+ )
374
+ ] }),
375
+ /* @__PURE__ */ c("div", { className: "border-base-300 bg-base-200/20 flex items-center justify-between gap-3 rounded-xl border p-4", children: [
376
+ /* @__PURE__ */ c("div", { children: [
377
+ /* @__PURE__ */ e("p", { className: "text-base-content text-sm font-semibold", children: "Hide footer" }),
378
+ /* @__PURE__ */ e("p", { className: "text-neutral-content mt-1 text-xs", children: "Suppress the site footer on this page." })
379
+ ] }),
380
+ /* @__PURE__ */ e(
381
+ "button",
382
+ {
383
+ type: "button",
384
+ onClick: () => s(!r),
385
+ className: `focus:ring-ring relative inline-flex h-6 w-11 shrink-0 items-center rounded-full transition-colors focus:ring-2 focus:ring-offset-2 focus:outline-none ${r ? "bg-primary" : "bg-base-300"}`,
386
+ "aria-pressed": r,
387
+ children: /* @__PURE__ */ e(
388
+ "span",
389
+ {
390
+ className: `bg-base-100 inline-block size-4 rounded-full transition-transform ${r ? "translate-x-6" : "translate-x-1"}`
391
+ }
392
+ )
393
+ }
394
+ )
395
+ ] })
396
+ ] })
397
+ ] }),
398
+ /* @__PURE__ */ c(L, { title: "Password protection", children: [
399
+ i ? /* @__PURE__ */ c("div", { className: "flex flex-wrap items-center gap-2", children: [
400
+ /* @__PURE__ */ e(
401
+ "span",
402
+ {
403
+ className: `${t} text-neutral-content flex-1 truncate ${ue} py-2 text-xs`,
404
+ children: "Protected (SHA-256)"
405
+ }
406
+ ),
407
+ /* @__PURE__ */ e("button", { type: "button", onClick: S, className: "btn btn-ghost btn-sm", children: "Remove" })
408
+ ] }) : /* @__PURE__ */ c("div", { className: "flex flex-wrap items-end gap-2", children: [
409
+ /* @__PURE__ */ e("div", { className: "min-w-0 flex-1", children: /* @__PURE__ */ e(N, { label: "Set password", htmlFor: "page-password-inline", children: /* @__PURE__ */ e(
410
+ "input",
411
+ {
412
+ id: "page-password-inline",
413
+ type: "password",
414
+ value: m,
415
+ onChange: (w) => f(w.target.value),
416
+ onKeyDown: (w) => w.key === "Enter" && void b(),
417
+ className: t,
418
+ placeholder: "Page password"
419
+ }
420
+ ) }) }),
421
+ /* @__PURE__ */ e(
422
+ "button",
423
+ {
424
+ type: "button",
425
+ onClick: () => void b(),
426
+ className: "btn btn-primary btn-sm shrink-0",
427
+ disabled: !m.trim(),
428
+ children: "Set"
429
+ }
430
+ )
431
+ ] }),
432
+ /* @__PURE__ */ e("p", { className: "text-neutral-content text-xs", children: "Only a SHA-256 hash is stored — not the raw password." })
433
+ ] })
434
+ ] });
435
+ }
436
+ function Nt({ className: t }) {
437
+ return /* @__PURE__ */ c("div", { role: "status", children: [
438
+ /* @__PURE__ */ c(
439
+ "svg",
440
+ {
441
+ "aria-hidden": "true",
442
+ className: `fill-neutral-content text-neutral-content size-6 animate-spin ${t || ""}`,
443
+ viewBox: "0 0 100 101",
444
+ fill: "none",
445
+ xmlns: "http://www.w3.org/2000/svg",
446
+ children: [
447
+ /* @__PURE__ */ e(
448
+ "path",
449
+ {
450
+ d: "M100 50.5908C100 78.2051 77.6142 100.591 50 100.591C22.3858 100.591 0 78.2051 0 50.5908C0 22.9766 22.3858 0.59082 50 0.59082C77.6142 0.59082 100 22.9766 100 50.5908ZM9.08144 50.5908C9.08144 73.1895 27.4013 91.5094 50 91.5094C72.5987 91.5094 90.9186 73.1895 90.9186 50.5908C90.9186 27.9921 72.5987 9.67226 50 9.67226C27.4013 9.67226 9.08144 27.9921 9.08144 50.5908Z",
451
+ fill: "currentColor"
452
+ }
453
+ ),
454
+ /* @__PURE__ */ e(
455
+ "path",
456
+ {
457
+ d: "M93.9676 39.0409C96.393 38.4038 97.8624 35.9116 97.0079 33.5539C95.2932 28.8227 92.871 24.3692 89.8167 20.348C85.8452 15.1192 80.8826 10.7238 75.2124 7.41289C69.5422 4.10194 63.2754 1.94025 56.7698 1.05124C51.7666 0.367541 46.6976 0.446843 41.7345 1.27873C39.2613 1.69328 37.813 4.19778 38.4501 6.62326C39.0873 9.04874 41.5694 10.4717 44.0505 10.1071C47.8511 9.54855 51.7191 9.52689 55.5402 10.0491C60.8642 10.7766 65.9928 12.5457 70.6331 15.2552C75.2735 17.9648 79.3347 21.5619 82.5849 25.841C84.9175 28.9121 86.7997 32.2913 88.1811 35.8758C89.083 38.2158 91.5421 39.6781 93.9676 39.0409Z",
458
+ fill: "currentFill"
459
+ }
460
+ )
461
+ ]
462
+ }
463
+ ),
464
+ /* @__PURE__ */ e("span", { className: "sr-only", children: "Loading..." })
465
+ ] });
466
+ }
467
+ const wt = (t, a) => {
468
+ var o, i;
469
+ const n = [], l = [];
470
+ for (let p = 0; p < ((i = (o = t.target) == null ? void 0 : o.files) == null ? void 0 : i.length); p++) {
471
+ const u = t.target.files[p];
472
+ l.push(u);
473
+ }
474
+ return a(n), l;
475
+ }, Ct = async (t, a, n) => {
476
+ const l = [];
477
+ for (const o of t)
478
+ try {
479
+ const { mediaId: i } = await Ee(o);
480
+ l.push(i);
481
+ } catch (i) {
482
+ const p = i instanceof Oe ? i.message : `Failed to upload ${o.name}`;
483
+ n([{ error: p, file: o }]);
484
+ }
485
+ return l;
486
+ }, ae = ({
487
+ value: t,
488
+ onChange: a,
489
+ label: n = "Upload Image",
490
+ help: l
491
+ }) => {
492
+ const { query: o } = ee(), [i, p] = P([]), [u, h] = P(!1), [r, s] = P(!1), [g, d] = P(!0), [m, f] = P(!1), b = qe(He);
493
+ let S;
494
+ const w = async (T) => {
495
+ S && clearTimeout(S), s(!1), p([]), h(!0), d(!1);
496
+ const C = wt(T, p);
497
+ if (C.length) {
498
+ const U = await Ct(C, b, p);
499
+ U.length > 0 && a(U[0]);
500
+ }
501
+ h(!1), d(!0), s(!0), S = setTimeout(() => {
502
+ s(!1);
503
+ }, 3e3);
504
+ }, F = (T) => {
505
+ T && (a(T), f(!1), s(!0), setTimeout(() => s(!1), 2e3));
506
+ }, k = () => {
507
+ a("");
508
+ };
509
+ let x = n;
510
+ u && (x = "Uploading"), r && (x = "Saved"), i.length && (x = "Error");
511
+ const { pageMedia: v } = E(() => _e(o), [o]), A = !!t, y = A ? Me(v, t) : null;
512
+ return /* @__PURE__ */ c("div", { className: "space-y-2", children: [
513
+ /* @__PURE__ */ c("div", { className: "flex gap-2", children: [
514
+ /* @__PURE__ */ c(
515
+ "label",
516
+ {
517
+ htmlFor: `file-upload-${n}`,
518
+ className: `btn btn-outline flex-1 ${i.length ? "btn-error" : r ? "btn-secondary" : u ? "btn-primary" : "border-base-300 hover:border-primary"} ${g ? "" : "btn-disabled"}`,
519
+ children: [
520
+ u ? /* @__PURE__ */ e(Nt, {}) : i.length ? /* @__PURE__ */ e(Ve, { className: "size-4" }) : /* @__PURE__ */ e(ze, { className: "size-4" }),
521
+ /* @__PURE__ */ e("span", { children: x }),
522
+ /* @__PURE__ */ e(
523
+ "input",
524
+ {
525
+ id: `file-upload-${n}`,
526
+ type: "file",
527
+ onChange: w,
528
+ disabled: !g,
529
+ accept: "image/png,image/jpeg,image/jpg,image/gif,image/webp,image/avif,image/svg+xml",
530
+ className: "hidden"
531
+ }
532
+ )
533
+ ]
534
+ }
535
+ ),
536
+ /* @__PURE__ */ c(
537
+ "button",
538
+ {
539
+ type: "button",
540
+ onClick: () => f(!0),
541
+ className: "btn btn-outline border-base-300 hover:border-primary",
542
+ children: [
543
+ /* @__PURE__ */ e(ye, { className: "size-4" }),
544
+ /* @__PURE__ */ e("span", { children: "Browse" })
545
+ ]
546
+ }
547
+ ),
548
+ A && /* @__PURE__ */ e(
549
+ "button",
550
+ {
551
+ type: "button",
552
+ onClick: k,
553
+ className: "btn btn-outline btn-error btn-square",
554
+ "aria-label": "Remove image",
555
+ children: /* @__PURE__ */ e(j, { className: "size-4" })
556
+ }
557
+ )
558
+ ] }),
559
+ l && /* @__PURE__ */ e("p", { className: "text-neutral-content text-xs", children: l }),
560
+ i.length > 0 && /* @__PURE__ */ e("div", { className: "text-error text-sm", children: i.map((T, C) => /* @__PURE__ */ e("div", { children: T.error }, C)) }),
561
+ A && y && /* @__PURE__ */ e("div", { className: "bg-neutral text-neutral-content relative h-48 w-full overflow-hidden rounded-lg", children: /* @__PURE__ */ e("img", { src: y, alt: "Preview", className: "size-full object-cover" }) }),
562
+ /* @__PURE__ */ e(
563
+ nt,
564
+ {
565
+ isOpen: m,
566
+ onClose: () => f(!1),
567
+ onSelect: F,
568
+ selectionMode: !0
569
+ }
570
+ )
571
+ ] });
572
+ }, St = "disabled:cursor-not-allowed disabled:border-base-300/50 disabled:bg-base-300/30 disabled:text-neutral-content/70";
573
+ function Tt({
574
+ inputClass: t,
575
+ pageName: a,
576
+ onPageNameChange: n,
577
+ pageSlug: l,
578
+ onSlugChange: o,
579
+ isHomePage: i,
580
+ setIsHomePage: p,
581
+ is404Page: u,
582
+ setIs404Page: h,
583
+ allowCustom404Page: r,
584
+ pageImage: s,
585
+ setPageImage: g,
586
+ showDeleteConfirm: d,
587
+ setShowDeleteConfirm: m,
588
+ onDeletePage: f
589
+ }) {
590
+ return /* @__PURE__ */ c("div", { className: q, children: [
591
+ /* @__PURE__ */ e(
592
+ I,
593
+ {
594
+ title: "Page basics",
595
+ description: "Name, URL, featured image, and whether this canvas is your home or custom 404 page."
596
+ }
597
+ ),
598
+ /* @__PURE__ */ e(L, { title: "Name and URL", children: /* @__PURE__ */ c("div", { className: "grid gap-4 sm:grid-cols-2", children: [
599
+ /* @__PURE__ */ e(N, { label: "Page name", htmlFor: "page-name", children: /* @__PURE__ */ e(
600
+ "input",
601
+ {
602
+ id: "page-name",
603
+ type: "text",
604
+ value: a,
605
+ onChange: (b) => n(b.target.value),
606
+ className: t,
607
+ placeholder: "Enter page name"
608
+ }
609
+ ) }),
610
+ /* @__PURE__ */ e(
611
+ N,
612
+ {
613
+ label: "URL slug",
614
+ htmlFor: "page-slug",
615
+ hint: i ? "Home uses / — no slug." : "Path segment after your domain.",
616
+ children: /* @__PURE__ */ c("div", { className: "flex items-center gap-2", children: [
617
+ /* @__PURE__ */ e("span", { className: "text-neutral-content shrink-0 text-sm", children: "/" }),
618
+ /* @__PURE__ */ e(
619
+ "input",
620
+ {
621
+ id: "page-slug",
622
+ type: "text",
623
+ value: i ? "" : l,
624
+ onChange: (b) => o(b.target.value),
625
+ disabled: i,
626
+ className: `${t} min-w-0 flex-1 ${St}`,
627
+ placeholder: i ? "home" : "page-url"
628
+ }
629
+ )
630
+ ] })
631
+ }
632
+ )
633
+ ] }) }),
634
+ /* @__PURE__ */ e(L, { title: "Featured image", children: /* @__PURE__ */ e(
635
+ ae,
636
+ {
637
+ value: s,
638
+ onChange: g,
639
+ label: "Upload image",
640
+ help: "Used as this page’s featured image where the theme expects one."
641
+ }
642
+ ) }),
643
+ /* @__PURE__ */ e(L, { title: "Behavior", children: /* @__PURE__ */ c("div", { className: "grid gap-4 md:grid-cols-2", children: [
644
+ /* @__PURE__ */ c("div", { className: "border-base-300 bg-base-200/20 flex flex-col justify-between gap-3 rounded-xl border p-4", children: [
645
+ /* @__PURE__ */ c("div", { children: [
646
+ /* @__PURE__ */ e("p", { className: "text-base-content text-sm font-semibold", children: "Home page" }),
647
+ /* @__PURE__ */ e("p", { className: "text-neutral-content mt-1 text-xs", children: "Serve this canvas at the site root (/)." })
648
+ ] }),
649
+ /* @__PURE__ */ e(
650
+ "button",
651
+ {
652
+ type: "button",
653
+ onClick: () => p(!i),
654
+ className: `focus:ring-ring relative ml-auto inline-flex h-6 w-11 shrink-0 items-center rounded-full transition-colors focus:ring-2 focus:ring-offset-2 focus:outline-none ${i ? "bg-primary" : "bg-base-300"}`,
655
+ "aria-pressed": i,
656
+ children: /* @__PURE__ */ e(
657
+ "span",
658
+ {
659
+ className: `bg-base-100 inline-block size-4 rounded-full transition-transform ${i ? "translate-x-6" : "translate-x-1"}`
660
+ }
661
+ )
662
+ }
663
+ )
664
+ ] }),
665
+ /* @__PURE__ */ c(
666
+ "div",
667
+ {
668
+ className: `border-base-300 bg-base-200/20 flex flex-col justify-between gap-3 rounded-xl border p-4 ${r ? "" : "opacity-85"}`,
669
+ children: [
670
+ /* @__PURE__ */ c("div", { className: "flex w-full items-start justify-between gap-3", children: [
671
+ /* @__PURE__ */ c("div", { children: [
672
+ /* @__PURE__ */ e("p", { className: "text-base-content text-sm font-semibold", children: "404 page" }),
673
+ /* @__PURE__ */ e("p", { className: "text-neutral-content mt-1 text-xs", children: r ? "Show this page when no other URL matches." : "Available on paid plans — custom page for unknown links." })
674
+ ] }),
675
+ r ? /* @__PURE__ */ e(
676
+ "button",
677
+ {
678
+ type: "button",
679
+ onClick: () => h(!u),
680
+ className: `focus:ring-ring relative inline-flex h-6 w-11 shrink-0 items-center rounded-full transition-colors focus:ring-2 focus:ring-offset-2 focus:outline-none ${u ? "bg-primary" : "bg-base-300"}`,
681
+ "aria-pressed": u,
682
+ children: /* @__PURE__ */ e(
683
+ "span",
684
+ {
685
+ className: `bg-base-100 inline-block size-4 rounded-full transition-transform ${u ? "translate-x-6" : "translate-x-1"}`
686
+ }
687
+ )
688
+ }
689
+ ) : null
690
+ ] }),
691
+ r ? null : /* @__PURE__ */ e($e, { href: "/pricing", className: "text-primary text-sm font-medium hover:underline", children: "View plans" })
692
+ ]
693
+ }
694
+ )
695
+ ] }) }),
696
+ /* @__PURE__ */ c(L, { title: "Danger zone", variant: "card", className: "border-error/25 bg-error/5", children: [
697
+ /* @__PURE__ */ e("p", { className: "text-neutral-content text-sm", children: "Deleting a page cannot be undone. Linked navigation and published URLs may break." }),
698
+ d ? /* @__PURE__ */ c("div", { className: "space-y-3", children: [
699
+ /* @__PURE__ */ c("p", { className: "text-base-content text-sm", children: [
700
+ "Delete “",
701
+ a,
702
+ "”? This cannot be undone."
703
+ ] }),
704
+ /* @__PURE__ */ c("div", { className: "flex flex-wrap gap-2", children: [
705
+ /* @__PURE__ */ e(
706
+ "button",
707
+ {
708
+ type: "button",
709
+ onClick: () => m(!1),
710
+ className: "btn btn-ghost btn-sm",
711
+ children: "Cancel"
712
+ }
713
+ ),
714
+ /* @__PURE__ */ e("button", { type: "button", onClick: f, className: "btn btn-error btn-sm", children: "Yes, delete page" })
715
+ ] })
716
+ ] }) : /* @__PURE__ */ c(
717
+ "button",
718
+ {
719
+ type: "button",
720
+ onClick: () => m(!0),
721
+ className: "btn btn-outline btn-error btn-sm gap-2",
722
+ children: [
723
+ /* @__PURE__ */ e(j, { className: "size-4" }),
724
+ "Delete page"
725
+ ]
726
+ }
727
+ )
728
+ ] })
729
+ ] });
730
+ }
731
+ const Pt = Re.lazy(
732
+ () => import("./HTMLCodeInput-CCe4Bj5z.js").then((t) => ({ default: t.HTMLCodeInput }))
733
+ );
734
+ function Ft({ headCode: t, setHeadCode: a }) {
735
+ const { query: n } = ee(), l = E(() => je(n), [n]);
736
+ return /* @__PURE__ */ c("div", { className: bt, children: [
737
+ /* @__PURE__ */ e(
738
+ I,
739
+ {
740
+ title: "Custom head code",
741
+ description: "HTML injected into <head> for this page only. Use for verification meta tags, page-specific <style>, or one-off scripts."
742
+ }
743
+ ),
744
+ /* @__PURE__ */ e(
745
+ Pt,
746
+ {
747
+ value: t,
748
+ onChange: a,
749
+ height: "100%",
750
+ placeholder: `<script>…<\/script>
751
+ <link rel="stylesheet" href="…">`,
752
+ formatMountKey: "page-settings-head-code",
753
+ variableCompletionOptions: l,
754
+ className: "min-h-0 flex-1",
755
+ editorContainerClassName: "flex-1 min-h-0"
756
+ }
757
+ )
758
+ ] });
759
+ }
760
+ function At({
761
+ inputClass: t,
762
+ selectClass: a,
763
+ ogTitle: n,
764
+ setOgTitle: l,
765
+ ogDescription: o,
766
+ setOgDescription: i,
767
+ ogImage: p,
768
+ setOgImage: u,
769
+ ogType: h,
770
+ setOgType: r
771
+ }) {
772
+ return /* @__PURE__ */ c("div", { className: q, children: [
773
+ /* @__PURE__ */ e(
774
+ I,
775
+ {
776
+ title: "Open Graph",
777
+ description: "How this page previews when shared on Facebook, LinkedIn, Slack, iMessage, and most social platforms."
778
+ }
779
+ ),
780
+ /* @__PURE__ */ c(L, { title: "Share preview", children: [
781
+ /* @__PURE__ */ e(
782
+ N,
783
+ {
784
+ label: "Title",
785
+ htmlFor: "og-title",
786
+ hint: "Leave empty to reuse the SEO meta title.",
787
+ children: /* @__PURE__ */ e(
788
+ "input",
789
+ {
790
+ id: "og-title",
791
+ type: "text",
792
+ value: n,
793
+ onChange: (d) => l(d.target.value),
794
+ className: t,
795
+ placeholder: "Social title"
796
+ }
797
+ )
798
+ }
799
+ ),
800
+ /* @__PURE__ */ e(
801
+ N,
802
+ {
803
+ label: "Description",
804
+ htmlFor: "og-description",
805
+ hint: "Leave empty to reuse the SEO meta description.",
806
+ children: /* @__PURE__ */ e(
807
+ "textarea",
808
+ {
809
+ id: "og-description",
810
+ value: o,
811
+ onChange: (d) => i(d.target.value),
812
+ rows: 2,
813
+ className: Ce,
814
+ placeholder: "Social description"
815
+ }
816
+ )
817
+ }
818
+ ),
819
+ /* @__PURE__ */ e(N, { label: "Image", hint: "Recommended 1200×630px (1.91:1 ratio).", children: /* @__PURE__ */ e(ae, { value: p, onChange: u, label: "Upload OG image" }) }),
820
+ /* @__PURE__ */ e(N, { label: "Type", htmlFor: "og-type", children: /* @__PURE__ */ c(
821
+ "select",
822
+ {
823
+ id: "og-type",
824
+ value: h,
825
+ onChange: (d) => r(d.target.value),
826
+ className: a,
827
+ children: [
828
+ /* @__PURE__ */ e("option", { value: "website", children: "Website" }),
829
+ /* @__PURE__ */ e("option", { value: "article", children: "Article" }),
830
+ /* @__PURE__ */ e("option", { value: "product", children: "Product" }),
831
+ /* @__PURE__ */ e("option", { value: "profile", children: "Profile" })
832
+ ]
833
+ }
834
+ ) })
835
+ ] })
836
+ ] });
837
+ }
838
+ function Lt({ entry: t, onChange: a }) {
839
+ const n = E(() => {
840
+ var o;
841
+ const l = (o = t.json) == null ? void 0 : o.trim();
842
+ if (!l) return null;
843
+ try {
844
+ return JSON.parse(l), null;
845
+ } catch (i) {
846
+ return i instanceof Error ? i.message : "Invalid JSON";
847
+ }
848
+ }, [t.json]);
849
+ return /* @__PURE__ */ c("div", { className: "space-y-3", children: [
850
+ /* @__PURE__ */ c("p", { className: "text-neutral-content text-sm leading-relaxed", children: [
851
+ "Paste a complete JSON-LD object. Useful for schema types not in the builder, or hand-tuned snippets copied from",
852
+ " ",
853
+ /* @__PURE__ */ e(
854
+ "a",
855
+ {
856
+ href: "https://schema.org/docs/full.html",
857
+ target: "_blank",
858
+ rel: "noopener noreferrer",
859
+ className: "text-primary hover:underline",
860
+ children: "schema.org"
861
+ }
862
+ ),
863
+ "."
864
+ ] }),
865
+ /* @__PURE__ */ e(
866
+ ot,
867
+ {
868
+ value: t.json,
869
+ onChange: (l) => a({ ...t, json: l }),
870
+ language: "javascript",
871
+ height: "280px",
872
+ placeholder: `{
873
+ "@context": "https://schema.org",
874
+ "@type": "WebPage",
875
+ "name": "About"
876
+ }`
877
+ }
878
+ ),
879
+ n ? /* @__PURE__ */ e(Se, { title: "JSON error", children: /* @__PURE__ */ e("code", { className: "text-error font-mono text-xs", children: n }) }) : null
880
+ ] });
881
+ }
882
+ function V({
883
+ field: t,
884
+ value: a,
885
+ onChange: n,
886
+ inputClass: l,
887
+ depth: o = 0
888
+ }) {
889
+ var p;
890
+ const i = t.help ? /* @__PURE__ */ c("span", { children: [
891
+ t.required ? /* @__PURE__ */ e("span", { className: "text-error", children: "Required. " }) : null,
892
+ t.help
893
+ ] }) : t.required ? /* @__PURE__ */ e("span", { className: "text-error", children: "Required." }) : void 0;
894
+ switch (t.kind) {
895
+ case "text":
896
+ case "url":
897
+ return /* @__PURE__ */ e(N, { label: t.label, hint: i, children: /* @__PURE__ */ e(
898
+ "input",
899
+ {
900
+ type: t.kind === "url" ? "url" : "text",
901
+ value: a || "",
902
+ onChange: (u) => n(u.target.value),
903
+ className: l,
904
+ placeholder: t.placeholder
905
+ }
906
+ ) });
907
+ case "number":
908
+ return /* @__PURE__ */ e(N, { label: t.label, hint: i, children: /* @__PURE__ */ e(
909
+ "input",
910
+ {
911
+ type: "number",
912
+ value: a ?? "",
913
+ onChange: (u) => n(u.target.value === "" ? "" : Number(u.target.value)),
914
+ className: l,
915
+ placeholder: t.placeholder
916
+ }
917
+ ) });
918
+ case "date":
919
+ return /* @__PURE__ */ e(N, { label: t.label, hint: i, children: /* @__PURE__ */ e(
920
+ "input",
921
+ {
922
+ type: "date",
923
+ value: a || "",
924
+ onChange: (u) => n(u.target.value),
925
+ className: l
926
+ }
927
+ ) });
928
+ case "datetime":
929
+ return /* @__PURE__ */ e(N, { label: t.label, hint: i, children: /* @__PURE__ */ e(
930
+ "input",
931
+ {
932
+ type: "datetime-local",
933
+ value: a || "",
934
+ onChange: (u) => n(u.target.value),
935
+ className: l
936
+ }
937
+ ) });
938
+ case "textarea":
939
+ return /* @__PURE__ */ e(N, { label: t.label, hint: i, children: /* @__PURE__ */ e(
940
+ "textarea",
941
+ {
942
+ value: a || "",
943
+ onChange: (u) => n(u.target.value),
944
+ className: `${l} min-h-[80px] resize-y`,
945
+ placeholder: t.placeholder
946
+ }
947
+ ) });
948
+ case "select":
949
+ return /* @__PURE__ */ e(N, { label: t.label, hint: i, children: /* @__PURE__ */ c(
950
+ "select",
951
+ {
952
+ value: a || "",
953
+ onChange: (u) => n(u.target.value),
954
+ className: l,
955
+ children: [
956
+ /* @__PURE__ */ e("option", { value: "", children: "— Select —" }),
957
+ (p = t.options) == null ? void 0 : p.map((u) => /* @__PURE__ */ e("option", { value: u.value, children: u.label }, u.value))
958
+ ]
959
+ }
960
+ ) });
961
+ case "image":
962
+ return /* @__PURE__ */ e(N, { label: t.label, hint: i, children: /* @__PURE__ */ e(ae, { value: a || "", onChange: n, label: t.label }) });
963
+ case "nested":
964
+ return /* @__PURE__ */ e(
965
+ Rt,
966
+ {
967
+ field: t,
968
+ value: a || {},
969
+ onChange: n,
970
+ inputClass: l,
971
+ depth: o
972
+ }
973
+ );
974
+ case "list":
975
+ return /* @__PURE__ */ e(
976
+ Et,
977
+ {
978
+ field: t,
979
+ value: Array.isArray(a) ? a : [],
980
+ onChange: n,
981
+ inputClass: l,
982
+ depth: o
983
+ }
984
+ );
985
+ default:
986
+ return null;
987
+ }
988
+ }
989
+ function Rt({
990
+ field: t,
991
+ value: a,
992
+ onChange: n,
993
+ inputClass: l,
994
+ depth: o
995
+ }) {
996
+ const i = t.nested || [], p = (u, h) => n({ ...a, [u]: h });
997
+ return /* @__PURE__ */ c("div", { className: "space-y-2", children: [
998
+ /* @__PURE__ */ e("label", { className: "text-base-content block text-sm font-semibold tracking-tight", children: t.label }),
999
+ /* @__PURE__ */ e("div", { className: "border-base-300 bg-base-200/30 space-y-4 rounded-xl border p-4", children: i.map((u) => /* @__PURE__ */ e(
1000
+ V,
1001
+ {
1002
+ field: u,
1003
+ value: a == null ? void 0 : a[u.key],
1004
+ onChange: (h) => p(u.key, h),
1005
+ inputClass: l,
1006
+ depth: o + 1
1007
+ },
1008
+ u.key
1009
+ )) })
1010
+ ] });
1011
+ }
1012
+ function Et({
1013
+ field: t,
1014
+ value: a,
1015
+ onChange: n,
1016
+ inputClass: l,
1017
+ depth: o
1018
+ }) {
1019
+ const i = t.itemFields || [], p = i.length === 1 && i[0].key === "value" && i[0].kind !== "nested" && i[0].kind !== "list", u = () => {
1020
+ if (p) {
1021
+ n([...a, { value: "" }]);
1022
+ return;
1023
+ }
1024
+ const s = {};
1025
+ for (const g of i)
1026
+ g.kind === "list" ? s[g.key] = [] : g.kind === "nested" ? s[g.key] = {} : s[g.key] = "";
1027
+ n([...a, s]);
1028
+ }, h = (s) => n(a.filter((g, d) => d !== s)), r = (s, g) => {
1029
+ const d = a.slice();
1030
+ d[s] = g, n(d);
1031
+ };
1032
+ return /* @__PURE__ */ c("div", { className: "space-y-2", children: [
1033
+ /* @__PURE__ */ e("label", { className: "text-base-content block text-sm font-semibold tracking-tight", children: t.label }),
1034
+ t.help ? /* @__PURE__ */ e("p", { className: "text-neutral-content text-xs leading-relaxed", children: t.help }) : null,
1035
+ /* @__PURE__ */ e("div", { className: "space-y-3", children: a.map((s, g) => /* @__PURE__ */ c(
1036
+ "div",
1037
+ {
1038
+ className: "border-base-300 bg-base-200/30 relative rounded-xl border p-4",
1039
+ children: [
1040
+ /* @__PURE__ */ e(
1041
+ "button",
1042
+ {
1043
+ type: "button",
1044
+ onClick: () => h(g),
1045
+ className: "text-neutral-content hover:text-error absolute top-2 right-2 rounded-md p-1 transition-colors",
1046
+ "aria-label": `Remove ${t.itemLabel || "item"} ${g + 1}`,
1047
+ children: /* @__PURE__ */ e(ke, { className: "size-4" })
1048
+ }
1049
+ ),
1050
+ p ? /* @__PURE__ */ e(
1051
+ V,
1052
+ {
1053
+ field: i[0],
1054
+ value: s == null ? void 0 : s.value,
1055
+ onChange: (d) => r(g, { value: d }),
1056
+ inputClass: l,
1057
+ depth: o + 1
1058
+ }
1059
+ ) : /* @__PURE__ */ e("div", { className: "space-y-4 pr-6", children: i.map((d) => /* @__PURE__ */ e(
1060
+ V,
1061
+ {
1062
+ field: d,
1063
+ value: s == null ? void 0 : s[d.key],
1064
+ onChange: (m) => r(g, { ...s, [d.key]: m }),
1065
+ inputClass: l,
1066
+ depth: o + 1
1067
+ },
1068
+ d.key
1069
+ )) })
1070
+ ]
1071
+ },
1072
+ g
1073
+ )) }),
1074
+ /* @__PURE__ */ c(
1075
+ "button",
1076
+ {
1077
+ type: "button",
1078
+ onClick: u,
1079
+ className: "btn btn-outline btn-sm gap-2",
1080
+ children: [
1081
+ /* @__PURE__ */ e($, { className: "size-4" }),
1082
+ t.itemLabel || `Add ${t.label.toLowerCase()}`
1083
+ ]
1084
+ }
1085
+ )
1086
+ ] });
1087
+ }
1088
+ const K = [
1089
+ { key: "streetAddress", label: "Street address", kind: "text" },
1090
+ { key: "addressLocality", label: "City", kind: "text" },
1091
+ { key: "addressRegion", label: "State / region", kind: "text" },
1092
+ { key: "postalCode", label: "Postal code", kind: "text" },
1093
+ { key: "addressCountry", label: "Country code", kind: "text", placeholder: "US" }
1094
+ ], Ot = [
1095
+ { key: "latitude", label: "Latitude", kind: "number" },
1096
+ { key: "longitude", label: "Longitude", kind: "number" }
1097
+ ], Q = [
1098
+ { key: "name", label: "Name", kind: "text", required: !0 },
1099
+ { key: "url", label: "Profile URL", kind: "url" }
1100
+ ], pe = [
1101
+ { key: "name", label: "Publisher name", kind: "text", required: !0 },
1102
+ {
1103
+ key: "logo",
1104
+ label: "Logo",
1105
+ kind: "nested",
1106
+ nestedType: "ImageObject",
1107
+ nested: [{ key: "url", label: "Logo URL", kind: "image", required: !0 }]
1108
+ }
1109
+ ], me = [
1110
+ { key: "price", label: "Price", kind: "text", placeholder: "29.99", required: !0 },
1111
+ { key: "priceCurrency", label: "Currency", kind: "text", placeholder: "USD", required: !0 },
1112
+ { key: "url", label: "Buy URL", kind: "url" },
1113
+ {
1114
+ key: "availability",
1115
+ label: "Availability",
1116
+ kind: "select",
1117
+ options: [
1118
+ { label: "In stock", value: "https://schema.org/InStock" },
1119
+ { label: "Out of stock", value: "https://schema.org/OutOfStock" },
1120
+ { label: "Pre-order", value: "https://schema.org/PreOrder" },
1121
+ { label: "Discontinued", value: "https://schema.org/Discontinued" }
1122
+ ]
1123
+ }
1124
+ ], Z = [
1125
+ {
1126
+ type: "Organization",
1127
+ label: "Organization",
1128
+ group: "Business",
1129
+ description: "Your company. Place once site-wide so Google links your brand.",
1130
+ summary: (t) => t.name || "Untitled organization",
1131
+ fields: [
1132
+ { key: "name", label: "Name", kind: "text", required: !0, placeholder: "Acme Inc." },
1133
+ { key: "url", label: "Website URL", kind: "url", required: !0 },
1134
+ { key: "logo", label: "Logo", kind: "image", help: "Square, ideally 600×600 or larger." },
1135
+ { key: "email", label: "Contact email", kind: "text", placeholder: "hello@example.com" },
1136
+ { key: "telephone", label: "Phone", kind: "text" },
1137
+ {
1138
+ key: "address",
1139
+ label: "Address",
1140
+ kind: "nested",
1141
+ nestedType: "PostalAddress",
1142
+ nested: K
1143
+ },
1144
+ {
1145
+ key: "sameAs",
1146
+ label: "Social profile URLs",
1147
+ kind: "list",
1148
+ itemLabel: "Add profile",
1149
+ itemFields: [{ key: "value", label: "URL", kind: "url", required: !0 }]
1150
+ }
1151
+ ]
1152
+ },
1153
+ {
1154
+ type: "LocalBusiness",
1155
+ label: "Local Business",
1156
+ group: "Business",
1157
+ description: "Physical business location — gets you on Google Maps surfaces.",
1158
+ summary: (t) => t.name || "Untitled business",
1159
+ fields: [
1160
+ { key: "name", label: "Name", kind: "text", required: !0 },
1161
+ { key: "url", label: "Website URL", kind: "url", required: !0 },
1162
+ { key: "image", label: "Photo", kind: "image", required: !0 },
1163
+ { key: "telephone", label: "Phone", kind: "text" },
1164
+ { key: "priceRange", label: "Price range", kind: "text", placeholder: "$$" },
1165
+ {
1166
+ key: "address",
1167
+ label: "Address",
1168
+ kind: "nested",
1169
+ nestedType: "PostalAddress",
1170
+ nested: K
1171
+ },
1172
+ { key: "geo", label: "Geo coordinates", kind: "nested", nestedType: "GeoCoordinates", nested: Ot },
1173
+ {
1174
+ key: "openingHours",
1175
+ label: "Opening hours",
1176
+ kind: "list",
1177
+ itemLabel: "Add hours line",
1178
+ itemFields: [
1179
+ {
1180
+ key: "value",
1181
+ label: "Hours",
1182
+ kind: "text",
1183
+ placeholder: "Mo-Fr 09:00-17:00",
1184
+ required: !0,
1185
+ help: 'Schema.org format — e.g. "Mo-Fr 09:00-17:00" or "Sa 10:00-14:00".'
1186
+ }
1187
+ ]
1188
+ }
1189
+ ]
1190
+ },
1191
+ {
1192
+ type: "WebSite",
1193
+ label: "Website",
1194
+ group: "Content",
1195
+ description: "Top-level site identity. Powers Google sitelinks search box.",
1196
+ summary: (t) => t.name || t.url || "Untitled website",
1197
+ fields: [
1198
+ { key: "name", label: "Site name", kind: "text", required: !0 },
1199
+ { key: "url", label: "Site URL", kind: "url", required: !0 },
1200
+ {
1201
+ key: "potentialAction",
1202
+ label: "Search action",
1203
+ kind: "nested",
1204
+ nestedType: "SearchAction",
1205
+ nested: [
1206
+ {
1207
+ key: "target",
1208
+ label: "Search URL template",
1209
+ kind: "text",
1210
+ placeholder: "https://example.com/search?q={search_term_string}",
1211
+ help: 'Include the literal "{search_term_string}" placeholder.'
1212
+ }
1213
+ ]
1214
+ }
1215
+ ]
1216
+ },
1217
+ {
1218
+ type: "WebPage",
1219
+ label: "Web Page",
1220
+ group: "Content",
1221
+ description: "Generic page description. Use Article/BlogPosting for editorial pages.",
1222
+ summary: (t) => t.name || "Untitled page",
1223
+ fields: [
1224
+ { key: "name", label: "Page name", kind: "text", required: !0 },
1225
+ { key: "description", label: "Description", kind: "textarea" },
1226
+ { key: "url", label: "Canonical URL", kind: "url" },
1227
+ { key: "primaryImageOfPage", label: "Hero image URL", kind: "image" }
1228
+ ]
1229
+ },
1230
+ {
1231
+ type: "Article",
1232
+ label: "Article",
1233
+ group: "Content",
1234
+ description: "News/journalism. Enables top-stories carousel eligibility.",
1235
+ summary: (t) => t.headline || "Untitled article",
1236
+ fields: [
1237
+ { key: "headline", label: "Headline", kind: "text", required: !0 },
1238
+ { key: "image", label: "Hero image", kind: "image", required: !0 },
1239
+ { key: "description", label: "Description", kind: "textarea" },
1240
+ { key: "datePublished", label: "Published", kind: "datetime", required: !0 },
1241
+ { key: "dateModified", label: "Last modified", kind: "datetime" },
1242
+ { key: "author", label: "Author", kind: "nested", nestedType: "Person", nested: Q },
1243
+ {
1244
+ key: "publisher",
1245
+ label: "Publisher",
1246
+ kind: "nested",
1247
+ nestedType: "Organization",
1248
+ nested: pe
1249
+ }
1250
+ ]
1251
+ },
1252
+ {
1253
+ type: "BlogPosting",
1254
+ label: "Blog Post",
1255
+ group: "Content",
1256
+ description: "Blog entries. Same shape as Article with a different @type.",
1257
+ summary: (t) => t.headline || "Untitled post",
1258
+ fields: [
1259
+ { key: "headline", label: "Headline", kind: "text", required: !0 },
1260
+ { key: "image", label: "Hero image", kind: "image", required: !0 },
1261
+ { key: "description", label: "Description", kind: "textarea" },
1262
+ { key: "datePublished", label: "Published", kind: "datetime", required: !0 },
1263
+ { key: "dateModified", label: "Last modified", kind: "datetime" },
1264
+ { key: "author", label: "Author", kind: "nested", nestedType: "Person", nested: Q },
1265
+ {
1266
+ key: "publisher",
1267
+ label: "Publisher",
1268
+ kind: "nested",
1269
+ nestedType: "Organization",
1270
+ nested: pe
1271
+ }
1272
+ ]
1273
+ },
1274
+ {
1275
+ type: "Product",
1276
+ label: "Product",
1277
+ group: "Commerce",
1278
+ description: "Single product. Enables price/availability snippets in search.",
1279
+ summary: (t) => t.name || "Untitled product",
1280
+ fields: [
1281
+ { key: "name", label: "Name", kind: "text", required: !0 },
1282
+ { key: "description", label: "Description", kind: "textarea" },
1283
+ {
1284
+ key: "image",
1285
+ label: "Images",
1286
+ kind: "list",
1287
+ itemLabel: "Add image",
1288
+ itemFields: [{ key: "value", label: "Image", kind: "image", required: !0 }]
1289
+ },
1290
+ { key: "sku", label: "SKU", kind: "text" },
1291
+ { key: "brand", label: "Brand", kind: "nested", nestedType: "Brand", nested: [{ key: "name", label: "Brand name", kind: "text", required: !0 }] },
1292
+ { key: "offers", label: "Offer", kind: "nested", nestedType: "Offer", nested: me }
1293
+ ]
1294
+ },
1295
+ {
1296
+ type: "FAQPage",
1297
+ label: "FAQ Page",
1298
+ group: "Content",
1299
+ description: "Question + answer pairs. Renders as an expandable list in search results.",
1300
+ summary: (t) => `${(t.mainEntity || []).length} question(s)`,
1301
+ fields: [
1302
+ {
1303
+ key: "mainEntity",
1304
+ label: "Questions",
1305
+ kind: "list",
1306
+ itemLabel: "Add question",
1307
+ itemType: "Question",
1308
+ itemFields: [
1309
+ { key: "name", label: "Question", kind: "text", required: !0 },
1310
+ {
1311
+ key: "acceptedAnswer",
1312
+ label: "Answer",
1313
+ kind: "nested",
1314
+ nestedType: "Answer",
1315
+ nested: [{ key: "text", label: "Answer text", kind: "textarea", required: !0 }]
1316
+ }
1317
+ ]
1318
+ }
1319
+ ]
1320
+ },
1321
+ {
1322
+ type: "BreadcrumbList",
1323
+ label: "Breadcrumbs",
1324
+ group: "Misc",
1325
+ description: "Trail of parent pages. Replaces the URL line in search results with named hops.",
1326
+ summary: (t) => `${(t.itemListElement || []).length} crumb(s)`,
1327
+ fields: [
1328
+ {
1329
+ key: "itemListElement",
1330
+ label: "Crumbs",
1331
+ kind: "list",
1332
+ itemLabel: "Add crumb",
1333
+ itemType: "ListItem",
1334
+ itemFields: [
1335
+ { key: "name", label: "Label", kind: "text", required: !0 },
1336
+ { key: "item", label: "URL", kind: "url", required: !0 }
1337
+ ]
1338
+ }
1339
+ ]
1340
+ },
1341
+ {
1342
+ type: "Event",
1343
+ label: "Event",
1344
+ group: "Event",
1345
+ description: "Concert, conference, webinar. Enables event rich result.",
1346
+ summary: (t) => t.name || "Untitled event",
1347
+ fields: [
1348
+ { key: "name", label: "Event name", kind: "text", required: !0 },
1349
+ { key: "startDate", label: "Start", kind: "datetime", required: !0 },
1350
+ { key: "endDate", label: "End", kind: "datetime" },
1351
+ { key: "description", label: "Description", kind: "textarea" },
1352
+ { key: "image", label: "Image", kind: "image" },
1353
+ {
1354
+ key: "location",
1355
+ label: "Location",
1356
+ kind: "nested",
1357
+ nestedType: "Place",
1358
+ nested: [
1359
+ { key: "name", label: "Venue name", kind: "text", required: !0 },
1360
+ {
1361
+ key: "address",
1362
+ label: "Address",
1363
+ kind: "nested",
1364
+ nestedType: "PostalAddress",
1365
+ nested: K
1366
+ }
1367
+ ]
1368
+ },
1369
+ { key: "offers", label: "Ticket offer", kind: "nested", nestedType: "Offer", nested: me }
1370
+ ]
1371
+ },
1372
+ {
1373
+ type: "Recipe",
1374
+ label: "Recipe",
1375
+ group: "Content",
1376
+ description: "Cooking recipe with ingredients and steps.",
1377
+ summary: (t) => t.name || "Untitled recipe",
1378
+ fields: [
1379
+ { key: "name", label: "Name", kind: "text", required: !0 },
1380
+ { key: "image", label: "Photo", kind: "image", required: !0 },
1381
+ { key: "description", label: "Description", kind: "textarea" },
1382
+ { key: "recipeYield", label: "Yield", kind: "text", placeholder: "4 servings" },
1383
+ { key: "prepTime", label: "Prep time", kind: "text", placeholder: "PT15M", help: "ISO 8601 duration." },
1384
+ { key: "cookTime", label: "Cook time", kind: "text", placeholder: "PT30M" },
1385
+ {
1386
+ key: "recipeIngredient",
1387
+ label: "Ingredients",
1388
+ kind: "list",
1389
+ itemLabel: "Add ingredient",
1390
+ itemFields: [{ key: "value", label: "Ingredient", kind: "text", required: !0 }]
1391
+ },
1392
+ {
1393
+ key: "recipeInstructions",
1394
+ label: "Steps",
1395
+ kind: "list",
1396
+ itemLabel: "Add step",
1397
+ itemType: "HowToStep",
1398
+ itemFields: [{ key: "text", label: "Step", kind: "textarea", required: !0 }]
1399
+ }
1400
+ ]
1401
+ },
1402
+ {
1403
+ type: "Review",
1404
+ label: "Review",
1405
+ group: "Commerce",
1406
+ description: "Single review of a product, service, or place.",
1407
+ summary: (t) => {
1408
+ var a;
1409
+ return ((a = t.reviewBody) == null ? void 0 : a.slice(0, 60)) || "Untitled review";
1410
+ },
1411
+ fields: [
1412
+ {
1413
+ key: "itemReviewed",
1414
+ label: "Item reviewed",
1415
+ kind: "nested",
1416
+ nestedType: "Thing",
1417
+ nested: [{ key: "name", label: "Name", kind: "text", required: !0 }]
1418
+ },
1419
+ {
1420
+ key: "reviewRating",
1421
+ label: "Rating",
1422
+ kind: "nested",
1423
+ nestedType: "Rating",
1424
+ nested: [
1425
+ { key: "ratingValue", label: "Rating value", kind: "number", required: !0, placeholder: "5" },
1426
+ { key: "bestRating", label: "Best possible rating", kind: "number", placeholder: "5" }
1427
+ ]
1428
+ },
1429
+ { key: "author", label: "Author", kind: "nested", nestedType: "Person", nested: Q },
1430
+ { key: "reviewBody", label: "Review text", kind: "textarea" }
1431
+ ]
1432
+ },
1433
+ {
1434
+ type: "VideoObject",
1435
+ label: "Video",
1436
+ group: "Media",
1437
+ description: "Hosted video. Enables video thumbnail + duration in search.",
1438
+ summary: (t) => t.name || "Untitled video",
1439
+ fields: [
1440
+ { key: "name", label: "Title", kind: "text", required: !0 },
1441
+ { key: "description", label: "Description", kind: "textarea", required: !0 },
1442
+ { key: "thumbnailUrl", label: "Thumbnail", kind: "image", required: !0 },
1443
+ { key: "uploadDate", label: "Upload date", kind: "datetime", required: !0 },
1444
+ { key: "contentUrl", label: "Video URL", kind: "url" },
1445
+ { key: "embedUrl", label: "Embed URL", kind: "url" },
1446
+ { key: "duration", label: "Duration", kind: "text", placeholder: "PT2M30S", help: "ISO 8601 duration." }
1447
+ ]
1448
+ },
1449
+ {
1450
+ type: "HowTo",
1451
+ label: "How-To",
1452
+ group: "Content",
1453
+ description: "Step-by-step guide. Enables numbered-step rich result.",
1454
+ summary: (t) => t.name || "Untitled guide",
1455
+ fields: [
1456
+ { key: "name", label: "Title", kind: "text", required: !0 },
1457
+ { key: "description", label: "Description", kind: "textarea" },
1458
+ { key: "image", label: "Image", kind: "image" },
1459
+ { key: "totalTime", label: "Total time", kind: "text", placeholder: "PT1H" },
1460
+ {
1461
+ key: "step",
1462
+ label: "Steps",
1463
+ kind: "list",
1464
+ itemLabel: "Add step",
1465
+ itemType: "HowToStep",
1466
+ itemFields: [
1467
+ { key: "name", label: "Step name", kind: "text" },
1468
+ { key: "text", label: "Step text", kind: "textarea", required: !0 },
1469
+ { key: "image", label: "Step image", kind: "image" }
1470
+ ]
1471
+ }
1472
+ ]
1473
+ }
1474
+ ], Ut = Z.reduce(
1475
+ (t, a) => (t[a.type] = a, t),
1476
+ {}
1477
+ );
1478
+ function B(t) {
1479
+ return Ut[t];
1480
+ }
1481
+ function It(t) {
1482
+ const a = {};
1483
+ for (const n of t.fields)
1484
+ n.kind === "list" ? a[n.key] = [] : n.kind === "nested" ? a[n.key] = {} : a[n.key] = "";
1485
+ return a;
1486
+ }
1487
+ function Dt(t) {
1488
+ return t == null ? !0 : typeof t == "string" ? t.trim() === "" : Array.isArray(t) ? t.length === 0 : typeof t == "object" ? Object.keys(t).length === 0 : !1;
1489
+ }
1490
+ function z(t, a) {
1491
+ if (!Dt(a))
1492
+ switch (t.kind) {
1493
+ case "number": {
1494
+ const n = typeof a == "number" ? a : Number(a);
1495
+ return Number.isFinite(n) ? n : void 0;
1496
+ }
1497
+ case "list": {
1498
+ if (!Array.isArray(a)) return;
1499
+ const n = a.map((l, o) => qt(t, l, o)).filter((l) => l !== void 0);
1500
+ return n.length ? n : void 0;
1501
+ }
1502
+ case "nested":
1503
+ return Ht(t, a);
1504
+ default:
1505
+ return typeof a == "string" ? a.trim() : a;
1506
+ }
1507
+ }
1508
+ function qt(t, a, n) {
1509
+ const l = t.itemFields || [];
1510
+ if (l.length === 1 && l[0].key === "value" && l[0].kind !== "nested" && l[0].kind !== "list")
1511
+ return z(l[0], a == null ? void 0 : a.value);
1512
+ const o = {};
1513
+ t.itemType && (o["@type"] = t.itemType), t.itemType === "ListItem" && ((a == null ? void 0 : a.position) == null || (a == null ? void 0 : a.position) === "") && (o.position = n + 1);
1514
+ for (const i of l) {
1515
+ const p = z(i, a == null ? void 0 : a[i.key]);
1516
+ p !== void 0 && (o[i.key] = p);
1517
+ }
1518
+ return Object.keys(o).length > (t.itemType ? 1 : 0) ? o : void 0;
1519
+ }
1520
+ function Ht(t, a) {
1521
+ const n = t.nested || [], l = {};
1522
+ t.nestedType && (l["@type"] = t.nestedType);
1523
+ for (const o of n) {
1524
+ const i = z(o, a == null ? void 0 : a[o.key]);
1525
+ i !== void 0 && (l[o.key] = i);
1526
+ }
1527
+ return Object.keys(l).length > (t.nestedType ? 1 : 0) ? l : void 0;
1528
+ }
1529
+ function _t(t) {
1530
+ var l, o;
1531
+ if (t.kind === "raw") {
1532
+ const i = (l = t.json) == null ? void 0 : l.trim();
1533
+ if (!i) return null;
1534
+ try {
1535
+ const p = JSON.parse(i);
1536
+ return p && typeof p == "object" ? p : null;
1537
+ } catch {
1538
+ return null;
1539
+ }
1540
+ }
1541
+ const a = B(t.type);
1542
+ if (!a) return null;
1543
+ const n = {
1544
+ "@context": "https://schema.org",
1545
+ "@type": t.type
1546
+ };
1547
+ for (const i of a.fields) {
1548
+ const p = z(i, (o = t.fields) == null ? void 0 : o[i.key]);
1549
+ p !== void 0 && (n[i.key] = p);
1550
+ }
1551
+ return n;
1552
+ }
1553
+ function Mt({ entry: t, onChange: a, inputClass: n }) {
1554
+ const l = B(t.type), [o, i] = P(!1), p = E(() => _t(t), [t]), u = E(
1555
+ () => p ? JSON.stringify(p, null, 2) : "// (empty — fill in required fields)",
1556
+ [p]
1557
+ );
1558
+ if (!l)
1559
+ return /* @__PURE__ */ c("p", { className: "text-error text-sm", children: [
1560
+ "Unknown schema type: ",
1561
+ t.type
1562
+ ] });
1563
+ const h = (r, s) => a({ ...t, fields: { ...t.fields, [r]: s } });
1564
+ return /* @__PURE__ */ c("div", { className: "space-y-5", children: [
1565
+ /* @__PURE__ */ e("p", { className: "text-neutral-content text-sm leading-relaxed", children: l.description }),
1566
+ l.fields.map((r) => {
1567
+ var s;
1568
+ return /* @__PURE__ */ e(
1569
+ V,
1570
+ {
1571
+ field: r,
1572
+ value: (s = t.fields) == null ? void 0 : s[r.key],
1573
+ onChange: (g) => h(r.key, g),
1574
+ inputClass: n
1575
+ },
1576
+ r.key
1577
+ );
1578
+ }),
1579
+ /* @__PURE__ */ c("div", { className: "border-base-300 overflow-hidden rounded-xl border", children: [
1580
+ /* @__PURE__ */ c(
1581
+ "button",
1582
+ {
1583
+ type: "button",
1584
+ onClick: () => i((r) => !r),
1585
+ className: "bg-base-200/40 hover:bg-base-200/70 flex w-full items-center gap-2 px-4 py-2.5 text-left transition-colors",
1586
+ children: [
1587
+ o ? /* @__PURE__ */ e(ve, { className: "size-4 shrink-0" }) : /* @__PURE__ */ e(xe, { className: "size-4 shrink-0" }),
1588
+ /* @__PURE__ */ e("span", { className: "text-base-content text-sm font-semibold", children: "JSON-LD preview" }),
1589
+ /* @__PURE__ */ e("span", { className: "text-neutral-content ml-auto text-xs", children: "What search engines will see" })
1590
+ ]
1591
+ }
1592
+ ),
1593
+ o ? /* @__PURE__ */ e("pre", { className: "bg-base-300/40 text-base-content max-h-72 overflow-auto px-4 py-3 font-mono text-xs leading-relaxed", children: u }) : null
1594
+ ] })
1595
+ ] });
1596
+ }
1597
+ function Vt({
1598
+ entry: t,
1599
+ onChange: a,
1600
+ onRemove: n,
1601
+ inputClass: l,
1602
+ defaultOpen: o = !1
1603
+ }) {
1604
+ const [i, p] = P(o), { title: u, subtitle: h } = t.kind === "raw" ? $t(t) : zt(t);
1605
+ return /* @__PURE__ */ c("div", { className: "border-base-300 overflow-hidden rounded-xl border", children: [
1606
+ /* @__PURE__ */ c("header", { className: "bg-base-200/30 flex items-center gap-3 px-4 py-3", children: [
1607
+ /* @__PURE__ */ e(
1608
+ "button",
1609
+ {
1610
+ type: "button",
1611
+ onClick: () => p((r) => !r),
1612
+ className: "text-neutral-content hover:text-base-content shrink-0 transition-colors",
1613
+ "aria-label": i ? "Collapse entry" : "Expand entry",
1614
+ children: i ? /* @__PURE__ */ e(ve, { className: "size-4" }) : /* @__PURE__ */ e(xe, { className: "size-4" })
1615
+ }
1616
+ ),
1617
+ /* @__PURE__ */ c(
1618
+ "button",
1619
+ {
1620
+ type: "button",
1621
+ onClick: () => p((r) => !r),
1622
+ className: "flex min-w-0 flex-1 flex-col items-start gap-0.5 text-left",
1623
+ children: [
1624
+ /* @__PURE__ */ c("span", { className: "flex items-center gap-2", children: [
1625
+ t.kind === "raw" ? /* @__PURE__ */ e(te, { className: "text-neutral-content size-3.5", "aria-hidden": !0 }) : null,
1626
+ /* @__PURE__ */ e("span", { className: "text-base-content text-sm font-semibold", children: u })
1627
+ ] }),
1628
+ /* @__PURE__ */ e("span", { className: "text-neutral-content truncate text-xs", children: h })
1629
+ ]
1630
+ }
1631
+ ),
1632
+ /* @__PURE__ */ e(
1633
+ "button",
1634
+ {
1635
+ type: "button",
1636
+ onClick: n,
1637
+ className: "text-neutral-content hover:text-error rounded-md p-1.5 transition-colors",
1638
+ "aria-label": "Remove entry",
1639
+ children: /* @__PURE__ */ e(j, { className: "size-4" })
1640
+ }
1641
+ )
1642
+ ] }),
1643
+ i ? /* @__PURE__ */ e("div", { className: "bg-base-100 px-4 py-4", children: t.kind === "builder" ? /* @__PURE__ */ e(
1644
+ Mt,
1645
+ {
1646
+ entry: t,
1647
+ onChange: a,
1648
+ inputClass: l
1649
+ }
1650
+ ) : /* @__PURE__ */ e(
1651
+ Lt,
1652
+ {
1653
+ entry: t,
1654
+ onChange: a
1655
+ }
1656
+ ) }) : null
1657
+ ] });
1658
+ }
1659
+ function zt(t) {
1660
+ const a = B(t.type), n = (a == null ? void 0 : a.label) || t.type;
1661
+ let l = "";
1662
+ try {
1663
+ l = (a == null ? void 0 : a.summary(t.fields || {})) || "";
1664
+ } catch {
1665
+ l = "";
1666
+ }
1667
+ return { title: n, subtitle: l || `@type: ${t.type}` };
1668
+ }
1669
+ function $t(t) {
1670
+ var n;
1671
+ const a = (n = t.json) == null ? void 0 : n.trim();
1672
+ if (!a) return { title: "Raw JSON-LD", subtitle: "(empty)" };
1673
+ try {
1674
+ const l = JSON.parse(a), o = l == null ? void 0 : l["@type"], i = (l == null ? void 0 : l.name) || (l == null ? void 0 : l.headline) || "";
1675
+ return {
1676
+ title: typeof o == "string" ? `Raw · ${o}` : "Raw JSON-LD",
1677
+ subtitle: typeof i == "string" && i ? i : "Custom schema"
1678
+ };
1679
+ } catch {
1680
+ return { title: "Raw JSON-LD", subtitle: "Invalid JSON" };
1681
+ }
1682
+ }
1683
+ const jt = ["Business", "Content", "Commerce", "Event", "Media", "Misc"];
1684
+ function Bt({ open: t, onClose: a, onPickType: n, onPickRaw: l }) {
1685
+ const [o, i] = P(""), [p, u] = P(!1), h = O(null), r = ct();
1686
+ R(() => u(!0), []), R(() => {
1687
+ if (!t || !r) return;
1688
+ const d = h.current;
1689
+ if (d)
1690
+ return r(d);
1691
+ }, [t, p, r]), Be({
1692
+ id: "schema-type-picker",
1693
+ isOpen: t,
1694
+ onDismiss: a
1695
+ });
1696
+ const s = E(() => {
1697
+ const d = o.trim().toLowerCase(), m = d ? Z.filter(
1698
+ (b) => b.label.toLowerCase().includes(d) || b.type.toLowerCase().includes(d) || b.description.toLowerCase().includes(d)
1699
+ ) : Z, f = /* @__PURE__ */ new Map();
1700
+ for (const b of m) {
1701
+ const S = f.get(b.group) || [];
1702
+ S.push(b), f.set(b.group, S);
1703
+ }
1704
+ return jt.filter((b) => f.has(b)).map((b) => ({ group: b, types: f.get(b) }));
1705
+ }, [o]);
1706
+ if (!t || !p) return null;
1707
+ const g = /* @__PURE__ */ e(
1708
+ "div",
1709
+ {
1710
+ ref: h,
1711
+ className: "fixed inset-0 flex items-center justify-center bg-black/40 p-4",
1712
+ style: { zIndex: we + 1 },
1713
+ onClick: (d) => {
1714
+ d.target === d.currentTarget && a();
1715
+ },
1716
+ children: /* @__PURE__ */ c(
1717
+ "div",
1718
+ {
1719
+ className: "bg-base-100 border-base-300 flex max-h-[80vh] w-full max-w-2xl flex-col overflow-hidden rounded-2xl border shadow-2xl",
1720
+ onClick: (d) => d.stopPropagation(),
1721
+ children: [
1722
+ /* @__PURE__ */ c("header", { className: "border-base-300 flex items-center gap-3 border-b px-5 py-4", children: [
1723
+ /* @__PURE__ */ c("div", { className: "flex-1", children: [
1724
+ /* @__PURE__ */ e("h3", { className: "text-base-content text-base font-semibold", children: "Add schema" }),
1725
+ /* @__PURE__ */ e("p", { className: "text-neutral-content text-xs", children: "Pick a schema.org type to add structured data to this page." })
1726
+ ] }),
1727
+ /* @__PURE__ */ e(
1728
+ "button",
1729
+ {
1730
+ type: "button",
1731
+ onClick: a,
1732
+ className: "text-neutral-content hover:text-base-content rounded-md p-1.5 transition-colors",
1733
+ "aria-label": "Close",
1734
+ children: /* @__PURE__ */ e(ke, { className: "size-5" })
1735
+ }
1736
+ )
1737
+ ] }),
1738
+ /* @__PURE__ */ e("div", { className: "border-base-300 border-b px-5 py-3", children: /* @__PURE__ */ c("div", { className: "bg-base-200/50 border-base-300 flex items-center gap-2 rounded-lg border px-3 py-2", children: [
1739
+ /* @__PURE__ */ e(Ne, { className: "text-neutral-content size-4 shrink-0" }),
1740
+ /* @__PURE__ */ e(
1741
+ "input",
1742
+ {
1743
+ type: "text",
1744
+ value: o,
1745
+ onChange: (d) => i(d.target.value),
1746
+ placeholder: "Search schema types…",
1747
+ className: "text-base-content placeholder:text-neutral-content w-full bg-transparent text-sm outline-none",
1748
+ autoFocus: !0
1749
+ }
1750
+ )
1751
+ ] }) }),
1752
+ /* @__PURE__ */ e("div", { className: "min-h-0 flex-1 overflow-y-auto px-5 py-4", children: s.length === 0 ? /* @__PURE__ */ c("p", { className: "text-neutral-content py-8 text-center text-sm", children: [
1753
+ "No schema types match “",
1754
+ o,
1755
+ "”."
1756
+ ] }) : /* @__PURE__ */ e("div", { className: "space-y-5", children: s.map(({ group: d, types: m }) => /* @__PURE__ */ c("section", { className: "space-y-2", children: [
1757
+ /* @__PURE__ */ e("h4", { className: "text-neutral-content text-xs font-semibold tracking-wide uppercase", children: d }),
1758
+ /* @__PURE__ */ e("div", { className: "grid gap-2 sm:grid-cols-2", children: m.map((f) => /* @__PURE__ */ c(
1759
+ "button",
1760
+ {
1761
+ type: "button",
1762
+ onClick: () => {
1763
+ n(f.type), a();
1764
+ },
1765
+ className: "border-base-300 hover:border-primary hover:bg-base-200/40 group flex flex-col gap-1 rounded-xl border p-3 text-left transition-colors",
1766
+ children: [
1767
+ /* @__PURE__ */ e("span", { className: "text-base-content group-hover:text-primary text-sm font-semibold", children: f.label }),
1768
+ /* @__PURE__ */ e("span", { className: "text-neutral-content text-xs leading-snug", children: f.description })
1769
+ ]
1770
+ },
1771
+ f.type
1772
+ )) })
1773
+ ] }, d)) }) }),
1774
+ /* @__PURE__ */ e("footer", { className: "border-base-300 bg-base-200/30 border-t px-5 py-3", children: /* @__PURE__ */ c(
1775
+ "button",
1776
+ {
1777
+ type: "button",
1778
+ onClick: () => {
1779
+ l(), a();
1780
+ },
1781
+ className: "text-neutral-content hover:text-base-content flex items-center gap-2 text-sm transition-colors",
1782
+ children: [
1783
+ /* @__PURE__ */ e(te, { className: "size-4" }),
1784
+ "Paste raw JSON-LD instead"
1785
+ ]
1786
+ }
1787
+ ) })
1788
+ ]
1789
+ }
1790
+ )
1791
+ }
1792
+ );
1793
+ return dt(g, document.body);
1794
+ }
1795
+ function he() {
1796
+ return `sch_${Math.random().toString(36).slice(2, 9)}`;
1797
+ }
1798
+ function Gt({ schema: t, setSchema: a, inputClass: n }) {
1799
+ const [l, o] = P(!1), [i, p] = P(null), u = Array.isArray(t) ? t : [], h = (d) => {
1800
+ const m = B(d);
1801
+ if (!m) return;
1802
+ const f = he(), b = { kind: "builder", id: f, type: d, fields: It(m) };
1803
+ a([...u, b]), p(f);
1804
+ }, r = () => {
1805
+ const d = he(), m = { kind: "raw", id: d, json: "" };
1806
+ a([...u, m]), p(d);
1807
+ }, s = (d, m) => a(u.map((f) => f.id === d ? m : f)), g = (d) => a(u.filter((m) => m.id !== d));
1808
+ return /* @__PURE__ */ c("div", { className: q, children: [
1809
+ /* @__PURE__ */ e(
1810
+ I,
1811
+ {
1812
+ title: "Structured data (JSON-LD)",
1813
+ description: "Tell search engines what this page is about. Add one entry per thing — your business, an article, a product, FAQs — and each shows up as its own rich result in Google."
1814
+ }
1815
+ ),
1816
+ u.length === 0 ? /* @__PURE__ */ e(Se, { title: "No schema yet", children: "Add an Organization or LocalBusiness entry to help Google identify your brand, or pick a page-specific type like Article, Product, or FAQ." }) : /* @__PURE__ */ e("div", { className: "space-y-3", children: u.map((d) => /* @__PURE__ */ e(
1817
+ Vt,
1818
+ {
1819
+ entry: d,
1820
+ onChange: (m) => s(d.id, m),
1821
+ onRemove: () => g(d.id),
1822
+ inputClass: n,
1823
+ defaultOpen: d.id === i
1824
+ },
1825
+ d.id
1826
+ )) }),
1827
+ /* @__PURE__ */ e("div", { children: /* @__PURE__ */ c(
1828
+ "button",
1829
+ {
1830
+ type: "button",
1831
+ onClick: () => o(!0),
1832
+ className: "btn btn-primary gap-2",
1833
+ children: [
1834
+ /* @__PURE__ */ e($, { className: "size-4" }),
1835
+ "Add schema"
1836
+ ]
1837
+ }
1838
+ ) }),
1839
+ /* @__PURE__ */ e(
1840
+ Bt,
1841
+ {
1842
+ open: l,
1843
+ onClose: () => o(!1),
1844
+ onPickType: h,
1845
+ onPickRaw: r
1846
+ }
1847
+ )
1848
+ ] });
1849
+ }
1850
+ function Jt({
1851
+ inputClass: t,
1852
+ pageTitle: a,
1853
+ setPageTitle: n,
1854
+ pageDescription: l,
1855
+ setPageDescription: o,
1856
+ pageKeywords: i,
1857
+ setPageKeywords: p,
1858
+ pageAuthor: u,
1859
+ setPageAuthor: h
1860
+ }) {
1861
+ const r = Ce;
1862
+ return /* @__PURE__ */ c("div", { className: q, children: [
1863
+ /* @__PURE__ */ e(
1864
+ I,
1865
+ {
1866
+ title: "SEO",
1867
+ description: "Defaults for search engines. Open Graph and Twitter cards live in their own tabs and override these when set."
1868
+ }
1869
+ ),
1870
+ /* @__PURE__ */ c(L, { title: "Search", children: [
1871
+ /* @__PURE__ */ e(
1872
+ N,
1873
+ {
1874
+ label: "Meta title",
1875
+ htmlFor: "meta-title",
1876
+ hint: "Roughly 50–60 characters works well in results.",
1877
+ children: /* @__PURE__ */ e(
1878
+ "textarea",
1879
+ {
1880
+ id: "meta-title",
1881
+ value: a,
1882
+ onChange: (s) => n(s.target.value),
1883
+ rows: 2,
1884
+ className: r,
1885
+ placeholder: "Page title"
1886
+ }
1887
+ )
1888
+ }
1889
+ ),
1890
+ /* @__PURE__ */ e(
1891
+ N,
1892
+ {
1893
+ label: "Meta description",
1894
+ htmlFor: "meta-description",
1895
+ hint: "Roughly 150–160 characters for snippets.",
1896
+ children: /* @__PURE__ */ e(
1897
+ "textarea",
1898
+ {
1899
+ id: "meta-description",
1900
+ value: l,
1901
+ onChange: (s) => o(s.target.value),
1902
+ rows: 3,
1903
+ className: r,
1904
+ placeholder: "Meta description"
1905
+ }
1906
+ )
1907
+ }
1908
+ ),
1909
+ /* @__PURE__ */ c("div", { className: "grid gap-4 sm:grid-cols-2", children: [
1910
+ /* @__PURE__ */ e(N, { label: "Keywords", htmlFor: "page-keywords", children: /* @__PURE__ */ e(
1911
+ "input",
1912
+ {
1913
+ id: "page-keywords",
1914
+ type: "text",
1915
+ value: i,
1916
+ onChange: (s) => p(s.target.value),
1917
+ className: t,
1918
+ placeholder: "keyword1, keyword2"
1919
+ }
1920
+ ) }),
1921
+ /* @__PURE__ */ e(N, { label: "Author", htmlFor: "page-author", children: /* @__PURE__ */ e(
1922
+ "input",
1923
+ {
1924
+ id: "page-author",
1925
+ type: "text",
1926
+ value: u,
1927
+ onChange: (s) => h(s.target.value),
1928
+ className: t,
1929
+ placeholder: "Author name"
1930
+ }
1931
+ ) })
1932
+ ] })
1933
+ ] })
1934
+ ] });
1935
+ }
1936
+ function Wt({
1937
+ inputClass: t,
1938
+ themeOverrides: a,
1939
+ setThemeOverrides: n
1940
+ }) {
1941
+ const l = () => {
1942
+ n([...a, { varName: "", value: "" }]);
1943
+ }, o = (p, u, h) => {
1944
+ const r = [...a];
1945
+ r[p] = { ...r[p], [u]: h }, n(r);
1946
+ }, i = (p) => {
1947
+ n(a.filter((u, h) => h !== p));
1948
+ };
1949
+ return /* @__PURE__ */ c("div", { className: q, children: [
1950
+ /* @__PURE__ */ e(
1951
+ I,
1952
+ {
1953
+ title: "Theme overrides",
1954
+ description: "Override design tokens for this page only. Use CSS variable names without the leading --."
1955
+ }
1956
+ ),
1957
+ /* @__PURE__ */ c(L, { title: "Variables", children: [
1958
+ /* @__PURE__ */ c("div", { className: "flex items-center justify-between gap-2", children: [
1959
+ /* @__PURE__ */ e("p", { className: "text-neutral-content text-sm", children: a.length === 0 ? "No overrides yet." : `${a.length} ${a.length === 1 ? "override" : "overrides"}` }),
1960
+ /* @__PURE__ */ c(
1961
+ "button",
1962
+ {
1963
+ type: "button",
1964
+ onClick: l,
1965
+ className: "btn btn-secondary btn-sm shrink-0 gap-1",
1966
+ children: [
1967
+ /* @__PURE__ */ e($, { className: "size-3.5" }),
1968
+ "Add override"
1969
+ ]
1970
+ }
1971
+ )
1972
+ ] }),
1973
+ a.length > 0 ? /* @__PURE__ */ c("div", { className: "space-y-2", children: [
1974
+ /* @__PURE__ */ c("div", { className: "text-neutral-content grid grid-cols-[minmax(0,1fr)_minmax(0,2fr)_auto] gap-2 text-xs font-medium", children: [
1975
+ /* @__PURE__ */ e("span", { children: "Variable" }),
1976
+ /* @__PURE__ */ e("span", { children: "Value" }),
1977
+ /* @__PURE__ */ e("span", { className: "size-9", "aria-hidden": !0 })
1978
+ ] }),
1979
+ a.map((p, u) => /* @__PURE__ */ c(
1980
+ "div",
1981
+ {
1982
+ className: "grid grid-cols-[minmax(0,1fr)_minmax(0,2fr)_auto] items-center gap-2",
1983
+ children: [
1984
+ /* @__PURE__ */ c("label", { className: "input flex items-center", children: [
1985
+ /* @__PURE__ */ e("span", { className: "text-neutral-content shrink-0 font-mono text-xs", children: "--" }),
1986
+ /* @__PURE__ */ e(
1987
+ "input",
1988
+ {
1989
+ type: "text",
1990
+ value: p.varName,
1991
+ onChange: (h) => o(u, "varName", h.target.value),
1992
+ className: "grow font-mono text-xs",
1993
+ placeholder: "var-name",
1994
+ "aria-label": "CSS variable name"
1995
+ }
1996
+ )
1997
+ ] }),
1998
+ /* @__PURE__ */ e(
1999
+ "input",
2000
+ {
2001
+ type: "text",
2002
+ value: p.value,
2003
+ onChange: (h) => o(u, "value", h.target.value),
2004
+ className: `${t} font-mono text-xs`,
2005
+ placeholder: "#fff or 1rem",
2006
+ "aria-label": "CSS value"
2007
+ }
2008
+ ),
2009
+ /* @__PURE__ */ e(
2010
+ "button",
2011
+ {
2012
+ type: "button",
2013
+ onClick: () => i(u),
2014
+ className: "btn btn-ghost btn-square btn-sm hover:text-error",
2015
+ "aria-label": "Remove override",
2016
+ children: /* @__PURE__ */ e(j, { className: "size-4" })
2017
+ }
2018
+ )
2019
+ ]
2020
+ },
2021
+ u
2022
+ ))
2023
+ ] }) : null
2024
+ ] })
2025
+ ] });
2026
+ }
2027
+ function Kt({
2028
+ inputClass: t,
2029
+ selectClass: a,
2030
+ twitterCard: n,
2031
+ setTwitterCard: l,
2032
+ twitterSite: o,
2033
+ setTwitterSite: i,
2034
+ twitterCreator: p,
2035
+ setTwitterCreator: u
2036
+ }) {
2037
+ return /* @__PURE__ */ c("div", { className: q, children: [
2038
+ /* @__PURE__ */ e(
2039
+ I,
2040
+ {
2041
+ title: "Twitter / X card",
2042
+ description: "Override how this page previews on Twitter / X. Falls back to Open Graph when these are empty."
2043
+ }
2044
+ ),
2045
+ /* @__PURE__ */ c(L, { title: "Card", children: [
2046
+ /* @__PURE__ */ e(N, { label: "Card type", htmlFor: "twitter-card", children: /* @__PURE__ */ c(
2047
+ "select",
2048
+ {
2049
+ id: "twitter-card",
2050
+ value: n,
2051
+ onChange: (r) => l(r.target.value),
2052
+ className: a,
2053
+ children: [
2054
+ /* @__PURE__ */ e("option", { value: "summary_large_image", children: "Summary, large image" }),
2055
+ /* @__PURE__ */ e("option", { value: "summary", children: "Summary" })
2056
+ ]
2057
+ }
2058
+ ) }),
2059
+ /* @__PURE__ */ c("div", { className: "grid gap-4 sm:grid-cols-2", children: [
2060
+ /* @__PURE__ */ e(N, { label: "Site", htmlFor: "twitter-site", hint: "The site's @ handle.", children: /* @__PURE__ */ e(
2061
+ "input",
2062
+ {
2063
+ id: "twitter-site",
2064
+ type: "text",
2065
+ value: o,
2066
+ onChange: (r) => i(r.target.value),
2067
+ className: t,
2068
+ placeholder: "@yourusername"
2069
+ }
2070
+ ) }),
2071
+ /* @__PURE__ */ e(
2072
+ N,
2073
+ {
2074
+ label: "Creator",
2075
+ htmlFor: "twitter-creator",
2076
+ hint: "The author's @ handle.",
2077
+ children: /* @__PURE__ */ e(
2078
+ "input",
2079
+ {
2080
+ id: "twitter-creator",
2081
+ type: "text",
2082
+ value: p,
2083
+ onChange: (r) => u(r.target.value),
2084
+ className: t,
2085
+ placeholder: "@authorusername"
2086
+ }
2087
+ )
2088
+ }
2089
+ )
2090
+ ] })
2091
+ ] })
2092
+ ] });
2093
+ }
2094
+ function Qt({
2095
+ actions: t,
2096
+ query: a,
2097
+ autoSlug: n,
2098
+ pageSlug: l,
2099
+ setPageSlug: o,
2100
+ setAutoSlug: i,
2101
+ showDeleteConfirm: p,
2102
+ setShowDeleteConfirm: u,
2103
+ onClose: h
2104
+ }) {
2105
+ return E(
2106
+ () => [
2107
+ {
2108
+ key: "basic",
2109
+ label: "Basic",
2110
+ order: 100,
2111
+ icon: /* @__PURE__ */ e(Ge, {}),
2112
+ render: (r) => /* @__PURE__ */ e(
2113
+ Tt,
2114
+ {
2115
+ inputClass: r.inputClass,
2116
+ pageName: r.draft.pageName,
2117
+ onPageNameChange: (s) => {
2118
+ if (r.updateField("pageName", s), n) {
2119
+ const g = fe(s || "untitled-page", "-");
2120
+ o(g), r.updateField("pageSlug", "");
2121
+ }
2122
+ },
2123
+ pageSlug: l,
2124
+ onSlugChange: (s) => {
2125
+ o(s), i(!1), r.updateField("pageSlug", s);
2126
+ },
2127
+ isHomePage: r.draft.isHomePage,
2128
+ setIsHomePage: (s) => r.updateField("isHomePage", s),
2129
+ is404Page: r.draft.is404Page,
2130
+ setIs404Page: (s) => r.updateField("is404Page", s),
2131
+ allowCustom404Page: r.allowCustom404Page,
2132
+ pageImage: r.draft.pageImage,
2133
+ setPageImage: (s) => r.updateField("pageImage", s),
2134
+ showDeleteConfirm: p,
2135
+ setShowDeleteConfirm: u,
2136
+ onDeletePage: () => {
2137
+ if (r.pageId) {
2138
+ try {
2139
+ t.delete(r.pageId);
2140
+ } catch {
2141
+ }
2142
+ window.dispatchEvent(
2143
+ new CustomEvent("pagehub:page-deleted", { detail: { pageId: r.pageId } })
2144
+ ), h();
2145
+ }
2146
+ }
2147
+ }
2148
+ )
2149
+ },
2150
+ {
2151
+ key: "seo",
2152
+ label: "SEO",
2153
+ order: 200,
2154
+ icon: /* @__PURE__ */ e(Ne, {}),
2155
+ render: (r) => /* @__PURE__ */ e(
2156
+ Jt,
2157
+ {
2158
+ inputClass: r.inputClass,
2159
+ pageTitle: r.draft.pageTitle,
2160
+ setPageTitle: (s) => r.updateField("pageTitle", s),
2161
+ pageDescription: r.draft.pageDescription,
2162
+ setPageDescription: (s) => r.updateField("pageDescription", s),
2163
+ pageKeywords: r.draft.pageKeywords,
2164
+ setPageKeywords: (s) => r.updateField("pageKeywords", s),
2165
+ pageAuthor: r.draft.pageAuthor,
2166
+ setPageAuthor: (s) => r.updateField("pageAuthor", s)
2167
+ }
2168
+ )
2169
+ },
2170
+ {
2171
+ key: "open-graph",
2172
+ label: "Open Graph",
2173
+ order: 210,
2174
+ icon: /* @__PURE__ */ e(ye, {}),
2175
+ render: (r) => /* @__PURE__ */ e(
2176
+ At,
2177
+ {
2178
+ inputClass: r.inputClass,
2179
+ selectClass: r.selectClass,
2180
+ ogTitle: r.draft.ogTitle,
2181
+ setOgTitle: (s) => r.updateField("ogTitle", s),
2182
+ ogDescription: r.draft.ogDescription,
2183
+ setOgDescription: (s) => r.updateField("ogDescription", s),
2184
+ ogImage: r.draft.ogImage,
2185
+ setOgImage: (s) => r.updateField("ogImage", s),
2186
+ ogType: r.draft.ogType,
2187
+ setOgType: (s) => r.updateField("ogType", s)
2188
+ }
2189
+ )
2190
+ },
2191
+ {
2192
+ key: "twitter",
2193
+ label: "Twitter / X",
2194
+ order: 220,
2195
+ icon: /* @__PURE__ */ e(Je, {}),
2196
+ render: (r) => /* @__PURE__ */ e(
2197
+ Kt,
2198
+ {
2199
+ inputClass: r.inputClass,
2200
+ selectClass: r.selectClass,
2201
+ twitterCard: r.draft.twitterCard,
2202
+ setTwitterCard: (s) => r.updateField("twitterCard", s),
2203
+ twitterSite: r.draft.twitterSite,
2204
+ setTwitterSite: (s) => r.updateField("twitterSite", s),
2205
+ twitterCreator: r.draft.twitterCreator,
2206
+ setTwitterCreator: (s) => r.updateField("twitterCreator", s)
2207
+ }
2208
+ )
2209
+ },
2210
+ {
2211
+ key: "advanced",
2212
+ label: "Advanced",
2213
+ order: 300,
2214
+ icon: /* @__PURE__ */ e(We, {}),
2215
+ render: (r) => /* @__PURE__ */ e(
2216
+ xt,
2217
+ {
2218
+ inputClass: r.inputClass,
2219
+ canonicalUrl: r.draft.canonicalUrl,
2220
+ setCanonicalUrl: (s) => r.updateField("canonicalUrl", s),
2221
+ bodyClass: r.draft.bodyClass,
2222
+ setBodyClass: (s) => r.updateField("bodyClass", s),
2223
+ pagePassword: r.draft.pagePassword,
2224
+ setPagePassword: (s) => r.updateField("pagePassword", s),
2225
+ hideHeader: !!r.draft.hideHeader,
2226
+ setHideHeader: (s) => r.updateField("hideHeader", s),
2227
+ hideFooter: !!r.draft.hideFooter,
2228
+ setHideFooter: (s) => r.updateField("hideFooter", s),
2229
+ hideChrome: !!r.draft.hideChrome,
2230
+ setHideChrome: (s) => r.updateField("hideChrome", s)
2231
+ }
2232
+ )
2233
+ },
2234
+ {
2235
+ key: "head-code",
2236
+ label: "Custom code",
2237
+ order: 310,
2238
+ icon: /* @__PURE__ */ e(te, {}),
2239
+ render: (r) => /* @__PURE__ */ e(
2240
+ Ft,
2241
+ {
2242
+ headCode: r.draft.headCode,
2243
+ setHeadCode: (s) => r.updateField("headCode", s)
2244
+ }
2245
+ )
2246
+ },
2247
+ {
2248
+ key: "schema",
2249
+ label: "Schema",
2250
+ order: 320,
2251
+ icon: /* @__PURE__ */ e(Ke, {}),
2252
+ render: (r) => /* @__PURE__ */ e(
2253
+ Gt,
2254
+ {
2255
+ schema: Array.isArray(r.draft.schema) ? r.draft.schema : [],
2256
+ setSchema: (s) => r.updateField("schema", s),
2257
+ inputClass: r.inputClass
2258
+ }
2259
+ )
2260
+ },
2261
+ {
2262
+ key: "theme",
2263
+ label: "Theme",
2264
+ order: 330,
2265
+ icon: /* @__PURE__ */ e(Qe, {}),
2266
+ render: (r) => /* @__PURE__ */ e(
2267
+ Wt,
2268
+ {
2269
+ inputClass: r.inputClass,
2270
+ themeOverrides: r.draft.themeOverrides,
2271
+ setThemeOverrides: (s) => r.updateField("themeOverrides", s)
2272
+ }
2273
+ )
2274
+ },
2275
+ {
2276
+ key: "access",
2277
+ label: "Access",
2278
+ order: 400,
2279
+ icon: /* @__PURE__ */ e(Xe, {}),
2280
+ render: (r) => {
2281
+ const g = Ye(a).filter((d) => d !== r.pageId).map((d) => {
2282
+ var f, b;
2283
+ const m = a.node(d).get();
2284
+ return { id: d, name: ((b = (f = m == null ? void 0 : m.data) == null ? void 0 : f.custom) == null ? void 0 : b.displayName) || d };
2285
+ });
2286
+ return /* @__PURE__ */ e(
2287
+ kt,
2288
+ {
2289
+ inputClass: r.inputClass,
2290
+ selectClass: r.selectClass,
2291
+ conditionGroups: r.draft.conditionGroups || [],
2292
+ setConditionGroups: (d) => r.updateField("conditionGroups", d),
2293
+ pageConditionFailAction: r.draft.pageConditionFailAction || "",
2294
+ setPageConditionFailAction: (d) => r.updateField("pageConditionFailAction", d),
2295
+ pageConditionRedirectUrl: r.draft.pageConditionRedirectUrl || "",
2296
+ setPageConditionRedirectUrl: (d) => r.updateField("pageConditionRedirectUrl", d),
2297
+ pageConditionFallbackPageId: r.draft.pageConditionFallbackPageId || "",
2298
+ setPageConditionFallbackPageId: (d) => r.updateField("pageConditionFallbackPageId", d),
2299
+ pages: g
2300
+ }
2301
+ );
2302
+ }
2303
+ }
2304
+ ],
2305
+ // eslint-disable-next-line react-hooks/exhaustive-deps
2306
+ [t, n, h, l, p]
2307
+ );
2308
+ }
2309
+ function ge(t) {
2310
+ return !!t && typeof t.then == "function";
2311
+ }
2312
+ function Yt({
2313
+ isOpen: t,
2314
+ loadDraft: a,
2315
+ getDraftSignature: n,
2316
+ commitDraft: l,
2317
+ debounceMs: o = 350,
2318
+ reloadKey: i
2319
+ }) {
2320
+ const [p, u] = P(void 0), [h, r] = P(!0), s = O(void 0), g = O(""), d = O(() => {
2321
+ }), m = O(null), f = O(a), b = O(n), S = O(l);
2322
+ R(() => {
2323
+ f.current = a;
2324
+ }, [a]), R(() => {
2325
+ b.current = n;
2326
+ }, [n]), R(() => {
2327
+ S.current = l;
2328
+ }, [l]);
2329
+ const w = H(() => {
2330
+ const y = s.current;
2331
+ if (y === void 0) return;
2332
+ const T = b.current(y);
2333
+ if (T === g.current) return;
2334
+ const C = S.current(y);
2335
+ g.current = T, ge(C) && C.catch((U) => X.error("Error saving settings:", U));
2336
+ }, []), F = E(() => Ze(w, o), [w, o]);
2337
+ R(() => {
2338
+ d.current = w;
2339
+ }, [w]), R(() => (m.current = F, () => {
2340
+ var y;
2341
+ return (y = m.current) == null ? void 0 : y.cancel();
2342
+ }), [F]), R(() => {
2343
+ s.current = p;
2344
+ }, [p]);
2345
+ const k = H((y) => {
2346
+ s.current = y, u(y), g.current = b.current(y), r(!1);
2347
+ }, []);
2348
+ R(() => {
2349
+ if (!t) return;
2350
+ let y = !1;
2351
+ r(!0);
2352
+ const T = f.current();
2353
+ return ge(T) ? T.then((C) => {
2354
+ y || k(C);
2355
+ }).catch((C) => {
2356
+ X.error("Error loading settings:", C), y || r(!1);
2357
+ }) : y || k(T), () => {
2358
+ var C;
2359
+ y = !0, (C = m.current) == null || C.cancel(), d.current();
2360
+ };
2361
+ }, [t, i, k]), R(() => {
2362
+ var y;
2363
+ !t || h || (y = m.current) == null || y.call(m);
2364
+ }, [p, t, h]);
2365
+ const x = H(() => {
2366
+ var y;
2367
+ (y = m.current) == null || y.cancel(), d.current();
2368
+ }, []), v = H(() => {
2369
+ var y;
2370
+ (y = m.current) == null || y.cancel();
2371
+ }, []), A = H(
2372
+ (y, T) => {
2373
+ u((C) => {
2374
+ const U = typeof T == "function" ? T(C[y]) : T, _ = { ...C, [y]: U };
2375
+ return s.current = _, _;
2376
+ });
2377
+ },
2378
+ []
2379
+ );
2380
+ return {
2381
+ draft: p,
2382
+ setDraft: u,
2383
+ updateField: A,
2384
+ loading: h,
2385
+ requestSave: () => {
2386
+ var y;
2387
+ return (y = m.current) == null ? void 0 : y.call(m);
2388
+ },
2389
+ flushSave: x,
2390
+ cancelSave: v
2391
+ };
2392
+ }
2393
+ const G = [
2394
+ // Basic
2395
+ { key: "pageSlug", defaultValue: "" },
2396
+ { key: "pageImage", defaultValue: "" },
2397
+ // SEO — nested under seo.* on the node
2398
+ { key: "pageTitle", nodePath: "seo.title", defaultValue: "" },
2399
+ { key: "pageDescription", nodePath: "seo.description", defaultValue: "" },
2400
+ { key: "pageKeywords", nodePath: "seo.keywords", defaultValue: "" },
2401
+ { key: "pageAuthor", nodePath: "seo.author", defaultValue: "" },
2402
+ { key: "ogTitle", nodePath: "seo.ogTitle", defaultValue: "" },
2403
+ { key: "ogDescription", nodePath: "seo.ogDescription", defaultValue: "" },
2404
+ { key: "ogImage", nodePath: "seo.ogImage", defaultValue: "" },
2405
+ { key: "ogType", nodePath: "seo.ogType", defaultValue: "website" },
2406
+ { key: "twitterCard", nodePath: "seo.twitterCard", defaultValue: "summary_large_image" },
2407
+ { key: "twitterSite", nodePath: "seo.twitterSite", defaultValue: "" },
2408
+ { key: "twitterCreator", nodePath: "seo.twitterCreator", defaultValue: "" },
2409
+ // Advanced
2410
+ { key: "canonicalUrl", nodePath: "seo.canonicalUrl", defaultValue: "" },
2411
+ { key: "headCode", defaultValue: "" },
2412
+ { key: "bodyClass", defaultValue: "" },
2413
+ { key: "hideHeader", defaultValue: !1 },
2414
+ { key: "hideFooter", defaultValue: !1 },
2415
+ { key: "hideChrome", defaultValue: !1 },
2416
+ { key: "jsonLd", nodePath: "seo.jsonLd", defaultValue: "" },
2417
+ { key: "schema", nodePath: "seo.schema", defaultValue: [] },
2418
+ { key: "pagePassword", defaultValue: "" },
2419
+ { key: "themeOverrides", defaultValue: [] },
2420
+ // Access Control (conditionGroups is the same prop used by node-level conditions)
2421
+ { key: "conditionGroups", defaultValue: [] },
2422
+ { key: "pageConditionFailAction", defaultValue: "" },
2423
+ { key: "pageConditionRedirectUrl", defaultValue: "" },
2424
+ { key: "pageConditionFallbackPageId", defaultValue: "" }
2425
+ ];
2426
+ G.map((t) => t.key);
2427
+ function Xt(t, a) {
2428
+ return a.includes(".") ? a.split(".").reduce((n, l) => n == null ? n : n[l], t) : t[a];
2429
+ }
2430
+ function Zt(t, a, n) {
2431
+ if (!a.includes(".")) {
2432
+ t[a] = n;
2433
+ return;
2434
+ }
2435
+ const l = a.split(".");
2436
+ let o = t;
2437
+ for (let i = 0; i < l.length - 1; i++) {
2438
+ const p = l[i];
2439
+ (o[p] == null || typeof o[p] != "object") && (o[p] = {}), o = o[p];
2440
+ }
2441
+ o[l[l.length - 1]] = n;
2442
+ }
2443
+ function ea() {
2444
+ const t = {};
2445
+ for (const a of G) t[a.key] = a.defaultValue;
2446
+ return t;
2447
+ }
2448
+ function ta(t) {
2449
+ const a = {};
2450
+ for (const n of G) {
2451
+ const l = n.nodePath || n.key, o = Xt(t, l);
2452
+ a[n.key] = o !== void 0 ? o : n.defaultValue;
2453
+ }
2454
+ return a;
2455
+ }
2456
+ function Te(t, a) {
2457
+ for (const n of G) {
2458
+ const l = a[n.key], o = n.nodePath || n.key;
2459
+ Zt(t, o, l), n.nodePath && n.nodePath !== n.key && n.key in t && delete t[n.key];
2460
+ }
2461
+ }
2462
+ function Y() {
2463
+ return {
2464
+ _remote: !1,
2465
+ pageName: "",
2466
+ isHomePage: !1,
2467
+ is404Page: !1,
2468
+ ...ea()
2469
+ };
2470
+ }
2471
+ function be(t, a, n, l, o, i) {
2472
+ return {
2473
+ _remote: i,
2474
+ pageName: t || "Untitled Page",
2475
+ isHomePage: !!a,
2476
+ is404Page: o ? !!n : !1,
2477
+ ...ta(l)
2478
+ };
2479
+ }
2480
+ function aa(t, a) {
2481
+ const n = {};
2482
+ return Te(n, t), {
2483
+ displayName: t.pageName,
2484
+ isHomePage: t.isHomePage,
2485
+ is404Page: a && t.is404Page,
2486
+ props: n
2487
+ };
2488
+ }
2489
+ function na(t) {
2490
+ const { _remote: a, ...n } = t;
2491
+ return JSON.stringify(n);
2492
+ }
2493
+ function ra({
2494
+ isOpen: t,
2495
+ pageId: a,
2496
+ allowCustom404Page: n,
2497
+ query: l,
2498
+ actions: o,
2499
+ queryRef: i,
2500
+ configRef: p,
2501
+ allTabs: u,
2502
+ applySlugDefaults: h
2503
+ }) {
2504
+ return Yt({
2505
+ isOpen: t,
2506
+ loadDraft: () => {
2507
+ var s, g;
2508
+ if (!a) return Y();
2509
+ if (et().has(a)) {
2510
+ const d = i.current.node(a).get(), m = ((s = d == null ? void 0 : d.data) == null ? void 0 : s.props) || {}, f = ((g = d == null ? void 0 : d.data) == null ? void 0 : g.custom) || {}, b = be(
2511
+ f.displayName,
2512
+ m.isHomePage,
2513
+ m.is404Page,
2514
+ m,
2515
+ n,
2516
+ !1
2517
+ );
2518
+ return h(b), b;
2519
+ }
2520
+ const { fetchPageSettings: r } = p.current.callbacks;
2521
+ return r ? r(a).then((d) => {
2522
+ if (d) {
2523
+ const m = be(
2524
+ d.displayName,
2525
+ d.isHomePage,
2526
+ d.is404Page,
2527
+ d.props || {},
2528
+ n,
2529
+ !0
2530
+ );
2531
+ return h(m), m;
2532
+ }
2533
+ return Y();
2534
+ }) : Y();
2535
+ },
2536
+ getDraftSignature: na,
2537
+ commitDraft: (r) => {
2538
+ var s, g, d, m, f, b, S, w;
2539
+ if (a) {
2540
+ if (r._remote) {
2541
+ const { savePageSettings: F } = p.current.callbacks;
2542
+ return F ? F(a, aa(r, n)) : void 0;
2543
+ }
2544
+ try {
2545
+ const F = n && r.is404Page;
2546
+ if (F) {
2547
+ const k = l.node(ce).get();
2548
+ for (const x of ((s = k == null ? void 0 : k.data) == null ? void 0 : s.nodes) || []) {
2549
+ if (x === a) continue;
2550
+ const v = l.node(x).get();
2551
+ ((d = (g = v == null ? void 0 : v.data) == null ? void 0 : g.props) == null ? void 0 : d.type) === "page" && ((f = (m = v == null ? void 0 : v.data) == null ? void 0 : m.props) != null && f.is404Page) && o.setProp(x, (A) => {
2552
+ A.is404Page = !1;
2553
+ });
2554
+ }
2555
+ }
2556
+ o.setCustom(a, (k) => {
2557
+ k.displayName = r.pageName;
2558
+ }), o.setProp(a, (k) => {
2559
+ var x;
2560
+ k.isHomePage = r.isHomePage, k.is404Page = F, Te(k, r);
2561
+ for (const v of u)
2562
+ (x = v.onSave) == null || x.call(v, {
2563
+ query: l,
2564
+ actions: o,
2565
+ draft: r,
2566
+ pageId: a,
2567
+ allowCustom404Page: n,
2568
+ setProp: (A) => A(k)
2569
+ });
2570
+ });
2571
+ try {
2572
+ const k = l.node(ce).get(), x = !!r.hideChrome;
2573
+ for (const v of ((b = k == null ? void 0 : k.data) == null ? void 0 : b.nodes) || []) {
2574
+ const A = l.node(v).get(), y = (w = (S = A == null ? void 0 : A.data) == null ? void 0 : S.props) == null ? void 0 : w.type;
2575
+ y !== "page" && (x ? o.setHidden(v, !0) : y === "header" ? o.setHidden(v, !!r.hideHeader) : y === "footer" ? o.setHidden(v, !!r.hideFooter) : o.setHidden(v, !1));
2576
+ }
2577
+ } catch {
2578
+ }
2579
+ } catch (F) {
2580
+ X.error("Error saving page settings:", F);
2581
+ }
2582
+ }
2583
+ },
2584
+ debounceMs: 350,
2585
+ reloadKey: a
2586
+ });
2587
+ }
2588
+ function ya({
2589
+ isOpen: t,
2590
+ onClose: a,
2591
+ pageId: n,
2592
+ extraTabs: l = []
2593
+ }) {
2594
+ const { actions: o, query: i } = ee(), p = O(i), { config: u, features: h } = tt(), r = O(u), s = !!h.custom404Page, d = !at(), m = typeof window < "u" ? window.innerHeight : 800, f = Math.max(520, Math.min(680, Math.round(m * 0.72))), b = Math.max(600, Math.min(760, Math.round(m * 0.82))), [S, w] = P("basic"), [F, k] = P(""), [x, v] = P(!0), [A, y] = P(!1);
2595
+ R(() => {
2596
+ p.current = i;
2597
+ }, [i]), R(() => {
2598
+ r.current = u;
2599
+ }, [u]);
2600
+ const T = H((D) => {
2601
+ const oe = D.pageSlug;
2602
+ k(oe || fe(D.pageName || "untitled-page", "-")), v(!oe), y(!1);
2603
+ }, []), C = Qt({
2604
+ actions: o,
2605
+ query: i,
2606
+ autoSlug: x,
2607
+ pageSlug: F,
2608
+ setPageSlug: k,
2609
+ setAutoSlug: v,
2610
+ showDeleteConfirm: A,
2611
+ setShowDeleteConfirm: y,
2612
+ onClose: a
2613
+ }), U = E(() => gt(l), [l]), _ = E(
2614
+ () => ut(C, U),
2615
+ [C, U]
2616
+ ), { draft: ne, setDraft: re, updateField: le, loading: Pe, requestSave: se, flushSave: M } = ra({
2617
+ isOpen: t,
2618
+ pageId: n,
2619
+ allowCustom404Page: s,
2620
+ query: i,
2621
+ actions: o,
2622
+ queryRef: p,
2623
+ configRef: r,
2624
+ allTabs: _,
2625
+ applySlugDefaults: T
2626
+ }), Fe = mt, Ae = ht, J = E(
2627
+ () => ({
2628
+ inputClass: Fe,
2629
+ selectClass: Ae,
2630
+ query: i,
2631
+ actions: o,
2632
+ draft: ne,
2633
+ setDraft: re,
2634
+ updateField: le,
2635
+ requestSave: se,
2636
+ flushSave: M,
2637
+ pageId: n,
2638
+ allowCustom404Page: s
2639
+ }),
2640
+ [
2641
+ o,
2642
+ s,
2643
+ ne,
2644
+ M,
2645
+ n,
2646
+ i,
2647
+ se,
2648
+ re,
2649
+ le
2650
+ ]
2651
+ ), W = E(() => pt(_, J), [_, J]), ie = W.find((D) => D.key === S) ?? W[0], Le = H(() => {
2652
+ M(), a();
2653
+ }, [M, a]);
2654
+ return !t || !n ? null : /* @__PURE__ */ e(
2655
+ rt,
2656
+ {
2657
+ isOpen: t,
2658
+ onClose: Le,
2659
+ title: "Page Settings",
2660
+ storageKey: "page-settings",
2661
+ defaultWidth: 920,
2662
+ defaultHeight: f,
2663
+ minWidth: 640,
2664
+ maxWidth: 1280,
2665
+ minHeight: 400,
2666
+ maxHeight: b,
2667
+ dockToEdge: d ? "right" : "left",
2668
+ zIndex: we,
2669
+ tabs: W.map((D) => ({ key: D.key, label: D.label, icon: D.icon })),
2670
+ activeTab: S,
2671
+ setActiveTab: w,
2672
+ children: Pe ? /* @__PURE__ */ e("div", { className: "flex h-full items-center justify-center", children: /* @__PURE__ */ e("span", { className: "loading loading-spinner loading-md text-primary" }) }) : ie ? ie.render(J) : null
2673
+ }
2674
+ );
2675
+ }
2676
+ export {
2677
+ ya as PageSettingsModal
2678
+ };